CIntObject.cpp 7.5 KB

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