CIntObjectClasses.h 18 KB

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