1 /* 2 This file is part of Warzone 2100. 3 Copyright (C) 1999-2004 Eidos Interactive 4 Copyright (C) 2005-2020 Warzone 2100 Project 5 6 Warzone 2100 is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 Warzone 2100 is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with Warzone 2100; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 /** 21 * @file lib/widget/widget.h 22 * Definitions for the Widget library 23 * @defgroup Widget Widget system 24 * Warzone uses a pixel layout, callback based widget code. While it has several 25 * fallbacks for drawing standard widgets, usually you want to specify your 26 * own drawing callbacks. 27 * @{ 28 */ 29 30 #ifndef __INCLUDED_LIB_WIDGET_WIDGET_H__ 31 #define __INCLUDED_LIB_WIDGET_WIDGET_H__ 32 33 #include "lib/framework/frame.h" 34 #include "lib/ivis_opengl/piepalette.h" 35 #include "widgbase.h" 36 #include <string> 37 38 /*********************************************************************************** 39 * 40 * Widget style definitions - these control how the basic widget appears on screen 41 */ 42 43 /************ Form styles ****************/ 44 45 #define WFORM_PLAIN 0 ///< Plain form 46 47 /** Invisible (i.e. see through) form - can be used in conjunction with WFORM_PLAIN. */ 48 #define WFORM_INVISIBLE 2 49 50 #define WFORM_CLICKABLE 4 ///< Clickable form - return form id when the form is clicked 51 #define WFORM_NOCLICKMOVE 8 ///< Disable movement on a clickable form 52 53 /** 54 * Control whether the primary or secondary buttons work on a clickable form. 55 * Primary works by default - this turns it off. 56 */ 57 #define WFORM_NOPRIMARY 0x10 58 #define WFORM_SECONDARY 0x20 ///< Enable secondary buttons 59 60 /************ Label styles ***************/ 61 62 #define WLAB_PLAIN 0 ///< Plain text only label 63 enum WzTextAlignment 64 { 65 WLAB_ALIGNLEFT = 0, ///< Align the text at the left of the box 66 WLAB_ALIGNCENTRE = 1, ///< Centre the text 67 WLAB_ALIGNRIGHT = 2, ///< Align the text at the right of the box 68 WLAB_ALIGNTOPLEFT = 4, ///< Align the text at the top left of the box 69 WLAB_ALIGNTOP = 4 + 1, ///< Align the text at the top of the box 70 WLAB_ALIGNTOPRIGHT = 4 + 2, ///< Align the text at the top right of the box 71 WLAB_ALIGNBOTTOMLEFT = 8, ///< Align the text at the bottom left of the box 72 WLAB_ALIGNBOTTOM = 8 + 1, ///< Align the text at the bottom of the box 73 WLAB_ALIGNBOTTOMRIGHT = 8 + 2, ///< Align the text at the bottom rightof the box 74 }; 75 76 /************ Button styles **************/ 77 78 #define WBUT_PLAIN 0 ///< Plain button (text with a box around it) 79 80 81 /** 82 * Control whether the primary or secondary buttons work on a button. Primary works by default - 83 * this turns it off. 84 */ 85 #define WBUT_NOPRIMARY 0x10 86 #define WBUT_SECONDARY 0x20 ///< Enable secondary buttons. 87 #define WBUT_TXTCENTRE 0x40 ///< Text only buttons. centre the text? 88 89 /*********** Edit Box styles *************/ 90 91 #define WEDB_PLAIN 0 ///< Plain edit box (text with a box around it) 92 93 /*********** Bar Graph styles ************/ 94 95 #define WBAR_PLAIN 0 ////< Plain bar graph 96 #define WBAR_TROUGH 1 ///< Bar graph with a trough showing empty percentage 97 #define WBAR_DOUBLE 2 ///< Double bar graph, one on top of other 98 99 /*********** Slider styles ***************/ 100 101 #define WSLD_PLAIN 0 ///< Plain slider 102 103 /***********************************************************************************/ 104 105 /* An optional function that is used to initialize the pUserData pointer per widget instance */ 106 /* (Useful if re-using a W_*INIT structure for multiple widget instances) */ 107 typedef std::function<void* ()> WIDGET_INITIALIZE_PUSERDATA_FUNC; 108 109 struct Padding 110 { 111 uint32_t top; 112 uint32_t right; 113 uint32_t bottom; 114 uint32_t left; 115 }; 116 117 /** The basic initialisation structure */ 118 struct W_INIT 119 { 120 W_INIT(); 121 122 UDWORD formID; ///< ID number of form to put widget on. ID == 0 specifies the default form for the screen 123 UWORD majorID; ///< Which tab to put the widget on for a tabbed form 124 UDWORD id; ///< Unique id number (chosen by user) 125 UDWORD style; ///< widget style 126 SWORD x, y; ///< screen location 127 UWORD width, height; ///< widget size 128 WIDGET_DISPLAY pDisplay; ///< Optional display function 129 WIDGET_CALLBACK pCallback; ///< Optional callback function 130 void *pUserData; ///< Optional user data pointer 131 UDWORD UserData; ///< User data (if any) 132 WIDGET_CALCLAYOUT_FUNC calcLayout; ///< Optional calculate layout callback function 133 WIDGET_ONDELETE_FUNC onDelete; ///< Optional callback called when the Widget is about to be deleted 134 WIDGET_HITTEST_FUNC customHitTest; ///< Optional custom hit-testing function 135 WIDGET_INITIALIZE_PUSERDATA_FUNC initPUserDataFunc; ///< (Optional) Used to initialize the pUserData pointer per widget instance 136 }; 137 138 /** Form initialisation structure */ 139 struct W_FORMINIT : public W_INIT 140 { 141 W_FORMINIT(); 142 143 bool disableChildren; 144 std::string pTip; ///< Tool tip for the form itself 145 }; 146 147 /** Label initialisation structure */ 148 struct W_LABINIT : public W_INIT 149 { 150 W_LABINIT(); 151 152 WzString pText; ///< label text 153 std::string pTip; ///< Tool tip for the label. 154 enum iV_fonts FontID; ///< ID of the IVIS font to use for this widget. 155 }; 156 157 /** Button initialisation structure */ 158 struct W_BUTINIT : public W_INIT 159 { 160 W_BUTINIT(); 161 162 const char *pText; ///< Button text 163 std::string pTip; ///< Tool tip text 164 enum iV_fonts FontID; //< ID of the IVIS font to use for this widget. 165 }; 166 167 /** Edit box initialisation structure */ 168 struct W_EDBINIT : public W_INIT 169 { 170 W_EDBINIT(); 171 172 const char *pText; ///< initial contents of the edit box 173 enum iV_fonts FontID; ///< ID of the IVIS font to use for this widget. 174 WIDGET_DISPLAY pBoxDisplay; ///< Optional callback to display the form. 175 }; 176 177 /* Orientation flags for the bar graph */ 178 enum WBAR_ORIENTATION 179 { 180 WBAR_LEFT = 1, ///< Bar graph fills from left to right 181 WBAR_RIGHT, ///< Bar graph fills from right to left 182 WBAR_TOP, ///< Bar graph fills from top to bottom 183 WBAR_BOTTOM, ///< Bar graph fills from bottom to top 184 }; 185 186 /** Bar Graph initialisation structure */ 187 struct W_BARINIT : public W_INIT 188 { 189 W_BARINIT(); 190 191 WBAR_ORIENTATION orientation; ///< Orientation of the bar on the widget 192 UWORD size; ///< Initial percentage of the graph that is filled 193 UWORD minorSize; ///< Percentage of second bar graph if there is one 194 UWORD iRange; ///< Maximum range 195 int denominator; ///< Denominator, 1 by default. 196 int precision; ///< Number of places after the decimal point to display, 0 by default. 197 PIELIGHT sCol; ///< Bar colour 198 PIELIGHT sMinorCol; ///< Minor bar colour 199 std::string pTip; ///< Tool tip text 200 }; 201 202 203 /* Orientation of the slider */ 204 enum WSLD_ORIENTATION 205 { 206 WSLD_LEFT = 1, ///< Slider is horizontal and starts at left 207 WSLD_RIGHT, ///< Slider is horizontal and starts at the right 208 WSLD_TOP, ///< Slider is vertical and starts at the top 209 WSLD_BOTTOM, ///< Slider is vertical and starts at the bottom 210 }; 211 212 /** Slider initialisation structure */ 213 struct W_SLDINIT : public W_INIT 214 { 215 W_SLDINIT(); 216 217 WSLD_ORIENTATION orientation; ///< Orientation of the slider 218 UWORD numStops; ///< Number of stops on the slider 219 UWORD barSize; ///< Size of the bar 220 UWORD pos; ///< Initial position of the slider bar 221 std::string pTip; ///< Tip string 222 }; 223 224 /***********************************************************************************/ 225 226 /** The maximum value for bar graph size */ 227 #define WBAR_SCALE 100 228 229 /** Initialise the widget module */ 230 bool widgInitialise(); 231 232 /** Reset the widget module */ 233 void widgReset(); 234 235 /** Shut down the widget module */ 236 void widgShutDown(); 237 238 /** Used by the notifications system to register forms that are "over the top", and may consume click / mouse-over events */ 239 void widgRegisterOverlayScreen(const std::shared_ptr<W_SCREEN> &psScreen, uint16_t zOrder); 240 void widgRegisterOverlayScreenOnTopOfScreen(const std::shared_ptr<W_SCREEN> &psScreen, const std::shared_ptr<W_SCREEN> &priorScreen); 241 void widgRemoveOverlayScreen(const std::shared_ptr<W_SCREEN> &psScreen); 242 bool isMouseOverScreenOverlayChild(int mx, int my); // global mouse coordinates - i.e. those returned from mouseX()/mouseY() 243 bool isMouseClickDownOnScreenOverlayChild(); 244 bool isMouseOverSomeWidget(const std::shared_ptr<W_SCREEN> &psScreen); 245 void widgScheduleTask(std::function<void ()> f); 246 247 /** Add a form to the widget screen */ 248 WZ_DECL_NONNULL(2) W_FORM *widgAddForm(const std::shared_ptr<W_SCREEN> &psScreen, const W_FORMINIT *psInit); 249 250 /** Add a label to the widget screen */ 251 WZ_DECL_NONNULL(2) W_LABEL *widgAddLabel(const std::shared_ptr<W_SCREEN> &psScreen, const W_LABINIT *psInit); 252 253 /** Add a button to a form */ 254 WZ_DECL_NONNULL(2) W_BUTTON *widgAddButton(const std::shared_ptr<W_SCREEN> &psScreen, const W_BUTINIT *psInit); 255 256 /** Add an edit box to a form */ 257 WZ_DECL_NONNULL(2) W_EDITBOX *widgAddEditBox(const std::shared_ptr<W_SCREEN> &psScreen, const W_EDBINIT *psInit); 258 259 /** Add a bar graph to a form */ 260 WZ_DECL_NONNULL(2) W_BARGRAPH *widgAddBarGraph(const std::shared_ptr<W_SCREEN> &psScreen, const W_BARINIT *psInit); 261 262 /** Add a slider to a form */ 263 WZ_DECL_NONNULL(2) W_SLIDER *widgAddSlider(const std::shared_ptr<W_SCREEN> &psScreen, const W_SLDINIT *psInit); 264 265 /** Delete a widget from the screen */ 266 void widgDelete(WIDGET *widget); 267 void widgDelete(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 268 void widgDeleteLater(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 269 270 /** Hide a widget */ 271 void widgHide(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 272 273 /** Reveal a widget */ 274 void widgReveal(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 275 276 /** Return a pointer to a buffer containing the current string of a widget if any. 277 * This will always return a valid string pointer. 278 * NOTE: The string must be copied out of the buffer 279 */ 280 const char *widgGetString(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 281 282 /** Return the current string of a widget, if any. 283 * This will always return a string. If the widget doesn't have a string, it will return an empty WzString. 284 */ 285 const WzString& widgGetWzString(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 286 287 /** Set the text in a widget */ 288 void widgSetString(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, const char *pText); 289 290 /** Get the current position of a slider bar */ 291 UDWORD widgGetSliderPos(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 292 293 /** Set the current size of a bar graph */ 294 void widgSetBarSize(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD size); 295 296 /** Set the current size of a minor bar on a double graph */ 297 void widgSetMinorBarSize(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD size); 298 299 /** Return the ID of the widget the mouse was over this frame */ 300 UDWORD widgGetMouseOver(const std::shared_ptr<W_SCREEN> &psScreen); 301 302 /** Return the user data for a widget */ 303 void *widgGetUserData(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 304 305 /** Set the user data for a widget */ 306 void widgSetUserData(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, void *UserData); 307 308 /** Return the user data for a widget */ 309 UDWORD widgGetUserData2(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 310 311 /** Set the user data for a widget */ 312 void widgSetUserData2(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD UserData); 313 314 /** Get widget structure */ 315 WIDGET *widgGetFromID(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 316 317 /* Find a widget on a form from its id number */ 318 std::shared_ptr<WIDGET> widgFormGetFromID(const std::shared_ptr<WIDGET>& widget, UDWORD id); 319 320 /** Set tip string for a widget */ 321 void widgSetTip(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, std::string pTip); 322 323 /** Colour numbers */ 324 enum _w_colour 325 { 326 WCOL_BKGRND, ///< Background colours 327 WCOL_TEXT, ///< Text colour 328 WCOL_LIGHT, ///< Light colour for 3D effects 329 WCOL_DARK, ///< Dark colour for 3D effects 330 WCOL_HILITE, ///< Hilite colour 331 WCOL_CURSOR, ///< Edit Box cursor colour 332 WCOL_TIPBKGRND, ///< Background for the tool tip window 333 WCOL_DISABLE, ///< Text colour on a disabled button 334 335 WCOL_MAX, ///< All colour numbers are less than this 336 }; 337 338 /** Set the global toop tip text colour. */ 339 void widgSetTipColour(PIELIGHT colour); 340 341 void widgSetButtonFlash(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 342 void widgClearButtonFlash(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 343 344 /** Get a button or clickable form's state */ 345 UDWORD widgGetButtonState(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id); 346 347 /** Set a button or clickable form's state */ 348 void widgSetButtonState(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD state); 349 350 351 /** Return which key was used to press the last returned widget */ 352 UDWORD widgGetButtonKey_DEPRECATED(const std::shared_ptr<W_SCREEN> &psScreen); 353 354 /** Execute a set of widgets for one cycle. 355 * Return the id of the widget that was activated, or 0 for none. 356 */ 357 WidgetTriggers const &widgRunScreen(const std::shared_ptr<W_SCREEN> &psScreen); 358 359 /** Display the screen's widgets in their current state 360 * (Call after calling widgRunScreen, this allows the input 361 * processing to be separated from the display of the widgets). 362 */ 363 void widgDisplayScreen(const std::shared_ptr<W_SCREEN> &psScreen); 364 365 366 /** Set the current audio callback function and audio id's. */ 367 void WidgSetAudio(WIDGET_AUDIOCALLBACK Callback, SWORD HilightID, SWORD ClickedID, SWORD ErrorID); 368 369 /** Get pointer to current audio callback function. */ 370 WIDGET_AUDIOCALLBACK WidgGetAudioCallback(); 371 372 /** Get current audio ID for hilight. */ 373 SWORD WidgGetHilightAudioID(); 374 375 /** Get current audio ID for clicked. */ 376 SWORD WidgGetClickedAudioID(); 377 378 // error ID 379 SWORD WidgGetErrorAudioID(); 380 381 /** Enable or disable all sliders. */ 382 void sliderEnableDrag(bool Enable); 383 384 void setWidgetsStatus(bool var); 385 bool getWidgetsStatus(); 386 387 /** @} */ 388 389 #endif // __INCLUDED_LIB_WIDGET_WIDGET_H__ 390