CIntObjectClasses.h 17 KB

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