tron@2186: /* $Id$ */ tron@2186: rubidium@8602: /** @file window_gui.h Functions, definitions and such used only by the GUI. */ belugas@6443: rubidium@8602: #ifndef WINDOW_GUI_H rubidium@8602: #define WINDOW_GUI_H truelight@0: rubidium@8718: #include "core/bitmath_func.hpp" rubidium@8635: #include "vehicle_type.h" rubidium@8720: #include "viewport_type.h" rubidium@8750: #include "player_type.h" rubidium@8760: #include "strings_type.h" truelight@4299: rubidium@8564: /** rubidium@8564: * The maximum number of windows that can be opened. rubidium@8564: */ rubidium@8564: static const int MAX_NUMBER_OF_WINDOWS = 25; rubidium@8564: truelight@0: typedef void WindowProc(Window *w, WindowEvent *e); truelight@0: truelight@867: /* How the resize system works: truelight@867: First, you need to add a WWT_RESIZEBOX to the widgets, and you need truelight@867: to add the flag WDF_RESIZABLE to the window. Now the window is ready truelight@867: to resize itself. truelight@867: As you may have noticed, all widgets have a RESIZE_XXX in their line. truelight@867: This lines controls how the widgets behave on resize. RESIZE_NONE means truelight@867: it doesn't do anything. Any other option let's one of the borders truelight@867: move with the changed width/height. So if a widget has truelight@867: RESIZE_RIGHT, and the window is made 5 pixels wider by the user, truelight@867: the right of the window will also be made 5 pixels wider. truelight@867: Now, what if you want to clamp a widget to the bottom? Give it the flag truelight@867: RESIZE_TB. This is RESIZE_TOP + RESIZE_BOTTOM. Now if the window gets truelight@867: 5 pixels bigger, both the top and bottom gets 5 bigger, so the whole truelight@867: widgets moves downwards without resizing, and appears to be clamped truelight@867: to the bottom. Nice aint it? truelight@867: You should know one more thing about this system. Most windows can't truelight@867: handle an increase of 1 pixel. So there is a step function, which truelight@867: let the windowsize only be changed by X pixels. You configure this truelight@867: after making the window, like this: truelight@867: w->resize.step_height = 10; truelight@867: Now the window will only change in height in steps of 10. truelight@867: You can also give a minimum width and height. The default value is truelight@867: the default height/width of the window itself. You can change this truelight@867: AFTER window-creation, with: truelight@867: w->resize.width or w->resize.height. truelight@867: That was all.. good luck, and enjoy :) -- TrueLight */ truelight@867: rubidium@6574: enum ResizeFlag { belugas@6505: RESIZE_NONE = 0, ///< no resize required truelight@867: belugas@6505: RESIZE_LEFT = 1, ///< left resize flag belugas@6505: RESIZE_RIGHT = 2, ///< rigth resize flag belugas@6505: RESIZE_TOP = 4, ///< top resize flag belugas@6505: RESIZE_BOTTOM = 8, ///< bottom resize flag truelight@867: belugas@6505: RESIZE_LR = RESIZE_LEFT | RESIZE_RIGHT, ///< combination of left and right resize flags belugas@6505: RESIZE_RB = RESIZE_RIGHT | RESIZE_BOTTOM, ///< combination of right and bottom resize flags belugas@6505: RESIZE_TB = RESIZE_TOP | RESIZE_BOTTOM, ///< combination of top and bottom resize flags belugas@6505: RESIZE_LRB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_BOTTOM, ///< combination of left, right and bottom resize flags belugas@6505: RESIZE_LRTB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM, ///< combination of all resize flags belugas@6505: RESIZE_RTB = RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM, ///< combination of right, top and bottom resize flag belugas@4749: belugas@4749: /* The following flags are used by the system to specify what is disabled, hidden, or clicked belugas@4749: * They are used in the same place as the above RESIZE_x flags, Widget visual_flags. belugas@4749: * These states are used in exceptions. If nothing is specified, they will indicate belugas@4749: * Enabled, visible or unclicked widgets*/ belugas@6443: WIDG_DISABLED = 4, ///< widget is greyed out, not available belugas@6443: WIDG_HIDDEN = 5, ///< widget is made invisible belugas@6443: WIDG_LOWERED = 6, ///< widget is paint lowered, a pressed button in fact rubidium@6574: }; truelight@867: glx@4755: enum { belugas@6505: WIDGET_LIST_END = -1, ///< indicate the end of widgets' list for vararg functions glx@4755: }; glx@4755: rubidium@10083: /** rubidium@10083: * Window widget data structure rubidium@10083: */ rubidium@6574: struct Widget { belugas@6443: byte type; ///< Widget type, see WindowWidgetTypes belugas@6443: byte display_flags; ///< Resize direction, alignment, etc. during resizing, see ResizeFlags Darkvater@4547: byte color; ///< Widget colour, see docs/ottd-colourtext-palette.png bjarni@6224: int16 left, right, top, bottom; ///< The position offsets inside the window Darkvater@4547: uint16 data; ///< The String/Image or special code (list-matrixes) of a widget Darkvater@4547: StringID tooltips; ///< Tooltips that are shown when rightclicking on a widget rubidium@6574: }; truelight@0: rubidium@10083: /** rubidium@10083: * Flags to describe the look of the frame rubidium@10083: */ rubidium@6574: enum FrameFlags { belugas@8504: FR_NONE = 0, belugas@8504: FR_TRANSPARENT = 1 << 0, ///< Makes the background transparent if set belugas@8504: FR_BORDERONLY = 1 << 4, ///< Draw border only, no background belugas@8504: FR_LOWERED = 1 << 5, ///< If set the frame is lowered and the background color brighter (ie. buttons when pressed) belugas@8504: FR_DARKENED = 1 << 6, ///< If set the background is darker, allows for lowered frames with normal background color when used with FR_LOWERED (ie. dropdown boxes) rubidium@6574: }; tron@4437: rubidium@5838: DECLARE_ENUM_AS_BIT_SET(FrameFlags); rubidium@5838: rubidium@10083: /* wiget.cpp */ tron@4437: void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags); hackykid@1938: rubidium@10083: /** rubidium@10083: * Available window events rubidium@10083: */ belugas@4634: enum WindowEventCodes { rubidium@10083: WE_CREATE, ///< Initialize the Window rubidium@10083: WE_DESTROY, ///< Prepare for deletion of the window rubidium@10083: WE_PAINT, ///< Repaint the window contents rubidium@10083: WE_KEYPRESS, ///< Key pressed rubidium@10083: WE_CLICK, ///< Left mouse button click rubidium@10083: WE_DOUBLE_CLICK, ///< Left mouse button double click rubidium@10083: WE_RCLICK, ///< Right mouse button click Darkvater@5664: WE_MOUSEOVER, Darkvater@5664: WE_MOUSELOOP, Darkvater@5664: WE_MOUSEWHEEL, rubidium@10083: WE_TICK, ///< Regularly occurring event (about once every 20 seconds orso, 10 days) for slowly changing content (typically list sorting) rubidium@10083: WE_4, ///< Regularly occurring event for updating continuously changing window content (other than view ports), or timer expiring Darkvater@5664: WE_TIMEOUT, Darkvater@5664: WE_PLACE_OBJ, Darkvater@5664: WE_ABORT_PLACE_OBJ, Darkvater@5664: WE_ON_EDIT_TEXT, Darkvater@5664: WE_ON_EDIT_TEXT_CANCEL, Darkvater@5664: WE_POPUPMENU_SELECT, Darkvater@5664: WE_POPUPMENU_OVER, Darkvater@5664: WE_DRAGDROP, Darkvater@5664: WE_PLACE_DRAG, Darkvater@5664: WE_PLACE_MOUSEUP, Darkvater@5664: WE_PLACE_PRESIZE, Darkvater@5664: WE_DROPDOWN_SELECT, rubidium@10083: WE_RESIZE, ///< Request to resize the window, @see WindowEvent.we.resize rubidium@10083: WE_MESSAGE, ///< Receipt of a message from another window. @see WindowEvent.we.message, SendWindowMessage(), SendWindowMessageClass() Darkvater@5664: WE_SCROLL, rubidium@10083: WE_INVALIDATE_DATA, ///< Notification that data displayed by the window is obsolete rubidium@10083: WE_CTRL_CHANGED, ///< CTRL key has changed state belugas@4634: }; truelight@0: rubidium@10083: /** rubidium@10083: * Data structures for additional data associated with a window event rubidium@10083: * @see WindowEventCodes rubidium@10083: */ belugas@4634: struct WindowEvent { belugas@4634: byte event; belugas@4634: union { rubidium@7863: struct { rubidium@7863: void *data; rubidium@7863: } create; rubidium@7863: rubidium@7863: struct { belugas@4634: Point pt; belugas@4634: int widget; belugas@4634: } click; truelight@543: belugas@4634: struct { belugas@4634: Point pt; belugas@4634: TileIndex tile; belugas@4634: TileIndex starttile; rubidium@8384: ViewportPlaceMethod select_method; maedhros@7165: byte select_proc; belugas@4634: } place; darkvater@1648: belugas@4634: struct { belugas@4634: Point pt; belugas@4634: int widget; belugas@4634: } dragdrop; truelight@4335: belugas@4634: struct { belugas@4634: Point size; belugas@4634: Point diff; belugas@4634: } sizing; truelight@4337: belugas@4634: struct { belugas@4634: char *str; belugas@4634: } edittext; belugas@4634: belugas@4634: struct { belugas@4634: Point pt; belugas@4634: } popupmenu; belugas@4634: belugas@4634: struct { belugas@4634: int button; belugas@4634: int index; belugas@4634: } dropdown; belugas@4634: belugas@4634: struct { belugas@4634: Point pt; belugas@4634: int widget; belugas@4634: } mouseover; belugas@4634: belugas@4634: struct { belugas@6443: bool cont; ///< continue the search? (default true) belugas@6443: uint16 key; ///< 16-bit Unicode value of the key belugas@6443: uint16 keycode; ///< untranslated key (including shift-state) belugas@4634: } keypress; belugas@4634: belugas@4634: struct { belugas@6443: int msg; ///< message to be sent belugas@6443: int wparam; ///< additional message-specific information belugas@6443: int lparam; ///< additional message-specific information belugas@4634: } message; belugas@4634: belugas@4634: struct { belugas@6443: Point delta; ///< delta position against position of last call belugas@4634: } scroll; belugas@4634: belugas@4634: struct { belugas@6443: int wheel; ///< how much was 'wheel'd' belugas@4634: } wheel; smatz@9082: smatz@9082: struct { smatz@9082: bool cont; ///< continue the search? (default true) smatz@9082: } ctrl; belugas@4634: } we; truelight@0: }; truelight@0: rubidium@10083: /** rubidium@10083: * High level window description rubidium@10083: */ rubidium@6574: struct WindowDesc { rubidium@10083: int16 left; ///< Prefered x position of left edge of the window, @see WindowDefaultPosition() rubidium@10083: int16 top; ///< Prefered y position of the top of the window, @see WindowDefaultPosition() rubidium@10083: int16 minimum_width; ///< Minimal width of the window rubidium@10083: int16 minimum_height; ///< Minimal height of the window rubidium@10083: int16 default_width; ///< Prefered initial width of the window rubidium@10083: int16 default_height; ///< Prefered initial height of the window rubidium@10083: WindowClass cls; ///< Class of the window, @see WindowClass rubidium@10083: WindowClass parent_cls; ///< Class of the parent window, @see WindowClass rubidium@10083: uint32 flags; ///< Flags, @see WindowDefaultFlags rubidium@10083: const Widget *widgets; ///< List of widgets with their position and size for the window rubidium@10083: WindowProc *proc; ///< Window event handler function for the window rubidium@6574: }; truelight@0: rubidium@10083: /** rubidium@10083: * Window default widget/window handling flags rubidium@10083: */ Darkvater@5664: enum WindowDefaultFlag { belugas@8504: WDF_STD_TOOLTIPS = 1 << 0, ///< use standard routine when displaying tooltips rubidium@10083: WDF_DEF_WIDGET = 1 << 1, ///< Default widget control for some widgets in the on click event, @see DispatchLeftClickEvent() rubidium@10083: WDF_STD_BTN = 1 << 2, ///< Default handling for close and titlebar widgets (widget no 0 and 1) belugas@8515: rubidium@10083: WDF_UNCLICK_BUTTONS = 1 << 4, ///< Unclick buttons when the window event times out belugas@8504: WDF_STICKY_BUTTON = 1 << 5, ///< Set window to sticky mode; they are not closed unless closed with 'X' (widget 2) rubidium@10083: WDF_RESIZABLE = 1 << 6, ///< Window can be resized belugas@8504: WDF_MODAL = 1 << 7, ///< The window is a modal child of some other window, meaning the parent is 'inactive' truelight@0: }; truelight@0: rubidium@10083: /** rubidium@10083: * Special values for 'left' and 'top' to cause a specific placement rubidium@10083: */ Darkvater@5664: enum WindowDefaultPosition { Darkvater@5072: WDP_AUTO = -1, ///< Find a place automatically Darkvater@5072: WDP_CENTER = -2, ///< Center the window (left/right or top/bottom) Darkvater@5072: WDP_ALIGN_TBR = -3, ///< Align the right side of the window with the right side of the main toolbar Darkvater@5072: WDP_ALIGN_TBL = -4, ///< Align the left side of the window with the left side of the main toolbar truelight@0: }; truelight@0: rubidium@8578: #define WP(ptr, str) (*(str*)(ptr)->custom) truelight@0: rubidium@10083: /** rubidium@10083: * Scrollbar data structure rubidium@10083: */ rubidium@6574: struct Scrollbar { rubidium@10083: uint16 count; ///< Number of elements in the list rubidium@10083: uint16 cap; ///< Number of visible elements of the scroll bar rubidium@10083: uint16 pos; rubidium@6574: }; truelight@0: rubidium@10083: /** rubidium@10083: * Data structure for resizing a window rubidium@10083: */ rubidium@6574: struct ResizeInfo { rubidium@10083: uint width; ///< Minimum allowed width of the window rubidium@10083: uint height; ///< Minimum allowed height of the window rubidium@10083: uint step_width; ///< Step-size of width resize changes rubidium@10083: uint step_height; ///< Step-size of height resize changes rubidium@6574: }; truelight@867: rubidium@10083: /** rubidium@10083: * Message data structure for messages sent between winodows rubidium@10083: * @see SendWindowMessageW() rubidium@10083: */ rubidium@6574: struct WindowMessage { rubidium@6574: int msg; rubidium@6574: int wparam; rubidium@6574: int lparam; rubidium@6574: }; darkvater@1648: rubidium@10083: /** rubidium@10083: * Data structure for an opened window rubidium@10083: */ truelight@0: struct Window { rubidium@10083: uint16 flags4; ///< Window flags, @see WindowFlags rubidium@10083: WindowClass window_class; ///< Window class rubidium@10083: WindowNumber window_number; ///< Window number within the window class truelight@0: rubidium@10083: int left; ///< x position of left edge of the window rubidium@10083: int top; ///< y position of top edge of the window rubidium@10083: int width; ///< width of the window (number of pixels to the right in x direction) rubidium@10083: int height; ///< Height of the window (number of pixels down in y direction) truelight@0: rubidium@10083: Scrollbar hscroll; ///< Horizontal scroll bar rubidium@10083: Scrollbar vscroll; ///< First vertical scroll bar rubidium@10083: Scrollbar vscroll2; ///< Second vertical scroll bar rubidium@10083: ResizeInfo resize; ///< Resize information truelight@0: rubidium@10083: byte caption_color; ///< Background color of the window caption, contains PlayerID rubidium@10083: rubidium@10083: WindowProc *wndproc; ///< Event handler function for the window rubidium@10083: ViewPort *viewport; ///< Pointer to viewport, if present (structure is part of derived class) rubidium@10083: const Widget *original_widget; ///< Original widget layout, copied from WindowDesc rubidium@10083: Widget *widget; ///< Widgets of the window rubidium@10083: uint widget_count; ///< Number of widgets of the window rubidium@10083: uint32 desc_flags; ///< Window/widgets default flags setting, @see WindowDefaultFlag rubidium@10083: rubidium@10083: WindowMessage message; ///< Buffer for storing received messages (for communication between different window events) rubidium@10083: Window *parent; ///< Parent window rubidium@10083: byte custom[WINDOW_CUSTOM_SIZE]; ///< Additional data depending on window type belugas@8489: belugas@8531: void HandleButtonClick(byte widget); belugas@8531: belugas@8489: void SetWidgetDisabledState(byte widget_index, bool disab_stat); belugas@8489: void DisableWidget(byte widget_index); belugas@8489: void EnableWidget(byte widget_index); rubidium@8491: bool IsWidgetDisabled(byte widget_index) const; belugas@8489: void SetWidgetHiddenState(byte widget_index, bool hidden_stat); belugas@8489: void HideWidget(byte widget_index); belugas@8489: void ShowWidget(byte widget_index); rubidium@8491: bool IsWidgetHidden(byte widget_index) const; belugas@8489: void SetWidgetLoweredState(byte widget_index, bool lowered_stat); rubidium@8492: void ToggleWidgetLoweredState(byte widget_index); belugas@8489: void LowerWidget(byte widget_index); belugas@8489: void RaiseWidget(byte widget_index); rubidium@8491: bool IsWidgetLowered(byte widget_index) const; belugas@8489: belugas@8489: void RaiseButtons(); belugas@8489: void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...); belugas@8489: void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...); belugas@8489: void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...); glx@8522: void InvalidateWidget(byte widget_index) const; truelight@0: }; truelight@0: rubidium@6574: struct menu_d { belugas@6443: byte item_count; ///< follow_vehicle belugas@6443: byte sel_index; ///< scrollpos_x belugas@6443: byte main_button; ///< scrollpos_y truelight@0: byte action_id; belugas@6443: StringID string_id; ///< unk30 belugas@6443: uint16 checked_items; ///< unk32 celestar@2216: byte disabled_items; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(menu_d)); truelight@0: rubidium@6574: struct def_d { truelight@0: int16 data_1, data_2, data_3; truelight@0: int16 data_4, data_5; tron@2596: bool close; truelight@0: byte byte_1; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(def_d)); truelight@0: rubidium@6574: struct void_d { truelight@0: void *data; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(void_d)); truelight@0: rubidium@6574: struct tree_d { tron@2596: uint16 base; tron@2596: uint16 count; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tree_d)); truelight@0: rubidium@6574: struct tooltips_d { truelight@0: StringID string_id; Darkvater@4834: byte paramcount; rubidium@7502: uint64 params[5]; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d)); truelight@0: rubidium@6574: struct depot_d { truelight@0: VehicleID sel; rubidium@7134: VehicleType type; bjarni@4739: bool generate_list; bjarni@4635: uint16 engine_list_length; bjarni@4635: uint16 wagon_list_length; bjarni@4635: uint16 engine_count; bjarni@4635: uint16 wagon_count; bjarni@4635: Vehicle **vehicle_list; bjarni@4635: Vehicle **wagon_list; rubidium@6574: }; bjarni@4638: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(depot_d)); truelight@0: rubidium@6574: struct order_d { truelight@0: int sel; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d)); truelight@0: rubidium@8026: struct vehicledetails_d { truelight@0: byte tab; rubidium@6574: }; rubidium@8026: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehicledetails_d)); truelight@0: rubidium@6574: struct smallmap_d { tron@849: int32 scroll_x; tron@849: int32 scroll_y; tron@849: int32 subscroll; rubidium@6574: }; truelight@4318: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d)); truelight@0: rubidium@6574: struct vp_d { tron@2116: VehicleID follow_vehicle; tron@849: int32 scrollpos_x; tron@849: int32 scrollpos_y; peter1138@7226: int32 dest_scrollpos_x; peter1138@7226: int32 dest_scrollpos_y; rubidium@6574: }; Darkvater@5123: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp_d)); miham@1004: rubidium@6574: struct highscore_d { darkvater@998: uint32 background_img; darkvater@998: int8 rank; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(highscore_d)); darkvater@998: rubidium@6574: struct scroller_d { darkvater@998: int height; darkvater@998: uint16 counter; rubidium@6574: }; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(scroller_d)); darkvater@859: rubidium@6574: enum SortListFlags { belugas@8504: VL_NONE = 0, ///< no sort belugas@8504: VL_DESC = 1 << 0, ///< sort descending or ascending belugas@8504: VL_RESORT = 1 << 1, ///< instruct the code to resort the list in the next loop belugas@8504: VL_REBUILD = 1 << 2, ///< create sort-listing to use for qsort and friends belugas@8504: VL_END = 1 << 3, rubidium@6574: }; tron@588: rubidium@5838: DECLARE_ENUM_AS_BIT_SET(SortListFlags); rubidium@5838: rubidium@6574: struct Listing { belugas@6443: bool order; ///< Ascending/descending belugas@6443: byte criteria; ///< Sorting criteria rubidium@6574: }; tron@588: rubidium@6574: struct list_d { belugas@6443: uint16 list_length; ///< length of the list being sorted belugas@6443: byte sort_type; ///< what criteria to sort on belugas@6443: SortListFlags flags; ///< used to control sorting/resorting/etc. belugas@6443: uint16 resort_timer; ///< resort list after a given amount of ticks if set rubidium@6574: }; Darkvater@2888: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(list_d)); Darkvater@2888: rubidium@6574: struct message_d { darkvater@1648: int msg; darkvater@1648: int wparam; darkvater@1648: int lparam; rubidium@6574: }; darkvater@1648: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(message_d)); darkvater@1648: rubidium@7139: struct vehiclelist_d { rubidium@7139: const Vehicle** sort_list; // List of vehicles (sorted) rubidium@7139: Listing *_sorting; // pointer to the appropiate subcategory of _sorting rubidium@7139: uint16 length_of_sort_list; // Keeps track of how many vehicle pointers sort list got space for rubidium@7139: VehicleType vehicle_type; // The vehicle type that is sorted rubidium@7139: list_d l; // General list struct rubidium@7139: }; rubidium@7139: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d)); rubidium@7139: truelight@0: /****************** THESE ARE NOT WIDGET TYPES!!!!! *******************/ truelight@0: enum WindowWidgetBehaviours { rubidium@4344: WWB_PUSHBUTTON = 1 << 5, Darkvater@4938: Darkvater@4938: WWB_MASK = 0xE0, truelight@0: }; truelight@0: truelight@0: rubidium@10083: /** rubidium@10083: * Window widget types rubidium@10083: */ truelight@0: enum WindowWidgetTypes { rubidium@10083: WWT_EMPTY, ///< Empty widget, place holder to reserve space in widget array Darkvater@4938: rubidium@10083: WWT_PANEL, ///< Simple depressed panel rubidium@10083: WWT_INSET, ///< Pressed (inset) panel, most commonly used as combo box _text_ area rubidium@10083: WWT_IMGBTN, ///< Button with image rubidium@10083: WWT_IMGBTN_2, ///< Button with diff image when clicked truelight@0: rubidium@10083: WWT_TEXTBTN, ///< Button with text rubidium@10083: WWT_TEXTBTN_2, ///< Button with diff text when clicked rubidium@10083: WWT_LABEL, ///< Centered label rubidium@10083: WWT_TEXT, ///< Pure simple text rubidium@10083: WWT_MATRIX, ///< List of items underneath each other rubidium@10083: WWT_SCROLLBAR, ///< Vertical scrollbar rubidium@10083: WWT_FRAME, ///< Frame rubidium@10083: WWT_CAPTION, ///< Window caption (window title between closebox and stickybox) rubidium@10083: rubidium@10083: WWT_HSCROLLBAR, ///< Horizontal scrollbar rubidium@10083: WWT_STICKYBOX, ///< Sticky box (normally at top-right of a window) belugas@6443: WWT_SCROLL2BAR, ///< 2nd vertical scrollbar rubidium@10083: WWT_RESIZEBOX, ///< Resize box (normally at bottom-right of a window) rubidium@10083: WWT_CLOSEBOX, ///< Close box (at top-left of a window) peter1138@8831: WWT_DROPDOWN, ///< Raised drop down list (regular) peter1138@8831: WWT_DROPDOWNIN, ///< Inset drop down list (used on game options only) rubidium@9233: WWT_EDITBOX, ///< a textbox for typing (don't forget to call ShowOnScreenKeyboard() when clicked) belugas@6443: WWT_LAST, ///< Last Item. use WIDGETS_END to fill up padding!! Darkvater@4939: Darkvater@4939: WWT_MASK = 0x1F, truelight@0: Darkvater@4938: WWT_PUSHBTN = WWT_PANEL | WWB_PUSHBUTTON, rubidium@4434: WWT_PUSHTXTBTN = WWT_TEXTBTN | WWB_PUSHBUTTON, rubidium@4434: WWT_PUSHIMGBTN = WWT_IMGBTN | WWB_PUSHBUTTON, truelight@0: }; truelight@0: truelight@867: #define WIDGETS_END WWT_LAST, RESIZE_NONE, 0, 0, 0, 0, 0, 0, STR_NULL darkvater@176: rubidium@10083: /** rubidium@10083: * Window flags rubidium@10083: */ truelight@0: enum WindowFlags { rubidium@10083: WF_TIMEOUT_SHL = 0, ///< Window timeout counter shift rubidium@10083: WF_TIMEOUT_MASK = 7, ///< Window timeout counter bit mask (3 bits), @see WF_TIMEOUT_SHL rubidium@10083: WF_DRAGGING = 1 << 3, ///< Window is being dragged rubidium@10083: WF_SCROLL_UP = 1 << 4, ///< Upper scroll button has been pressed, @see ScrollbarClickHandler() rubidium@10083: WF_SCROLL_DOWN = 1 << 5, ///< Lower scroll button has been pressed, @see ScrollbarClickHandler() rubidium@10083: WF_SCROLL_MIDDLE = 1 << 6, ///< Scrollbar scrolling, @see ScrollbarClickHandler() rubidium@4344: WF_HSCROLL = 1 << 7, rubidium@4344: WF_SIZING = 1 << 8, rubidium@10083: WF_STICKY = 1 << 9, ///< Window is made sticky by user truelight@867: rubidium@10083: WF_DISABLE_VP_SCROLL = 1 << 10, ///< Window does not do autoscroll, @see HandleAutoscroll() truelight@0: rubidium@4344: WF_WHITE_BORDER_ONE = 1 << 11, Darkvater@5667: WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE, rubidium@4344: WF_SCROLL2 = 1 << 13, truelight@0: }; truelight@0: belugas@6443: /* window.cpp */ truelight@0: void CallWindowEventNP(Window *w, int event); rubidium@6573: void CallWindowTickEvent(); rubidium@8041: belugas@4171: void SetWindowDirty(const Window *w); rubidium@5838: void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam); rubidium@5838: void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam); truelight@0: truelight@0: Window *FindWindowById(WindowClass cls, WindowNumber number); truelight@0: void DeleteWindow(Window *w); bjarni@5077: void DeletePlayerWindows(PlayerID pi); bjarni@5077: void ChangeWindowOwner(PlayerID old_player, PlayerID new_player); truelight@0: Window *BringWindowToFrontById(WindowClass cls, WindowNumber number); truelight@0: Window *FindWindowFromPt(int x, int y); truelight@0: belugas@4171: bool IsWindowOfPrototype(const Window *w, const Widget *widget); truelight@867: void AssignWidgetToWindow(Window *w, const Widget *widget); truelight@0: Window *AllocateWindow( truelight@0: int x, truelight@0: int y, truelight@0: int width, truelight@0: int height, truelight@158: WindowProc *proc, truelight@0: WindowClass cls, rubidium@7863: const Widget *widget, rubidium@7863: void *data = NULL); truelight@0: rubidium@7863: Window *AllocateWindowDesc(const WindowDesc *desc, void *data = NULL); rubidium@7863: Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number, void *data = NULL); truelight@0: Darkvater@5120: void DrawWindowViewport(const Window *w); Darkvater@5268: void ResizeWindow(Window *w, int x, int y); truelight@0: rubidium@6573: void InitWindowSystem(); rubidium@6573: void UnInitWindowSystem(); rubidium@6573: void ResetWindowSystem(); Darkvater@2436: int GetMenuItemIndex(const Window *w, int x, int y); rubidium@6573: void InputLoop(); bjarni@4766: void InvalidateThisWindowData(Window *w); bjarni@4739: void InvalidateWindowData(WindowClass cls, WindowNumber number); truelight@0: void RelocateAllWindows(int neww, int newh); truelight@0: belugas@6443: /* misc_gui.cpp */ rubidium@7502: void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint64 params[]); Darkvater@4834: static inline void GuiShowTooltips(StringID str) Darkvater@4834: { Darkvater@4834: GuiShowTooltipsWithArgs(str, 0, NULL); Darkvater@4834: } belugas@4719: belugas@6443: /* widget.cpp */ Darkvater@2436: int GetWidgetFromPos(const Window *w, int x, int y); Darkvater@2436: void DrawWindowWidgets(const Window *w); truelight@0: peter1138@8845: enum SortButtonState { peter1138@8845: SBS_OFF, peter1138@8845: SBS_DOWN, peter1138@8845: SBS_UP, peter1138@8845: }; peter1138@8845: peter1138@8845: void DrawSortButtonState(const Window *w, int widget, SortButtonState state); peter1138@8845: truelight@0: rubidium@6573: Window *GetCallbackWnd(); rubidium@6573: void DeleteNonVitalWindows(); rubidium@6573: void DeleteAllNonVitalWindows(); rubidium@6573: void HideVitalWindows(); rubidium@6573: void ShowVitalWindows(); Darkvater@5124: Window **FindWindowZPosition(const Window *w); truelight@0: belugas@6443: /* window.cpp */ Darkvater@5124: extern Window *_z_windows[]; Darkvater@5124: extern Window **_last_z_window; Darkvater@5124: #define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++) truelight@0: rubidium@8764: extern Point _cursorpos_drag_start; truelight@0: rubidium@8764: extern int _scrollbar_start_pos; rubidium@8764: extern int _scrollbar_size; rubidium@8764: extern byte _scroller_click_timeout; truelight@0: rubidium@8764: extern bool _scrolling_scrollbar; rubidium@8764: extern bool _scrolling_viewport; rubidium@8764: extern bool _popup_menu_active; truelight@0: rubidium@8764: extern byte _special_mouse_mode; truelight@0: enum SpecialMouseMode { rubidium@4344: WSM_NONE = 0, truelight@0: WSM_DRAGDROP = 1, rubidium@4344: WSM_SIZING = 2, rubidium@4344: WSM_PRESIZE = 3, truelight@0: }; truelight@0: truelight@0: void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y); truelight@0: bjarni@6073: void ResizeButtons(Window *w, byte left, byte right); bjarni@6073: peter1138@8914: void ResizeWindowForWidget(Window *w, int widget, int delta_x, int delta_y); peter1138@8914: belugas@8489: belugas@8489: /** belugas@8489: * Sets the enabled/disabled status of a widget. belugas@8489: * By default, widgets are enabled. belugas@8489: * On certain conditions, they have to be disabled. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: * @param disab_stat : status to use ie: disabled = true, enabled = false belugas@8489: */ belugas@8489: inline void Window::SetWidgetDisabledState(byte widget_index, bool disab_stat) belugas@8489: { belugas@8489: assert(widget_index < this->widget_count); belugas@8489: SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Sets a widget to disabled. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: */ belugas@8489: inline void Window::DisableWidget(byte widget_index) belugas@8489: { belugas@8489: SetWidgetDisabledState(widget_index, true); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Sets a widget to Enabled. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: */ rubidium@8491: inline void Window::EnableWidget(byte widget_index) rubidium@8491: { rubidium@8491: SetWidgetDisabledState(widget_index, false); rubidium@8491: } belugas@8489: belugas@8489: /** belugas@8489: * Gets the enabled/disabled status of a widget. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: * @return status of the widget ie: disabled = true, enabled = false belugas@8489: */ rubidium@8491: inline bool Window::IsWidgetDisabled(byte widget_index) const belugas@8489: { belugas@8489: assert(widget_index < this->widget_count); belugas@8489: return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Sets the hidden/shown status of a widget. belugas@8489: * By default, widgets are visible. belugas@8489: * On certain conditions, they have to be hidden. belugas@8489: * @param widget_index index of this widget in the window belugas@8489: * @param hidden_stat status to use ie. hidden = true, visible = false belugas@8489: */ belugas@8489: inline void Window::SetWidgetHiddenState(byte widget_index, bool hidden_stat) belugas@8489: { belugas@8489: assert(widget_index < this->widget_count); belugas@8489: SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Sets a widget hidden. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: */ belugas@8489: inline void Window::HideWidget(byte widget_index) belugas@8489: { belugas@8489: SetWidgetHiddenState(widget_index, true); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Sets a widget visible. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: */ belugas@8489: inline void Window::ShowWidget(byte widget_index) belugas@8489: { belugas@8489: SetWidgetHiddenState(widget_index, false); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Gets the visibility of a widget. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: * @return status of the widget ie: hidden = true, visible = false belugas@8489: */ rubidium@8491: inline bool Window::IsWidgetHidden(byte widget_index) const belugas@8489: { belugas@8489: assert(widget_index < this->widget_count); belugas@8489: return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Sets the lowered/raised status of a widget. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: * @param lowered_stat : status to use ie: lowered = true, raised = false belugas@8489: */ belugas@8489: inline void Window::SetWidgetLoweredState(byte widget_index, bool lowered_stat) belugas@8489: { belugas@8489: assert(widget_index < this->widget_count); belugas@8489: SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Invert the lowered/raised status of a widget. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: */ rubidium@8492: inline void Window::ToggleWidgetLoweredState(byte widget_index) belugas@8489: { belugas@8489: assert(widget_index < this->widget_count); belugas@8489: ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Marks a widget as lowered. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: */ belugas@8489: inline void Window::LowerWidget(byte widget_index) belugas@8489: { belugas@8489: SetWidgetLoweredState(widget_index, true); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Marks a widget as raised. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: */ belugas@8489: inline void Window::RaiseWidget(byte widget_index) belugas@8489: { belugas@8489: SetWidgetLoweredState(widget_index, false); belugas@8489: } belugas@8489: belugas@8489: /** belugas@8489: * Gets the lowered state of a widget. belugas@8489: * @param widget_index : index of this widget in the window belugas@8489: * @return status of the widget ie: lowered = true, raised= false belugas@8489: */ rubidium@8491: inline bool Window::IsWidgetLowered(byte widget_index) const belugas@8489: { belugas@8489: assert(widget_index < this->widget_count); belugas@8489: return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED); belugas@8489: } belugas@8489: rubidium@8602: #endif /* WINDOW_GUI_H */