CIntObject.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #include "StdInc.h"
  2. #include "GL2D.h"
  3. #include "CIntObject.h"
  4. #include "CGuiHandler.h"
  5. #include "SDL_Extensions.h"
  6. #include "../CMessage.h"
  7. CIntObject::CIntObject(int used_, Point offset) :
  8. used(used_),
  9. parent_m(nullptr),
  10. active_m(0),
  11. parent(parent_m),
  12. active(active_m),
  13. pos(offset)
  14. {
  15. pressedL = pressedR = hovered = captureAllKeys = strongInterest = false;
  16. toNextTick = timerDelay = 0;
  17. recActions = defActions = GH.defActionsDef;
  18. if(GH.captureChildren)
  19. GH.createdObj.front()->addChild(this, true);
  20. }
  21. void CIntObject::setTimer(int msToTrigger)
  22. {
  23. if (!(active & TIME))
  24. activate(TIME);
  25. toNextTick = timerDelay = msToTrigger;
  26. used |= TIME;
  27. }
  28. void CIntObject::onTimer(int timePassed)
  29. {
  30. toNextTick -= timePassed;
  31. if (toNextTick < 0)
  32. {
  33. toNextTick += timerDelay;
  34. tick();
  35. }
  36. }
  37. void CIntObject::show()
  38. {
  39. if(defActions & UPDATE)
  40. for(size_t i = 0; i < children.size(); i++)
  41. if(children[i]->recActions & UPDATE)
  42. children[i]->show();
  43. }
  44. void CIntObject::showAll()
  45. {
  46. if(defActions & SHOWALL)
  47. {
  48. for(size_t i = 0; i < children.size(); i++)
  49. if(children[i]->recActions & SHOWALL)
  50. children[i]->showAll();
  51. }
  52. }
  53. void CIntObject::activate()
  54. {
  55. if (active_m)
  56. {
  57. if ((used | GENERAL) == active_m)
  58. return;
  59. else
  60. {
  61. tlog1 << "Warning: IntObject re-activated with mismatching used and active\n";
  62. deactivate(); //FIXME: better to avoid such possibility at all
  63. }
  64. }
  65. active_m |= GENERAL;
  66. activate(used);
  67. if(defActions & ACTIVATE)
  68. for(size_t i = 0; i < children.size(); ++i)
  69. if(children[i]->recActions & ACTIVATE)
  70. children[i]->activate();
  71. }
  72. void CIntObject::activate(ui16 what)
  73. {
  74. GH.handleElementActivate(this, what);
  75. }
  76. void CIntObject::deactivate()
  77. {
  78. if (!active_m)
  79. return;
  80. active_m &= ~ GENERAL;
  81. deactivate(active_m);
  82. assert(!active_m);
  83. if(defActions & DEACTIVATE)
  84. for(size_t i = 0; i < children.size(); i++)
  85. if(children[i]->recActions & DEACTIVATE)
  86. children[i]->deactivate();
  87. }
  88. void CIntObject::deactivate(ui16 what)
  89. {
  90. GH.handleElementDeActivate(this, what);
  91. }
  92. CIntObject::~CIntObject()
  93. {
  94. if (active_m)
  95. deactivate();
  96. if(defActions & DISPOSE)
  97. {
  98. while (!children.empty())
  99. if(children.front()->recActions & DISPOSE)
  100. delete children.front();
  101. else
  102. removeChild(children.front());
  103. }
  104. if(parent_m)
  105. parent_m->removeChild(this);
  106. }
  107. void CIntObject::printAtLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
  108. {
  109. graphics->fonts[font]->renderTextLeft(dst, text, kolor, Point(pos.x + x, pos.y + y));
  110. }
  111. void CIntObject::printAtMiddleLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
  112. {
  113. printAtMiddleLoc(text, Point(x,y), font, kolor, dst);
  114. }
  115. void CIntObject::printAtMiddleLoc(const std::string & text, Point p, EFonts font, SDL_Color kolor, SDL_Surface * dst)
  116. {
  117. graphics->fonts[font]->renderTextCenter(dst, text, kolor, p += pos);
  118. }
  119. void CIntObject::blitAtLoc( SDL_Surface * src, int x, int y, SDL_Surface * dst )
  120. {
  121. blitAt(src, pos.x + x, pos.y + y, dst);
  122. }
  123. void CIntObject::blitAtLoc(SDL_Surface * src, const Point &p, SDL_Surface * dst)
  124. {
  125. blitAtLoc(src, p.x, p.y, dst);
  126. }
  127. void CIntObject::printAtMiddleWBLoc( const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst)
  128. {
  129. graphics->fonts[font]->renderTextLinesCenter(dst, CMessage::breakText(text, charpr, font), kolor, Point(pos.x + x, pos.y + y));
  130. }
  131. void CIntObject::printToLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst )
  132. {
  133. graphics->fonts[font]->renderTextRight(dst, text, kolor, Point(pos.x + x, pos.y + y));
  134. }
  135. void CIntObject::addUsedEvents(ui16 newActions)
  136. {
  137. if (active_m)
  138. activate(~used & newActions);
  139. used |= newActions;
  140. }
  141. void CIntObject::removeUsedEvents(ui16 newActions)
  142. {
  143. if (active_m)
  144. deactivate(used & newActions);
  145. used &= ~newActions;
  146. }
  147. void CIntObject::disable()
  148. {
  149. if(active)
  150. deactivate();
  151. recActions = DISPOSE;
  152. }
  153. void CIntObject::enable()
  154. {
  155. if(!active_m && parent_m->active)
  156. activate();
  157. recActions = 255;
  158. }
  159. bool CIntObject::isItInLoc(const Rect &rect, int x, int y)
  160. {
  161. return isItIn(&rect, x - pos.x, y - pos.y);
  162. }
  163. bool CIntObject::isItInLoc(const Rect &rect, Point p)
  164. {
  165. return isItIn(&rect, p.x - pos.x, p.y - pos.y);
  166. }
  167. void CIntObject::fitToScreen(int borderWidth, bool propagate)
  168. {
  169. Point newPos = pos.topLeft();
  170. vstd::amax(newPos.x, borderWidth);
  171. vstd::amax(newPos.y, borderWidth);
  172. vstd::amin(newPos.x, GL2D::getScreenWidth() - borderWidth - pos.w);
  173. vstd::amin(newPos.y, GL2D::getScreenHeight() - borderWidth - pos.h);
  174. if (newPos != pos.topLeft())
  175. moveTo(newPos, propagate);
  176. }
  177. void CIntObject::moveBy(Point p, bool propagate /*= true*/ )
  178. {
  179. pos.x += p.x;
  180. pos.y += p.y;
  181. if(propagate)
  182. for(size_t i = 0; i < children.size(); ++i)
  183. children[i]->moveBy(p, propagate);
  184. }
  185. void CIntObject::moveTo(Point p, bool propagate /*= true*/ )
  186. {
  187. moveBy(Point(p.x - pos.x, p.y - pos.y), propagate);
  188. }
  189. void CIntObject::addChild(CIntObject *child, bool adjustPosition /*= false*/)
  190. {
  191. if (vstd::contains(children, child))
  192. {
  193. // tlog4<< "Warning: object already assigned to this parent!\n";
  194. return;
  195. }
  196. if (child->parent_m)
  197. {
  198. // tlog4<< "Warning: object already has parent!\n";
  199. child->parent_m->removeChild(child, adjustPosition);
  200. }
  201. children.push_back(child);
  202. child->parent_m = this;
  203. if(adjustPosition)
  204. child->pos += pos;
  205. if (!active && child->active)
  206. child->deactivate();
  207. if (active && !child->active)
  208. child->activate();
  209. }
  210. void CIntObject::removeChild(CIntObject *child, bool adjustPosition /*= false*/)
  211. {
  212. if (!child)
  213. return;
  214. assert(vstd::contains(children, child));
  215. assert(child->parent_m == this);
  216. children -= child;
  217. child->parent_m = NULL;
  218. if(adjustPosition)
  219. child->pos -= pos;
  220. }
  221. void CIntObject::drawBorderLoc(SDL_Surface * sur, const Rect &r, const int3 &color)
  222. {
  223. //* CSDL_Ext::drawBorder(sur, r + pos, color);
  224. }
  225. void CIntObject::redraw()
  226. {
  227. //currently most of calls come from active objects so this check won't affect them
  228. //it should fix glitches when called by inactive elements located below active window
  229. if (active)
  230. {
  231. if (parent_m && (type & REDRAW_PARENT))
  232. {
  233. parent_m->redraw();
  234. }
  235. else
  236. {
  237. showAll();
  238. }
  239. }
  240. }
  241. const Rect & CIntObject::center( const Rect &r, bool propagate )
  242. {
  243. pos.w = r.w;
  244. pos.h = r.h;
  245. return center(Point(GL2D::getScreenWidth()/2, GL2D::getScreenHeight()/2), propagate);
  246. }
  247. const Rect & CIntObject::center( bool propagate )
  248. {
  249. return center(pos, propagate);
  250. }
  251. const Rect & CIntObject::center(Point p, bool propagate /*= true*/)
  252. {
  253. moveBy(Point(p.x - pos.w/2 - pos.x,
  254. p.y - pos.h/2 - pos.y),
  255. propagate);
  256. return pos;
  257. }
  258. bool CIntObject::captureThisEvent(const SDL_KeyboardEvent & key)
  259. {
  260. return captureAllKeys;
  261. }
  262. void CKeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
  263. {
  264. if(vstd::contains(assignedKeys,key.keysym.sym)
  265. || vstd::contains(assignedKeys, CGuiHandler::numToDigit(key.keysym.sym)))
  266. {
  267. bool prev = pressedL;
  268. if(key.state == SDL_PRESSED)
  269. {
  270. pressedL = true;
  271. clickLeft(true, prev);
  272. }
  273. else
  274. {
  275. pressedL = false;
  276. clickLeft(false, prev);
  277. }
  278. }
  279. }