tron@2186: /* $Id$ */ tron@2186: truelight@0: #ifndef WINDOW_H truelight@0: #define WINDOW_H truelight@0: belugas@4692: #include "macros.h" truelight@4299: #include "string.h" bjarni@4712: #include "order.h" truelight@4299: belugas@4634: typedef struct WindowEvent WindowEvent; truelight@0: 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: Darkvater@4547: enum ResizeFlags { truelight@867: RESIZE_NONE = 0, truelight@867: truelight@867: RESIZE_LEFT = 1, truelight@867: RESIZE_RIGHT = 2, truelight@867: RESIZE_TOP = 4, truelight@867: RESIZE_BOTTOM = 8, truelight@867: truelight@867: RESIZE_LR = RESIZE_LEFT | RESIZE_RIGHT, truelight@867: RESIZE_RB = RESIZE_RIGHT | RESIZE_BOTTOM, truelight@867: RESIZE_TB = RESIZE_TOP | RESIZE_BOTTOM, truelight@867: RESIZE_LRB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_BOTTOM, truelight@867: RESIZE_LRTB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM, truelight@867: RESIZE_RTB = RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM, 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@4749: WIDG_DISABLED = 4, // widget is greyed out, not available belugas@4749: WIDG_HIDDEN = 5, // widget is made invisible belugas@4749: WIDG_LOWERED = 6, // widget is paint lowered, a pressed button in fact Darkvater@4547: } ResizeFlag; truelight@867: glx@4755: /* used to indicate the end of widgets' list for vararg functions */ glx@4755: enum { glx@4755: WIDGET_LIST_END = -1, glx@4755: }; glx@4755: truelight@0: typedef struct Widget { Darkvater@4547: byte type; ///< Widget type, see @WindowWidgetTypes belugas@4749: byte display_flags; ///< Resize direction, alignment, etc. during resizing, see @ResizeFlags Darkvater@4547: byte color; ///< Widget colour, see docs/ottd-colourtext-palette.png Darkvater@4547: uint16 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 truelight@0: } Widget; truelight@0: tron@4437: typedef enum FrameFlags { hackykid@1938: FR_TRANSPARENT = 0x01, ///< Makes the background transparent if set hackykid@1938: FR_BORDERONLY = 0x10, ///< Draw border only, no background hackykid@1938: FR_LOWERED = 0x20, ///< If set the frame is lowered and the background color brighter (ie. buttons when pressed) hackykid@1938: FR_DARKENED = 0x40, ///< If set the background is darker, allows for lowered frames with normal background color when used with FR_LOWERED (ie. dropdown boxes) tron@4437: } FrameFlags; tron@4437: tron@4437: void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags); hackykid@1938: belugas@4634: enum WindowEventCodes { Darkvater@5664: WE_CREATE, Darkvater@5664: WE_DESTROY, Darkvater@5664: WE_PAINT, Darkvater@5664: WE_KEYPRESS, Darkvater@5664: WE_CLICK, Darkvater@5664: WE_RCLICK, Darkvater@5664: WE_MOUSEOVER, Darkvater@5664: WE_MOUSELOOP, Darkvater@5664: WE_MOUSEWHEEL, Darkvater@5664: WE_TICK, Darkvater@5664: WE_4, 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, Darkvater@5664: WE_RESIZE, Darkvater@5664: WE_MESSAGE, Darkvater@5664: WE_SCROLL, Darkvater@5664: WE_INVALIDATE_DATA, belugas@4634: }; truelight@0: belugas@4634: struct WindowEvent { belugas@4634: byte event; belugas@4634: union { belugas@4634: 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; belugas@4634: int userdata; 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@4634: bool cont; // continue the search? (default true) peter1138@5108: uint16 key; // 16-bit Unicode value of the key belugas@4634: uint16 keycode;// untranslated key (including shift-state) belugas@4634: } keypress; belugas@4634: belugas@4634: struct { belugas@4634: uint msg; // message to be sent belugas@4634: uint wparam; // additional message-specific information belugas@4634: uint lparam; // additional message-specific information belugas@4634: } message; belugas@4634: belugas@4634: struct { belugas@4634: Point delta; // delta position against position of last call belugas@4634: } scroll; belugas@4634: belugas@4634: struct { belugas@4634: int wheel; // how much was 'wheel'd' belugas@4634: } wheel; belugas@4634: } we; truelight@0: }; truelight@0: truelight@0: enum WindowKeyCodes { truelight@0: WKC_SHIFT = 0x8000, truelight@0: WKC_CTRL = 0x4000, truelight@0: WKC_ALT = 0x2000, truelight@0: WKC_META = 0x1000, truelight@158: truelight@0: // Special ones rubidium@4344: WKC_NONE = 0, rubidium@4344: WKC_ESC = 1, rubidium@4344: WKC_BACKSPACE = 2, rubidium@4344: WKC_INSERT = 3, rubidium@4344: WKC_DELETE = 4, truelight@0: rubidium@4344: WKC_PAGEUP = 5, rubidium@4344: WKC_PAGEDOWN = 6, rubidium@4344: WKC_END = 7, rubidium@4344: WKC_HOME = 8, truelight@0: truelight@0: // Arrow keys rubidium@4344: WKC_LEFT = 9, rubidium@4344: WKC_UP = 10, rubidium@4344: WKC_RIGHT = 11, rubidium@4344: WKC_DOWN = 12, truelight@0: truelight@0: // Return & tab rubidium@4344: WKC_RETURN = 13, rubidium@4344: WKC_TAB = 14, truelight@158: truelight@0: // Numerical keyboard rubidium@4344: WKC_NUM_0 = 16, rubidium@4344: WKC_NUM_1 = 17, rubidium@4344: WKC_NUM_2 = 18, rubidium@4344: WKC_NUM_3 = 19, rubidium@4344: WKC_NUM_4 = 20, rubidium@4344: WKC_NUM_5 = 21, rubidium@4344: WKC_NUM_6 = 22, rubidium@4344: WKC_NUM_7 = 23, rubidium@4344: WKC_NUM_8 = 24, rubidium@4344: WKC_NUM_9 = 25, rubidium@4344: WKC_NUM_DIV = 26, rubidium@4344: WKC_NUM_MUL = 27, rubidium@4344: WKC_NUM_MINUS = 28, rubidium@4344: WKC_NUM_PLUS = 29, rubidium@4344: WKC_NUM_ENTER = 30, truelight@0: WKC_NUM_DECIMAL = 31, truelight@0: truelight@0: // Space rubidium@4344: WKC_SPACE = 32, truelight@0: truelight@0: // Function keys rubidium@4344: WKC_F1 = 33, rubidium@4344: WKC_F2 = 34, rubidium@4344: WKC_F3 = 35, rubidium@4344: WKC_F4 = 36, rubidium@4344: WKC_F5 = 37, rubidium@4344: WKC_F6 = 38, rubidium@4344: WKC_F7 = 39, rubidium@4344: WKC_F8 = 40, rubidium@4344: WKC_F9 = 41, rubidium@4344: WKC_F10 = 42, rubidium@4344: WKC_F11 = 43, rubidium@4344: WKC_F12 = 44, truelight@0: dominik@129: // backquote is the key left of "1" dominik@129: // we only store this key here, no matter what character is really mapped to it dominik@129: // on a particular keyboard. (US keyboard: ` and ~ ; German keyboard: ^ and °) rubidium@4344: WKC_BACKQUOTE = 45, rubidium@4344: WKC_PAUSE = 46, truelight@158: truelight@0: // 0-9 are mapped to 48-57 truelight@0: // A-Z are mapped to 65-90 truelight@0: // a-z are mapped to 97-122 truelight@0: }; truelight@0: truelight@0: typedef struct WindowDesc { truelight@0: int16 left, top, width, height; tron@2788: WindowClass cls; tron@2788: WindowClass parent_cls; truelight@0: uint32 flags; truelight@0: const Widget *widgets; truelight@0: WindowProc *proc; truelight@0: } WindowDesc; truelight@0: Darkvater@5664: enum WindowDefaultFlag { Darkvater@5667: WDF_STD_TOOLTIPS = 1, /* use standard routine when displaying tooltips */ Darkvater@5667: WDF_DEF_WIDGET = 2, /* default widget control for some widgets in the on click event */ Darkvater@5667: WDF_STD_BTN = 4, /* default handling for close and drag widgets (widget no 0 and 1) */ ludde@2064: Darkvater@5667: WDF_UNCLICK_BUTTONS = 16, /* Unclick buttons when the window event times out */ Darkvater@5667: WDF_STICKY_BUTTON = 32, /* Set window to sticky mode; they are not closed unless closed with 'X' (widget 2) */ Darkvater@5667: WDF_RESIZABLE = 64, /* A window can be resized */ Darkvater@5667: WDF_MODAL = 128, /* The window is a modal child of some other window, meaning the parent is 'inactive' */ truelight@0: }; truelight@0: truelight@0: /* can be used as x or y coordinates to cause a specific placement */ 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: Darkvater@1390: typedef struct Textbuf { Darkvater@1390: char *buf; /* buffer in which text is saved */ rubidium@5698: uint16 maxlength, maxwidth; /* the maximum size of the buffer. Maxwidth specifies screensize in pixels, maxlength is in bytes */ rubidium@5698: uint16 length, width; /* the current size of the string. Width specifies screensize in pixels, length is in bytes */ Darkvater@1390: bool caret; /* is the caret ("_") visible or not */ rubidium@5698: uint16 caretpos; /* the current position of the caret in the buffer, in bytes */ Darkvater@1390: uint16 caretxoffs; /* the current position of the caret in pixels */ Darkvater@1390: } Textbuf; Darkvater@1390: truelight@0: #define WP(ptr,str) (*(str*)(ptr)->custom) Darkvater@2906: /* You cannot 100% reliably calculate the biggest custom struct as Darkvater@2906: * the number of pointers in it and alignment will have a huge impact. truelight@4299: * 96 is the largest window-size for 64-bit machines currently */ truelight@4299: #define WINDOW_CUSTOM_SIZE 96 truelight@0: tron@2596: typedef struct Scrollbar { dominik@62: uint16 count, cap, pos; truelight@0: } Scrollbar; truelight@0: tron@2596: typedef struct ResizeInfo { truelight@867: uint width; /* Minimum width and height */ truelight@867: uint height; truelight@867: truelight@867: uint step_width; /* In how big steps the width and height go */ truelight@867: uint step_height; truelight@867: } ResizeInfo; truelight@867: truelight@2622: typedef struct WindowMessage { darkvater@1648: int msg; darkvater@1648: int wparam; darkvater@1648: int lparam; truelight@2622: } WindowMessage; darkvater@1648: truelight@0: struct Window { truelight@0: uint16 flags4; truelight@0: WindowClass window_class; truelight@0: WindowNumber window_number; truelight@0: truelight@867: int left, top; truelight@867: int width, height; truelight@0: bjarni@842: Scrollbar hscroll, vscroll, vscroll2; truelight@867: ResizeInfo resize; truelight@0: truelight@0: byte caption_color; truelight@0: truelight@0: WindowProc *wndproc; truelight@0: ViewPort *viewport; truelight@867: const Widget *original_widget; tron@4077: Widget *widget; rubidium@5232: uint widget_count; truelight@0: uint32 desc_flags; truelight@0: truelight@2622: WindowMessage message; Darkvater@5666: Window *parent; truelight@158: byte custom[WINDOW_CUSTOM_SIZE]; truelight@0: }; truelight@0: truelight@4299: typedef struct querystr_d { truelight@4299: StringID caption; truelight@4299: Textbuf text; truelight@4299: const char *orig; truelight@4299: CharSetFilter afilter; Darkvater@5682: bool handled; truelight@4299: } querystr_d; truelight@4299: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(querystr_d)); truelight@4299: truelight@0: typedef struct { belugas@4171: byte item_count; /* follow_vehicle */ belugas@4171: byte sel_index; /* scrollpos_x */ belugas@4171: byte main_button; /* scrollpos_y */ truelight@0: byte action_id; belugas@4171: StringID string_id; /* unk30 */ truelight@0: uint16 checked_items; /* unk32 */ celestar@2216: byte disabled_items; truelight@0: } menu_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(menu_d)); truelight@0: truelight@0: typedef struct { 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; truelight@0: } def_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(def_d)); truelight@0: truelight@0: typedef struct { truelight@0: void *data; truelight@0: } void_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(void_d)); truelight@0: truelight@0: typedef struct { tron@2596: uint16 base; tron@2596: uint16 count; truelight@0: } tree_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tree_d)); truelight@0: truelight@0: typedef struct { truelight@0: StringID string_id; Darkvater@4834: byte paramcount; Darkvater@4834: uint32 params[5]; truelight@0: } tooltips_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d)); truelight@0: truelight@0: typedef struct { bjarni@4800: byte vehicle_type; KUDr@5187: union { KUDr@5187: byte railtype; KUDr@5187: byte acc_planes; // AIRCRAFT_ONLY, ALL, HELICOPTERS_ONLY KUDr@5187: } filter; Darkvater@5199: byte sel_index; // deprecated value, used for 'unified' ship and road KUDr@5187: bool descending_sort_order; bjarni@4770: byte sort_criteria; tron@2498: EngineID sel_engine; tron@2498: EngineID rename_engine; KUDr@5187: EngineList eng_list; bjarni@4790: } buildvehicle_d; bjarni@4790: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(buildvehicle_d)); truelight@0: truelight@0: typedef struct { bjarni@842: byte vehicletype; bjarni@842: byte sel_index[2]; peter1138@2746: EngineID sel_engine[2]; bjarni@842: uint16 count[2]; rubidium@4434: bool wagon_btnstate; // true means engine is selected bjarni@842: } replaceveh_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(replaceveh_d)); bjarni@842: bjarni@842: typedef struct { truelight@0: VehicleID sel; bjarni@4638: byte 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; bjarni@4638: } depot_d; bjarni@4638: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(depot_d)); truelight@0: truelight@0: typedef struct { truelight@0: int sel; truelight@0: } order_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d)); truelight@0: truelight@0: typedef struct { truelight@0: byte tab; truelight@0: } traindetails_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(traindetails_d)); truelight@0: truelight@0: typedef struct { tron@849: int32 scroll_x; tron@849: int32 scroll_y; tron@849: int32 subscroll; truelight@0: } smallmap_d; truelight@4318: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d)); truelight@0: truelight@0: typedef struct { truelight@0: uint32 face; truelight@0: byte gender; truelight@0: } facesel_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(facesel_d)); truelight@0: truelight@0: typedef struct { truelight@0: int sel; peter1138@4695: struct RefitOption *cargo; peter1138@4694: struct RefitList *list; peter1138@4694: uint length; bjarni@4712: VehicleOrderID order; truelight@0: } refit_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(refit_d)); truelight@0: truelight@0: typedef struct { tron@2116: VehicleID follow_vehicle; tron@849: int32 scrollpos_x; tron@849: int32 scrollpos_y; truelight@0: } vp_d; Darkvater@5123: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp_d)); miham@1004: miham@1004: // vp2_d is the same as vp_d, except for the data_# values.. miham@1004: typedef struct { Darkvater@5123: VehicleID follow_vehicle; miham@1004: int32 scrollpos_x; miham@1004: int32 scrollpos_y; miham@1004: byte data_1; miham@1004: byte data_2; miham@1004: byte data_3; miham@1004: } vp2_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp2_d)); truelight@0: truelight@0: typedef struct { truelight@0: uint16 follow_vehicle; tron@849: int32 scrollpos_x; tron@849: int32 scrollpos_y; truelight@0: NewsItem *ni; truelight@0: } news_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(news_d)); truelight@0: darkvater@859: typedef struct { darkvater@998: uint32 background_img; darkvater@998: int8 rank; darkvater@998: } highscore_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(highscore_d)); darkvater@998: darkvater@998: typedef struct { darkvater@998: int height; darkvater@998: uint16 counter; darkvater@998: } scroller_d; miham@1004: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(scroller_d)); darkvater@859: Darkvater@4542: typedef enum SortListFlags { Darkvater@2888: VL_DESC = 0x01, // sort descending or ascending Darkvater@2888: VL_RESORT = 0x02, // instruct the code to resort the list in the next loop Darkvater@2888: VL_REBUILD = 0x04 // create sort-listing to use for qsort and friends Darkvater@4542: } SortListFlags; tron@588: Darkvater@4542: typedef struct Listing { Darkvater@4542: bool order; // Ascending/descending Darkvater@4542: byte criteria; // Sorting criteria Darkvater@4542: } Listing; tron@588: Darkvater@2888: typedef struct list_d { Darkvater@4542: uint16 list_length; // length of the list being sorted Darkvater@4542: byte sort_type; // what criteria to sort on Darkvater@4542: SortListFlags flags; // used to control sorting/resorting/etc. Darkvater@4542: uint16 resort_timer; // resort list after a given amount of ticks if set Darkvater@2888: } list_d; Darkvater@2888: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(list_d)); Darkvater@2888: darkvater@1648: typedef struct message_d { darkvater@1648: int msg; darkvater@1648: int wparam; darkvater@1648: int lparam; darkvater@1648: } message_d; darkvater@1648: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(message_d)); darkvater@1648: peter1138@2636: typedef struct dropdown_d { peter1138@2683: uint32 disabled_state; peter1138@2683: uint32 hidden_state; peter1138@2636: WindowClass parent_wnd_class; peter1138@2636: WindowNumber parent_wnd_num; peter1138@2636: byte parent_button; peter1138@2636: byte num_items; peter1138@2636: byte selected_index; peter1138@2636: const StringID *items; peter1138@2636: byte click_delay; peter1138@2636: bool drag_mode; peter1138@2636: } dropdown_d; peter1138@2636: assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(dropdown_d)); peter1138@2636: truelight@0: 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: truelight@0: enum WindowWidgetTypes { Darkvater@4939: WWT_EMPTY, truelight@158: Darkvater@4939: WWT_PANEL, /* simple depressed panel */ Darkvater@4939: WWT_INSET, /* pressed (inset) panel, most commonly used as combo box _text_ area */ Darkvater@4939: WWT_IMGBTN, /* button with image */ Darkvater@4939: WWT_IMGBTN_2, /* button with diff image when clicked */ Darkvater@4938: Darkvater@4939: WWT_TEXTBTN, /* button with text */ Darkvater@4939: WWT_TEXTBTN_2, /* button with diff text when clicked */ Darkvater@4939: WWT_LABEL, /* centered label */ Darkvater@4939: WWT_MATRIX, Darkvater@4939: WWT_SCROLLBAR, Darkvater@4939: WWT_FRAME, /* frame */ Darkvater@4939: WWT_CAPTION, truelight@0: Darkvater@4939: WWT_HSCROLLBAR, Darkvater@4939: WWT_STICKYBOX, Darkvater@4939: WWT_SCROLL2BAR, /* 2nd vertical scrollbar*/ Darkvater@4939: WWT_RESIZEBOX, Darkvater@4939: WWT_CLOSEBOX, Darkvater@4939: 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: truelight@0: enum WindowFlags { rubidium@4344: WF_TIMEOUT_SHL = 0, rubidium@4344: WF_TIMEOUT_MASK = 7, rubidium@4344: WF_DRAGGING = 1 << 3, rubidium@4344: WF_SCROLL_UP = 1 << 4, rubidium@4344: WF_SCROLL_DOWN = 1 << 5, rubidium@4344: WF_SCROLL_MIDDLE = 1 << 6, rubidium@4344: WF_HSCROLL = 1 << 7, rubidium@4344: WF_SIZING = 1 << 8, rubidium@4344: WF_STICKY = 1 << 9, truelight@867: truelight@0: WF_DISABLE_VP_SCROLL = 1 << 10, 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: truelight@0: /* window.c */ truelight@0: void CallWindowEventNP(Window *w, int event); tron@1093: void CallWindowTickEvent(void); belugas@4171: void SetWindowDirty(const Window *w); darkvater@1648: void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, uint msg, uint wparam, uint lparam); Darkvater@5043: void SendWindowMessageClass(WindowClass wnd_class, uint msg, uint wparam, uint 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, truelight@0: const Widget *widget); truelight@0: truelight@0: Window *AllocateWindowDesc(const WindowDesc *desc); bjarni@4520: Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number); truelight@0: Darkvater@5120: void DrawWindowViewport(const Window *w); Darkvater@5268: void ResizeWindow(Window *w, int x, int y); truelight@0: belugas@4692: /** belugas@4692: * Sets the enabled/disabled status of a widget. belugas@4692: * By default, widgets are enabled. belugas@4692: * On certain conditions, they have to be disabled. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: * @param disab_stat : status to use ie: disabled = true, enabled = false belugas@4692: */ belugas@4692: static inline void SetWindowWidgetDisabledState(Window *w, byte widget_index, bool disab_stat) belugas@4692: { rubidium@5232: assert(widget_index < w->widget_count); belugas@4749: SB(w->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Sets a widget to disabled. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: */ belugas@4692: static inline void DisableWindowWidget(Window *w, byte widget_index) belugas@4692: { belugas@4692: SetWindowWidgetDisabledState(w, widget_index, true); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Sets a widget to Enabled. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: */ belugas@4692: static inline void EnableWindowWidget(Window *w, byte widget_index) belugas@4692: { belugas@4692: SetWindowWidgetDisabledState(w, widget_index, false); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Gets the enabled/disabled status of a widget. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: * @return status of the widget ie: disabled = true, enabled = false belugas@4692: */ rubidium@5233: static inline bool IsWindowWidgetDisabled(const Window *w, byte widget_index) belugas@4692: { rubidium@5232: assert(widget_index < w->widget_count); rubidium@5236: return HASBIT(w->widget[widget_index].display_flags, WIDG_DISABLED); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Sets the hidden/shown status of a widget. belugas@4692: * By default, widgets are visible. belugas@4692: * On certain conditions, they have to be hidden. belugas@4692: * @param w Window on which the widget is located belugas@4692: * @param widget_index index of this widget in the window belugas@4692: * @param hidden_stat status to use ie. hidden = true, visible = false belugas@4692: */ belugas@4692: static inline void SetWindowWidgetHiddenState(Window *w, byte widget_index, bool hidden_stat) belugas@4692: { rubidium@5232: assert(widget_index < w->widget_count); belugas@4749: SB(w->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Sets a widget hidden. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: */ belugas@4692: static inline void HideWindowWidget(Window *w, byte widget_index) belugas@4692: { belugas@4692: SetWindowWidgetHiddenState(w, widget_index, true); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Sets a widget visible. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: */ belugas@4692: static inline void ShowWindowWidget(Window *w, byte widget_index) belugas@4692: { belugas@4692: SetWindowWidgetHiddenState(w, widget_index, false); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Gets the visibility of a widget. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: * @return status of the widget ie: hidden = true, visible = false belugas@4692: */ rubidium@5233: static inline bool IsWindowWidgetHidden(const Window *w, byte widget_index) belugas@4692: { rubidium@5232: assert(widget_index < w->widget_count); rubidium@5236: return HASBIT(w->widget[widget_index].display_flags, WIDG_HIDDEN); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Sets the lowered/raised status of a widget. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: * @param hidden_stat : status to use ie: lowered = true, raised = false belugas@4692: */ belugas@4727: static inline void SetWindowWidgetLoweredState(Window *w, byte widget_index, bool lowered_stat) belugas@4692: { rubidium@5232: assert(widget_index < w->widget_count); belugas@4749: SB(w->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Invert the lowered/raised status of a widget. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: */ belugas@4692: static inline void ToggleWidgetLoweredState(Window *w, byte widget_index) belugas@4692: { rubidium@5232: assert(widget_index < w->widget_count); belugas@4749: TOGGLEBIT(w->widget[widget_index].display_flags, WIDG_LOWERED); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Marks a widget as lowered. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: */ belugas@4692: static inline void LowerWindowWidget(Window *w, byte widget_index) belugas@4692: { glx@4730: SetWindowWidgetLoweredState(w, widget_index, true); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Marks a widget as raised. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: */ belugas@4692: static inline void RaiseWindowWidget(Window *w, byte widget_index) belugas@4692: { glx@4730: SetWindowWidgetLoweredState(w, widget_index, false); belugas@4692: } belugas@4692: belugas@4692: /** belugas@4692: * Gets the lowered state of a widget. belugas@4692: * @param w : Window on which the widget is located belugas@4692: * @param widget_index : index of this widget in the window belugas@4692: * @return status of the widget ie: lowered = true, raised= false belugas@4692: */ rubidium@5233: static inline bool IsWindowWidgetLowered(const Window *w, byte widget_index) belugas@4692: { rubidium@5232: assert(widget_index < w->widget_count); belugas@4749: return HASBIT(w->widget[widget_index].display_flags, WIDG_LOWERED); belugas@4692: } belugas@4692: tron@1093: void InitWindowSystem(void); Darkvater@1474: void UnInitWindowSystem(void); Darkvater@1474: void ResetWindowSystem(void); Darkvater@2436: int GetMenuItemIndex(const Window *w, int x, int y); pasky@1570: void InputLoop(void); Darkvater@5086: void HandleKeypress(uint32 key); Darkvater@5090: void HandleMouseEvents(void); tron@1093: void UpdateWindows(void); belugas@4171: void InvalidateWidget(const Window *w, byte widget_index); bjarni@4766: void InvalidateThisWindowData(Window *w); bjarni@4739: void InvalidateWindowData(WindowClass cls, WindowNumber number); belugas@4719: void RaiseWindowButtons(Window *w); truelight@0: void RelocateAllWindows(int neww, int newh); tron@380: int PositionMainToolbar(Window *w); glx@4755: void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...); glx@4755: void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...); glx@4755: void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...); truelight@0: belugas@4719: /* misc_gui.c*/ Darkvater@4884: void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint params[]); Darkvater@4834: static inline void GuiShowTooltips(StringID str) Darkvater@4834: { Darkvater@4834: GuiShowTooltipsWithArgs(str, 0, NULL); Darkvater@4834: } belugas@4719: truelight@0: /* widget.c */ Darkvater@2436: int GetWidgetFromPos(const Window *w, int x, int y); Darkvater@2436: void DrawWindowWidgets(const Window *w); peter1138@2448: void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask); truelight@0: truelight@0: void HandleButtonClick(Window *w, byte widget); truelight@0: tron@1093: Window *GetCallbackWnd(void); tron@1093: void DeleteNonVitalWindows(void); darkvater@763: void DeleteAllNonVitalWindows(void); darkvater@983: void HideVitalWindows(void); darkvater@983: void ShowVitalWindows(void); Darkvater@5124: Window **FindWindowZPosition(const Window *w); truelight@0: truelight@0: /* window.c */ 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: truelight@0: VARDEF Point _cursorpos_drag_start; truelight@0: truelight@0: VARDEF bool _left_button_down; truelight@0: VARDEF bool _left_button_clicked; truelight@0: truelight@0: VARDEF bool _right_button_down; truelight@0: VARDEF bool _right_button_clicked; truelight@0: truelight@0: VARDEF int _scrollbar_start_pos; truelight@0: VARDEF int _scrollbar_size; truelight@0: VARDEF byte _scroller_click_timeout; truelight@0: truelight@0: VARDEF bool _scrolling_scrollbar; truelight@0: VARDEF bool _scrolling_viewport; truelight@0: VARDEF bool _popup_menu_active; truelight@0: truelight@0: VARDEF 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: truelight@0: #endif /* WINDOW_H */