20 #include "sortlist_type.h" |
20 #include "sortlist_type.h" |
21 #include "widgets/dropdown_func.h" |
21 #include "widgets/dropdown_func.h" |
22 |
22 |
23 #include "table/strings.h" |
23 #include "table/strings.h" |
24 |
24 |
25 /* Save the sorting during runtime */ |
|
26 static Listing _bridge_sorting = {false, 0}; |
|
27 |
|
28 /** |
25 /** |
29 * Carriage for the data we need if we want to build a bridge |
26 * Carriage for the data we need if we want to build a bridge |
30 */ |
27 */ |
31 struct BuildBridgeData { |
28 struct BuildBridgeData { |
32 BridgeType index; |
29 BridgeType index; |
33 const BridgeSpec *spec; |
30 const BridgeSpec *spec; |
34 Money cost; |
31 Money cost; |
35 }; |
32 }; |
36 |
33 |
37 typedef GUIList<BuildBridgeData> GUIBridgeList; |
34 typedef GUIList<BuildBridgeData> GUIBridgeList; |
38 |
|
39 /** Sort the bridges by their index */ |
|
40 static int CDECL BridgeIndexSorter(const void *a, const void *b) |
|
41 { |
|
42 const BuildBridgeData* ba = (BuildBridgeData*)a; |
|
43 const BuildBridgeData* bb = (BuildBridgeData*)b; |
|
44 int r = ba->index - bb->index; |
|
45 |
|
46 return (_bridge_sorting.order) ? -r : r; |
|
47 } |
|
48 |
|
49 /** Sort the bridges by their price */ |
|
50 static int CDECL BridgePriceSorter(const void *a, const void *b) |
|
51 { |
|
52 const BuildBridgeData* ba = (BuildBridgeData*)a; |
|
53 const BuildBridgeData* bb = (BuildBridgeData*)b; |
|
54 int r = ba->cost - bb->cost; |
|
55 |
|
56 return (_bridge_sorting.order) ? -r : r; |
|
57 } |
|
58 |
|
59 /** Sort the bridges by their maximum speed */ |
|
60 static int CDECL BridgeSpeedSorter(const void *a, const void *b) |
|
61 { |
|
62 const BuildBridgeData* ba = (BuildBridgeData*)a; |
|
63 const BuildBridgeData* bb = (BuildBridgeData*)b; |
|
64 int r = ba->spec->speed - bb->spec->speed; |
|
65 |
|
66 return (_bridge_sorting.order) ? -r : r; |
|
67 } |
|
68 |
|
69 typedef int CDECL BridgeSortListingTypeFunction(const void*, const void*); |
|
70 |
|
71 /* Availible bridge sorting functions */ |
|
72 static BridgeSortListingTypeFunction* const _bridge_sorter[] = { |
|
73 &BridgeIndexSorter, |
|
74 &BridgePriceSorter, |
|
75 &BridgeSpeedSorter |
|
76 }; |
|
77 |
|
78 /* Names of the sorting functions */ |
|
79 static const StringID _bridge_sort_listing[] = { |
|
80 STR_SORT_BY_NUMBER, |
|
81 STR_ENGINE_SORT_COST, |
|
82 STR_SORT_BY_MAX_SPEED, |
|
83 INVALID_STRING_ID |
|
84 }; |
|
85 |
35 |
86 /** |
36 /** |
87 * Callback executed after a build Bridge CMD has been called |
37 * Callback executed after a build Bridge CMD has been called |
88 * |
38 * |
89 * @param scucess True if the build succeded |
39 * @param scucess True if the build succeded |
107 BBSW_RESIZEBOX |
57 BBSW_RESIZEBOX |
108 }; |
58 }; |
109 |
59 |
110 class BuildBridgeWindow : public Window { |
60 class BuildBridgeWindow : public Window { |
111 private: |
61 private: |
112 /* The last size of the build bridge window |
62 /* Runtime saved values */ |
113 * is saved during runtime */ |
|
114 static uint last_size; |
63 static uint last_size; |
115 |
64 static Listing last_sorting; |
|
65 |
|
66 /* Constants for sorting the bridges */ |
|
67 static const StringID sorter_names[]; |
|
68 static const GUIBridgeList::SortFunction *const sorter_funcs[]; |
|
69 |
|
70 /* Internal variables */ |
116 TileIndex start_tile; |
71 TileIndex start_tile; |
117 TileIndex end_tile; |
72 TileIndex end_tile; |
118 uint32 type; |
73 uint32 type; |
119 GUIBridgeList *bridges; |
74 GUIBridgeList *bridges; |
120 |
75 |
|
76 /** Sort the bridges by their index */ |
|
77 static int BridgeIndexSorter(const BuildBridgeData *a, const BuildBridgeData *b) |
|
78 { |
|
79 return a->index - b->index; |
|
80 } |
|
81 |
|
82 /** Sort the bridges by their price */ |
|
83 static int BridgePriceSorter(const BuildBridgeData *a, const BuildBridgeData *b) |
|
84 { |
|
85 return a->cost - b->cost; |
|
86 } |
|
87 |
|
88 /** Sort the bridges by their maximum speed */ |
|
89 static int BridgeSpeedSorter(const BuildBridgeData *a, const BuildBridgeData *b) |
|
90 { |
|
91 return a->spec->speed - b->spec->speed; |
|
92 } |
|
93 |
121 void BuildBridge(uint8 i) |
94 void BuildBridge(uint8 i) |
122 { |
95 { |
123 DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index, |
96 DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index, |
124 CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE)); |
97 CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE)); |
125 } |
98 } |
126 |
99 |
127 /** Sort the builable bridges */ |
100 /** Sort the builable bridges */ |
128 void SortBridgeList() |
101 void SortBridgeList() |
129 { |
102 { |
130 /* Skip sorting if resort bit is not set */ |
103 this->bridges->Sort(); |
131 if (!(bridges->flags & VL_RESORT)) return; |
|
132 |
|
133 qsort(this->bridges->Begin(), this->bridges->Length(), sizeof(this->bridges->Begin()), _bridge_sorter[_bridge_sorting.criteria]); |
|
134 |
104 |
135 /* Display the current sort variant */ |
105 /* Display the current sort variant */ |
136 this->widget[BBSW_DROPDOWN_CRITERIA].data = _bridge_sort_listing[this->bridges->sort_type]; |
106 this->widget[BBSW_DROPDOWN_CRITERIA].data = this->sorter_names[this->bridges->SortType()]; |
137 |
|
138 bridges->flags &= ~VL_RESORT; |
|
139 |
107 |
140 /* Set the modified widgets dirty */ |
108 /* Set the modified widgets dirty */ |
141 this->InvalidateWidget(BBSW_DROPDOWN_CRITERIA); |
109 this->InvalidateWidget(BBSW_DROPDOWN_CRITERIA); |
142 this->InvalidateWidget(BBSW_BRIDGE_LIST); |
110 this->InvalidateWidget(BBSW_BRIDGE_LIST); |
143 } |
111 } |
147 start_tile(start), |
115 start_tile(start), |
148 end_tile(end), |
116 end_tile(end), |
149 type(br_type), |
117 type(br_type), |
150 bridges(bl) |
118 bridges(bl) |
151 { |
119 { |
|
120 this->bridges->SetListing(this->last_sorting); |
|
121 this->bridges->SetSortFuncs(this->sorter_funcs); |
152 this->SortBridgeList(); |
122 this->SortBridgeList(); |
153 |
123 |
154 /* Change the data, or the caption of the gui. Set it to road or rail, accordingly */ |
124 /* Change the data, or the caption of the gui. Set it to road or rail, accordingly */ |
155 this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE; |
125 this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE; |
156 |
126 |
222 } |
194 } |
223 } |
195 } |
224 } break; |
196 } break; |
225 |
197 |
226 case BBSW_DROPDOWN_ORDER: |
198 case BBSW_DROPDOWN_ORDER: |
227 /* Revers the sort order */ |
199 this->bridges->ToggleSortOrder(); |
228 this->bridges->flags ^= VL_DESC; |
200 this->SetDirty(); |
229 _bridge_sorting.order = !_bridge_sorting.order; |
|
230 |
|
231 this->bridges->flags |= VL_RESORT; |
|
232 this->SortBridgeList(); |
|
233 break; |
201 break; |
234 |
202 |
235 case BBSW_DROPDOWN_CRITERIA: |
203 case BBSW_DROPDOWN_CRITERIA: |
236 ShowDropDownMenu(this, _bridge_sort_listing, bridges->sort_type, BBSW_DROPDOWN_CRITERIA, 0, 0); |
204 ShowDropDownMenu(this, this->sorter_names, this->bridges->SortType(), BBSW_DROPDOWN_CRITERIA, 0, 0); |
237 break; |
205 break; |
238 } |
206 } |
239 } |
207 } |
240 |
208 |
241 virtual void OnDropdownSelect(int widget, int index) |
209 virtual void OnDropdownSelect(int widget, int index) |
242 { |
210 { |
243 if (widget == BBSW_DROPDOWN_CRITERIA && this->bridges->sort_type != index) { |
211 if (widget == BBSW_DROPDOWN_CRITERIA && this->bridges->SortType() != index) { |
244 this->bridges->sort_type = index; |
212 this->bridges->SetSortType(index); |
245 _bridge_sorting.criteria = index; |
213 |
246 |
|
247 this->bridges->flags |= VL_RESORT; |
|
248 this->SortBridgeList(); |
214 this->SortBridgeList(); |
249 } |
215 } |
250 } |
216 } |
251 |
217 |
252 virtual void OnResize(Point new_size, Point delta) |
218 virtual void OnResize(Point new_size, Point delta) |
259 } |
225 } |
260 }; |
226 }; |
261 |
227 |
262 /* Set the default size of the Build Bridge Window */ |
228 /* Set the default size of the Build Bridge Window */ |
263 uint BuildBridgeWindow::last_size = 4; |
229 uint BuildBridgeWindow::last_size = 4; |
|
230 /* Set the default sorting for the bridges */ |
|
231 Listing BuildBridgeWindow::last_sorting = {false, 0}; |
|
232 |
|
233 /* Availible bridge sorting functions */ |
|
234 GUIBridgeList::SortFunction* const BuildBridgeWindow::sorter_funcs[] = { |
|
235 &BridgeIndexSorter, |
|
236 &BridgePriceSorter, |
|
237 &BridgeSpeedSorter |
|
238 }; |
|
239 |
|
240 /* Names of the sorting functions */ |
|
241 const StringID BuildBridgeWindow::sorter_names[] = { |
|
242 STR_SORT_BY_NUMBER, |
|
243 STR_ENGINE_SORT_COST, |
|
244 STR_SORT_BY_MAX_SPEED, |
|
245 INVALID_STRING_ID |
|
246 }; |
264 |
247 |
265 /* Widget definition for the rail bridge selection window */ |
248 /* Widget definition for the rail bridge selection window */ |
266 static const Widget _build_bridge_widgets[] = { |
249 static const Widget _build_bridge_widgets[] = { |
267 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // BBSW_CLOSEBOX |
250 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // BBSW_CLOSEBOX |
268 { WWT_CAPTION, RESIZE_NONE, 7, 11, 199, 0, 13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS}, // BBSW_CAPTION |
251 { WWT_CAPTION, RESIZE_NONE, 7, 11, 199, 0, 13, STR_100D_SELECT_RAIL_BRIDGE, STR_018C_WINDOW_TITLE_DRAG_THIS}, // BBSW_CAPTION |