00001
00002
00005 #ifndef WINDOW_GUI_H
00006 #define WINDOW_GUI_H
00007
00008 #include "core/bitmath_func.hpp"
00009 #include "vehicle_type.h"
00010 #include "viewport_type.h"
00011 #include "player_type.h"
00012 #include "strings_type.h"
00013
00017 static const int MAX_NUMBER_OF_WINDOWS = 25;
00018
00019 typedef void WindowProc(Window *w, WindowEvent *e);
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 enum ResizeFlag {
00049 RESIZE_NONE = 0,
00050
00051 RESIZE_LEFT = 1,
00052 RESIZE_RIGHT = 2,
00053 RESIZE_TOP = 4,
00054 RESIZE_BOTTOM = 8,
00055
00056 RESIZE_LR = RESIZE_LEFT | RESIZE_RIGHT,
00057 RESIZE_RB = RESIZE_RIGHT | RESIZE_BOTTOM,
00058 RESIZE_TB = RESIZE_TOP | RESIZE_BOTTOM,
00059 RESIZE_LRB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_BOTTOM,
00060 RESIZE_LRTB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM,
00061 RESIZE_RTB = RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM,
00062
00063
00064
00065
00066
00067 WIDG_DISABLED = 4,
00068 WIDG_HIDDEN = 5,
00069 WIDG_LOWERED = 6,
00070 };
00071
00072 enum {
00073 WIDGET_LIST_END = -1,
00074 };
00075
00076 struct Widget {
00077 byte type;
00078 byte display_flags;
00079 byte color;
00080 int16 left, right, top, bottom;
00081 uint16 data;
00082 StringID tooltips;
00083 };
00084
00085 enum FrameFlags {
00086 FR_NONE = 0,
00087 FR_TRANSPARENT = 1 << 0,
00088 FR_BORDERONLY = 1 << 4,
00089 FR_LOWERED = 1 << 5,
00090 FR_DARKENED = 1 << 6,
00091 };
00092
00093 DECLARE_ENUM_AS_BIT_SET(FrameFlags);
00094
00095 void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags);
00096
00097 enum WindowEventCodes {
00098 WE_CREATE,
00099 WE_DESTROY,
00100 WE_PAINT,
00101 WE_KEYPRESS,
00102 WE_CLICK,
00103 WE_DOUBLE_CLICK,
00104 WE_RCLICK,
00105 WE_MOUSEOVER,
00106 WE_MOUSELOOP,
00107 WE_MOUSEWHEEL,
00108 WE_TICK,
00109 WE_4,
00110 WE_TIMEOUT,
00111 WE_PLACE_OBJ,
00112 WE_ABORT_PLACE_OBJ,
00113 WE_ON_EDIT_TEXT,
00114 WE_ON_EDIT_TEXT_CANCEL,
00115 WE_POPUPMENU_SELECT,
00116 WE_POPUPMENU_OVER,
00117 WE_DRAGDROP,
00118 WE_PLACE_DRAG,
00119 WE_PLACE_MOUSEUP,
00120 WE_PLACE_PRESIZE,
00121 WE_DROPDOWN_SELECT,
00122 WE_RESIZE,
00123 WE_MESSAGE,
00124 WE_SCROLL,
00125 WE_INVALIDATE_DATA,
00126 WE_CTRL_CHANGED,
00127 };
00128
00129 struct WindowEvent {
00130 byte event;
00131 union {
00132 struct {
00133 void *data;
00134 } create;
00135
00136 struct {
00137 Point pt;
00138 int widget;
00139 } click;
00140
00141 struct {
00142 Point pt;
00143 TileIndex tile;
00144 TileIndex starttile;
00145 ViewportPlaceMethod select_method;
00146 byte select_proc;
00147 } place;
00148
00149 struct {
00150 Point pt;
00151 int widget;
00152 } dragdrop;
00153
00154 struct {
00155 Point size;
00156 Point diff;
00157 } sizing;
00158
00159 struct {
00160 char *str;
00161 } edittext;
00162
00163 struct {
00164 Point pt;
00165 } popupmenu;
00166
00167 struct {
00168 int button;
00169 int index;
00170 } dropdown;
00171
00172 struct {
00173 Point pt;
00174 int widget;
00175 } mouseover;
00176
00177 struct {
00178 bool cont;
00179 uint16 key;
00180 uint16 keycode;
00181 } keypress;
00182
00183 struct {
00184 int msg;
00185 int wparam;
00186 int lparam;
00187 } message;
00188
00189 struct {
00190 Point delta;
00191 } scroll;
00192
00193 struct {
00194 int wheel;
00195 } wheel;
00196
00197 struct {
00198 bool cont;
00199 } ctrl;
00200 } we;
00201 };
00202
00203 struct WindowDesc {
00204 int16 left, top, minimum_width, minimum_height, default_width, default_height;
00205 WindowClass cls;
00206 WindowClass parent_cls;
00207 uint32 flags;
00208 const Widget *widgets;
00209 WindowProc *proc;
00210 };
00211
00212 enum WindowDefaultFlag {
00213 WDF_STD_TOOLTIPS = 1 << 0,
00214 WDF_DEF_WIDGET = 1 << 1,
00215 WDF_STD_BTN = 1 << 2,
00216
00217 WDF_UNCLICK_BUTTONS = 1 << 4,
00218 WDF_STICKY_BUTTON = 1 << 5,
00219 WDF_RESIZABLE = 1 << 6,
00220 WDF_MODAL = 1 << 7,
00221 };
00222
00223
00224 enum WindowDefaultPosition {
00225 WDP_AUTO = -1,
00226 WDP_CENTER = -2,
00227 WDP_ALIGN_TBR = -3,
00228 WDP_ALIGN_TBL = -4,
00229 };
00230
00231 #define WP(ptr, str) (*(str*)(ptr)->custom)
00232
00233 struct Scrollbar {
00234 uint16 count, cap, pos;
00235 };
00236
00237 struct ResizeInfo {
00238 uint width;
00239 uint height;
00240 uint step_width;
00241 uint step_height;
00242 };
00243
00244 struct WindowMessage {
00245 int msg;
00246 int wparam;
00247 int lparam;
00248 };
00249
00250 struct Window {
00251 uint16 flags4;
00252 WindowClass window_class;
00253 WindowNumber window_number;
00254
00255 int left, top;
00256 int width, height;
00257
00258 Scrollbar hscroll, vscroll, vscroll2;
00259 ResizeInfo resize;
00260
00261 byte caption_color;
00262
00263 WindowProc *wndproc;
00264 ViewPort *viewport;
00265 const Widget *original_widget;
00266 Widget *widget;
00267 uint widget_count;
00268 uint32 desc_flags;
00269
00270 WindowMessage message;
00271 Window *parent;
00272 byte custom[WINDOW_CUSTOM_SIZE];
00273
00274 void HandleButtonClick(byte widget);
00275
00276 void SetWidgetDisabledState(byte widget_index, bool disab_stat);
00277 void DisableWidget(byte widget_index);
00278 void EnableWidget(byte widget_index);
00279 bool IsWidgetDisabled(byte widget_index) const;
00280 void SetWidgetHiddenState(byte widget_index, bool hidden_stat);
00281 void HideWidget(byte widget_index);
00282 void ShowWidget(byte widget_index);
00283 bool IsWidgetHidden(byte widget_index) const;
00284 void SetWidgetLoweredState(byte widget_index, bool lowered_stat);
00285 void ToggleWidgetLoweredState(byte widget_index);
00286 void LowerWidget(byte widget_index);
00287 void RaiseWidget(byte widget_index);
00288 bool IsWidgetLowered(byte widget_index) const;
00289
00290 void RaiseButtons();
00291 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00292 void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
00293 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00294 void InvalidateWidget(byte widget_index) const;
00295 };
00296
00297 struct menu_d {
00298 byte item_count;
00299 byte sel_index;
00300 byte main_button;
00301 byte action_id;
00302 StringID string_id;
00303 uint16 checked_items;
00304 byte disabled_items;
00305 };
00306 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(menu_d));
00307
00308 struct def_d {
00309 int16 data_1, data_2, data_3;
00310 int16 data_4, data_5;
00311 bool close;
00312 byte byte_1;
00313 };
00314 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(def_d));
00315
00316 struct void_d {
00317 void *data;
00318 };
00319 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(void_d));
00320
00321 struct tree_d {
00322 uint16 base;
00323 uint16 count;
00324 };
00325 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tree_d));
00326
00327 struct tooltips_d {
00328 StringID string_id;
00329 byte paramcount;
00330 uint64 params[5];
00331 };
00332 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d));
00333
00334 struct replaceveh_d {
00335 byte sel_index[2];
00336 EngineID sel_engine[2];
00337 uint16 count[2];
00338 bool wagon_btnstate;
00339 EngineList list[2];
00340 bool update_left;
00341 bool update_right;
00342 bool init_lists;
00343 GroupID sel_group;
00344 };
00345 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(replaceveh_d));
00346
00347 struct depot_d {
00348 VehicleID sel;
00349 VehicleType type;
00350 bool generate_list;
00351 uint16 engine_list_length;
00352 uint16 wagon_list_length;
00353 uint16 engine_count;
00354 uint16 wagon_count;
00355 Vehicle **vehicle_list;
00356 Vehicle **wagon_list;
00357 };
00358 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(depot_d));
00359
00360 struct order_d {
00361 int sel;
00362 };
00363 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d));
00364
00365 struct vehicledetails_d {
00366 byte tab;
00367 };
00368 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehicledetails_d));
00369
00370 struct smallmap_d {
00371 int32 scroll_x;
00372 int32 scroll_y;
00373 int32 subscroll;
00374 };
00375 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d));
00376
00377 struct refit_d {
00378 int sel;
00379 struct RefitOption *cargo;
00380 struct RefitList *list;
00381 uint length;
00382 VehicleOrderID order;
00383 };
00384 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(refit_d));
00385
00386 struct vp_d {
00387 VehicleID follow_vehicle;
00388 int32 scrollpos_x;
00389 int32 scrollpos_y;
00390 int32 dest_scrollpos_x;
00391 int32 dest_scrollpos_y;
00392 };
00393 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp_d));
00394
00395 struct news_d {
00396 uint16 follow_vehicle;
00397 int32 scrollpos_x;
00398 int32 scrollpos_y;
00399 int32 dest_scrollpos_x;
00400 int32 dest_scrollpos_y;
00401 NewsItem *ni;
00402 };
00403 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(news_d));
00404
00405 struct highscore_d {
00406 uint32 background_img;
00407 int8 rank;
00408 };
00409 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(highscore_d));
00410
00411 struct scroller_d {
00412 int height;
00413 uint16 counter;
00414 };
00415 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(scroller_d));
00416
00417 enum SortListFlags {
00418 VL_NONE = 0,
00419 VL_DESC = 1 << 0,
00420 VL_RESORT = 1 << 1,
00421 VL_REBUILD = 1 << 2,
00422 VL_END = 1 << 3,
00423 };
00424
00425 DECLARE_ENUM_AS_BIT_SET(SortListFlags);
00426
00427 struct Listing {
00428 bool order;
00429 byte criteria;
00430 };
00431
00432 struct list_d {
00433 uint16 list_length;
00434 byte sort_type;
00435 SortListFlags flags;
00436 uint16 resort_timer;
00437 };
00438 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(list_d));
00439
00440 struct message_d {
00441 int msg;
00442 int wparam;
00443 int lparam;
00444 };
00445 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(message_d));
00446
00447 struct vehiclelist_d {
00448 const Vehicle** sort_list;
00449 Listing *_sorting;
00450 uint16 length_of_sort_list;
00451 VehicleType vehicle_type;
00452 list_d l;
00453 };
00454 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d));
00455
00456 struct grouplist_d {
00457 const Group **sort_list;
00458 list_d l;
00459 };
00460 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(grouplist_d));
00461
00462 struct groupveh_d : vehiclelist_d {
00463 GroupID group_sel;
00464 VehicleID vehicle_sel;
00465
00466 grouplist_d gl;
00467 };
00468 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(groupveh_d));
00469
00470
00471 enum WindowWidgetBehaviours {
00472 WWB_PUSHBUTTON = 1 << 5,
00473
00474 WWB_MASK = 0xE0,
00475 };
00476
00477
00478 enum WindowWidgetTypes {
00479 WWT_EMPTY,
00480
00481 WWT_PANEL,
00482 WWT_INSET,
00483 WWT_IMGBTN,
00484 WWT_IMGBTN_2,
00485
00486 WWT_TEXTBTN,
00487 WWT_TEXTBTN_2,
00488 WWT_LABEL,
00489 WWT_TEXT,
00490 WWT_MATRIX,
00491 WWT_SCROLLBAR,
00492 WWT_FRAME,
00493 WWT_CAPTION,
00494
00495 WWT_HSCROLLBAR,
00496 WWT_STICKYBOX,
00497 WWT_SCROLL2BAR,
00498 WWT_RESIZEBOX,
00499 WWT_CLOSEBOX,
00500 WWT_DROPDOWN,
00501 WWT_DROPDOWNIN,
00502 WWT_LAST,
00503
00504 WWT_MASK = 0x1F,
00505
00506 WWT_PUSHBTN = WWT_PANEL | WWB_PUSHBUTTON,
00507 WWT_PUSHTXTBTN = WWT_TEXTBTN | WWB_PUSHBUTTON,
00508 WWT_PUSHIMGBTN = WWT_IMGBTN | WWB_PUSHBUTTON,
00509 };
00510
00511 #define WIDGETS_END WWT_LAST, RESIZE_NONE, 0, 0, 0, 0, 0, 0, STR_NULL
00512
00513 enum WindowFlags {
00514 WF_TIMEOUT_SHL = 0,
00515 WF_TIMEOUT_MASK = 7,
00516 WF_DRAGGING = 1 << 3,
00517 WF_SCROLL_UP = 1 << 4,
00518 WF_SCROLL_DOWN = 1 << 5,
00519 WF_SCROLL_MIDDLE = 1 << 6,
00520 WF_HSCROLL = 1 << 7,
00521 WF_SIZING = 1 << 8,
00522 WF_STICKY = 1 << 9,
00523
00524 WF_DISABLE_VP_SCROLL = 1 << 10,
00525
00526 WF_WHITE_BORDER_ONE = 1 << 11,
00527 WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
00528 WF_SCROLL2 = 1 << 13,
00529 };
00530
00531
00532 void CallWindowEventNP(Window *w, int event);
00533 void CallWindowTickEvent();
00534
00540 void SetWindowDirty(const Window *w);
00541 void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam);
00542 void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam);
00543
00544 Window *FindWindowById(WindowClass cls, WindowNumber number);
00545 void DeleteWindow(Window *w);
00546 void DeletePlayerWindows(PlayerID pi);
00547 void ChangeWindowOwner(PlayerID old_player, PlayerID new_player);
00548 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00549 Window *FindWindowFromPt(int x, int y);
00550
00551 bool IsWindowOfPrototype(const Window *w, const Widget *widget);
00552 void AssignWidgetToWindow(Window *w, const Widget *widget);
00553 Window *AllocateWindow(
00554 int x,
00555 int y,
00556 int width,
00557 int height,
00558 WindowProc *proc,
00559 WindowClass cls,
00560 const Widget *widget,
00561 void *data = NULL);
00562
00563 Window *AllocateWindowDesc(const WindowDesc *desc, void *data = NULL);
00564 Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number, void *data = NULL);
00565
00566 void DrawWindowViewport(const Window *w);
00567 void ResizeWindow(Window *w, int x, int y);
00568
00569 void InitWindowSystem();
00570 void UnInitWindowSystem();
00571 void ResetWindowSystem();
00572 int GetMenuItemIndex(const Window *w, int x, int y);
00573 void InputLoop();
00574 void InvalidateThisWindowData(Window *w);
00575 void InvalidateWindowData(WindowClass cls, WindowNumber number);
00576 void RelocateAllWindows(int neww, int newh);
00577
00578
00579 void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint64 params[]);
00580 static inline void GuiShowTooltips(StringID str)
00581 {
00582 GuiShowTooltipsWithArgs(str, 0, NULL);
00583 }
00584
00585
00586 int GetWidgetFromPos(const Window *w, int x, int y);
00587 void DrawWindowWidgets(const Window *w);
00588
00589 enum SortButtonState {
00590 SBS_OFF,
00591 SBS_DOWN,
00592 SBS_UP,
00593 };
00594
00595 void DrawSortButtonState(const Window *w, int widget, SortButtonState state);
00596
00597
00598 Window *GetCallbackWnd();
00599 void DeleteNonVitalWindows();
00600 void DeleteAllNonVitalWindows();
00601 void HideVitalWindows();
00602 void ShowVitalWindows();
00603 Window **FindWindowZPosition(const Window *w);
00604
00605
00606 extern Window *_z_windows[];
00607 extern Window **_last_z_window;
00608 #define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++)
00609
00610 extern Point _cursorpos_drag_start;
00611
00612 extern int _scrollbar_start_pos;
00613 extern int _scrollbar_size;
00614 extern byte _scroller_click_timeout;
00615
00616 extern bool _scrolling_scrollbar;
00617 extern bool _scrolling_viewport;
00618 extern bool _popup_menu_active;
00619
00620 extern byte _special_mouse_mode;
00621 enum SpecialMouseMode {
00622 WSM_NONE = 0,
00623 WSM_DRAGDROP = 1,
00624 WSM_SIZING = 2,
00625 WSM_PRESIZE = 3,
00626 };
00627
00628 void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
00629
00636 void ResizeButtons(Window *w, byte left, byte right);
00637
00640 void ResizeWindowForWidget(Window *w, int widget, int delta_x, int delta_y);
00641
00642
00650 inline void Window::SetWidgetDisabledState(byte widget_index, bool disab_stat)
00651 {
00652 assert(widget_index < this->widget_count);
00653 SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
00654 }
00655
00660 inline void Window::DisableWidget(byte widget_index)
00661 {
00662 SetWidgetDisabledState(widget_index, true);
00663 }
00664
00669 inline void Window::EnableWidget(byte widget_index)
00670 {
00671 SetWidgetDisabledState(widget_index, false);
00672 }
00673
00679 inline bool Window::IsWidgetDisabled(byte widget_index) const
00680 {
00681 assert(widget_index < this->widget_count);
00682 return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
00683 }
00684
00692 inline void Window::SetWidgetHiddenState(byte widget_index, bool hidden_stat)
00693 {
00694 assert(widget_index < this->widget_count);
00695 SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
00696 }
00697
00702 inline void Window::HideWidget(byte widget_index)
00703 {
00704 SetWidgetHiddenState(widget_index, true);
00705 }
00706
00711 inline void Window::ShowWidget(byte widget_index)
00712 {
00713 SetWidgetHiddenState(widget_index, false);
00714 }
00715
00721 inline bool Window::IsWidgetHidden(byte widget_index) const
00722 {
00723 assert(widget_index < this->widget_count);
00724 return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
00725 }
00726
00732 inline void Window::SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00733 {
00734 assert(widget_index < this->widget_count);
00735 SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
00736 }
00737
00742 inline void Window::ToggleWidgetLoweredState(byte widget_index)
00743 {
00744 assert(widget_index < this->widget_count);
00745 ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00746 }
00747
00752 inline void Window::LowerWidget(byte widget_index)
00753 {
00754 SetWidgetLoweredState(widget_index, true);
00755 }
00756
00761 inline void Window::RaiseWidget(byte widget_index)
00762 {
00763 SetWidgetLoweredState(widget_index, false);
00764 }
00765
00771 inline bool Window::IsWidgetLowered(byte widget_index) const
00772 {
00773 assert(widget_index < this->widget_count);
00774 return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00775 }
00776
00777 #endif