2
0

CIntObjectClasses.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. #pragma once
  2. #include "../gui/CIntObject.h"
  3. #include "../gui/SDL_Extensions.h"
  4. #include "../../lib/FunctionList.h"
  5. struct SDL_Surface;
  6. struct Rect;
  7. class CAnimImage;
  8. class CLabel;
  9. class CAnimation;
  10. class CDefHandler;
  11. /*
  12. * CPicture.h, part of VCMI engine
  13. *
  14. * Authors: listed in file AUTHORS in main folder
  15. *
  16. * License: GNU General Public License v2.0 or later
  17. * Full text of license available in license.txt file, in main folder
  18. *
  19. */
  20. // Window GUI class
  21. class CSimpleWindow : public CIntObject
  22. {
  23. public:
  24. SDL_Surface * bitmap; //background
  25. virtual void show(SDL_Surface * to);
  26. CSimpleWindow():bitmap(nullptr){}; //c-tor
  27. virtual ~CSimpleWindow(); //d-tor
  28. };
  29. // Image class
  30. class CPicture : public CIntObject
  31. {
  32. void setSurface(SDL_Surface *to);
  33. public:
  34. SDL_Surface * bg;
  35. Rect * srcRect; //if nullptr then whole surface will be used
  36. bool freeSurf; //whether surface will be freed upon CPicture destruction
  37. bool needRefresh;//Surface needs to be displayed each frame
  38. operator SDL_Surface*()
  39. {
  40. return bg;
  41. }
  42. CPicture(const Rect & r, const SDL_Color & color, bool screenFormat = false); //rect filled with given color
  43. CPicture(const Rect & r, ui32 color, bool screenFormat = false); //rect filled with given color
  44. CPicture(SDL_Surface * BG, int x = 0, int y=0, bool Free = true); //wrap existing SDL_Surface
  45. CPicture(const std::string &bmpname, int x=0, int y=0);
  46. CPicture(SDL_Surface *BG, const Rect &SrcRext, int x = 0, int y = 0, bool free = false); //wrap subrect of given surface
  47. ~CPicture();
  48. void init();
  49. //set alpha value for whole surface. Note: may be messed up if surface is shared
  50. // 0=transparent, 255=opaque
  51. void setAlpha(int value);
  52. void scaleTo(Point size);
  53. void createSimpleRect(const Rect &r, bool screenFormat, ui32 color);
  54. void show(SDL_Surface * to);
  55. void showAll(SDL_Surface * to);
  56. void convertToScreenBPP();
  57. void colorizeAndConvert(PlayerColor player);
  58. void colorize(PlayerColor player);
  59. };
  60. /// area filled with specific texture
  61. class CFilledTexture : CIntObject
  62. {
  63. SDL_Surface * texture;
  64. public:
  65. CFilledTexture(std::string imageName, Rect position);
  66. ~CFilledTexture();
  67. void showAll(SDL_Surface *to);
  68. };
  69. namespace config{struct ButtonInfo;}
  70. /// Base class for buttons.
  71. class CButtonBase : public CKeyShortcut
  72. {
  73. public:
  74. enum ButtonState
  75. {
  76. NORMAL=0,
  77. PRESSED=1,
  78. BLOCKED=2,
  79. HIGHLIGHTED=3
  80. };
  81. private:
  82. int bitmapOffset; // base offset of visible bitmap from animation
  83. ButtonState state;//current state of button from enum
  84. public:
  85. bool swappedImages,//fix for some buttons: normal and pressed image are swapped
  86. keepFrame; // don't change visual representation
  87. void addOverlay(CIntObject * newOverlay);
  88. void addTextOverlay(const std::string &Text, EFonts font, SDL_Color color = Colors::WHITE);
  89. void update();//to refresh button after image or text change
  90. void setOffset(int newOffset);
  91. void setState(ButtonState newState);
  92. ButtonState getState();
  93. //just to make code clearer
  94. void block(bool on);
  95. bool isBlocked();
  96. bool isHighlighted();
  97. CAnimImage * image; //image for this button
  98. CIntObject * overlay;//object-overlay
  99. CButtonBase(); //c-tor
  100. virtual ~CButtonBase(); //d-tor
  101. };
  102. /// Typical Heroes 3 button which can be inactive or active and can
  103. /// hold further information if you right-click it
  104. class CAdventureMapButton : public CButtonBase
  105. {
  106. std::vector<std::string> imageNames;//store list of images that can be used by this button
  107. size_t currentImage;
  108. void onButtonClicked(); // calls callback
  109. public:
  110. std::map<int, std::string> hoverTexts; //text for statusbar
  111. std::string helpBox; //for right-click help
  112. CFunctionList<void()> callback;
  113. bool actOnDown,//runs when mouse is pressed down over it, not when up
  114. hoverable,//if true, button will be highlighted when hovered
  115. borderEnabled,
  116. soundDisabled;
  117. SDL_Color borderColor;
  118. void clickRight(tribool down, bool previousState);
  119. virtual void clickLeft(tribool down, bool previousState);
  120. void hover (bool on);
  121. CAdventureMapButton(); //c-tor
  122. CAdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, int key=0, std::vector<std::string> * add = nullptr, bool playerColoredButton = false );//c-tor
  123. CAdventureMapButton( const std::pair<std::string, std::string> &help, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, int key=0, std::vector<std::string> * add = nullptr, bool playerColoredButton = false );//c-tor
  124. CAdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, config::ButtonInfo *info, int key=0);//c-tor
  125. void init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key );
  126. void setIndex(size_t index, bool playerColoredButton=false);
  127. void setImage(CAnimation* anim, bool playerColoredButton=false, int animFlags=0);
  128. void setPlayerColor(PlayerColor player);
  129. void showAll(SDL_Surface * to);
  130. };
  131. /// A button which can be selected/deselected
  132. class CHighlightableButton
  133. : public CAdventureMapButton
  134. {
  135. public:
  136. CHighlightableButton(const CFunctionList<void()> &onSelect, const CFunctionList<void()> &onDeselect, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key=0);
  137. CHighlightableButton(const std::pair<std::string, std::string> &help, const CFunctionList<void()> &onSelect, int x, int y, const std::string &defName, int myid, int key=0, std::vector<std::string> * add = nullptr, bool playerColoredButton = false );//c-tor
  138. CHighlightableButton(const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &onSelect, int x, int y, const std::string &defName, int myid, int key=0, std::vector<std::string> * add = nullptr, bool playerColoredButton = false );//c-tor
  139. bool onlyOn;//button can not be de-selected
  140. bool selected;//state of highlightable button
  141. int ID; //for identification
  142. CFunctionList<void()> callback2; //when de-selecting
  143. void select(bool on);
  144. void clickLeft(tribool down, bool previousState);
  145. };
  146. /// A group of buttons where one button can be selected
  147. class CHighlightableButtonsGroup : public CIntObject
  148. {
  149. public:
  150. CFunctionList<void(int)> onChange; //called when changing selected button with new button's id
  151. std::vector<CHighlightableButton*> buttons;
  152. bool musicLike; //determines the behaviour of this group
  153. //void addButton(const std::map<int,std::string> &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid);
  154. void addButton(CHighlightableButton* bt);//add existing button, it'll be deleted by CHighlightableButtonsGroup destructor
  155. void addButton(const std::map<int,std::string> &tooltip, const std::string &HelpBox, const std::string &defName, int x, int y, int uid, const CFunctionList<void()> &OnSelect=0, int key=0); //creates new button
  156. CHighlightableButtonsGroup(const CFunctionList<void(int)> & OnChange, bool musicLikeButtons = false);
  157. ~CHighlightableButtonsGroup();
  158. void select(int id, bool mode); //mode==0: id is serial; mode==1: id is unique button id
  159. void selectionChanged(int to);
  160. void show(SDL_Surface * to);
  161. void showAll(SDL_Surface * to);
  162. void block(ui8 on);
  163. };
  164. /// A typical slider which can be orientated horizontally/vertically.
  165. class CSlider : public CIntObject
  166. {
  167. public:
  168. CAdventureMapButton *left, *right, *slider; //if vertical then left=up
  169. int capacity;//how many elements can be active at same time (e.g. hero list = 5)
  170. int amount; //total amount of elements (e.g. hero list = 0-8)
  171. int positions; //number of highest position (0 if there is only one)
  172. int value; //first active element
  173. int scrollStep; // how many elements will be scrolled via one click, default = 1
  174. bool horizontal;
  175. bool wheelScrolling;
  176. bool keyScrolling;
  177. std::function<void(int)> moved;
  178. void redrawSlider();
  179. void sliderClicked();
  180. void moveLeft();
  181. void moveRight();
  182. void moveTo(int to);
  183. void block(bool on);
  184. void setAmount(int to);
  185. void keyPressed(const SDL_KeyboardEvent & key);
  186. void wheelScrolled(bool down, bool in);
  187. void clickLeft(tribool down, bool previousState);
  188. void mouseMoved (const SDL_MouseMotionEvent & sEvent);
  189. void showAll(SDL_Surface * to);
  190. CSlider(int x, int y, int totalw, std::function<void(int)> Moved, int Capacity, int Amount,
  191. int Value=0, bool Horizontal=true, int style = 0); //style 0 - brown, 1 - blue
  192. ~CSlider();
  193. void moveToMax();
  194. };
  195. /// Used as base for Tabs and List classes
  196. class CObjectList : public CIntObject
  197. {
  198. public:
  199. typedef std::function<CIntObject* (size_t)> CreateFunc;
  200. typedef std::function<void(CIntObject *)> DestroyFunc;
  201. private:
  202. CreateFunc createObject;
  203. DestroyFunc destroyObject;
  204. protected:
  205. //Internal methods for safe creation of items (Children capturing and activation/deactivation if needed)
  206. void deleteItem(CIntObject* item);
  207. CIntObject* createItem(size_t index);
  208. CObjectList(CreateFunc create, DestroyFunc destroy = DestroyFunc());//Protected constructor
  209. };
  210. /// Window element with multiple tabs
  211. class CTabbedInt : public CObjectList
  212. {
  213. private:
  214. CIntObject * activeTab;
  215. size_t activeID;
  216. public:
  217. //CreateFunc, DestroyFunc - see CObjectList
  218. //Pos - position of object, all tabs will be moved to this position
  219. //ActiveID - ID of initially active tab
  220. CTabbedInt(CreateFunc create, DestroyFunc destroy = DestroyFunc(), Point position=Point(), size_t ActiveID=0);
  221. void setActive(size_t which);
  222. //recreate active tab
  223. void reset();
  224. //return currently active item
  225. CIntObject * getItem();
  226. };
  227. /// List of IntObjects with optional slider
  228. class CListBox : public CObjectList
  229. {
  230. private:
  231. std::list< CIntObject* > items;
  232. size_t first;
  233. size_t totalSize;
  234. Point itemOffset;
  235. CSlider * slider;
  236. void updatePositions();
  237. public:
  238. //CreateFunc, DestroyFunc - see CObjectList
  239. //Pos - position of first item
  240. //ItemOffset - distance between items in the list
  241. //VisibleSize - maximal number of displayable at once items
  242. //TotalSize
  243. //Slider - slider style, bit field: 1 = present(disabled), 2=horisontal(vertical), 4=blue(brown)
  244. //SliderPos - position of slider, if present
  245. CListBox(CreateFunc create, DestroyFunc destroy, Point Pos, Point ItemOffset, size_t VisibleSize,
  246. size_t TotalSize, size_t InitialPos=0, int Slider=0, Rect SliderPos=Rect() );
  247. //recreate all visible items
  248. void reset();
  249. //change or get total amount of items in the list
  250. void resize(size_t newSize);
  251. size_t size();
  252. //return item with index which or null if not present
  253. CIntObject * getItem(size_t which);
  254. //return currently active items
  255. const std::list< CIntObject * > & getItems();
  256. //get index of this item. -1 if not found
  257. size_t getIndexOf(CIntObject * item);
  258. //scroll list to make item which visible
  259. void scrollTo(size_t which);
  260. //scroll list to specified position
  261. void moveToPos(size_t which);
  262. void moveToNext();
  263. void moveToPrev();
  264. size_t getPos();
  265. };
  266. /// Small helper class to manage group of similar labels
  267. class CLabelGroup : public CIntObject
  268. {
  269. std::list<CLabel*> labels;
  270. EFonts font;
  271. EAlignment align;
  272. SDL_Color color;
  273. public:
  274. CLabelGroup(EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE);
  275. void add(int x=0, int y=0, const std::string &text = "");
  276. };
  277. /// Base class for all text-related widgets.
  278. /// Controls text blitting-related options
  279. class CTextContainer : public virtual CIntObject
  280. {
  281. protected:
  282. /// returns size of border, for left- or right-aligned text
  283. virtual Point getBorderSize() = 0;
  284. /// do actual blitting of line. Text "what" will be placed at "where" and aligned according to alignment
  285. void blitLine(SDL_Surface * to, Rect where, std::string what);
  286. CTextContainer(EAlignment alignment, EFonts font, SDL_Color color);
  287. public:
  288. EAlignment alignment;
  289. EFonts font;
  290. SDL_Color color; // default font color. Can be overridden by placing "{}" into the string
  291. };
  292. /// Label which shows text
  293. class CLabel : public CTextContainer
  294. {
  295. protected:
  296. Point getBorderSize() override;
  297. virtual std::string visibleText();
  298. CPicture *bg;
  299. public:
  300. std::string text;
  301. bool autoRedraw; //whether control will redraw itself on setTxt
  302. std::string getText();
  303. virtual void setText(const std::string &Txt);
  304. CLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT,
  305. const SDL_Color &Color = Colors::WHITE, const std::string &Text = "");
  306. void showAll(SDL_Surface * to); //shows statusbar (with current text)
  307. };
  308. /// Multi-line label that can display multiple lines of text
  309. /// If text is too big to fit into requested area remaining part will not be visible
  310. class CMultiLineLabel : public CLabel
  311. {
  312. // text to blit, split into lines that are no longer than widget width
  313. std::vector<std::string> lines;
  314. // area of text that actually will be printed, default is widget size
  315. Rect visibleSize;
  316. void splitText(const std::string &Txt);
  317. Rect getTextLocation();
  318. public:
  319. // total size of text, x = longest line of text, y = total height of lines
  320. Point textSize;
  321. CMultiLineLabel(Rect position, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "");
  322. void setText(const std::string &Txt);
  323. void showAll(SDL_Surface * to);
  324. void setVisibleSize(Rect visibleSize);
  325. // scrolls text visible in widget. Positive value will move text up
  326. void scrollTextTo(int distance);
  327. void scrollTextBy(int distance);
  328. };
  329. /// a multi-line label that tries to fit text with given available width and height;
  330. /// if not possible, it creates a slider for scrolling text
  331. class CTextBox : public CIntObject
  332. {
  333. int sliderStyle;
  334. public:
  335. CMultiLineLabel * label;
  336. CSlider *slider;
  337. CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE);
  338. void resize(Point newSize);
  339. void setText(const std::string &Txt);
  340. void sliderMoved(int to);
  341. };
  342. /// Status bar which is shown at the bottom of the in-game screens
  343. class CGStatusBar : public CLabel
  344. {
  345. bool textLock; //Used for blocking changes to the text
  346. void init();
  347. CGStatusBar *oldStatusBar;
  348. protected:
  349. Point getBorderSize() override;
  350. public:
  351. void clear();//clears statusbar and refreshes
  352. void setText(const std::string & Text) override; //prints text and refreshes statusbar
  353. void show(SDL_Surface * to); //shows statusbar (with current text)
  354. CGStatusBar(CPicture *BG, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = Colors::WHITE); //given CPicture will be captured by created sbar and it's pos will be used as pos for sbar
  355. CGStatusBar(int x, int y, std::string name, int maxw=-1);
  356. ~CGStatusBar();
  357. void lock(bool shouldLock); //If true, current text cannot be changed until lock(false) is called
  358. };
  359. /// UIElement which can get input focus
  360. class CFocusable : public virtual CIntObject
  361. {
  362. protected:
  363. virtual void focusGot(){};
  364. virtual void focusLost(){};
  365. public:
  366. bool focus; //only one focusable control can have focus at one moment
  367. void giveFocus(); //captures focus
  368. void moveFocus(); //moves focus to next active control (may be used for tab switching)
  369. static std::list<CFocusable*> focusables; //all existing objs
  370. static CFocusable *inputWithFocus; //who has focus now
  371. CFocusable();
  372. ~CFocusable();
  373. };
  374. /// Text input box where players can enter text
  375. class CTextInput : public CLabel, public CFocusable
  376. {
  377. std::string newText;
  378. protected:
  379. std::string visibleText() override;
  380. void focusGot() override;
  381. void focusLost() override;
  382. public:
  383. CFunctionList<void(const std::string &)> cb;
  384. CFunctionList<void(std::string &, const std::string &)> filters;
  385. void setText(const std::string &nText, bool callCb = false);
  386. CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(const std::string &)> &CB);
  387. CTextInput(const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB);
  388. CTextInput(const Rect &Pos, SDL_Surface *srf = nullptr);
  389. void clickLeft(tribool down, bool previousState) override;
  390. void keyPressed(const SDL_KeyboardEvent & key) override;
  391. bool captureThisEvent(const SDL_KeyboardEvent & key) override;
  392. #ifndef VCMI_SDL1
  393. void textInputed(const SDL_TextInputEvent & event) override;
  394. void textEdited(const SDL_TextEditingEvent & event) override;
  395. #endif // VCMI_SDL1
  396. //Filter that will block all characters not allowed in filenames
  397. static void filenameFilter(std::string &text, const std::string & oldText);
  398. //Filter that will allow only input of numbers in range min-max (min-max are allowed)
  399. //min-max should be set via something like boost::bind
  400. static void numberFilter(std::string &text, const std::string & oldText, int minValue, int maxValue);
  401. };
  402. /// Shows a text by moving the mouse cursor over the object
  403. class CHoverableArea: public virtual CIntObject
  404. {
  405. public:
  406. std::string hoverText;
  407. virtual void hover (bool on);
  408. CHoverableArea();
  409. virtual ~CHoverableArea();
  410. };
  411. /// Can interact on left and right mouse clicks, plus it shows a text when by hovering over it
  412. class LRClickableAreaWText: public CHoverableArea
  413. {
  414. public:
  415. std::string text;
  416. LRClickableAreaWText();
  417. LRClickableAreaWText(const Rect &Pos, const std::string &HoverText = "", const std::string &ClickText = "");
  418. virtual ~LRClickableAreaWText();
  419. void init();
  420. virtual void clickLeft(tribool down, bool previousState);
  421. virtual void clickRight(tribool down, bool previousState);
  422. };
  423. /// Basic class for windows
  424. class CWindowObject : public CIntObject
  425. {
  426. CPicture * createBg(std::string imageName, bool playerColored);
  427. int getUsedEvents(int options);
  428. CIntObject *shadow;
  429. void setShadow(bool on);
  430. int options;
  431. protected:
  432. CPicture * background;
  433. //Simple function with call to GH.popInt
  434. void close();
  435. //Used only if RCLICK_POPUP was set
  436. void clickRight(tribool down, bool previousState);
  437. //To display border
  438. void showAll(SDL_Surface *to);
  439. //change or set background image
  440. void setBackground(std::string filename);
  441. void updateShadow();
  442. public:
  443. enum EOptions
  444. {
  445. PLAYER_COLORED=1, //background will be player-colored
  446. RCLICK_POPUP=2, // window will behave as right-click popup
  447. BORDERED=4, // window will have border if current resolution is bigger than size of window
  448. SHADOW_DISABLED=8 //this window won't display any shadow
  449. };
  450. /*
  451. * options - EOpions enum
  452. * imageName - name for background image, can be empty
  453. * centerAt - position of window center. Default - center of the screen
  454. */
  455. CWindowObject(int options, std::string imageName, Point centerAt);
  456. CWindowObject(int options, std::string imageName = "");
  457. ~CWindowObject();
  458. };