CIntObject.cpp 7.4 KB

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