| 1 | /* |
| 2 | * LegacyClonk |
| 3 | * |
| 4 | * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design) |
| 5 | * Copyright (c) 2017-2022, The LegacyClonk Team and contributors |
| 6 | * |
| 7 | * Distributed under the terms of the ISC license; see accompanying file |
| 8 | * "COPYING" for details. |
| 9 | * |
| 10 | * "Clonk" is a registered trademark of Matthes Bender, used with permission. |
| 11 | * See accompanying file "TRADEMARK" for details. |
| 12 | * |
| 13 | * To redistribute this file separately, substitute the full license texts |
| 14 | * for the above references. |
| 15 | */ |
| 16 | |
| 17 | /* In-game menu as used by objects, players, and fullscreen options */ |
| 18 | |
| 19 | #pragma once |
| 20 | |
| 21 | #include "C4ForwardDeclarations.h" |
| 22 | #include "C4Id.h" |
| 23 | #include "C4FacetEx.h" |
| 24 | #include "C4Shape.h" |
| 25 | #include "C4Gui.h" |
| 26 | #include "C4GuiDialogs.h" |
| 27 | #include "C4IDList.h" |
| 28 | #include "StdFile.h" |
| 29 | |
| 30 | class C4Viewport; |
| 31 | |
| 32 | enum |
| 33 | { |
| 34 | C4MN_SymbolSize = 16, |
| 35 | C4MN_FrameWidth = 2 |
| 36 | }; |
| 37 | enum |
| 38 | { |
| 39 | C4MN_Style_Normal = 0, |
| 40 | C4MN_Style_Context = 1, |
| 41 | C4MN_Style_Info = 2, |
| 42 | C4MN_Style_Dialog = 3, |
| 43 | C4MN_Style_BaseMask = 127, |
| 44 | C4MN_Style_EqualItemHeight = 128 |
| 45 | }; |
| 46 | enum |
| 47 | { |
| 48 | = 0, |
| 49 | = 1, |
| 50 | = 2, |
| 51 | = 3, |
| 52 | = 4, |
| 53 | = 5, |
| 54 | = 6, |
| 55 | = 7, |
| 56 | }; |
| 57 | enum |
| 58 | { |
| 59 | C4MN_Align_Left = 1, |
| 60 | C4MN_Align_Right = 2, |
| 61 | C4MN_Align_Top = 4, |
| 62 | C4MN_Align_Bottom = 8, |
| 63 | C4MN_Align_Free = 16 |
| 64 | }; |
| 65 | enum |
| 66 | { |
| 67 | C4MN_Item_NoCount = 12345678 |
| 68 | }; |
| 69 | enum |
| 70 | { |
| 71 | C4MN_AdjustPosition = 1 << 31, |
| 72 | }; |
| 73 | |
| 74 | void (int32_t , C4Facet &cgo, int32_t iOwner, C4Object *cObj); |
| 75 | |
| 76 | class : public C4GUI::Element |
| 77 | { |
| 78 | friend class C4Menu; |
| 79 | |
| 80 | public: |
| 81 | (); |
| 82 | |
| 83 | protected: |
| 84 | char [C4MaxTitle + 1]; |
| 85 | char Command[_MAX_FNAME + 30 + 1]; |
| 86 | char Command2[_MAX_FNAME + 30 + 1]; |
| 87 | char [2 * C4MaxTitle + 1]; |
| 88 | int32_t ; |
| 89 | C4ID ; |
| 90 | C4Object *; |
| 91 | C4FacetExSurface ; |
| 92 | uint32_t ; |
| 93 | bool ; // if set, a specific value is to be shown |
| 94 | int32_t ; // specific value to be shown |
| 95 | bool ; // item is selected; set by menu |
| 96 | int32_t ; |
| 97 | class C4Menu *; |
| 98 | int32_t ; |
| 99 | bool ; |
| 100 | int32_t ; // dialog menus only: Amount of text which is to be displayed already (-1 for everything) |
| 101 | C4IDList ; // components to be displayed in info line if item is selected |
| 102 | |
| 103 | private: |
| 104 | bool (); |
| 105 | int32_t (int32_t iForHeight); |
| 106 | |
| 107 | protected: |
| 108 | virtual void (C4FacetEx &cgo) override; // draw menu item |
| 109 | |
| 110 | (C4Menu *, int32_t iIndex, const char *szCaption, const char *szCommand, |
| 111 | int32_t iCount, C4Object *pObject, const char *szInfoCaption, |
| 112 | C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, int32_t iStyle, bool fIsSelectable); |
| 113 | void (C4FacetExSurface &fctSymbol) { Symbol.GrabFrom(rSource&: fctSymbol); if (Symbol.Surface) dwSymbolClr = Symbol.Surface->GetClr(); } |
| 114 | void (const C4FacetEx &fctSymbol) { Symbol.Set(fctSymbol); if (Symbol.Surface) dwSymbolClr = Symbol.Surface->GetClr(); } |
| 115 | void (bool fToVal) { fSelected = fToVal; } |
| 116 | void (int32_t &riByVal); // progress number of shown characters by given amount |
| 117 | |
| 118 | // GUI calls |
| 119 | virtual void (class C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, uint32_t dwKeyParam) override; // input: mouse movement or buttons |
| 120 | virtual void (class C4GUI::CMouse &rMouse) override; // called when mouse cursor enters element region: Select this item (deselects any other) |
| 121 | virtual void (class C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, uint32_t dwKeyParam) override; // called by mouse: dragging process |
| 122 | virtual void (class C4GUI::CMouse &rMouse, int32_t iX, int32_t iY, uint32_t dwKeyParam) override; // called by mouse: mouse released after dragging process |
| 123 | |
| 124 | public: |
| 125 | C4ID () const { return id; } |
| 126 | C4Object *() const { return Object; } |
| 127 | const char *GetCommand() const { return Command; } |
| 128 | |
| 129 | void () { Object = nullptr; } |
| 130 | |
| 131 | friend class C4DefGraphicsPtrBackup; |
| 132 | }; |
| 133 | |
| 134 | class : public C4GUI::Dialog |
| 135 | { |
| 136 | typedef C4GUI::Dialog ; |
| 137 | |
| 138 | public: |
| 139 | (); |
| 140 | virtual () { Clear(); } |
| 141 | |
| 142 | void (); |
| 143 | virtual void (); |
| 144 | |
| 145 | protected: |
| 146 | bool ; |
| 147 | bool ; |
| 148 | bool ; |
| 149 | int32_t ; |
| 150 | int32_t , ; |
| 151 | int32_t ; |
| 152 | int32_t , ; |
| 153 | int32_t , ; |
| 154 | int32_t ; |
| 155 | int32_t ; |
| 156 | int32_t Columns; // sync |
| 157 | int32_t ; // async |
| 158 | int32_t ; |
| 159 | int32_t ; |
| 160 | int32_t ; // used by AutoContextMenus |
| 161 | StdStrBuf CloseCommand; // script command that will be executed on menu close |
| 162 | char [C4MaxTitle + 1]; |
| 163 | C4FacetExSurface ; |
| 164 | C4GUI::ScrollWindow *; // window containing the menu items |
| 165 | bool ; // if set, first menu item is used at a portrait at topleft of menu |
| 166 | bool ; // if true, text is being shown progressively (dialog menus) |
| 167 | bool ; // for dialog menus only: If set, all options with an icon are forced to have the same height |
| 168 | bool ; // set if menu is shown - independent of GUI to keep synchronized when there's no GUI |
| 169 | |
| 170 | public: |
| 171 | bool (int32_t &rCom, int32_t &rData, bool fAsyncConversion); |
| 172 | void (C4Object *pObj); |
| 173 | bool (); |
| 174 | void (); |
| 175 | void (bool fPermanent); |
| 176 | void (int32_t iAlignment); |
| 177 | int32_t (); |
| 178 | int32_t (); |
| 179 | int32_t (); |
| 180 | bool () { return Style == C4MN_Style_Context; } |
| 181 | int (); |
| 182 | int32_t () { return ItemHeight; } |
| 183 | C4MenuItem *(); |
| 184 | C4MenuItem *(int32_t iIndex); |
| 185 | virtual C4Object *() { return nullptr; } |
| 186 | bool (int32_t iBy, bool fAdjustPosition, bool fDoCalls); |
| 187 | bool (int32_t iSelection, bool fAdjustPosition, bool fDoCalls); |
| 188 | bool (int32_t iPosition); |
| 189 | void (int32_t iToWdt, int32_t iToHgt); |
| 190 | bool (bool fRight = false); |
| 191 | bool (); |
| 192 | bool (uint8_t byCom, int32_t iData); |
| 193 | bool (uint8_t byCom); // direct keyboard callback |
| 194 | bool (const char *szCaption, const C4FacetEx &fctSymbol, const char *szCommand, |
| 195 | int32_t iCount = C4MN_Item_NoCount, C4Object *pObject = nullptr, |
| 196 | const char *szInfoCaption = nullptr, |
| 197 | C4ID idID = C4ID_None, const char *szCommand2 = nullptr, bool fOwnValue = false, int32_t iValue = 0, bool fIsSelectable = true); |
| 198 | bool (const char *szCaption, C4FacetExSurface &fctSymbol, const char *szCommand, |
| 199 | int32_t iCount = C4MN_Item_NoCount, C4Object *pObject = nullptr, |
| 200 | const char *szInfoCaption = nullptr, |
| 201 | C4ID idID = C4ID_None, const char *szCommand2 = nullptr, bool fOwnValue = false, int32_t iValue = 0, bool fIsSelectable = true); |
| 202 | void (bool fResetSelection = false); |
| 203 | void () { LocationSet = false; } |
| 204 | bool (int32_t iX, int32_t iY); // set location relative to user viewport |
| 205 | bool (int32_t iToProgress, bool fAdd); // enable/disable progressive text display and set starting pos |
| 206 | void (bool fToVal) { fEqualIconItemHeight = fToVal; } // enable/disable equal item heights |
| 207 | bool (bool fOK, bool fControl); |
| 208 | void SetCloseCommand(const char *strCommand); |
| 209 | |
| 210 | #ifndef NDEBUG |
| 211 | void AssertSurfaceNotUsed(C4Surface *sfc); |
| 212 | #endif |
| 213 | |
| 214 | private: |
| 215 | bool (C4MenuItem *pNew, const char *szCaption, const char *szCommand, |
| 216 | int32_t iCount, C4Object *pObject, const char *szInfoCaption, |
| 217 | C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable); |
| 218 | bool (const char *szEmpty, int32_t , int32_t , int32_t iId, int32_t iStyle); |
| 219 | |
| 220 | protected: |
| 221 | bool (const C4FacetEx &fctSymbol, const char *szEmpty, int32_t = C4MN_Extra_None, int32_t = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); |
| 222 | bool (C4FacetExSurface &fctSymbol, const char *szEmpty, int32_t = C4MN_Extra_None, int32_t = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); |
| 223 | void (); |
| 224 | void (); |
| 225 | bool (); |
| 226 | void (C4Surface *sfcSurface, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt); |
| 227 | void (C4Facet &cgo); |
| 228 | void (); |
| 229 | void (); // call InitSize if a scroll bar is needed but not present or vice vera |
| 230 | void (int32_t Player, C4MenuItem *pItem); // select item (direct) or do control (object menus) |
| 231 | void (int32_t Player, C4MenuItem *pItem, bool fRight); // enter on an item |
| 232 | bool (); // returns whether the controlling player has mouse control |
| 233 | |
| 234 | virtual bool (bool &rfRefilled) { return true; } |
| 235 | virtual bool MenuCommand(const char *szCommand, bool fIsCloseCommand) { return true; } |
| 236 | virtual void (int32_t iNewSelection) {} // do object callbacks if selection changed in user menus |
| 237 | virtual bool () { return false; } // do MenuQueryCancel-callbacks for user menus |
| 238 | virtual void (int32_t Player, int32_t iIndex) {} |
| 239 | virtual void (int32_t Player, int32_t iIndex, bool fRight) {} |
| 240 | virtual void () {} |
| 241 | virtual bool () { return false; } // determine whether the menu is just viewed by an observer, and should not issue any calls |
| 242 | virtual int32_t () { return NO_OWNER; } |
| 243 | |
| 244 | virtual const char *() override { return nullptr; } // no ID needed, because it's a viewport dlg |
| 245 | |
| 246 | bool () { return fHasPortrait; } // dialog menus only: Whether a portrait is shown in the topleft |
| 247 | |
| 248 | protected: |
| 249 | // C4GUI |
| 250 | virtual C4Viewport *() override; // return associated viewport |
| 251 | virtual bool () override { return true; } // drawn by viewport drawing proc |
| 252 | virtual bool () override { return false; } |
| 253 | virtual void () override; |
| 254 | void (); // reposition list items so they are stacked vertically |
| 255 | virtual int32_t () override { return -1; } |
| 256 | virtual void (C4FacetEx &cgo) override; |
| 257 | virtual void (C4FacetEx &cgo) override; // draw menu |
| 258 | virtual bool () override { return true; } |
| 259 | virtual void (bool fOK) override; |
| 260 | |
| 261 | // bottom area needed for extra info |
| 262 | virtual int32_t () override { return ((Extra || DrawMenuControls) ? C4MN_SymbolSize : 0) + C4MN_FrameWidth + BaseClass::GetMarginBottom(); } |
| 263 | virtual int32_t () override { return C4MN_FrameWidth + BaseClass::GetMarginLeft(); } |
| 264 | virtual int32_t () override { return C4MN_FrameWidth + BaseClass::GetMarginRight(); } |
| 265 | |
| 266 | friend C4Viewport; // for drawing |
| 267 | friend class C4MenuItem; |
| 268 | }; |
| 269 | |