47 } |
47 } |
48 } |
48 } |
49 |
49 |
50 struct TimetableWindow : Window { |
50 struct TimetableWindow : Window { |
51 int sel_index; |
51 int sel_index; |
|
52 const Vehicle *vehicle; |
52 |
53 |
53 TimetableWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number) |
54 TimetableWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number) |
54 { |
55 { |
55 this->caption_color = GetVehicle(window_number)->owner; |
56 this->vehicle = GetVehicle(window_number); |
|
57 this->caption_color = this->vehicle->owner; |
56 this->vscroll.cap = 8; |
58 this->vscroll.cap = 8; |
57 this->resize.step_height = 10; |
59 this->resize.step_height = 10; |
58 this->sel_index = -1; |
60 this->sel_index = -1; |
59 |
61 |
60 this->FindWindowPlacementAndResize(desc); |
62 this->FindWindowPlacementAndResize(desc); |
74 sel += this->vscroll.pos; |
76 sel += this->vscroll.pos; |
75 |
77 |
76 return (sel < v->num_orders * 2 && sel >= 0) ? sel : INVALID_ORDER; |
78 return (sel < v->num_orders * 2 && sel >= 0) ? sel : INVALID_ORDER; |
77 } |
79 } |
78 |
80 |
79 void OnPaint() |
81 virtual void OnInvalidateData(int data) |
80 { |
82 { |
81 const Vehicle *v = GetVehicle(this->window_number); |
83 switch (data) { |
|
84 case 0: |
|
85 /* Autoreplace replaced the vehicle */ |
|
86 this->vehicle = GetVehicle(this->window_number); |
|
87 break; |
|
88 |
|
89 case -1: |
|
90 /* Removed / replaced all orders (after deleting / sharing) */ |
|
91 if (this->sel_index == -1) break; |
|
92 |
|
93 this->DeleteChildWindows(); |
|
94 this->sel_index = -1; |
|
95 break; |
|
96 |
|
97 default: { |
|
98 /* Moving an order. If one of these is INVALID_VEH_ORDER_ID, then |
|
99 * the order is being created / removed */ |
|
100 if (this->sel_index == -1) break; |
|
101 |
|
102 VehicleOrderID from = GB(data, 0, 8); |
|
103 VehicleOrderID to = GB(data, 8, 8); |
|
104 |
|
105 if (from == to) break; // no need to change anything |
|
106 |
|
107 /* if from == INVALID_VEH_ORDER_ID, one order was added; if to == INVALID_VEH_ORDER_ID, one order was removed */ |
|
108 uint old_num_orders = this->vehicle->num_orders - (uint)(from == INVALID_VEH_ORDER_ID) + (uint)(to == INVALID_VEH_ORDER_ID); |
|
109 |
|
110 VehicleOrderID selected_order = (this->sel_index + 1) / 2; |
|
111 if (selected_order == old_num_orders) selected_order = 0; // when last travel time is selected, it belongs to order 0 |
|
112 |
|
113 bool travel = HasBit(this->sel_index, 0); |
|
114 |
|
115 if (from != selected_order) { |
|
116 /* Moving from preceeding order? */ |
|
117 selected_order -= (int)(from <= selected_order); |
|
118 /* Moving to preceeding order? */ |
|
119 selected_order += (int)(to <= selected_order); |
|
120 } else { |
|
121 /* Now we are modifying the selected order */ |
|
122 if (to == INVALID_VEH_ORDER_ID) { |
|
123 /* Deleting selected order */ |
|
124 this->DeleteChildWindows(); |
|
125 this->sel_index = -1; |
|
126 break; |
|
127 } else { |
|
128 /* Moving selected order */ |
|
129 selected_order = to; |
|
130 } |
|
131 } |
|
132 |
|
133 /* recompute new sel_index */ |
|
134 this->sel_index = 2 * selected_order - (int)travel; |
|
135 /* travel time of first order needs special handling */ |
|
136 if (this->sel_index == -1) this->sel_index = this->vehicle->num_orders * 2 - 1; |
|
137 } break; |
|
138 } |
|
139 } |
|
140 |
|
141 |
|
142 virtual void OnPaint() |
|
143 { |
|
144 const Vehicle *v = this->vehicle; |
82 int selected = this->sel_index; |
145 int selected = this->sel_index; |
83 |
146 |
84 SetVScrollCount(this, v->num_orders * 2); |
147 SetVScrollCount(this, v->num_orders * 2); |
85 |
148 |
86 if (v->owner == _local_player) { |
149 if (v->owner == _local_player) { |
191 return v->index | (order_number << 16) | (is_journey << 24); |
254 return v->index | (order_number << 16) | (is_journey << 24); |
192 } |
255 } |
193 |
256 |
194 virtual void OnClick(Point pt, int widget) |
257 virtual void OnClick(Point pt, int widget) |
195 { |
258 { |
196 const Vehicle *v = GetVehicle(this->window_number); |
259 const Vehicle *v = this->vehicle; |
197 |
260 |
198 switch (widget) { |
261 switch (widget) { |
199 case TTV_ORDER_VIEW: /* Order view button */ |
262 case TTV_ORDER_VIEW: /* Order view button */ |
200 ShowOrdersWindow(v); |
263 ShowOrdersWindow(v); |
201 break; |
264 break; |
202 |
265 |
203 case TTV_TIMETABLE_PANEL: { /* Main panel. */ |
266 case TTV_TIMETABLE_PANEL: { /* Main panel. */ |
204 int selected = GetOrderFromTimetableWndPt(pt.y, v); |
267 int selected = GetOrderFromTimetableWndPt(pt.y, v); |
205 |
268 |
206 if (selected == INVALID_ORDER || selected == this->sel_index) { |
269 this->DeleteChildWindows(); |
207 /* Deselect clicked order */ |
270 this->sel_index = (selected == INVALID_ORDER || selected == this->sel_index) ? -1 : selected; |
208 this->sel_index = -1; |
|
209 } else { |
|
210 /* Select clicked order */ |
|
211 this->sel_index = selected; |
|
212 } |
|
213 } break; |
271 } break; |
214 |
272 |
215 case TTV_CHANGE_TIME: { /* "Wait For" button. */ |
273 case TTV_CHANGE_TIME: { /* "Wait For" button. */ |
216 int selected = this->sel_index; |
274 int selected = this->sel_index; |
217 VehicleOrderID real = (selected + 1) / 2; |
275 VehicleOrderID real = (selected + 1) / 2; |
253 |
311 |
254 virtual void OnQueryTextFinished(char *str) |
312 virtual void OnQueryTextFinished(char *str) |
255 { |
313 { |
256 if (str == NULL) return; |
314 if (str == NULL) return; |
257 |
315 |
258 const Vehicle *v = GetVehicle(this->window_number); |
316 const Vehicle *v = this->vehicle; |
259 |
317 |
260 uint32 p1 = PackTimetableArgs(v, this->sel_index); |
318 uint32 p1 = PackTimetableArgs(v, this->sel_index); |
261 |
319 |
262 uint64 time = StrEmpty(str) ? 0 : strtoul(str, NULL, 10); |
320 uint64 time = StrEmpty(str) ? 0 : strtoul(str, NULL, 10); |
263 if (!_settings_client.gui.timetable_in_ticks) time *= DAY_TICKS; |
321 if (!_settings_client.gui.timetable_in_ticks) time *= DAY_TICKS; |