1 // CoMET - The Crimson Fields Map Editing Tool
2 // Copyright (C) 2002-2007 Jens Granseuer
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18
19 ////////////////////////////////////////////////////////////////////////
20 // eventwindow.cpp
21 ///////////////////////////////////////////////////////////////////////
22
23 #include "eventwindow.h"
24 #include "extwindow.h"
25 #include "extwindow2.h"
26 #include "uiaux.h"
27
28 extern const char *player2_labels[];
29 extern const char *dir_labels[];
30 extern const char *size_labels[];
31 extern const char *xp_labels[];
32 static const char *uselect_labels[] = { "Single Unit", "Unit Type", 0 };
33
34 ////////////////////////////////////////////////////////////////////////
35 // NAME : EdEventGenericWindow::EdEventGenericWindow
36 // DESCRIPTION: This window allows modification of the fields common to
37 // all event types, and also offers links to event-specific
38 // options.
39 // PARAMETERS : event - event to edit
40 // mission - current mission
41 // view - pointer to the window's view
42 // RETURNS : -
43 ////////////////////////////////////////////////////////////////////////
44
EdEventGenericWindow(Event & event,Mission & mission,View * view)45 EdEventGenericWindow::EdEventGenericWindow( Event &event,
46 Mission &mission, View *view ) :
47 Window(WIN_CENTER, view), event(event), mission(mission) {
48 // calculate dimensions
49 SetSize( MIN(sfont->Width() * 35 + 20, view->Width()),
50 MIN(sfont->Height() * 12 + 125, view->Height()) );
51
52 unsigned short wdh = sfont->Height() + 8, wdx, wdy = 5;
53 Widget *wd;
54 char buf[48] = "";
55
56 wd = new NumberWidget( 0, sfont->Width() * 2 + 10, wdy,
57 sfont->Width() * 6, wdh, event.ID(),
58 0, 32767, WIDGET_STR_CONST|WIDGET_ALIGN_LEFT, "ID", this );
59
60 wdx = wd->LeftEdge() + wd->Width() + sfont->TextWidth("Player") + 10;
61
62 wd = new CheckboxWidget( B_ID_DISABLED,
63 w - 5 - DEFAULT_CBW_SIZE, wdy + (wdh - DEFAULT_CBW_SIZE)/2,
64 DEFAULT_CBW_SIZE, DEFAULT_CBW_SIZE, event.Flags() & EFLAG_DISABLED,
65 WIDGET_STYLE_GFX|WIDGET_STYLE_NOBORDER|WIDGET_ALIGN_LEFT,
66 "_Disabled", this );
67 wd->SetHook( this );
68
69 wd = new CycleWidget( B_ID_PLAYER, wdx, wdy,
70 wd->LeftEdge() - wdx - 15 - sfont->TextWidth("Disabled"), wdh,
71 0, "_Player", event.Player(), player2_labels, this );
72 wd->SetHook( this );
73
74 wdy += wd->Height() + 5;
75 wd = new ButtonWidget( B_ID_TITLE, 5, wdy,
76 sfont->Width() * 9 + 10, wdh, 0, "Msg _Title", this );
77 wd->SetHook( this );
78
79 wdx = wd->LeftEdge() + wd->Width() + 5;
80 e_title = new StringWidget( 0, wdx, wdy, w - wdx - 5, wdh,
81 (mission.GetMessage(event.Title()) ?
82 mission.GetMessage(event.Title()) : ""),
83 30, WIDGET_STR_CONST, NULL, this );
84
85 wdy += wd->Height() + 5;
86 wd = new ButtonWidget( B_ID_MSG, 5, wdy, w - 10, wdh,
87 0, "Set Event _Message", this );
88 wd->SetHook( this );
89
90 wdy += wd->Height() + 5;
91 e_msg = new TextScrollWidget( 0, 5, wdy, w - 10, sfont->Height() * 5,
92 (mission.GetMessage(event.Message()) ?
93 mission.GetMessage(event.Message()) : ""),
94 0, NULL, this );
95
96 wdy += e_msg->Height() + 5;
97 wd = new ButtonWidget( B_ID_TRIGGER, 5, wdy,
98 sfont->Width() * 12 + 10, wdh, 0,
99 "Edit T_rigger", this );
100 wd->SetHook( this );
101
102 wdy += wd->Height() + 5;
103 wd = new ButtonWidget( B_ID_EVENT, 5, wdy, wd->Width(), wdh,
104 0, "Edit _Event", this );
105 wd->SetHook( this );
106
107 wdy += wd->Height() + 5;
108 wd = new ButtonWidget( B_ID_DEPEND, 5, wdy, wd->Width(), wdh,
109 0, "Depends o_n", this );
110 wd->SetHook( this );
111
112 wdx = wd->LeftEdge() + wd->Width() + 5;
113 if ( event.Dependency() >= 0 ) {
114 Event *e = mission.GetEventByID( event.Dependency() );
115 if ( e ) sprintf( buf, "%s (%d)", e->Name(), e->ID() );
116 }
117 e_depends = new StringWidget( 0, wdx, wdy, w - wdx - 5, wdh,
118 buf, 47, WIDGET_STR_CONST, NULL, this );
119
120 wdy += wd->Height() + 5;
121 wd = new ButtonWidget( B_ID_DISCARD, 5, wdy, wd->Width(), wdh,
122 0, "D_iscards", this );
123 wd->SetHook( this );
124
125 buf[0] = '\0';
126 if ( event.Discard() >= 0 ) {
127 Event *e = mission.GetEventByID( event.Discard() );
128 if ( e ) sprintf( buf, "%s (%d)", e->Name(), e->ID() );
129 }
130 e_discards = new StringWidget( 0, wdx, wdy,
131 e_depends->Width(), wdh, buf, 47,
132 WIDGET_STR_CONST, NULL, this );
133
134 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
135 WIDGET_DEFAULT, "_OK", this );
136
137 Draw();
138 Show();
139 }
140
141 ////////////////////////////////////////////////////////////////////////
142 // NAME : EdEventGenericWindow::Draw
143 // DESCRIPTION: Draw the window.
144 // PARAMETERS : -
145 // RETURNS : -
146 ////////////////////////////////////////////////////////////////////////
147
Draw(void)148 void EdEventGenericWindow::Draw( void ) {
149 Window::Draw();
150
151 unsigned short lblx = sfont->Width() * 12 + 20,
152 lbly = e_msg->TopEdge() + e_msg->Height() + 9;
153
154 sfont->Write( ':', this, lblx, lbly );
155 sfont->Write( event.TriggerName(), this, lblx + sfont->Width() * 2, lbly );
156
157 lbly += sfont->Height() + 13;
158 sfont->Write( ':', this, lblx, lbly );
159 sfont->Write( event.Name(), this, lblx + sfont->Width() * 2, lbly );
160 }
161
162 ////////////////////////////////////////////////////////////////////////
163 // NAME : EdEventGenericWindow::WidgetActivated
164 // DESCRIPTION: React to user actions.
165 // PARAMETERS : widget - activated widget
166 // win - window containing the button
167 // RETURNS : GUI status
168 ////////////////////////////////////////////////////////////////////////
169
WidgetActivated(Widget * widget,Window * win)170 GUI_Status EdEventGenericWindow::WidgetActivated( Widget *widget, Window *win ) {
171 TLWNode *n;
172
173 switch ( widget->ID() ) {
174 case B_ID_TITLE:
175 TLWListBuilder::BuildMsgList( mission.GetMessages(), tlist );
176 new ListSelectWindow( "Select event title", tlist, event.Title(),
177 true, this, B_ID_TITLE_OK, view );
178 break;
179
180 case B_ID_TITLE_OK:
181 n = static_cast<ListSelectWindow *>(win)->Selected();
182 event.SetTitle( n ? n->ID() : -1 );
183 e_title->SetString( n ? n->Name() : NULL, true );
184 tlist.Clear();
185 break;
186
187 case B_ID_MSG:
188 TLWListBuilder::BuildMsgList( mission.GetMessages(), tlist );
189 new ListSelectWindow( "Select event message", tlist, event.Message(),
190 true, this, B_ID_MSG_OK, view );
191 break;
192
193 case B_ID_MSG_OK:
194 n = static_cast<ListSelectWindow *>(win)->Selected();
195 event.SetMessage( n ? n->ID() : -1 );
196 e_msg->SetText( n ? mission.GetMessage(n->ID()) : NULL );
197 e_msg->Draw();
198 e_msg->Show();
199 tlist.Clear();
200 break;
201
202 case B_ID_DEPEND:
203 TLWListBuilder::BuildEventList( mission.GetEvents(), tlist );
204 new ListSelectWindow( "Select event", tlist, event.Dependency(),
205 true, this, B_ID_DEPEND_OK, view );
206 break;
207
208 case B_ID_DEPEND_OK:
209 n = static_cast<ListSelectWindow *>(win)->Selected();
210 event.SetDependency( n ? n->ID() : -1 );
211 e_depends->SetString( n ? n->Name() : NULL );
212 tlist.Clear();
213 break;
214
215 case B_ID_DISCARD:
216 TLWListBuilder::BuildEventList( mission.GetEvents(), tlist );
217 new ListSelectWindow( "Select event", tlist, event.Discard(),
218 true, this, B_ID_DISCARD_OK, view );
219 break;
220
221 case B_ID_DISCARD_OK:
222 n = static_cast<ListSelectWindow *>(win)->Selected();
223 event.SetDiscard( n ? n->ID() : -1 );
224 e_discards->SetString( n ? n->Name() : NULL );
225 tlist.Clear();
226 break;
227
228 case B_ID_TRIGGER:
229 switch ( event.Trigger() ) {
230 case ETRIGGER_HAVE_BUILDING:
231 new EdTrigHaveShopWindow( event, mission, view ); break;
232 case ETRIGGER_HAVE_CRYSTALS:
233 new EdTrigHaveCrystalsWindow( event, mission, view ); break;
234 case ETRIGGER_HAVE_UNIT:
235 new EdTrigHaveUnitWindow( event, mission, view ); break;
236 case ETRIGGER_TIMER:
237 new EdTrigTimerWindow( event, view ); break;
238 case ETRIGGER_UNIT_DESTROYED:
239 new EdTrigUnitDestroyedWindow( event, mission, view ); break;
240 case ETRIGGER_UNIT_POSITION:
241 new EdTrigUnitPositionWindow( event, mission, view ); break;
242 case ETRIGGER_HANDICAP:
243 new EdTrigHandicapWindow( event, view ); break;
244 default:
245 new NoteWindow("Sorry", "Not yet implemented", 0, view);
246 }
247 break;
248
249 case B_ID_EVENT:
250 switch ( event.Type() ) {
251 case EVENT_CONFIGURE:
252 new EdEventConfigureWindow( event, mission, view ); break;
253 case EVENT_CREATE_UNIT:
254 new EdEventCreateUnitWindow( event, mission, view ); break;
255 case EVENT_DESTROY_UNIT:
256 new EdEventDestroyUnitWindow( event, mission, view ); break;
257 case EVENT_MANIPULATE_EVENT:
258 new EdEventManipEventWindow( event, mission, view ); break;
259 case EVENT_MESSAGE:
260 new EdEventMessageWindow( event, mission, view ); break;
261 case EVENT_MINING:
262 new EdEventMiningWindow( event, mission, view ); break;
263 case EVENT_RESEARCH:
264 new EdEventResearchWindow( event, mission, view ); break;
265 case EVENT_SCORE:
266 new EdEventScoreWindow( event, mission, view ); break;
267 case EVENT_SET_HEX:
268 new EdEventSetHexWindow( event, mission, view ); break;
269 case EVENT_SET_TIMER:
270 new EdEventSetTimerWindow( event, mission, view ); break;
271 default:
272 new NoteWindow("Sorry", "Not yet implemented", 0, view);
273 }
274 break;
275 case B_ID_PLAYER:
276 event.SetPlayer( static_cast<CycleWidget *>(widget)->GetValue() );
277 break;
278 case B_ID_DISABLED:
279 event.ToggleFlags( EFLAG_DISABLED );
280 }
281
282 return GUI_OK;
283 }
284
285 ////////////////////////////////////////////////////////////////////////
286 // NAME : EdEventConfigureWindow::EdEventConfigureWindow
287 // DESCRIPTION: This window allows configuration of a NEXT_MAP event.
288 // PARAMETERS : event - event to edit
289 // mission - current mission
290 // view - pointer to the window's view
291 // RETURNS : -
292 ////////////////////////////////////////////////////////////////////////
293
EdEventConfigureWindow(Event & event,Mission & mission,View * view)294 EdEventConfigureWindow::EdEventConfigureWindow( Event &event,
295 Mission &mission, View *view ) :
296 Window(WIN_CENTER, view), event(event), mission(mission) {
297 static const char *setting_labels[] = {
298 "Briefing Player 1", "Briefing Player 2", "Next Map", 0 };
299
300 SetSize( MIN(sfont->Width() * 20 + 15, view->Width()),
301 sfont->Height() * 3 + 40 );
302
303 unsigned short wdh = sfont->Height() + 8, wdx;
304 Widget *wd;
305
306 wdx = 10 + sfont->TextWidth( "Setting" );
307 wd = new CycleWidget( B_ID_SETTING, wdx, 5, w - 5 - wdx, wdh,
308 0, "_Setting", event.GetData(0), setting_labels, this );
309 wd->SetHook( this );
310
311 e_msg_but = new ButtonWidget( B_ID_MSG,
312 5, wd->TopEdge() + wd->Height() + 5,
313 sfont->Width() * 7 + 10, wdh,
314 event.GetData(0) == 2 ? WIDGET_DISABLED : 0,
315 "_Message", this );
316 e_msg_but->SetHook( this );
317
318 wdx = e_msg_but->LeftEdge() + e_msg_but->Width() + 5;
319 e_msg = new StringWidget( S_ID_VALUE, wdx, e_msg_but->TopEdge(),
320 w - wdx - 5, wdh, GetValueString(), 30,
321 event.GetData(0) == 2 ? 0 : WIDGET_STR_CONST,
322 NULL, this );
323 e_msg->SetHook( this );
324
325 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
326 WIDGET_DEFAULT, "_OK", this );
327 Draw();
328 Show();
329 }
330
331 ////////////////////////////////////////////////////////////////////////
332 // NAME : EdEventConfigureWindow::WidgetActivated
333 // DESCRIPTION: React to user actions.
334 // PARAMETERS : widget - activated widget
335 // win - window containing the widget
336 // RETURNS : GUI status
337 ////////////////////////////////////////////////////////////////////////
338
WidgetActivated(Widget * widget,Window * win)339 GUI_Status EdEventConfigureWindow::WidgetActivated( Widget *widget, Window *win ) {
340 switch( widget->ID() ) {
341 case B_ID_SETTING:
342 event.SetData( 0, static_cast<CycleWidget *>(widget)->GetValue() );
343 if ( event.GetData(0) == 2 ) {
344 e_msg_but->Disable();
345 e_msg->UnsetFlags( WIDGET_STR_CONST );
346 } else {
347 e_msg_but->Enable();
348 e_msg->SetFlags( WIDGET_STR_CONST );
349 }
350 e_msg->SetString( GetValueString() );
351 Draw();
352 Show();
353 break;
354 case B_ID_MSG:
355 TLWListBuilder::BuildMsgList( mission.GetMessages(), tlist );
356 new ListSelectWindow( "Select message", tlist,
357 event.GetData(1), false, this, B_ID_MSG_OK, view );
358 break;
359 case B_ID_MSG_OK: {
360 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
361 event.SetData( 1, n ? n->ID() : -1 );
362 e_msg->SetString( n ? n->Name() : "<None>" );
363 tlist.Clear(); }
364 break;
365 case S_ID_VALUE:
366 event.SetTmpBuf( e_msg->String() ? e_msg->String() : "" );
367 break;
368 }
369 return GUI_OK;
370 }
371
372 ////////////////////////////////////////////////////////////////////////
373 // NAME : EdEventConfigureWindow::GetValueString
374 // DESCRIPTION: Get the string representation of the "value" parameter
375 // that should be shown to the user.
376 // PARAMETERS : -
377 // RETURNS : display string
378 ////////////////////////////////////////////////////////////////////////
379
GetValueString(void) const380 const char *EdEventConfigureWindow::GetValueString( void ) const {
381 const char *ret = NULL;
382
383 switch (event.GetData(0) ) {
384 case 0:
385 case 1:
386 ret = mission.GetMessage(event.GetData(1));
387 break;
388 case 2:
389 if ( event.GetTmpBuf() != "" ) ret = event.GetTmpBuf().c_str();
390 break;
391 }
392 return ( ret == NULL ) ? "<None>" : ret;
393 }
394
395 ////////////////////////////////////////////////////////////////////////
396 // NAME : EdEventCreateUnitWindow::EdEventCreateUnitWindow
397 // DESCRIPTION: This window allows configuration of a CREATE_UNIT
398 // event.
399 // PARAMETERS : event - event to edit
400 // mission - current mission
401 // view - pointer to the window's view
402 // RETURNS : -
403 ////////////////////////////////////////////////////////////////////////
404
EdEventCreateUnitWindow(Event & event,Mission & mission,View * view)405 EdEventCreateUnitWindow::EdEventCreateUnitWindow( Event &event,
406 Mission &mission, View *view ) :
407 Window(WIN_CENTER, view), event(event), mission(mission) {
408 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
409 sfont->Height() * 4 + 50 );
410
411 Widget *wd;
412 unsigned short wdx, wdh = sfont->Height() + 8;
413 Point loc = mission.GetMap().Index2Hex( event.GetData(1) );
414
415 wd = new ButtonWidget( B_ID_UNIT, 5, 5,
416 sfont->Width() * 4 + 10, wdh, 0, "_Unit", this );
417 wd->SetHook( this );
418
419 wdx = wd->LeftEdge() + wd->Width() + 5;
420 e_unit = new StringWidget( 0, wdx, 5, w - wdx - 5, wdh,
421 mission.GetUnitSet().GetUnitInfo(event.GetData(0))->Name(),
422 30, WIDGET_STR_CONST, NULL, this );
423
424 wdx = 10 + sfont->TextWidth( "X" );
425 wd = new NumberWidget( N_ID_XPOS, wdx, wd->TopEdge() + wdh + 5,
426 sfont->Width() * 4 + 10, wdh, loc.x, 0,
427 mission.GetMap().Width() - 1, WIDGET_ALIGN_LEFT, "_X", this );
428 wd->SetHook( this );
429
430 wdx += wd->Width() + 10 + sfont->TextWidth( "Y" );
431 wd = new NumberWidget( N_ID_YPOS, wdx, wd->TopEdge(),
432 wd->Width(), wdh, loc.y, 0,
433 mission.GetMap().Height() - 1, WIDGET_ALIGN_LEFT, "_Y", this );
434 wd->SetHook( this );
435
436 wdx += wd->Width() + 10 + sfont->TextWidth( "Direction" );
437 wd = new CycleWidget( B_ID_DIRECTION,
438 wdx, wd->TopEdge(), w - 5 - wdx, wdh,
439 0, "_Direction", event.GetData(2) & 0x07, dir_labels, this );
440 wd->SetHook( this );
441
442 wdx = 10 + sfont->TextWidth("Squad Size");
443 wd = new CycleWidget( B_ID_SIZE, wdx, wd->TopEdge() + wd->Height() + 5,
444 w/2 - 5 - wdx, wdh, 0, "Squad _Size",
445 ((event.GetData(2) & 0x38) >> 3) - 1, size_labels, this );
446 wd->SetHook( this );
447
448 wdx += wd->Width() + sfont->TextWidth("XP Level") + 10;
449 wd = new CycleWidget( B_ID_XP, wdx,
450 wd->TopEdge(), w - 5 - wdx, wdh, 0, "XP _Level",
451 (event.GetData(2) & 0x1C0) >> 6, xp_labels, this );
452 wd->SetHook( this );
453
454 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
455 WIDGET_DEFAULT, "_OK", this );
456
457 Draw();
458 Show();
459 }
460
461 ////////////////////////////////////////////////////////////////////////
462 // NAME : EdEventCreateUnitWindow::WidgetActivated
463 // DESCRIPTION: React to user actions.
464 // PARAMETERS : widget - activated widget
465 // win - window containing the widget
466 // RETURNS : GUI status
467 ////////////////////////////////////////////////////////////////////////
468
WidgetActivated(Widget * widget,Window * win)469 GUI_Status EdEventCreateUnitWindow::WidgetActivated( Widget *widget, Window *win ) {
470 TLWNode *n;
471
472 switch( widget->ID() ) {
473 case B_ID_UNIT:
474 TLWListBuilder::BuildUnitTypesList( mission.GetUnitSet(), tlist );
475 new ListSelectWindow( "Select unit", tlist,
476 event.GetData(0), false, this, B_ID_UNIT_OK, view );
477 break;
478 case B_ID_UNIT_OK:
479 n = static_cast<ListSelectWindow *>(win)->Selected();
480 event.SetData( 0, n ? n->ID() : -1 );
481 e_unit->SetString( n ? n->Name() : "Error" );
482 tlist.Clear();
483 break;
484 case N_ID_XPOS:
485 case N_ID_YPOS: {
486 Point loc = mission.GetMap().Index2Hex( event.GetData(1) );
487 if ( widget->ID() == N_ID_XPOS )
488 loc.x = static_cast<NumberWidget *>(widget)->Number();
489 else
490 loc.y = static_cast<NumberWidget *>(widget)->Number();
491 event.SetData( 1, mission.GetMap().Hex2Index(loc) );
492 break; }
493 case B_ID_DIRECTION:
494 event.SetData( 2, (event.GetData(2) & ~0x0007) |
495 static_cast<CycleWidget *>(widget)->GetValue() );
496 break;
497 case B_ID_SIZE:
498 event.SetData( 2, (event.GetData(2) & ~0x0038) |
499 ((static_cast<CycleWidget *>(widget)->GetValue() + 1) << 3) );
500 break;
501 case B_ID_XP:
502 event.SetData( 2, (event.GetData(2) & ~0x01C0) |
503 (static_cast<CycleWidget *>(widget)->GetValue() << 6) );
504 break;
505 }
506
507 return GUI_OK;
508 }
509
510 ////////////////////////////////////////////////////////////////////////
511 // NAME : EdEventDestroyUnitWindow::EdEventDestroyUnitWindow
512 // DESCRIPTION: This window allows configuration of a DESTROY_UNIT
513 // event.
514 // PARAMETERS : event - event to edit
515 // mission - current mission
516 // view - pointer to the window's view
517 // RETURNS : -
518 ////////////////////////////////////////////////////////////////////////
519
EdEventDestroyUnitWindow(Event & event,Mission & mission,View * view)520 EdEventDestroyUnitWindow::EdEventDestroyUnitWindow( Event &event,
521 Mission &mission, View *view ) :
522 Window(WIN_CENTER, view), event(event), mission(mission) {
523 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
524 sfont->Height() * 5 + 60 );
525
526 Widget *wd;
527 unsigned short wdx, wdh = sfont->Height() + 8;
528 char buf[32] = "Any";
529 static const char *player_labels[] = { "Any", "One", "Two", 0 };
530 Point loc;
531
532 wd = new ButtonWidget( B_ID_UNIT, 5, 5,
533 sfont->Width() * 4 + 10, wdh, 0, "_Unit", this );
534 wd->SetHook( this );
535
536 Unit *u = mission.GetUnitByID( event.GetData(0) );
537 if ( u ) {
538 sprintf( buf, "%s (%d)", u->Name(), u->ID() );
539 loc = Point(0, 0);
540 } else {
541 loc = mission.GetMap().Index2Hex( event.GetData(2) );
542 }
543
544 wdx = wd->LeftEdge() + wd->Width() + 5;
545 e_unit = new StringWidget( 0, wdx, 5, w - wdx - 5, wdh,
546 buf, 30, WIDGET_STR_CONST, NULL, this );
547
548 wdx = 10 + sfont->TextWidth( "X" );
549 e_xpos = new NumberWidget( N_ID_XPOS, wdx, wd->TopEdge() + wdh + 5,
550 sfont->Width() * 4 + 10, wdh, loc.x, 0,
551 mission.GetMap().Width() - 1,
552 WIDGET_ALIGN_LEFT|(u ? WIDGET_DISABLED : 0), "_X", this );
553 e_xpos->SetHook( this );
554
555 wdx += wd->Width() + 10 + sfont->TextWidth( "Y" );
556 e_ypos = new NumberWidget( N_ID_YPOS, wdx, e_xpos->TopEdge(),
557 e_xpos->Width(), wdh, loc.y, 0,
558 mission.GetMap().Height() - 1,
559 WIDGET_ALIGN_LEFT|(u ? WIDGET_DISABLED : 0), "_Y", this );
560 e_ypos->SetHook( this );
561
562 wdx = sfont->Width() * 20 + 10;
563 wd = new CycleWidget( B_ID_PLAYER, wdx, e_ypos->TopEdge() + wdh + 10,
564 w - wdx - 5, wdh, 0, "Controlled by _Player",
565 event.GetData(1) + 1, player_labels, this );
566 wd->SetHook( this );
567
568 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
569 WIDGET_DEFAULT, "_OK", this );
570
571 Draw();
572 Show();
573 }
574
575 ////////////////////////////////////////////////////////////////////////
576 // NAME : EdEventDestroyUnitWindow::WidgetActivated
577 // DESCRIPTION: React to user actions.
578 // PARAMETERS : widget - activated widget
579 // win - window containing the widget
580 // RETURNS : GUI status
581 ////////////////////////////////////////////////////////////////////////
582
WidgetActivated(Widget * widget,Window * win)583 GUI_Status EdEventDestroyUnitWindow::WidgetActivated( Widget *widget, Window *win ) {
584
585 switch( widget->ID() ) {
586 case B_ID_UNIT:
587 TLWListBuilder::BuildUnitList( mission.GetUnits(), tlist );
588 new ListSelectWindow( "Select unit", tlist,
589 event.GetData(0), true, this, B_ID_UNIT_OK, view );
590 break;
591 case B_ID_UNIT_OK: {
592 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
593 if ( n ) {
594 event.SetData( 0, n->ID() );
595 event.SetData( 2, 0 );
596 e_unit->SetString( n->Name() );
597 e_xpos->SetNumber( 0 );
598 e_ypos->SetNumber( 0 );
599 e_xpos->Disable();
600 e_ypos->Disable();
601 } else {
602 event.SetData( 0, -1 );
603 e_unit->SetString( "Any" );
604 e_xpos->Enable();
605 e_ypos->Enable();
606 }
607 e_xpos->Draw();
608 e_ypos->Draw();
609 e_xpos->Show();
610 e_ypos->Show();
611 tlist.Clear();
612 break; }
613 case B_ID_PLAYER:
614 event.SetData( 1, static_cast<CycleWidget *>(widget)->GetValue() - 1 );
615 break;
616 case N_ID_XPOS:
617 case N_ID_YPOS: {
618 Point loc = mission.GetMap().Index2Hex( event.GetData(2) );
619 if ( widget->ID() == N_ID_XPOS )
620 loc.x = static_cast<NumberWidget *>(widget)->Number();
621 else
622 loc.y = static_cast<NumberWidget *>(widget)->Number();
623 event.SetData( 2, mission.GetMap().Hex2Index(loc) );
624 break; }
625 }
626
627 return GUI_OK;
628 }
629
630 ////////////////////////////////////////////////////////////////////////
631 // NAME : EdEventManipEventWindow::EdEventManipEventWindow
632 // DESCRIPTION: This window allows configuration of a MANIPULATE_EVENT
633 // event.
634 // PARAMETERS : event - event to edit
635 // mission - current mission
636 // view - pointer to the window's view
637 // RETURNS : -
638 ////////////////////////////////////////////////////////////////////////
639
EdEventManipEventWindow(Event & event,Mission & mission,View * view)640 EdEventManipEventWindow::EdEventManipEventWindow( Event &event,
641 Mission &mission, View *view ) :
642 Window(WIN_CENTER, view), event(event), mission(mission) {
643 static const char *action_labels[] = { "Set flags",
644 "Clear flags",
645 "Toggle flags", 0 };
646
647 SetSize( MIN(sfont->Width() * 25 + 15, view->Width()),
648 sfont->Height() * 4 + 50 );
649
650 Widget *wd;
651 unsigned short wdx, wdy, wdh = sfont->Height() + 8;
652 char buf[48] = "Error";
653
654 wd = new ButtonWidget( B_ID_EVENT, 5, 5,
655 sfont->Width() * 5 + 10, wdh, 0, "_Event", this );
656 wd->SetHook( this );
657
658 Event *e = mission.GetEventByID( event.GetData(0) );
659 if ( e ) sprintf( buf, "%s (%d)", e->Name(), e->ID() );
660 wdx = wd->LeftEdge() + wd->Width() + 5;
661 e_event = new StringWidget( 0, wdx, 5, w - wdx - 5, wdh,
662 buf, 30, WIDGET_STR_CONST, NULL, this );
663
664 wdx = sfont->Width() * 6 + 10;
665 wdy = wdh + 10;
666 wd = new CycleWidget( B_ID_ACTION, wdx, wdy,
667 w - wdx - 5, wdh, 0, "_Action",
668 event.GetData(2), action_labels, this );
669 wd->SetHook( this );
670
671 wdx = w - 10 - DEFAULT_CBW_SIZE;
672 wdy += wdh + 5;
673 wd = new CheckboxWidget( B_ID_DISABLED, wdx, wdy,
674 DEFAULT_CBW_SIZE, DEFAULT_CBW_SIZE,
675 event.GetData(1) & EFLAG_DISABLED,
676 WIDGET_STYLE_GFX|WIDGET_STYLE_NOBORDER|WIDGET_ALIGN_LEFT,
677 "_Disabled", this );
678 wd->SetHook( this );
679
680 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
681 WIDGET_DEFAULT, "_OK", this );
682 Draw();
683 Show();
684
685 TLWListBuilder::BuildEventList( mission.GetEvents(), tlist );
686 }
687
688 ////////////////////////////////////////////////////////////////////////
689 // NAME : EdEventManipEventWindow::WidgetActivated
690 // DESCRIPTION: React to user actions.
691 // PARAMETERS : widget - activated widget
692 // win - window containing the widget
693 // RETURNS : GUI status
694 ////////////////////////////////////////////////////////////////////////
695
WidgetActivated(Widget * widget,Window * win)696 GUI_Status EdEventManipEventWindow::WidgetActivated( Widget *widget, Window *win ) {
697
698 switch( widget->ID() ) {
699 case B_ID_EVENT:
700 new ListSelectWindow( "Select event", tlist,
701 event.GetData(0), false, this, B_ID_EVENT_OK, view );
702 break;
703 case B_ID_EVENT_OK: {
704 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
705 event.SetData( 0, n ? n->ID() : -1 );
706 e_event->SetString( n ? n->Name() : "Error" );
707 break; }
708 case B_ID_ACTION:
709 event.SetData( 2, static_cast<CycleWidget *>(widget)->GetValue() );
710 break;
711 case B_ID_DISABLED:
712 event.SetData( 1, event.GetData(1)^EFLAG_DISABLED );
713 }
714
715 return GUI_OK;
716 }
717
718 ////////////////////////////////////////////////////////////////////////
719 // NAME : EdEventMessageWindow::EdEventMessageWindow
720 // DESCRIPTION: This window allows configuration of a MESSAGE event.
721 // PARAMETERS : event - event to edit
722 // mission - current mission
723 // view - pointer to the window's view
724 // RETURNS : -
725 ////////////////////////////////////////////////////////////////////////
726
EdEventMessageWindow(Event & event,Mission & mission,View * view)727 EdEventMessageWindow::EdEventMessageWindow( Event &event, Mission &mission,
728 View *view ) :
729 Window(WIN_CENTER, view), event(event), mission(mission) {
730 SetSize( MIN(sfont->Width() * 15 + 15, view->Width()),
731 sfont->Height() * 2 + 25 );
732
733 unsigned short wdx, wdh = sfont->Height() + 8;
734 Point loc = mission.GetMap().Index2Hex( event.GetData(0) );
735
736 wdx = 10 + sfont->TextWidth( "X" );
737 e_xpos = new NumberWidget( 0,
738 wdx, 5, sfont->Width() * 4 + 10, wdh,
739 loc.x, -1, mission.GetMap().Width() - 1,
740 WIDGET_ALIGN_LEFT, "_X", this );
741
742 wdx += e_xpos->Width() + 10 + sfont->TextWidth( "Y" );
743 e_ypos = new NumberWidget( 0,
744 wdx, e_xpos->TopEdge(), e_xpos->Width(), wdh,
745 loc.y, -1, mission.GetMap().Height() - 1,
746 WIDGET_ALIGN_LEFT, "_Y", this );
747
748 ButtonWidget *wd = new ButtonWidget( GUI_CLOSE,
749 1, h - wdh - 1, w - 2, wdh,
750 WIDGET_DEFAULT, "_OK", this );
751 wd->SetHook( this );
752
753 Draw();
754 Show();
755 }
756
757 ////////////////////////////////////////////////////////////////////////
758 // NAME : EdEventMessageWindow::WidgetActivated
759 // DESCRIPTION: React to user actions.
760 // PARAMETERS : widget - activated widget
761 // win - window containing the widget
762 // RETURNS : GUI status
763 ////////////////////////////////////////////////////////////////////////
764
WidgetActivated(Widget * widget,Window * win)765 GUI_Status EdEventMessageWindow::WidgetActivated( Widget *widget, Window *win ) {
766 Point loc( e_xpos->Number(), e_ypos->Number() );
767 short idx = ((loc.x >= 0) && (loc.y >= 0)) ? mission.GetMap().Hex2Index(loc) : -1;
768 event.SetData( 0, idx );
769 return GUI_CLOSE;
770 }
771
772 ////////////////////////////////////////////////////////////////////////
773 // NAME : EdEventMiningWindow::EdEventMiningWindow
774 // DESCRIPTION: This window allows configuration of a MINING event.
775 // PARAMETERS : event - event to edit
776 // mission - current mission
777 // view - pointer to the window's view
778 // RETURNS : -
779 ////////////////////////////////////////////////////////////////////////
780
EdEventMiningWindow(Event & event,Mission & mission,View * view)781 EdEventMiningWindow::EdEventMiningWindow( Event &event,
782 Mission &mission, View *view ) :
783 Window(WIN_CENTER, view), event(event), mission(mission) {
784 static const char *action_labels[] = { "Set supplies",
785 "Modify supplies",
786 "Set production",
787 "Modify production", 0 };
788
789 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
790 sfont->Height() * 4 + 50 );
791
792 Widget *wd;
793 unsigned short wdx, wdy, wdh = sfont->Height() + 8;
794
795 wd = new ButtonWidget( B_ID_MINE, 5, 5,
796 sfont->Width() * 6, wdh, 0, "_Mine", this );
797 wd->SetHook( this );
798
799 wdx = wd->LeftEdge() + wd->Width() + 5;
800 Building *b = mission.GetBuildingByID( event.GetData(0) );
801 e_mine = new StringWidget( 0, wdx, wd->TopEdge(),
802 w - wdx - 5, wdh, b ? b->Name() : "Error",
803 30, WIDGET_STR_CONST, NULL, this );
804
805 wdy = wd->Height() + 10;
806 wd = new CycleWidget( B_ID_ACTION, wdx, wdy,
807 e_mine->Width(), wdh, 0, "_Action",
808 event.GetData(2), action_labels, this );
809 wd->SetHook( this );
810
811 wdy += wdh + 5;
812 e_crystals = new NumberWidget( N_ID_CRYSTALS,
813 wdx, wdy, wd->Width(), wdh,
814 event.GetData(1), -1000, 10000,
815 WIDGET_ALIGN_LEFT, "Amou_nt", this );
816 e_crystals->SetHook( this );
817
818 // this is kind of a hack: it's not (yet) possible to
819 // change the maximum string length after creation of
820 // the widget, so we assumed the maximum above and set
821 // the real values now
822 SetMiningRange( event.GetData(2) );
823
824 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
825 WIDGET_DEFAULT, "_OK", this );
826 Draw();
827 Show();
828 }
829
830 ////////////////////////////////////////////////////////////////////////
831 // NAME : EdEventMiningWindow::WidgetActivated
832 // DESCRIPTION: React to user actions.
833 // PARAMETERS : widget - activated widget
834 // win - window containing the widget
835 // RETURNS : GUI status
836 ////////////////////////////////////////////////////////////////////////
837
WidgetActivated(Widget * widget,Window * win)838 GUI_Status EdEventMiningWindow::WidgetActivated( Widget *widget, Window *win ) {
839 TLWNode *n;
840
841 switch( widget->ID() ) {
842 case B_ID_MINE:
843 TLWListBuilder::BuildShopList( mission.GetBuildings(), tlist );
844 new ListSelectWindow( "Select mine", tlist,
845 event.GetData(0), false, this, B_ID_MINE_OK, view );
846 break;
847 case B_ID_MINE_OK:
848 n = static_cast<ListSelectWindow *>(win)->Selected();
849 event.SetData( 0, n ? n->ID() : -1 );
850 e_mine->SetString( n ? n->Name() : "Error" );
851 tlist.Clear();
852 break;
853 case B_ID_ACTION:
854 event.SetData( 2, static_cast<CycleWidget *>(widget)->GetValue() );
855 SetMiningRange( static_cast<CycleWidget *>(widget)->GetValue() );
856 // fall through in case range has changed the number
857 case N_ID_CRYSTALS:
858 event.SetData( 1, e_crystals->Number() );
859 }
860
861 return GUI_OK;
862 }
863
864 ////////////////////////////////////////////////////////////////////////
865 // NAME : EdEventMiningWindow::SetMiningRange
866 // DESCRIPTION: The minimum and maximum numbers allowed in the "amount"
867 // widget are subject of the "action" chosen. We set the
868 // correct range here.
869 // PARAMETERS : action - action to set the range for
870 // RETURNS : -
871 ////////////////////////////////////////////////////////////////////////
872
SetMiningRange(short action) const873 void EdEventMiningWindow::SetMiningRange( short action ) const {
874 short min = 0, max = 0;
875 switch ( action ) {
876 case 0: max = 1000; break; // set supplies
877 case 1: min = -1000; max = 1000; break; // modify supplies
878 case 2: max = 200; break; // set production
879 case 3: min = -200; max = 200; break; // modify production;
880 }
881 e_crystals->SetMin( min );
882 e_crystals->SetMax( max );
883 }
884
885 ////////////////////////////////////////////////////////////////////////
886 // NAME : EdEventResearchWindow::EdEventResearchWindow
887 // DESCRIPTION: This window allows configuration of a RESEARCH event.
888 // PARAMETERS : event - event to edit
889 // mission - current mission
890 // view - pointer to the window's view
891 // RETURNS : -
892 ////////////////////////////////////////////////////////////////////////
893
EdEventResearchWindow(Event & event,Mission & mission,View * view)894 EdEventResearchWindow::EdEventResearchWindow( Event &event,
895 Mission &mission, View *view ) :
896 Window(WIN_CENTER, view), event(event), mission(mission) {
897 SetSize( MIN(sfont->Width() * 25, view->Width()),
898 sfont->Height() * 4 + 55 );
899
900 static const char *action_labels[] = { "Allow", "Disallow", 0 };
901 Widget *wd;
902 unsigned short wdx, wdh = sfont->Height() + 8;
903
904 wdx = sfont->TextWidth("Action") + 10;
905 wd = new CycleWidget( B_ID_ACTION, wdx, 5, w - wdx - 5, wdh,
906 0, "_Action", event.GetData(2), action_labels, this );
907 wd->SetHook( this );
908
909 wd = new ButtonWidget( B_ID_SHOP, 5, wd->TopEdge() + wdh + 5,
910 sfont->Width() * 4 + 10, wdh, 0, "_Shop", this );
911 wd->SetHook( this );
912
913 Building *b = mission.GetBuildingByID( event.GetData(0) );
914 wdx = wd->LeftEdge() + wd->Width() + 5;
915 e_shop = new StringWidget( 0, wdx, wd->TopEdge(), w - wdx - 5, wdh,
916 b ? b->Name() : "Error", 30, WIDGET_STR_CONST,
917 NULL, this );
918
919 wd = new ButtonWidget( B_ID_UNIT, 5, wd->TopEdge() + wdh + 5,
920 wd->Width(), wdh, 0, "_Unit", this );
921 wd->SetHook( this );
922
923 e_unit = new StringWidget( 0, wdx, wd->TopEdge(),
924 e_shop->Width(), wdh,
925 mission.GetUnitSet().GetUnitInfo(event.GetData(1))->Name(),
926 30, WIDGET_STR_CONST, NULL, this );
927
928 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
929 WIDGET_DEFAULT, "_OK", this );
930 Draw();
931 Show();
932 }
933
934 ////////////////////////////////////////////////////////////////////////
935 // NAME : EdEventResearchWindow::WidgetActivated
936 // DESCRIPTION: React to user actions.
937 // PARAMETERS : widget - activated widget
938 // win - window containing the widget
939 // RETURNS : GUI status
940 ////////////////////////////////////////////////////////////////////////
941
WidgetActivated(Widget * widget,Window * win)942 GUI_Status EdEventResearchWindow::WidgetActivated( Widget *widget, Window *win ) {
943 TLWNode *n;
944
945 switch( widget->ID() ) {
946 case B_ID_UNIT:
947 TLWListBuilder::BuildUnitTypesList( mission.GetUnitSet(), tlist );
948 new ListSelectWindow( "Select researched unit", tlist,
949 event.GetData(1), false, this, B_ID_UNIT_OK, view );
950 break;
951 case B_ID_UNIT_OK:
952 n = static_cast<ListSelectWindow *>(win)->Selected();
953 event.SetData( 1, n ? n->ID() : -1 );
954 e_unit->SetString( n ? n->Name() : "Error" );
955 tlist.Clear();
956 break;
957 case B_ID_SHOP:
958 TLWListBuilder::BuildShopList( mission.GetBuildings(), tlist );
959 new ListSelectWindow( "Select factory", tlist,
960 event.GetData(0), false, this, B_ID_SHOP_OK, view );
961 break;
962 case B_ID_SHOP_OK:
963 n = static_cast<ListSelectWindow *>(win)->Selected();
964 event.SetData( 0, n ? n->ID() : -1 );
965 e_shop->SetString( n ? n->Name() : "Error" );
966 tlist.Clear();
967 break;
968 case B_ID_ACTION:
969 event.SetData( 2, static_cast<CycleWidget *>(widget)->GetValue() );
970 break;
971 }
972
973 return GUI_OK;
974 }
975
976 ////////////////////////////////////////////////////////////////////////
977 // NAME : EdEventScoreWindow::EdEventScoreWindow
978 // DESCRIPTION: This window allows configuration of a SCORE event.
979 // PARAMETERS : event - event to edit
980 // mission - current mission
981 // view - pointer to the window's view
982 // RETURNS : -
983 ////////////////////////////////////////////////////////////////////////
984
EdEventScoreWindow(Event & event,Mission & mission,View * view)985 EdEventScoreWindow::EdEventScoreWindow( Event &event, Mission &mission, View *view ) :
986 Window(WIN_CENTER, view), event(event), mission(mission) {
987 SetSize( MIN(sfont->Width() * 20 + 15, view->Width()),
988 sfont->Height() * 4 + 50 );
989
990 unsigned short wdx = sfont->Width() * 5 + 10;
991 Widget *wd = new NumberWidget( N_ID_SCORE, wdx, 5,
992 w - wdx - 5, sfont->Height() + 8,
993 event.GetData(0), 1, 100,
994 WIDGET_ALIGN_LEFT, "_Score", this );
995 wd->SetHook( this );
996
997 wd = new ButtonWidget( B_ID_TITLE, 5, wd->TopEdge() + wd->Height() + 5,
998 sfont->Width() * 10, wd->Height(), 0, "Lose _Title", this );
999 wd->SetHook( this );
1000
1001 wdx = wd->LeftEdge() + wd->Width() + 5;
1002 const char *str = mission.GetMessage(event.GetData(2));
1003 other_title = new StringWidget( 0, wdx, wd->TopEdge(), w - wdx - 5, wd->Height(),
1004 (str || event.GetData(2) == -1) ? str : "Error", 30, WIDGET_STR_CONST,
1005 NULL, this );
1006
1007 wd = new ButtonWidget( B_ID_MSG, 5, wd->TopEdge() + wd->Height() + 5,
1008 wd->Width(), wd->Height(), 0, "Lose _Msg", this );
1009 wd->SetHook( this );
1010
1011 str = mission.GetMessage(event.GetData(1));
1012 other_msg = new StringWidget( 0, wdx, wd->TopEdge(), other_title->Width(), wd->Height(),
1013 (str || event.GetData(1) == -1) ? str : "Error", 30, WIDGET_STR_CONST,
1014 NULL, this );
1015
1016 new ButtonWidget( GUI_CLOSE, 1, h - wd->Height() - 1, w - 2, wd->Height(),
1017 WIDGET_DEFAULT, "_OK", this );
1018 Draw();
1019 Show();
1020
1021 TLWListBuilder::BuildMsgList( mission.GetMessages(), msglist );
1022 }
1023
1024 ////////////////////////////////////////////////////////////////////////
1025 // NAME : EdEventScoreWindow::WidgetActivated
1026 // DESCRIPTION: React to user actions.
1027 // PARAMETERS : widget - activated widget
1028 // win - window containing the widget
1029 // RETURNS : GUI status
1030 ////////////////////////////////////////////////////////////////////////
1031
WidgetActivated(Widget * widget,Window * win)1032 GUI_Status EdEventScoreWindow::WidgetActivated( Widget *widget, Window *win ) {
1033 TLWNode *n;
1034
1035 switch ( widget->ID() ) {
1036 case N_ID_SCORE:
1037 event.SetData( 0, static_cast<NumberWidget *>(widget)->Number() );
1038 break;
1039 case B_ID_MSG:
1040 new ListSelectWindow( "Select lose message", msglist, event.GetData(1),
1041 true, this, B_ID_MSG_OK, view );
1042 break;
1043 case B_ID_MSG_OK:
1044 n = static_cast<ListSelectWindow *>(win)->Selected();
1045 event.SetData( 1, n ? n->ID() : -1 );
1046 other_msg->SetString( n ? mission.GetMessage(n->ID()) : NULL );
1047 break;
1048 case B_ID_TITLE:
1049 new ListSelectWindow( "Select lose title", msglist, event.GetData(2),
1050 true, this, B_ID_TITLE_OK, view );
1051 break;
1052 case B_ID_TITLE_OK:
1053 n = static_cast<ListSelectWindow *>(win)->Selected();
1054 event.SetData( 2, n ? n->ID() : -1 );
1055 other_title->SetString( n ? mission.GetMessage(n->ID()) : NULL );
1056 }
1057
1058 return GUI_OK;
1059 }
1060
1061 ////////////////////////////////////////////////////////////////////////
1062 // NAME : EdEventSetHexWindow::EdEventSetHexWindow
1063 // DESCRIPTION: This window allows configuration of a SET_HEX event.
1064 // PARAMETERS : event - event to edit
1065 // mission - current mission
1066 // view - pointer to the window's view
1067 // RETURNS : -
1068 ////////////////////////////////////////////////////////////////////////
1069
EdEventSetHexWindow(Event & event,Mission & mission,View * view)1070 EdEventSetHexWindow::EdEventSetHexWindow( Event &event, Mission &mission,
1071 View *view ) :
1072 Window(WIN_CENTER, view), event(event), mission(mission) {
1073 const TerrainSet &set = mission.GetTerrainSet();
1074
1075 SetSize( MIN(sfont->Width() * 15 + 15, view->Width()),
1076 sfont->Height() * 2 + set.TileHeight() + 30 );
1077
1078 tilepos = Rect( (w - set.TileWidth()) / 2, 5,
1079 set.TileWidth(), set.TileHeight() );
1080
1081 Widget *wd;
1082 unsigned short wdx, wdh = sfont->Height() + 8;
1083 Point loc = mission.GetMap().Index2Hex( event.GetData(1) );
1084
1085 wd = new ButtonWidget( B_ID_TILE_PREV,
1086 tilepos.x - sfont->Width() - 10, 5,
1087 sfont->Width() + 10, tilepos.h, 0, "_<", this );
1088 wd->SetHook( this );
1089
1090 wd = new ButtonWidget( B_ID_TILE_NEXT, tilepos.x + tilepos.w, 5,
1091 wd->Width(), tilepos.h, 0, "_>", this );
1092 wd->SetHook( this );
1093
1094 wdx = 10 + sfont->TextWidth( "X" );
1095 wd = new NumberWidget( N_ID_XPOS, wdx, wd->TopEdge() + wd->Height() + 5,
1096 sfont->Width() * 4 + 10, wdh, loc.x, 0,
1097 mission.GetMap().Width() - 1, WIDGET_ALIGN_LEFT, "_X", this );
1098 wd->SetHook( this );
1099
1100 wdx += wd->Width() + 10 + sfont->TextWidth( "Y" );
1101 wd = new NumberWidget( N_ID_YPOS, wdx, wd->TopEdge(),
1102 wd->Width(), wdh, loc.y, 0,
1103 mission.GetMap().Height() - 1, WIDGET_ALIGN_LEFT, "_Y", this );
1104 wd->SetHook( this );
1105
1106 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1107 WIDGET_DEFAULT, "_OK", this );
1108
1109 Draw();
1110 Show();
1111 }
1112
1113 ////////////////////////////////////////////////////////////////////////
1114 // NAME : EdEventSetHexWindow::Draw
1115 // DESCRIPTION: Draw the window.
1116 // PARAMETERS : -
1117 // RETURNS : -
1118 ////////////////////////////////////////////////////////////////////////
1119
Draw(void)1120 void EdEventSetHexWindow::Draw( void ) {
1121 Window::Draw();
1122 DrawTerrain( event.GetData(0), false );
1123 }
1124
1125 ////////////////////////////////////////////////////////////////////////
1126 // NAME : EdEventSetHexWindow::WidgetActivated
1127 // DESCRIPTION: React to user actions.
1128 // PARAMETERS : widget - activated widget
1129 // win - window containing the widget
1130 // RETURNS : GUI status
1131 ////////////////////////////////////////////////////////////////////////
1132
WidgetActivated(Widget * widget,Window * win)1133 GUI_Status EdEventSetHexWindow::WidgetActivated( Widget *widget, Window *win ) {
1134 unsigned short num;
1135
1136 switch( widget->ID() ) {
1137 case B_ID_TILE_PREV:
1138 num = event.GetData( 0 );
1139 if ( num > 0 ) --num;
1140 else num = mission.GetTerrainSet().NumTiles() - 1;
1141 event.SetData( 0, num );
1142 DrawTerrain( num, true );
1143 Show( tilepos );
1144 break;
1145 case B_ID_TILE_NEXT:
1146 num = event.GetData( 0 );
1147 if ( ++num == mission.GetTerrainSet().NumTiles() ) num = 0;
1148 event.SetData( 0, num );
1149 DrawTerrain( num, true );
1150 Show( tilepos );
1151 break;
1152 case N_ID_XPOS:
1153 case N_ID_YPOS: {
1154 Point loc = mission.GetMap().Index2Hex( event.GetData(1) );
1155 if ( widget->ID() == N_ID_XPOS )
1156 loc.x = static_cast<NumberWidget *>(widget)->Number();
1157 else
1158 loc.y = static_cast<NumberWidget *>(widget)->Number();
1159 event.SetData( 1, mission.GetMap().Hex2Index(loc) );
1160 break; }
1161 }
1162
1163 return GUI_OK;
1164 }
1165
1166 ////////////////////////////////////////////////////////////////////////
1167 // NAME : EdEventSetHexWindow::DrawTerrain
1168 // DESCRIPTION: Draw a terrain image to the window surface.
1169 // PARAMETERS : terrain - terrain identifier
1170 // update - whether to update the display
1171 // RETURNS : -
1172 ////////////////////////////////////////////////////////////////////////
1173
DrawTerrain(unsigned short terrain,bool update)1174 void EdEventSetHexWindow::DrawTerrain( unsigned short terrain, bool update ) {
1175 const TerrainSet &set = mission.GetTerrainSet();
1176 const TerrainType *tt = set.GetTerrainInfo( terrain );
1177
1178 if ( tt ) {
1179 set.DrawTile( tt->tt_image, this, tilepos.x, tilepos.y, tilepos );
1180
1181 if ( update ) Show( tilepos );
1182 }
1183 }
1184
1185 ////////////////////////////////////////////////////////////////////////
1186 // NAME : EdEventSetTimerWindow::EdEventSetTimerWindow
1187 // DESCRIPTION: This window allows configuration of a SET_TIMER event.
1188 // PARAMETERS : event - event to edit
1189 // mission - current mission
1190 // view - pointer to the window's view
1191 // RETURNS : -
1192 ////////////////////////////////////////////////////////////////////////
1193
EdEventSetTimerWindow(Event & event,Mission & mission,View * view)1194 EdEventSetTimerWindow::EdEventSetTimerWindow( Event &event,
1195 Mission &mission, View *view ) :
1196 Window(WIN_CENTER, view), event(event), mission(mission) {
1197 static const char *offset_labels[] = { "None (absolute)",
1198 "Execution time",
1199 "Trigger configuration", 0 };
1200
1201 SetSize( MIN(sfont->Width() * 25 + 15, view->Width()),
1202 sfont->Height() * 4 + 50 );
1203
1204 Widget *wd;
1205 unsigned short wdx, wdy, wdh = sfont->Height() + 8;
1206 char buf[48] = "Error";
1207
1208 wd = new ButtonWidget( B_ID_EVENT, 5, 5,
1209 sfont->Width() * 5 + 10, wdh, 0, "_Event", this );
1210 wd->SetHook( this );
1211
1212 Event *e = mission.GetEventByID( event.GetData(0) );
1213 if ( e ) sprintf( buf, "%s (%d)", e->Name(), e->ID() );
1214 wdx = wd->LeftEdge() + wd->Width() + 5;
1215 e_event = new StringWidget( 0, wdx, 5, w - wdx - 5, wdh,
1216 buf, 30, WIDGET_STR_CONST, NULL, this );
1217
1218 wdy = wdh + 10;
1219 wd = new CycleWidget( B_ID_OFFSET, e_event->LeftEdge(), wdy,
1220 w - e_event->LeftEdge() - 5, wdh, 0, "O_ffset",
1221 event.GetData(2), offset_labels, this );
1222 wd->SetHook( this );
1223
1224 wdx = sfont->TextWidth("Time") + 10;
1225 wdy += wdh + 5;
1226 wd = new NumberWidget( N_ID_TIME,
1227 wdx, wdy, sfont->Width() * 5, wdh,
1228 event.GetData(1), 0, 100,
1229 WIDGET_ALIGN_LEFT, "_Time", this );
1230 wd->SetHook( this );
1231
1232 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1233 WIDGET_DEFAULT, "_OK", this );
1234 Draw();
1235 Show();
1236
1237 TLWListBuilder::BuildEventList( mission.GetEvents(), tlist );
1238 }
1239
1240 ////////////////////////////////////////////////////////////////////////
1241 // NAME : EdEventSetTimerWindow::WidgetActivated
1242 // DESCRIPTION: React to user actions.
1243 // PARAMETERS : widget - activated widget
1244 // win - window containing the widget
1245 // RETURNS : GUI status
1246 ////////////////////////////////////////////////////////////////////////
1247
WidgetActivated(Widget * widget,Window * win)1248 GUI_Status EdEventSetTimerWindow::WidgetActivated( Widget *widget, Window *win ) {
1249
1250 switch( widget->ID() ) {
1251 case B_ID_EVENT:
1252 new ListSelectWindow( "Select event", tlist,
1253 event.GetData(0), false, this, B_ID_EVENT_OK, view );
1254 break;
1255 case B_ID_EVENT_OK: {
1256 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
1257 if ( n ) {
1258 Event *e = static_cast<Event *>( n->UserData() );
1259 if ( e->Trigger() != ETRIGGER_TIMER ) {
1260 n = NULL;
1261 new NoteWindow( "Error", "Selected event has no 'Timer' trigger.",
1262 0, view );
1263 }
1264 }
1265 event.SetData( 0, n ? n->ID() : -1 );
1266 e_event->SetString( n ? n->Name() : "Error" );
1267 break; }
1268 case B_ID_OFFSET:
1269 event.SetData( 2, static_cast<CycleWidget *>(widget)->GetValue() );
1270 break;
1271 case N_ID_TIME:
1272 event.SetData( 1, static_cast<NumberWidget *>(widget)->Number() );
1273 break;
1274 }
1275
1276 return GUI_OK;
1277 }
1278
1279
1280 ////////////////////////////////////////////////////////////////////////
1281 // NAME : EdTrigHaveCrystalsWindow::EdTrigHaveCrystalsWindow
1282 // DESCRIPTION: This window allows configuration of a HAVE_CRYSTALS
1283 // trigger.
1284 // PARAMETERS : event - event to edit
1285 // mission - current mission
1286 // view - pointer to the window's view
1287 // RETURNS : -
1288 ////////////////////////////////////////////////////////////////////////
1289
EdTrigHaveCrystalsWindow(Event & event,Mission & mission,View * view)1290 EdTrigHaveCrystalsWindow::EdTrigHaveCrystalsWindow( Event &event,
1291 Mission &mission, View *view ) :
1292 Window(WIN_CENTER, view), event(event), mission(mission) {
1293 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
1294 sfont->Height() * 4 + 50 );
1295
1296 Widget *wd;
1297 unsigned short wdx, wdh = sfont->Height() + 8;
1298 static const char *moreless_labels[] = { ">=", "<", 0 };
1299
1300 wd = new ButtonWidget( B_ID_SHOP, 5, 5,
1301 sfont->Width() * 4 + 10, wdh, 0, "_Shop", this );
1302 wd->SetHook( this );
1303
1304 Building *b = mission.GetBuildingByID( event.GetTData(2) );
1305 wdx = wd->LeftEdge() + wd->Width() + 5;
1306 t_shop = new StringWidget( 0, wdx, 5, w - wdx - 5, wdh,
1307 b ? b->Name() : "All", 30, WIDGET_STR_CONST,
1308 NULL, this );
1309
1310 wdx = sfont->TextWidth("Player") + 10;
1311 wd = new CycleWidget( B_ID_PLAYER, wdx, wd->Height() + 10,
1312 sfont->Width() * 3 + 20, wdh, 0, "_Player",
1313 event.GetTData(1), player2_labels, this );
1314 wd->SetHook( this );
1315
1316 wdx = w - 5 - sfont->Width() * 4 - 20;
1317 wd = new CycleWidget( B_ID_MOREORLESS, wdx, wd->TopEdge(),
1318 sfont->Width() * 4 + 20, wdh, 0, NULL,
1319 event.GetTData(0) < 0 ? 1 : 0, moreless_labels, this );
1320 wd->SetHook( this );
1321
1322 wdx = wd->LeftEdge() - 5 - sfont->Width() * 6;
1323 wd = new NumberWidget( N_ID_CRYSTALS, wdx, wd->TopEdge(),
1324 sfont->Width() * 6, wdh, ABS(event.GetTData(0)),
1325 1, 5000, WIDGET_ALIGN_LEFT, "_Crystals", this );
1326 wd->SetHook( this );
1327
1328 t_transports = new CheckboxWidget( B_ID_TRANSPORTS,
1329 5, wd->TopEdge() + wd->Height() + 5,
1330 DEFAULT_CBW_SIZE, DEFAULT_CBW_SIZE,
1331 event.GetTData(2) == -2,
1332 WIDGET_STYLE_GFX|WIDGET_STYLE_NOBORDER|WIDGET_ALIGN_RIGHT|
1333 (event.GetTData(2) >= 0 ? WIDGET_DISABLED : 0),
1334 "_Include Transports", this );
1335 t_transports->SetHook( this );
1336
1337 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1338 WIDGET_DEFAULT, "_OK", this );
1339
1340 Draw();
1341 Show();
1342 }
1343
1344 ////////////////////////////////////////////////////////////////////////
1345 // NAME : EdTrigHaveCrystalsWindow::WidgetActivated
1346 // DESCRIPTION: React to user actions.
1347 // PARAMETERS : widget - activated widget
1348 // win - window containing the widget
1349 // RETURNS : GUI status
1350 ////////////////////////////////////////////////////////////////////////
1351
WidgetActivated(Widget * widget,Window * win)1352 GUI_Status EdTrigHaveCrystalsWindow::WidgetActivated( Widget *widget, Window *win ) {
1353
1354 switch( widget->ID() ) {
1355 case B_ID_SHOP:
1356 TLWListBuilder::BuildShopList( mission.GetBuildings(), tlist );
1357 new ListSelectWindow( "Select shop", tlist,
1358 event.GetTData(2), true, this, B_ID_SHOP_OK, view );
1359 break;
1360 case B_ID_SHOP_OK: {
1361 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
1362 event.SetTData( 2, n ? n->ID() : -1 );
1363 t_shop->SetString( n ? n->Name() : "All" );
1364 tlist.Clear();
1365
1366 if ( !n ) {
1367 t_transports->Enable();
1368 if ( t_transports->Clicked() ) event.SetTData( 2, -2 );
1369 } else t_transports->Disable();
1370 t_transports->Draw();
1371 Show();
1372 break; }
1373 case B_ID_PLAYER:
1374 event.SetTData( 1, static_cast<CycleWidget *>(widget)->GetValue() );
1375 break;
1376 case N_ID_CRYSTALS:
1377 event.SetTData( 0, SIGN(event.GetTData(0)) * static_cast<NumberWidget *>(widget)->Number() );
1378 break;
1379 case B_ID_MOREORLESS:
1380 event.SetTData( 0, event.GetTData( 0 ) * -1 );
1381 break;
1382 case B_ID_TRANSPORTS:
1383 event.SetTData( 2, widget->Clicked() ? -2 : -1 );
1384 }
1385
1386 return GUI_OK;
1387 }
1388
1389 ////////////////////////////////////////////////////////////////////////
1390 // NAME : EdTrigHaveShopWindow::EdTrigHaveShopWindow
1391 // DESCRIPTION: This window allows configuration of a HAVE_BUILDING
1392 // trigger.
1393 // PARAMETERS : event - event to edit
1394 // mission - current mission
1395 // view - pointer to the window's view
1396 // RETURNS : -
1397 ////////////////////////////////////////////////////////////////////////
1398
EdTrigHaveShopWindow(Event & event,Mission & mission,View * view)1399 EdTrigHaveShopWindow::EdTrigHaveShopWindow( Event &event,
1400 Mission &mission, View *view ) :
1401 Window(WIN_CENTER, view), event(event), mission(mission) {
1402 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
1403 sfont->Height() * 4 + 50 );
1404
1405 Widget *wd;
1406 unsigned short wdx, wdh = sfont->Height() + 8;
1407
1408 wd = new ButtonWidget( B_ID_SHOP, 5, 5,
1409 sfont->Width() * 4 + 10, wdh, 0, "_Shop", this );
1410 wd->SetHook( this );
1411
1412 Building *b = mission.GetBuildingByID( event.GetTData(0) );
1413 wdx = wd->LeftEdge() + wd->Width() + 5;
1414 t_shop = new StringWidget( 0, wdx, 5, w - wdx - 5, wdh,
1415 b ? b->Name() : "Error", 30, WIDGET_STR_CONST,
1416 NULL, this );
1417
1418 wdx = sfont->Width() * 20 + 10;
1419 wd = new CycleWidget( B_ID_PLAYER, wdx, wd->Height() + 10,
1420 w - wdx - 5, wdh, 0, "Controlled by _Player",
1421 event.GetTData(1), player2_labels, this );
1422 wd->SetHook( this );
1423
1424 wd = new NumberWidget( N_ID_TIMER,
1425 sfont->Width() * 7 + 10, wd->TopEdge() + wd->Height() + 5,
1426 sfont->Width() * 6, wdh, event.GetTData(2),
1427 -1, 999, WIDGET_ALIGN_LEFT, "At _Time", this );
1428 wd->SetHook( this );
1429
1430 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1431 WIDGET_DEFAULT, "_OK", this );
1432
1433 Draw();
1434 Show();
1435 }
1436
1437 ////////////////////////////////////////////////////////////////////////
1438 // NAME : EdTrigHaveShopWindow::WidgetActivated
1439 // DESCRIPTION: React to user actions.
1440 // PARAMETERS : widget - activated widget
1441 // win - window containing the widget
1442 // RETURNS : GUI status
1443 ////////////////////////////////////////////////////////////////////////
1444
WidgetActivated(Widget * widget,Window * win)1445 GUI_Status EdTrigHaveShopWindow::WidgetActivated( Widget *widget, Window *win ) {
1446
1447 switch( widget->ID() ) {
1448 case B_ID_SHOP:
1449 TLWListBuilder::BuildShopList( mission.GetBuildings(), tlist );
1450 new ListSelectWindow( "Select shop", tlist,
1451 event.GetTData(0), false, this, B_ID_SHOP_OK, view );
1452 break;
1453 case B_ID_SHOP_OK: {
1454 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
1455 event.SetTData( 0, n ? n->ID() : -1 );
1456 t_shop->SetString( n ? n->Name() : "Error" );
1457 tlist.Clear();
1458 break; }
1459 case B_ID_PLAYER:
1460 event.SetTData( 1, static_cast<CycleWidget *>(widget)->GetValue() );
1461 break;
1462 case N_ID_TIMER:
1463 event.SetTData( 2, static_cast<NumberWidget *>(widget)->Number() );
1464 }
1465
1466 return GUI_OK;
1467 }
1468
1469 ////////////////////////////////////////////////////////////////////////
1470 // NAME : EdTrigHaveUnitWindow::EdTrigHaveUnitWindow
1471 // DESCRIPTION: This window allows configuration of a HAVE_UNIT trigger.
1472 // PARAMETERS : event - event to edit
1473 // mission - current mission
1474 // view - pointer to the window's view
1475 // RETURNS : -
1476 ////////////////////////////////////////////////////////////////////////
1477
EdTrigHaveUnitWindow(Event & event,Mission & mission,View * view)1478 EdTrigHaveUnitWindow::EdTrigHaveUnitWindow( Event &event,
1479 Mission &mission, View *view ) :
1480 Window(WIN_CENTER, view), event(event), mission(mission) {
1481 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
1482 sfont->Height() * 4 + 50 );
1483
1484 Widget *wd;
1485 unsigned short wdx, wdh = sfont->Height() + 8;
1486 char buf[32] = "Error";
1487
1488 wd = new ButtonWidget( B_ID_UNIT, 5, 5,
1489 sfont->Width() * 4 + 10, wdh, 0, "_Unit", this );
1490 wd->SetHook( this );
1491
1492 Unit *u = mission.GetUnitByID( event.GetTData(0) );
1493 if ( u ) sprintf( buf, "%s (%d)", u->Name(), u->ID() );
1494
1495 wdx = wd->LeftEdge() + wd->Width() + 5;
1496 t_unit = new StringWidget( 0, wdx, 5, w - wdx - 5, wdh,
1497 buf, 30, WIDGET_STR_CONST, NULL, this );
1498
1499 wdx = sfont->Width() * 20 + 10;
1500 wd = new CycleWidget( B_ID_PLAYER, wdx, wd->Height() + 10,
1501 w - wdx - 5, wdh, 0, "Controlled by _Player",
1502 event.GetTData(1), player2_labels, this );
1503 wd->SetHook( this );
1504
1505 wd = new NumberWidget( N_ID_TIMER,
1506 sfont->Width() * 8 + 10, wd->TopEdge() + wd->Height() + 5,
1507 sfont->Width() * 6, wdh, event.GetTData(2),
1508 -1, 999, WIDGET_ALIGN_LEFT, "At _Time", this );
1509 wd->SetHook( this );
1510
1511 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1512 WIDGET_DEFAULT, "_OK", this );
1513
1514 Draw();
1515 Show();
1516 }
1517
1518 ////////////////////////////////////////////////////////////////////////
1519 // NAME : EdTrigHaveUnitWindow::WidgetActivated
1520 // DESCRIPTION: React to user actions.
1521 // PARAMETERS : widget - activated widget
1522 // win - window containing the widget
1523 // RETURNS : GUI status
1524 ////////////////////////////////////////////////////////////////////////
1525
WidgetActivated(Widget * widget,Window * win)1526 GUI_Status EdTrigHaveUnitWindow::WidgetActivated( Widget *widget, Window *win ) {
1527
1528 switch( widget->ID() ) {
1529 case B_ID_UNIT:
1530 TLWListBuilder::BuildUnitList( mission.GetUnits(), tlist );
1531 new ListSelectWindow( "Select unit", tlist,
1532 event.GetTData(0), false, this, B_ID_UNIT_OK, view );
1533 break;
1534 case B_ID_UNIT_OK: {
1535 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
1536 event.SetTData( 0, n ? n->ID() : -1 );
1537 t_unit->SetString( n ? n->Name() : "Error" );
1538 tlist.Clear();
1539 break; }
1540 case B_ID_PLAYER:
1541 event.SetTData( 1, static_cast<CycleWidget *>(widget)->GetValue() );
1542 break;
1543 case N_ID_TIMER:
1544 event.SetTData( 2, static_cast<NumberWidget *>(widget)->Number() );
1545 }
1546
1547 return GUI_OK;
1548 }
1549
1550 ////////////////////////////////////////////////////////////////////////
1551 // NAME : EdTrigTimerWindow::EdTrigTimerWindow
1552 // DESCRIPTION: This window allows configuration of a TIMER trigger.
1553 // PARAMETERS : event - event to edit
1554 // view - pointer to the window's view
1555 // RETURNS : -
1556 ////////////////////////////////////////////////////////////////////////
1557
EdTrigTimerWindow(Event & event,View * view)1558 EdTrigTimerWindow::EdTrigTimerWindow( Event &event, View *view ) :
1559 Window(WIN_CENTER, view), event(event) {
1560 SetSize( MIN(sfont->Width() * 21 + 15, view->Width()),
1561 sfont->Height() * 2 + 30 );
1562
1563 unsigned short wdx = sfont->Width() * 15 + 10,
1564 wdh = sfont->Height() + 8;
1565 Widget *wd = new NumberWidget( 0, wdx, 5, w - wdx - 5, wdh,
1566 event.GetTData(0), 0, 999, WIDGET_ALIGN_LEFT,
1567 "Execute at _time", this );
1568 wd->SetHook( this );
1569
1570 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1571 WIDGET_DEFAULT, "_OK", this );
1572 Draw();
1573 Show();
1574 }
1575
1576 ////////////////////////////////////////////////////////////////////////
1577 // NAME : EdTrigTimerWindow::WidgetActivated
1578 // DESCRIPTION: React to user actions.
1579 // PARAMETERS : widget - activated widget
1580 // win - window containing the widget
1581 // RETURNS : GUI status
1582 ////////////////////////////////////////////////////////////////////////
1583
WidgetActivated(Widget * widget,Window * win)1584 GUI_Status EdTrigTimerWindow::WidgetActivated( Widget *widget, Window *win ) {
1585 event.SetTData( 0, static_cast<NumberWidget *>(widget)->Number() );
1586 return GUI_OK;
1587 }
1588
1589 ////////////////////////////////////////////////////////////////////////
1590 // NAME : EdTrigUnitDestroyedWindow::EdTrigUnitDestroyedWindow
1591 // DESCRIPTION: This window allows configuration of a UNIT_DESTROYED
1592 // trigger.
1593 // PARAMETERS : event - event to edit
1594 // mission - current mission
1595 // view - pointer to the window's view
1596 // RETURNS : -
1597 ////////////////////////////////////////////////////////////////////////
1598
EdTrigUnitDestroyedWindow(Event & event,Mission & mission,View * view)1599 EdTrigUnitDestroyedWindow::EdTrigUnitDestroyedWindow( Event &event,
1600 Mission &mission, View *view ) :
1601 Window(WIN_CENTER, view), event(event), mission(mission) {
1602 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
1603 sfont->Height() * 4 + 50 );
1604
1605 Widget *wd;
1606 unsigned short wdx, wdh = sfont->Height() + 8;
1607 char buf[32] = "All";
1608
1609 wdx = 10 + sfont->TextWidth("Select");
1610 t_uselect = new CycleWidget( B_ID_USELECT, wdx, 5, w/2 - wdx - 5, wdh,
1611 0, "_Select", (event.GetTData(0) >= -1) ? 0 : 1,
1612 uselect_labels, this );
1613 t_uselect->SetHook( this );
1614
1615 wd = new ButtonWidget( B_ID_UNIT,
1616 5, t_uselect->TopEdge() + wdh + 5,
1617 sfont->Width() * 4 + 10, wdh, 0, "_Unit", this );
1618 wd->SetHook( this );
1619
1620 if ( event.GetTData(0) >= 0 ) {
1621 Unit *u = mission.GetUnitByID( event.GetTData(0) );
1622 if ( u ) sprintf( buf, "%s (%d)", u->Name(), u->ID() );
1623 } else if ( event.GetTData(0) < -1 ) {
1624 strcpy( buf, mission.GetUnitSet().GetUnitInfo(-event.GetTData(0) - 2)->Name() );
1625 }
1626 wdx = wd->LeftEdge() + wd->Width() + 5;
1627 t_unit = new StringWidget( 0, wdx, wd->TopEdge(), w - wdx - 5, wdh,
1628 buf, 30, WIDGET_STR_CONST, NULL, this );
1629
1630 wdx = sfont->Width() * 20 + 10;
1631 t_player = new CycleWidget( B_ID_PLAYER,
1632 wdx, wd->TopEdge() + wd->Height() + 5,
1633 w - wdx - 5, wdh,
1634 (event.GetTData(0) >= 0) ? WIDGET_DISABLED : 0,
1635 "Controlled by _Player", event.GetTData(1),
1636 player2_labels, this );
1637 t_player->SetHook( this );
1638
1639 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1640 WIDGET_DEFAULT, "_OK", this );
1641 Draw();
1642 Show();
1643 }
1644
1645 ////////////////////////////////////////////////////////////////////////
1646 // NAME : EdTrigUnitDestroyedWindow::WidgetActivated
1647 // DESCRIPTION: React to user actions.
1648 // PARAMETERS : widget - activated widget
1649 // win - window containing the widget
1650 // RETURNS : GUI status
1651 ////////////////////////////////////////////////////////////////////////
1652
WidgetActivated(Widget * widget,Window * win)1653 GUI_Status EdTrigUnitDestroyedWindow::WidgetActivated( Widget *widget, Window *win ) {
1654
1655 switch( widget->ID() ) {
1656 case B_ID_UNIT:
1657 if ( t_uselect->GetValue() == 0 ) {
1658 TLWListBuilder::BuildUnitList( mission.GetUnits(), tlist );
1659 new ListSelectWindow( "Select target unit", tlist,
1660 event.GetTData(0), true, this, B_ID_UNIT_OK, view );
1661 } else {
1662 TLWListBuilder::BuildUnitTypesList( mission.GetUnitSet(), tlist );
1663 new ListSelectWindow( "Select unit type", tlist,
1664 -event.GetTData(0) - 2, true, this, B_ID_UNIT_OK, view );
1665 }
1666 break;
1667 case B_ID_UNIT_OK: {
1668 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
1669 if ( t_uselect->GetValue() == 0 ) {
1670 event.SetTData( 0, n ? n->ID() : -1 );
1671 if ( n ) {
1672 event.SetTData( 1, static_cast<Unit *>(n->UserData())->Owner() );
1673 t_player->Disable();
1674 } else {
1675 event.SetTData( 1, event.Player()^1 );
1676 t_player->Enable();
1677 t_player->SetValue( event.GetTData(1) );
1678 }
1679 } else {
1680 event.SetTData( 0, n ? -n->ID() - 2 : -1);
1681 }
1682 t_unit->SetString( n ? n->Name() : "All", true );
1683
1684 Draw();
1685 Show();
1686 tlist.Clear();
1687 break; }
1688 case B_ID_USELECT:
1689 if ( t_uselect->GetValue() == 0 ) {
1690 event.SetTData( 0, -1 );
1691 t_unit->SetString( "All", true );
1692 } else if ( event.GetTData(0) != -1 ) {
1693 Unit *u = mission.GetUnitByID( event.GetTData(0) );
1694 if ( u ) {
1695 event.SetTData( 0, -u->Type()->ID() - 2 );
1696 t_unit->SetString( u->Name(), true );
1697 } else {
1698 event.SetTData( 0, -1 );
1699 t_unit->SetString( "All", true );
1700 }
1701 }
1702 t_player->Enable();
1703 t_player->SetValue( event.GetTData(1) );
1704 break;
1705 case B_ID_PLAYER:
1706 event.SetTData( 1, static_cast<CycleWidget *>(widget)->GetValue() );
1707 }
1708
1709 return GUI_OK;
1710 }
1711
1712 ////////////////////////////////////////////////////////////////////////
1713 // NAME : EdTrigUnitPositionWindow::EdTrigUnitPositionWindow
1714 // DESCRIPTION: This window allows configuration of a UNIT_POSITION
1715 // trigger.
1716 // PARAMETERS : event - event to edit
1717 // mission - current mission
1718 // view - pointer to the window's view
1719 // RETURNS : -
1720 ////////////////////////////////////////////////////////////////////////
1721
EdTrigUnitPositionWindow(Event & event,Mission & mission,View * view)1722 EdTrigUnitPositionWindow::EdTrigUnitPositionWindow( Event &event,
1723 Mission &mission, View *view ) :
1724 Window(WIN_CENTER, view), event(event), mission(mission) {
1725 SetSize( MIN(sfont->Width() * 30 + 15, view->Width()),
1726 sfont->Height() * 4 + 50 );
1727
1728 Widget *wd;
1729 unsigned short wdx, wdh = sfont->Height() + 8;
1730 char buf[32] = "Any";
1731 Point loc = mission.GetMap().Index2Hex( event.GetTData(1) );
1732
1733 wdx = 10 + sfont->TextWidth("Select");
1734 t_uselect = new CycleWidget( B_ID_USELECT, wdx, 5, w/2 - wdx - 5, wdh,
1735 0, "_Select", (event.GetTData(0) >= -1) ? 0 : 1,
1736 uselect_labels, this );
1737 t_uselect->SetHook( this );
1738
1739 wdx = w/2 + 10 + sfont->TextWidth("Player");
1740 wd = new CycleWidget( B_ID_PLAYER, wdx, t_uselect->TopEdge(),
1741 w - wdx - 5, wdh, 0, "_Player", event.GetTData(2),
1742 player2_labels, this );
1743 wd->SetHook( this );
1744
1745 wd = new ButtonWidget( B_ID_UNIT, 5, t_uselect->TopEdge() + wdh + 5,
1746 sfont->Width() * 4 + 10, wdh, 0, "_Unit", this );
1747 wd->SetHook( this );
1748
1749 if ( event.GetTData(0) >= 0 ) {
1750 Unit *u = mission.GetUnitByID( event.GetTData(0) );
1751 if ( u ) sprintf( buf, "%s (%d)", u->Name(), u->ID() );
1752 } else if ( event.GetTData(0) < -1 ) {
1753 strcpy( buf, mission.GetUnitSet().GetUnitInfo(-event.GetTData(0) - 2)->Name() );
1754 }
1755
1756 wdx = wd->LeftEdge() + wd->Width() + 5;
1757 t_unit = new StringWidget( 0, wdx, wd->TopEdge(), w - wdx - 5, wdh,
1758 buf, 30, WIDGET_STR_CONST, NULL, this );
1759
1760 wdx = sfont->Width() * 10 + 10;
1761 wd = new NumberWidget( N_ID_POSX,
1762 wdx, wd->TopEdge() + wd->Height() + 5,
1763 (w - wdx - sfont->Width() - 15) / 2, wdh,
1764 loc.x, 0, mission.GetMap().Width() - 1,
1765 WIDGET_ALIGN_LEFT, "Position _X", this );
1766 wd->SetHook( this );
1767
1768 wdx += wd->Width() + sfont->Width() + 10;
1769 wd = new NumberWidget( N_ID_POSY,
1770 wdx, wd->TopEdge(), w - wdx - 5, wdh,
1771 loc.y, 0, mission.GetMap().Height() - 1,
1772 WIDGET_ALIGN_LEFT, "_Y", this );
1773 wd->SetHook( this );
1774
1775 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1776 WIDGET_DEFAULT, "_OK", this );
1777 Draw();
1778 Show();
1779 }
1780
1781 ////////////////////////////////////////////////////////////////////////
1782 // NAME : EdTrigUnitPositionWindow::WidgetActivated
1783 // DESCRIPTION: React to user actions.
1784 // PARAMETERS : widget - activated widget
1785 // win - window containing the widget
1786 // RETURNS : GUI status
1787 ////////////////////////////////////////////////////////////////////////
1788
WidgetActivated(Widget * widget,Window * win)1789 GUI_Status EdTrigUnitPositionWindow::WidgetActivated( Widget *widget, Window *win ) {
1790 switch( widget->ID() ) {
1791 case B_ID_UNIT:
1792 if ( t_uselect->GetValue() == 0 ) {
1793 TLWListBuilder::BuildUnitList( mission.GetUnits(), tlist );
1794 new ListSelectWindow( "Select unit", tlist,
1795 event.GetTData(0), true, this, B_ID_UNIT_OK, view );
1796 } else {
1797 TLWListBuilder::BuildUnitTypesList( mission.GetUnitSet(), tlist );
1798 new ListSelectWindow( "Select unit type", tlist,
1799 -event.GetTData(0) - 2, true, this, B_ID_UNIT_OK, view );
1800 }
1801 break;
1802 case B_ID_UNIT_OK: {
1803 TLWNode *n = static_cast<ListSelectWindow *>(win)->Selected();
1804 if ( t_uselect->GetValue() == 0 )
1805 event.SetTData( 0, n ? n->ID() : -1 );
1806 else
1807 event.SetTData( 0, n ? -n->ID() - 2 : -1);
1808 t_unit->SetString( n ? n->Name() : "Any", true );
1809 tlist.Clear();
1810 break; }
1811 case N_ID_POSX:
1812 case N_ID_POSY: {
1813 Point loc = mission.GetMap().Index2Hex( event.GetTData(1) );
1814 if ( widget->ID() == N_ID_POSX )
1815 loc.x = static_cast<NumberWidget *>(widget)->Number();
1816 else
1817 loc.y = static_cast<NumberWidget *>(widget)->Number();
1818 event.SetTData( 1, mission.GetMap().Hex2Index(loc) );
1819 break; }
1820 case B_ID_USELECT:
1821 if ( t_uselect->GetValue() == 0 ) {
1822 event.SetTData( 0, -1 );
1823 t_unit->SetString( "Any", true );
1824 } else if ( event.GetTData(0) != -1 ) {
1825 Unit *u = mission.GetUnitByID( event.GetTData(0) );
1826 if ( u ) {
1827 event.SetTData( 0, -u->Type()->ID() - 2 );
1828 t_unit->SetString( u->Name(), true );
1829 } else {
1830 event.SetTData( 0, -1 );
1831 t_unit->SetString( "Any", true );
1832 }
1833 }
1834 break;
1835 case B_ID_PLAYER:
1836 event.SetTData( 2,
1837 static_cast<CycleWidget *>(widget)->GetValue() );
1838 break;
1839 }
1840
1841 return GUI_OK;
1842 }
1843
1844 ////////////////////////////////////////////////////////////////////////
1845 // NAME : EdTrigHandicapWindow::EdTrigHandicapWindow
1846 // DESCRIPTION: This window allows configuration of a HANDICAP trigger.
1847 // PARAMETERS : event - event to edit
1848 // view - pointer to the window's view
1849 // RETURNS : -
1850 ////////////////////////////////////////////////////////////////////////
1851
EdTrigHandicapWindow(Event & event,View * view)1852 EdTrigHandicapWindow::EdTrigHandicapWindow( Event &event, View *view ) :
1853 Window(WIN_CENTER, view), event(event) {
1854 SetSize( MIN(sfont->Width() * 20 + DEFAULT_CBW_SIZE + 15, view->Width()),
1855 sfont->Height() * 4 + 40 );
1856
1857 Widget *wd = new CheckboxWidget( HANDICAP_NONE, 5, 5,
1858 DEFAULT_CBW_SIZE, DEFAULT_CBW_SIZE,
1859 event.GetTData(0) & HANDICAP_NONE,
1860 WIDGET_STYLE_GFX|WIDGET_STYLE_NOBORDER|WIDGET_ALIGN_RIGHT,
1861 "_No handicap", this );
1862 wd->SetHook( this );
1863
1864 wd = new CheckboxWidget( HANDICAP_P1, 5, wd->TopEdge() + wd->Height() + 5,
1865 DEFAULT_CBW_SIZE, DEFAULT_CBW_SIZE,
1866 (event.GetTData(0) & HANDICAP_P1) != 0,
1867 WIDGET_STYLE_GFX|WIDGET_STYLE_NOBORDER|WIDGET_ALIGN_RIGHT,
1868 "Player _1 handicapped", this );
1869 wd->SetHook( this );
1870
1871 wd = new CheckboxWidget( HANDICAP_P2, 5, wd->TopEdge() + wd->Height() + 5,
1872 DEFAULT_CBW_SIZE, DEFAULT_CBW_SIZE,
1873 (event.GetTData(0) & HANDICAP_P2) != 0,
1874 WIDGET_STYLE_GFX|WIDGET_STYLE_NOBORDER|WIDGET_ALIGN_RIGHT,
1875 "Player _2 handicapped", this );
1876 wd->SetHook( this );
1877
1878 unsigned short wdh = sfont->Height() + 8;
1879 new ButtonWidget( GUI_CLOSE, 1, h - wdh - 1, w - 2, wdh,
1880 WIDGET_DEFAULT, "_OK", this );
1881 Draw();
1882 Show();
1883 }
1884
1885 ////////////////////////////////////////////////////////////////////////
1886 // NAME : EdTrigHandicapWindow::WidgetActivated
1887 // DESCRIPTION: React to user actions.
1888 // PARAMETERS : widget - activated widget
1889 // win - window containing the widget
1890 // RETURNS : GUI status
1891 ////////////////////////////////////////////////////////////////////////
1892
WidgetActivated(Widget * widget,Window * win)1893 GUI_Status EdTrigHandicapWindow::WidgetActivated( Widget *widget, Window *win ) {
1894 short handicap = event.GetTData( 0 );
1895 event.SetTData( 0, handicap ^ widget->ID() );
1896 return GUI_OK;
1897 }
1898
1899