tron@2186: /* $Id$ */ tron@2186: rubidium@8106: /** @file window_gui.h Functions, definitions and such used only by the GUI. */ belugas@6117: rubidium@8106: #ifndef WINDOW_GUI_H rubidium@8106: #define WINDOW_GUI_H truelight@0: rubidium@8222: #include "core/bitmath_func.hpp" rubidium@9127: #include "core/geometry_type.hpp" rubidium@8139: #include "vehicle_type.h" rubidium@8224: #include "viewport_type.h" rubidium@10208: #include "company_type.h" rubidium@8264: #include "strings_type.h" rubidium@8925: #include "core/alloc_type.hpp" rubidium@9127: #include "window_type.h" rubidium@9127: #include "tile_type.h" truelight@4299: rubidium@8068: /** rubidium@8068: * The maximum number of windows that can be opened. rubidium@8068: */ rubidium@8068: static const int MAX_NUMBER_OF_WINDOWS = 25; rubidium@8068: 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 rubidium@8969: 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@6248: enum ResizeFlag { belugas@6179: RESIZE_NONE = 0, ///< no resize required truelight@867: belugas@6179: RESIZE_LEFT = 1, ///< left resize flag belugas@6179: RESIZE_RIGHT = 2, ///< rigth resize flag belugas@6179: RESIZE_TOP = 4, ///< top resize flag belugas@6179: RESIZE_BOTTOM = 8, ///< bottom resize flag truelight@867: belugas@6179: RESIZE_LR = RESIZE_LEFT | RESIZE_RIGHT, ///< combination of left and right resize flags belugas@6179: RESIZE_RB = RESIZE_RIGHT | RESIZE_BOTTOM, ///< combination of right and bottom resize flags belugas@6179: RESIZE_TB = RESIZE_TOP | RESIZE_BOTTOM, ///< combination of top and bottom resize flags belugas@6179: RESIZE_LRB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_BOTTOM, ///< combination of left, right and bottom resize flags belugas@6179: RESIZE_LRTB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM, ///< combination of all resize flags belugas@6179: 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@6117: WIDG_DISABLED = 4, ///< widget is greyed out, not available belugas@6117: WIDG_HIDDEN = 5, ///< widget is made invisible belugas@6117: WIDG_LOWERED = 6, ///< widget is paint lowered, a pressed button in fact rubidium@6248: }; truelight@867: glx@4755: enum { belugas@6179: WIDGET_LIST_END = -1, ///< indicate the end of widgets' list for vararg functions glx@4755: }; glx@4755: rubidium@8857: /** rubidium@8857: * Window widget data structure rubidium@8857: */ rubidium@6248: struct Widget { belugas@6117: byte type; ///< Widget type, see WindowWidgetTypes rubidium@9773: byte display_flags; ///< Resize direction, alignment, etc. during resizing. @see ResizeFlags Darkvater@4547: byte color; ///< Widget colour, see docs/ottd-colourtext-palette.png rubidium@10238: int16 left; ///< The left edge of the widget rubidium@10238: int16 right; ///< The right edge of the widget rubidium@10238: int16 top; ///< The top edge of the widget rubidium@10238: int16 bottom; ///< The bottom edge of the widget 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@6248: }; truelight@0: rubidium@8857: /** rubidium@8857: * Flags to describe the look of the frame rubidium@8857: */ rubidium@6248: enum FrameFlags { belugas@8008: FR_NONE = 0, belugas@8008: FR_TRANSPARENT = 1 << 0, ///< Makes the background transparent if set belugas@8008: FR_BORDERONLY = 1 << 4, ///< Draw border only, no background belugas@8008: FR_LOWERED = 1 << 5, ///< If set the frame is lowered and the background color brighter (ie. buttons when pressed) belugas@8008: 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@6248: }; tron@4437: rubidium@5587: DECLARE_ENUM_AS_BIT_SET(FrameFlags); rubidium@5587: rubidium@8857: /* wiget.cpp */ tron@4437: void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags); hackykid@1938: rubidium@8857: /** rubidium@8857: * High level window description rubidium@8857: */ rubidium@6248: struct WindowDesc { rubidium@8857: int16 left; ///< Prefered x position of left edge of the window, @see WindowDefaultPosition() rubidium@8857: int16 top; ///< Prefered y position of the top of the window, @see WindowDefaultPosition() rubidium@8857: int16 minimum_width; ///< Minimal width of the window rubidium@8857: int16 minimum_height; ///< Minimal height of the window rubidium@8857: int16 default_width; ///< Prefered initial width of the window rubidium@8857: int16 default_height; ///< Prefered initial height of the window rubidium@8857: WindowClass cls; ///< Class of the window, @see WindowClass rubidium@8857: WindowClass parent_cls; ///< Class of the parent window, @see WindowClass rubidium@8857: uint32 flags; ///< Flags, @see WindowDefaultFlags rubidium@8857: const Widget *widgets; ///< List of widgets with their position and size for the window rubidium@6248: }; truelight@0: rubidium@8857: /** rubidium@8857: * Window default widget/window handling flags rubidium@8857: */ Darkvater@5413: enum WindowDefaultFlag { belugas@8008: WDF_STD_TOOLTIPS = 1 << 0, ///< use standard routine when displaying tooltips rubidium@8857: WDF_DEF_WIDGET = 1 << 1, ///< Default widget control for some widgets in the on click event, @see DispatchLeftClickEvent() rubidium@8857: WDF_STD_BTN = 1 << 2, ///< Default handling for close and titlebar widgets (widget no 0 and 1) belugas@8019: rubidium@8857: WDF_UNCLICK_BUTTONS = 1 << 4, ///< Unclick buttons when the window event times out belugas@8008: WDF_STICKY_BUTTON = 1 << 5, ///< Set window to sticky mode; they are not closed unless closed with 'X' (widget 2) rubidium@8857: WDF_RESIZABLE = 1 << 6, ///< Window can be resized belugas@8008: WDF_MODAL = 1 << 7, ///< The window is a modal child of some other window, meaning the parent is 'inactive' truelight@0: }; truelight@0: rubidium@8857: /** rubidium@8857: * Special values for 'left' and 'top' to cause a specific placement rubidium@8857: */ Darkvater@5413: 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@8857: /** rubidium@8857: * Scrollbar data structure rubidium@8857: */ rubidium@6248: struct Scrollbar { rubidium@8857: uint16 count; ///< Number of elements in the list rubidium@8857: uint16 cap; ///< Number of visible elements of the scroll bar rubidium@9773: uint16 pos; ///< Index of first visible item of the list rubidium@6248: }; truelight@0: rubidium@8857: /** rubidium@8857: * Data structure for resizing a window rubidium@8857: */ rubidium@6248: struct ResizeInfo { rubidium@8857: uint width; ///< Minimum allowed width of the window rubidium@8857: uint height; ///< Minimum allowed height of the window rubidium@8857: uint step_width; ///< Step-size of width resize changes rubidium@8857: uint step_height; ///< Step-size of height resize changes rubidium@6248: }; truelight@867: rubidium@9273: enum SortButtonState { rubidium@9273: SBS_OFF, rubidium@9273: SBS_DOWN, rubidium@9273: SBS_UP, rubidium@9273: }; rubidium@9273: rubidium@8857: /** glx@9184: * Data structure for a window viewport glx@9184: */ glx@9184: struct ViewportData : ViewPort { glx@9184: VehicleID follow_vehicle; glx@9184: int32 scrollpos_x; glx@9184: int32 scrollpos_y; glx@9184: int32 dest_scrollpos_x; glx@9184: int32 dest_scrollpos_y; glx@9184: }; glx@9184: belugas@9267: /** rubidium@8857: * Data structure for an opened window rubidium@8857: */ rubidium@8925: struct Window : ZeroedMemoryAllocator { rubidium@10238: /** State whether an event is handled or not */ rubidium@9285: enum EventState { rubidium@10238: ES_HANDLED, ///< The passed event is handled rubidium@10238: ES_NOT_HANDLED, ///< The passed event is not handled rubidium@9285: }; rubidium@9285: rubidium@9142: protected: rubidium@9178: void Initialize(int x, int y, int min_width, int min_height, rubidium@9317: WindowClass cls, const Widget *widget, int window_number); rubidium@9178: void FindWindowPlacementAndResize(int def_width, int def_height); rubidium@9178: void FindWindowPlacementAndResize(const WindowDesc *desc); rubidium@9142: rubidium@9082: public: rubidium@9301: Window(int x, int y, int width, int height, WindowClass cls, const Widget *widget); rubidium@9203: Window(const WindowDesc *desc, WindowNumber number = 0); rubidium@9142: rubidium@9115: virtual ~Window(); rubidium@9082: rubidium@8857: uint16 flags4; ///< Window flags, @see WindowFlags rubidium@8857: WindowClass window_class; ///< Window class rubidium@8857: WindowNumber window_number; ///< Window number within the window class truelight@0: rubidium@8857: int left; ///< x position of left edge of the window rubidium@8857: int top; ///< y position of top edge of the window rubidium@8857: int width; ///< width of the window (number of pixels to the right in x direction) rubidium@8857: int height; ///< Height of the window (number of pixels down in y direction) truelight@0: rubidium@8857: Scrollbar hscroll; ///< Horizontal scroll bar rubidium@8857: Scrollbar vscroll; ///< First vertical scroll bar rubidium@8857: Scrollbar vscroll2; ///< Second vertical scroll bar rubidium@8857: ResizeInfo resize; ///< Resize information truelight@0: rubidium@10207: byte caption_color; ///< Background color of the window caption, contains CompanyID rubidium@8857: glx@9184: ViewportData *viewport; ///< Pointer to viewport data, if present rubidium@8857: Widget *widget; ///< Widgets of the window rubidium@8857: uint widget_count; ///< Number of widgets of the window rubidium@8857: uint32 desc_flags; ///< Window/widgets default flags setting, @see WindowDefaultFlag rubidium@8857: rubidium@8857: Window *parent; ///< Parent window belugas@7993: belugas@8035: void HandleButtonClick(byte widget); belugas@8035: belugas@7993: void SetWidgetDisabledState(byte widget_index, bool disab_stat); belugas@7993: void DisableWidget(byte widget_index); belugas@7993: void EnableWidget(byte widget_index); rubidium@7995: bool IsWidgetDisabled(byte widget_index) const; belugas@7993: void SetWidgetHiddenState(byte widget_index, bool hidden_stat); belugas@7993: void HideWidget(byte widget_index); belugas@7993: void ShowWidget(byte widget_index); rubidium@7995: bool IsWidgetHidden(byte widget_index) const; belugas@7993: void SetWidgetLoweredState(byte widget_index, bool lowered_stat); rubidium@7996: void ToggleWidgetLoweredState(byte widget_index); belugas@7993: void LowerWidget(byte widget_index); belugas@7993: void RaiseWidget(byte widget_index); rubidium@7995: bool IsWidgetLowered(byte widget_index) const; rubidium@9660: void AlignWidgetRight(byte widget_index_a, byte widget_index_b); rubidium@9660: int GetWidgetWidth(byte widget_index) const; belugas@7993: belugas@7993: void RaiseButtons(); belugas@7993: void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...); belugas@7993: void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...); belugas@7993: void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...); glx@8026: void InvalidateWidget(byte widget_index) const; rubidium@9082: rubidium@9273: void DrawWidgets() const; rubidium@9273: void DrawViewport() const; rubidium@9273: void DrawSortButtonState(int widget, SortButtonState state) const; rubidium@9273: smatz@10184: void DeleteChildWindows() const; smatz@10184: rubidium@9115: void SetDirty() const; rubidium@9115: rubidium@9166: /*** Event handling ***/ rubidium@9166: rubidium@9166: /** rubidium@9166: * This window is currently being repainted. rubidium@9166: */ rubidium@9317: virtual void OnPaint() {} rubidium@9166: rubidium@9166: rubidium@9166: /** rubidium@9166: * A key has been pressed. rubidium@9166: * @param key the Unicode value of the key. rubidium@9166: * @param keycode the untranslated key code including shift state. rubidium@9285: * @return ES_HANDLED if the key press has been handled and no other rubidium@9166: * window should receive the event. rubidium@9166: */ rubidium@9317: virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; } rubidium@9166: rubidium@9166: /** rubidium@9166: * The state of the control key has changed rubidium@9285: * @return ES_HANDLED if the change has been handled and no other rubidium@9166: * window should receive the event. rubidium@9166: */ rubidium@9317: virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; } rubidium@9166: rubidium@9166: rubidium@9166: /** rubidium@9166: * A click with the left mouse button has been made on the window. rubidium@9166: * @param pt the point inside the window that has been clicked. rubidium@9166: * @param widget the clicked widget. rubidium@9166: */ rubidium@9317: virtual void OnClick(Point pt, int widget) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * A double click with the left mouse button has been made on the window. rubidium@9166: * @param pt the point inside the window that has been clicked. rubidium@9166: * @param widget the clicked widget. rubidium@9166: */ rubidium@9264: virtual void OnDoubleClick(Point pt, int widget) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * A click with the right mouse button has been made on the window. rubidium@9166: * @param pt the point inside the window that has been clicked. rubidium@9166: * @param widget the clicked widget. rubidium@9166: */ rubidium@9264: virtual void OnRightClick(Point pt, int widget) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * A dragged 'object' has been released. rubidium@9166: * @param pt the point inside the window where the release took place. rubidium@9166: * @param widget the widget where the release took place. rubidium@9166: */ rubidium@9264: virtual void OnDragDrop(Point pt, int widget) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * Handle the request for (viewport) scrolling. rubidium@9166: * @param delta the amount the viewport must be scrolled. rubidium@9166: */ rubidium@9264: virtual void OnScroll(Point delta) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * The mouse is currently moving over the window or has just moved outside rubidium@9166: * of the window. In the latter case pt is (-1, -1). rubidium@9166: * @param pt the point inside the window that the mouse hovers over. rubidium@9166: * @param widget the widget the mouse hovers over. rubidium@9166: */ rubidium@9264: virtual void OnMouseOver(Point pt, int widget) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * The mouse wheel has been turned. rubidium@9166: * @param wheel the amount of movement of the mouse wheel. rubidium@9166: */ rubidium@9264: virtual void OnMouseWheel(int wheel) {} rubidium@9166: rubidium@9166: rubidium@9166: /** rubidium@9166: * Called for every mouse loop run, which is at least once per (game) tick. rubidium@9166: */ rubidium@9317: virtual void OnMouseLoop() {} rubidium@9166: rubidium@9166: /** rubidium@9166: * Called once per (game) tick. rubidium@9166: */ rubidium@9317: virtual void OnTick() {} rubidium@9166: rubidium@9166: /** rubidium@9166: * Called once every 100 (game) ticks. rubidium@9166: */ rubidium@9317: virtual void OnHundredthTick() {} rubidium@9166: rubidium@9166: /** rubidium@9166: * Called when this window's timeout has been reached. rubidium@9166: */ rubidium@9317: virtual void OnTimeout() {} rubidium@9166: rubidium@9166: rubidium@9166: /** rubidium@9166: * Called when the window got resized. rubidium@9166: * @param new_size the new size of the window. rubidium@9166: * @param delta the amount of which the window size changed. rubidium@9166: */ rubidium@9317: virtual void OnResize(Point new_size, Point delta) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * A dropdown option associated to this window has been selected. rubidium@9166: * @param widget the widget (button) that the dropdown is associated with. rubidium@9166: * @param index the element in the dropdown that is selected. rubidium@9166: */ rubidium@9317: virtual void OnDropdownSelect(int widget, int index) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * The query window opened from this window has closed. rubidium@9166: * @param str the new value of the string or NULL if the window rubidium@9166: * was cancelled. rubidium@9166: */ rubidium@9317: virtual void OnQueryTextFinished(char *str) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * Some data on this window has become invalid. rubidium@9166: * @param data information about the changed data. rubidium@9166: */ rubidium@9317: virtual void OnInvalidateData(int data = 0) {} rubidium@9166: rubidium@9166: rubidium@9166: /** rubidium@9166: * The user clicked some place on the map when a tile highlight mode rubidium@9166: * has been set. rubidium@9166: * @param pt the exact point on the map that has been clicked. rubidium@9166: * @param tile the tile on the map that has been clicked. rubidium@9166: */ rubidium@9317: virtual void OnPlaceObject(Point pt, TileIndex tile) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * The user cancelled a tile highlight mode that has been set. rubidium@9166: */ rubidium@9317: virtual void OnPlaceObjectAbort() {} rubidium@9166: rubidium@9166: rubidium@9166: /** rubidium@9166: * The user is dragging over the map when the tile highlight mode rubidium@9166: * has been set. rubidium@9166: * @param select_method the method of selection (allowed directions) rubidium@9166: * @param select_proc what will be created when the drag is over. rubidium@9166: * @param pt the exact point on the map where the mouse is. rubidium@9166: */ rubidium@9317: virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * The user has dragged over the map when the tile highlight mode rubidium@9166: * has been set. rubidium@9166: * @param select_method the method of selection (allowed directions) rubidium@9166: * @param select_proc what should be created. rubidium@9166: * @param pt the exact point on the map where the mouse was released. rubidium@9166: * @param start_tile the begin tile of the drag. rubidium@9166: * @param end_tile the end tile of the drag. rubidium@9166: */ rubidium@9317: virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {} rubidium@9166: rubidium@9166: /** rubidium@9166: * The user moves over the map when a tile highlight mode has been set rubidium@9166: * when the special mouse mode has been set to 'PRESIZE' mode. An rubidium@9166: * example of this is the tile highlight for dock building. rubidium@9166: * @param pt the exact point on the map where the mouse is. rubidium@9166: * @param tile the tile on the map where the mouse is. rubidium@9166: */ rubidium@9317: virtual void OnPlacePresize(Point pt, TileIndex tile) {} rubidium@9166: rubidium@9166: /*** End of the event handling ***/ truelight@0: }; truelight@0: belugas@9267: /** belugas@9267: * Data structure for a window opened from a toolbar belugas@9267: */ belugas@9267: class PickerWindowBase : public Window { belugas@9267: belugas@9267: public: frosch@9338: PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc) frosch@9338: { frosch@9338: this->parent = parent; frosch@9338: }; belugas@9267: belugas@9267: virtual ~PickerWindowBase(); belugas@9267: }; belugas@9267: 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@8857: /** rubidium@8857: * Window widget types rubidium@8857: */ truelight@0: enum WindowWidgetTypes { rubidium@8857: WWT_EMPTY, ///< Empty widget, place holder to reserve space in widget array Darkvater@4938: rubidium@8857: WWT_PANEL, ///< Simple depressed panel rubidium@8857: WWT_INSET, ///< Pressed (inset) panel, most commonly used as combo box _text_ area rubidium@8857: WWT_IMGBTN, ///< Button with image rubidium@8857: WWT_IMGBTN_2, ///< Button with diff image when clicked truelight@0: rubidium@8857: WWT_TEXTBTN, ///< Button with text rubidium@8857: WWT_TEXTBTN_2, ///< Button with diff text when clicked rubidium@8857: WWT_LABEL, ///< Centered label rubidium@8857: WWT_TEXT, ///< Pure simple text rubidium@8857: WWT_MATRIX, ///< List of items underneath each other rubidium@8857: WWT_SCROLLBAR, ///< Vertical scrollbar rubidium@8857: WWT_FRAME, ///< Frame rubidium@8857: WWT_CAPTION, ///< Window caption (window title between closebox and stickybox) rubidium@8857: rubidium@8857: WWT_HSCROLLBAR, ///< Horizontal scrollbar rubidium@8857: WWT_STICKYBOX, ///< Sticky box (normally at top-right of a window) belugas@6117: WWT_SCROLL2BAR, ///< 2nd vertical scrollbar rubidium@8857: WWT_RESIZEBOX, ///< Resize box (normally at bottom-right of a window) rubidium@8857: WWT_CLOSEBOX, ///< Close box (at top-left of a window) peter1138@8335: WWT_DROPDOWN, ///< Raised drop down list (regular) peter1138@8335: WWT_DROPDOWNIN, ///< Inset drop down list (used on game options only) rubidium@8737: WWT_EDITBOX, ///< a textbox for typing (don't forget to call ShowOnScreenKeyboard() when clicked) belugas@6117: 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: rubidium@10238: /** Marker for the "end of widgets" in a Window(Desc) widget table. */ truelight@867: #define WIDGETS_END WWT_LAST, RESIZE_NONE, 0, 0, 0, 0, 0, 0, STR_NULL darkvater@176: rubidium@8857: /** rubidium@8857: * Window flags rubidium@8857: */ truelight@0: enum WindowFlags { rubidium@10181: WF_TIMEOUT_TRIGGER = 1, ///< When the timeout should start triggering rubidium@10181: WF_TIMEOUT_BEGIN = 7, ///< The initial value for the timeout rubidium@10180: WF_TIMEOUT_MASK = 7, ///< Window timeout counter bit mask (3 bits) rubidium@8857: WF_DRAGGING = 1 << 3, ///< Window is being dragged rubidium@8857: WF_SCROLL_UP = 1 << 4, ///< Upper scroll button has been pressed, @see ScrollbarClickHandler() rubidium@8857: WF_SCROLL_DOWN = 1 << 5, ///< Lower scroll button has been pressed, @see ScrollbarClickHandler() rubidium@8857: WF_SCROLL_MIDDLE = 1 << 6, ///< Scrollbar scrolling, @see ScrollbarClickHandler() rubidium@4344: WF_HSCROLL = 1 << 7, rubidium@4344: WF_SIZING = 1 << 8, rubidium@8857: WF_STICKY = 1 << 9, ///< Window is made sticky by user truelight@867: rubidium@8857: WF_DISABLE_VP_SCROLL = 1 << 10, ///< Window does not do autoscroll, @see HandleAutoscroll() truelight@0: rubidium@4344: WF_WHITE_BORDER_ONE = 1 << 11, Darkvater@5416: WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE, rubidium@4344: WF_SCROLL2 = 1 << 13, truelight@0: }; truelight@0: truelight@0: Window *BringWindowToFrontById(WindowClass cls, WindowNumber number); truelight@0: Window *FindWindowFromPt(int x, int y); truelight@0: rubidium@9143: /** rubidium@9143: * Open a new window. rubidium@10238: * @param desc The pointer to the WindowDesc to be created rubidium@9143: * @param window_number the window number of the new window rubidium@9143: * @return see Window pointer of the newly created window rubidium@9143: */ rubidium@9143: template rubidium@9203: Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number) rubidium@9143: { rubidium@9143: if (BringWindowToFrontById(desc->cls, window_number)) return NULL; rubidium@9203: return new Wcls(desc, window_number); rubidium@9143: } truelight@0: truelight@0: void RelocateAllWindows(int neww, int newh); truelight@0: belugas@6117: /* misc_gui.cpp */ frosch@9781: void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false); belugas@4719: belugas@6117: /* widget.cpp */ Darkvater@2436: int GetWidgetFromPos(const Window *w, int x, int y); truelight@0: belugas@6117: /* window.cpp */ Darkvater@5124: extern Window *_z_windows[]; Darkvater@5124: extern Window **_last_z_window; rubidium@10238: rubidium@10238: /** Iterate over all windows */ Darkvater@5124: #define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++) truelight@0: rubidium@9411: /** rubidium@10426: * Disable scrolling of the main viewport when an input-window is active. rubidium@10426: * This contains the count of windows with a textbox in them. rubidium@9411: */ rubidium@9411: extern byte _no_scroll; rubidium@9411: rubidium@8268: extern Point _cursorpos_drag_start; truelight@0: rubidium@8268: extern int _scrollbar_start_pos; rubidium@8268: extern int _scrollbar_size; rubidium@8268: extern byte _scroller_click_timeout; truelight@0: rubidium@8268: extern bool _scrolling_scrollbar; rubidium@8268: extern bool _scrolling_viewport; truelight@0: rubidium@8268: 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: rubidium@8995: Window *GetCallbackWnd(); rubidium@8995: Window **FindWindowZPosition(const Window *w); rubidium@8995: truelight@0: void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y); truelight@0: bjarni@5822: void ResizeButtons(Window *w, byte left, byte right); bjarni@5822: peter1138@9834: void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y); peter1138@8418: rubidium@9407: void SetVScrollCount(Window *w, int num); rubidium@9407: void SetVScroll2Count(Window *w, int num); rubidium@9407: void SetHScrollCount(Window *w, int num); rubidium@9407: belugas@7993: belugas@7993: /** belugas@7993: * Sets the enabled/disabled status of a widget. belugas@7993: * By default, widgets are enabled. belugas@7993: * On certain conditions, they have to be disabled. rubidium@10238: * @param widget_index index of this widget in the window rubidium@10238: * @param disab_stat status to use ie: disabled = true, enabled = false belugas@7993: */ belugas@7993: inline void Window::SetWidgetDisabledState(byte widget_index, bool disab_stat) belugas@7993: { belugas@7993: assert(widget_index < this->widget_count); belugas@7993: SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Sets a widget to disabled. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: */ belugas@7993: inline void Window::DisableWidget(byte widget_index) belugas@7993: { belugas@7993: SetWidgetDisabledState(widget_index, true); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Sets a widget to Enabled. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: */ rubidium@7995: inline void Window::EnableWidget(byte widget_index) rubidium@7995: { rubidium@7995: SetWidgetDisabledState(widget_index, false); rubidium@7995: } belugas@7993: belugas@7993: /** belugas@7993: * Gets the enabled/disabled status of a widget. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: * @return status of the widget ie: disabled = true, enabled = false belugas@7993: */ rubidium@7995: inline bool Window::IsWidgetDisabled(byte widget_index) const belugas@7993: { belugas@7993: assert(widget_index < this->widget_count); belugas@7993: return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Sets the hidden/shown status of a widget. belugas@7993: * By default, widgets are visible. belugas@7993: * On certain conditions, they have to be hidden. belugas@7993: * @param widget_index index of this widget in the window belugas@7993: * @param hidden_stat status to use ie. hidden = true, visible = false belugas@7993: */ belugas@7993: inline void Window::SetWidgetHiddenState(byte widget_index, bool hidden_stat) belugas@7993: { belugas@7993: assert(widget_index < this->widget_count); belugas@7993: SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Sets a widget hidden. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: */ belugas@7993: inline void Window::HideWidget(byte widget_index) belugas@7993: { belugas@7993: SetWidgetHiddenState(widget_index, true); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Sets a widget visible. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: */ belugas@7993: inline void Window::ShowWidget(byte widget_index) belugas@7993: { belugas@7993: SetWidgetHiddenState(widget_index, false); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Gets the visibility of a widget. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: * @return status of the widget ie: hidden = true, visible = false belugas@7993: */ rubidium@7995: inline bool Window::IsWidgetHidden(byte widget_index) const belugas@7993: { belugas@7993: assert(widget_index < this->widget_count); belugas@7993: return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Sets the lowered/raised status of a widget. rubidium@10238: * @param widget_index index of this widget in the window rubidium@10238: * @param lowered_stat status to use ie: lowered = true, raised = false belugas@7993: */ belugas@7993: inline void Window::SetWidgetLoweredState(byte widget_index, bool lowered_stat) belugas@7993: { belugas@7993: assert(widget_index < this->widget_count); belugas@7993: SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Invert the lowered/raised status of a widget. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: */ rubidium@7996: inline void Window::ToggleWidgetLoweredState(byte widget_index) belugas@7993: { belugas@7993: assert(widget_index < this->widget_count); belugas@7993: ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Marks a widget as lowered. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: */ belugas@7993: inline void Window::LowerWidget(byte widget_index) belugas@7993: { belugas@7993: SetWidgetLoweredState(widget_index, true); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Marks a widget as raised. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: */ belugas@7993: inline void Window::RaiseWidget(byte widget_index) belugas@7993: { belugas@7993: SetWidgetLoweredState(widget_index, false); belugas@7993: } belugas@7993: belugas@7993: /** belugas@7993: * Gets the lowered state of a widget. rubidium@10238: * @param widget_index index of this widget in the window belugas@7993: * @return status of the widget ie: lowered = true, raised= false belugas@7993: */ rubidium@7995: inline bool Window::IsWidgetLowered(byte widget_index) const belugas@7993: { belugas@7993: assert(widget_index < this->widget_count); belugas@7993: return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED); belugas@7993: } belugas@7993: rubidium@9660: /** rubidium@9660: * Align widgets a and b next to each other. rubidium@9660: * @param widget_index_a the left widget rubidium@9660: * @param widget_index_b the right widget (fixed) rubidium@9660: */ rubidium@9660: inline void Window::AlignWidgetRight(byte widget_index_a, byte widget_index_b) rubidium@9660: { rubidium@9660: assert(widget_index_a < this->widget_count); rubidium@9660: assert(widget_index_b < this->widget_count); rubidium@9660: int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left; rubidium@9660: this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1; rubidium@9660: this->widget[widget_index_a].left = this->widget[widget_index_a].right - w; rubidium@9660: } rubidium@9660: rubidium@9660: /** rubidium@9660: * Get the width of a widget. rubidium@9660: * @param widget_index the widget rubidium@9660: * @return width of the widget rubidium@9660: */ rubidium@9660: inline int Window::GetWidgetWidth(byte widget_index) const rubidium@9660: { rubidium@9660: assert(widget_index < this->widget_count); rubidium@9660: return this->widget[widget_index].right - this->widget[widget_index].left + 1; rubidium@9660: } rubidium@9660: rubidium@8106: #endif /* WINDOW_GUI_H */