CIntObject.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. #include "../StdInc.h"
  2. #include "CIntObject.h"
  3. #include "CGuiHandler.h"
  4. #include "SDL_Extensions.h"
  5. void CIntObject::activateLClick()
  6. {
  7. GH.lclickable.push_front(this);
  8. active_m |= LCLICK;
  9. }
  10. void CIntObject::deactivateLClick()
  11. {
  12. std::list<CIntObject*>::iterator hlp = std::find(GH.lclickable.begin(),GH.lclickable.end(),this);
  13. assert(hlp != GH.lclickable.end());
  14. GH.lclickable.erase(hlp);
  15. active_m &= ~LCLICK;
  16. }
  17. void CIntObject::activateRClick()
  18. {
  19. GH.rclickable.push_front(this);
  20. active_m |= RCLICK;
  21. }
  22. void CIntObject::deactivateRClick()
  23. {
  24. std::list<CIntObject*>::iterator hlp = std::find(GH.rclickable.begin(),GH.rclickable.end(),this);
  25. assert(hlp != GH.rclickable.end());
  26. GH.rclickable.erase(hlp);
  27. active_m &= ~RCLICK;
  28. }
  29. void CIntObject::activateHover()
  30. {
  31. GH.hoverable.push_front(this);
  32. active_m |= HOVER;
  33. }
  34. void CIntObject::deactivateHover()
  35. {
  36. std::list<CIntObject*>::iterator hlp = std::find(GH.hoverable.begin(),GH.hoverable.end(),this);
  37. assert(hlp != GH.hoverable.end());
  38. GH.hoverable.erase(hlp);
  39. active_m &= ~HOVER;
  40. }
  41. void CIntObject::activateKeys()
  42. {
  43. GH.keyinterested.push_front(this);
  44. active_m |= KEYBOARD;
  45. }
  46. void CIntObject::deactivateKeys()
  47. {
  48. std::list<CIntObject*>::iterator hlp = std::find(GH.keyinterested.begin(),GH.keyinterested.end(),this);
  49. assert(hlp != GH.keyinterested.end());
  50. GH.keyinterested.erase(hlp);
  51. active_m &= ~KEYBOARD;
  52. }
  53. void CIntObject::activateMouseMove()
  54. {
  55. GH.motioninterested.push_front(this);
  56. active_m |= MOVE;
  57. }
  58. void CIntObject::deactivateMouseMove()
  59. {
  60. std::list<CIntObject*>::iterator hlp = std::find(GH.motioninterested.begin(),GH.motioninterested.end(),this);
  61. assert(hlp != GH.motioninterested.end());
  62. GH.motioninterested.erase(hlp);
  63. active_m &= ~MOVE;
  64. }
  65. void CIntObject::activateWheel()
  66. {
  67. GH.wheelInterested.push_front(this);
  68. active_m |= WHEEL;
  69. }
  70. void CIntObject::deactivateWheel()
  71. {
  72. std::list<CIntObject*>::iterator hlp = std::find(GH.wheelInterested.begin(),GH.wheelInterested.end(),this);
  73. assert(hlp != GH.wheelInterested.end());
  74. GH.wheelInterested.erase(hlp);
  75. active_m &= ~WHEEL;
  76. }
  77. void CIntObject::activateDClick()
  78. {
  79. GH.doubleClickInterested.push_front(this);
  80. active_m |= DOUBLECLICK;
  81. }
  82. void CIntObject::deactivateDClick()
  83. {
  84. std::list<CIntObject*>::iterator hlp = std::find(GH.doubleClickInterested.begin(),GH.doubleClickInterested.end(),this);
  85. assert(hlp != GH.doubleClickInterested.end());
  86. GH.doubleClickInterested.erase(hlp);
  87. active_m &= ~DOUBLECLICK;
  88. }
  89. void CIntObject::activateTimer()
  90. {
  91. GH.timeinterested.push_back(this);
  92. active_m |= TIME;
  93. }
  94. void CIntObject::deactivateTimer()
  95. {
  96. std::list<CIntObject*>::iterator hlp = std::find(GH.timeinterested.begin(),GH.timeinterested.end(),this);
  97. assert(hlp != GH.timeinterested.end());
  98. GH.timeinterested.erase(hlp);
  99. active_m &= ~TIME;
  100. }
  101. CIntObject::CIntObject(int used_, Point pos_):
  102. parent_m(nullptr),
  103. active_m(0),
  104. parent(parent_m),
  105. active(active_m)
  106. {
  107. pressedL = pressedR = hovered = captureAllKeys = strongInterest = false;
  108. toNextTick = timerDelay = 0;
  109. used = used_;
  110. recActions = defActions = GH.defActionsDef;
  111. pos.x = pos_.x;
  112. pos.y = pos_.y;
  113. pos.w = 0;
  114. pos.h = 0;
  115. if(GH.captureChildren)
  116. GH.createdObj.front()->addChild(this, true);
  117. }
  118. void CIntObject::setTimer(int msToTrigger)
  119. {
  120. if (!(active & TIME))
  121. activateTimer();
  122. toNextTick = timerDelay = msToTrigger;
  123. used |= TIME;
  124. }
  125. void CIntObject::onTimer(int timePassed)
  126. {
  127. toNextTick -= timePassed;
  128. if (toNextTick < 0)
  129. {
  130. toNextTick += timerDelay;
  131. tick();
  132. }
  133. }
  134. void CIntObject::show(SDL_Surface * to)
  135. {
  136. if(defActions & UPDATE)
  137. for(size_t i = 0; i < children.size(); i++)
  138. if(children[i]->recActions & UPDATE)
  139. children[i]->show(to);
  140. }
  141. void CIntObject::showAll(SDL_Surface * to)
  142. {
  143. if(defActions & SHOWALL)
  144. {
  145. for(size_t i = 0; i < children.size(); i++)
  146. if(children[i]->recActions & SHOWALL)
  147. children[i]->showAll(to);
  148. }
  149. }
  150. void CIntObject::activate()
  151. {
  152. if (active_m)
  153. {
  154. if ((used | GENERAL) == active_m)
  155. return;
  156. else
  157. {
  158. tlog1 << "Warning: IntObject re-activated with mismatching used and active\n";
  159. deactivate(); //FIXME: better to avoid such possibility at all
  160. }
  161. }
  162. active_m |= GENERAL;
  163. activate(used);
  164. if(defActions & ACTIVATE)
  165. for(size_t i = 0; i < children.size(); i++)
  166. if(children[i]->recActions & ACTIVATE)
  167. children[i]->activate();
  168. }
  169. void CIntObject::activate(ui16 what)
  170. {
  171. if(what & LCLICK)
  172. activateLClick();
  173. if(what & RCLICK)
  174. activateRClick();
  175. if(what & HOVER)
  176. activateHover();
  177. if(what & MOVE)
  178. activateMouseMove();
  179. if(what & KEYBOARD)
  180. activateKeys();
  181. if(what & TIME)
  182. activateTimer();
  183. if(what & WHEEL)
  184. activateWheel();
  185. if(what & DOUBLECLICK)
  186. activateDClick();
  187. }
  188. void CIntObject::deactivate()
  189. {
  190. if (!active_m)
  191. return;
  192. active_m &= ~ GENERAL;
  193. deactivate(active_m);
  194. assert(!active_m);
  195. if(defActions & DEACTIVATE)
  196. for(size_t i = 0; i < children.size(); i++)
  197. if(children[i]->recActions & DEACTIVATE)
  198. children[i]->deactivate();
  199. }
  200. void CIntObject::deactivate(ui16 what)
  201. {
  202. if(what & LCLICK)
  203. deactivateLClick();
  204. if(what & RCLICK)
  205. deactivateRClick();
  206. if(what & HOVER)
  207. deactivateHover();
  208. if(what & MOVE)
  209. deactivateMouseMove();
  210. if(what & KEYBOARD)
  211. deactivateKeys();
  212. if(what & TIME)
  213. deactivateTimer();
  214. if(what & WHEEL)
  215. deactivateWheel();
  216. if(what & DOUBLECLICK)
  217. deactivateDClick();
  218. }
  219. CIntObject::~CIntObject()
  220. {
  221. if (active_m)
  222. deactivate();
  223. if(defActions & DISPOSE)
  224. {
  225. while (!children.empty())
  226. if(children.front()->recActions & DISPOSE)
  227. delete children.front();
  228. else
  229. removeChild(children.front());
  230. }
  231. if(parent_m)
  232. parent_m->removeChild(this);
  233. }
  234. void CIntObject::printAtLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::Cornsilk*/, SDL_Surface * dst/*=screen*/ )
  235. {
  236. CSDL_Ext::printAt(text, pos.x + x, pos.y + y, font, kolor, dst);
  237. }
  238. void CIntObject::printAtMiddleLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::Cornsilk*/, SDL_Surface * dst/*=screen*/ )
  239. {
  240. CSDL_Ext::printAtMiddle(text, pos.x + x, pos.y + y, font, kolor, dst);
  241. }
  242. void CIntObject::printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color kolor, SDL_Surface * dst)
  243. {
  244. printAtMiddleLoc(text, p.x, p.y, font, kolor, dst);
  245. }
  246. void CIntObject::blitAtLoc( SDL_Surface * src, int x, int y, SDL_Surface * dst )
  247. {
  248. blitAt(src, pos.x + x, pos.y + y, dst);
  249. }
  250. void CIntObject::blitAtLoc(SDL_Surface * src, const Point &p, SDL_Surface * dst)
  251. {
  252. blitAtLoc(src, p.x, p.y, dst);
  253. }
  254. void CIntObject::printAtMiddleWBLoc( const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst)
  255. {
  256. CSDL_Ext::printAtMiddleWB(text, pos.x + x, pos.y + y, font, charpr, kolor, dst);
  257. }
  258. void CIntObject::printToLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst )
  259. {
  260. CSDL_Ext::printTo(text, pos.x + x, pos.y + y, font, kolor, dst);
  261. }
  262. void CIntObject::addUsedEvents(ui16 newActions)
  263. {
  264. if (active_m)
  265. activate(~used & newActions);
  266. used |= newActions;
  267. }
  268. void CIntObject::removeUsedEvents(ui16 newActions)
  269. {
  270. if (active_m)
  271. deactivate(used & newActions);
  272. used &= ~newActions;
  273. }
  274. void CIntObject::disable()
  275. {
  276. if(active)
  277. deactivate();
  278. recActions = DISPOSE;
  279. }
  280. void CIntObject::enable()
  281. {
  282. if(!active_m && parent_m->active)
  283. activate();
  284. recActions = 255;
  285. }
  286. bool CIntObject::isItInLoc( const SDL_Rect &rect, int x, int y )
  287. {
  288. return isItIn(&rect, x - pos.x, y - pos.y);
  289. }
  290. bool CIntObject::isItInLoc( const SDL_Rect &rect, const Point &p )
  291. {
  292. return isItIn(&rect, p.x - pos.x, p.y - pos.y);
  293. }
  294. void CIntObject::fitToScreen(int borderWidth, bool propagate)
  295. {
  296. Point newPos = pos.topLeft();
  297. vstd::amax(newPos.x, borderWidth);
  298. vstd::amax(newPos.y, borderWidth);
  299. vstd::amin(newPos.x, screen->w - borderWidth - pos.w);
  300. vstd::amin(newPos.y, screen->h - borderWidth - pos.h);
  301. if (newPos != pos.topLeft())
  302. moveTo(newPos, propagate);
  303. }
  304. void CIntObject::moveBy( const Point &p, bool propagate /*= true*/ )
  305. {
  306. pos.x += p.x;
  307. pos.y += p.y;
  308. if(propagate)
  309. for(size_t i = 0; i < children.size(); i++)
  310. children[i]->moveBy(p, propagate);
  311. }
  312. void CIntObject::moveTo( const Point &p, bool propagate /*= true*/ )
  313. {
  314. moveBy(Point(p.x - pos.x, p.y - pos.y), propagate);
  315. }
  316. void CIntObject::addChild(CIntObject *child, bool adjustPosition /*= false*/)
  317. {
  318. if (vstd::contains(children, child))
  319. {
  320. // tlog4<< "Warning: object already assigned to this parent!\n";
  321. return;
  322. }
  323. if (child->parent_m)
  324. {
  325. // tlog4<< "Warning: object already has parent!\n";
  326. child->parent_m->removeChild(child, adjustPosition);
  327. }
  328. children.push_back(child);
  329. child->parent_m = this;
  330. if(adjustPosition)
  331. child->pos += pos;
  332. if (!active && child->active)
  333. child->deactivate();
  334. if (active && !child->active)
  335. child->activate();
  336. }
  337. void CIntObject::removeChild(CIntObject *child, bool adjustPosition /*= false*/)
  338. {
  339. if (!child)
  340. return;
  341. assert(vstd::contains(children, child));
  342. assert(child->parent_m == this);
  343. children -= child;
  344. child->parent_m = NULL;
  345. if(adjustPosition)
  346. child->pos -= pos;
  347. }
  348. void CIntObject::drawBorderLoc(SDL_Surface * sur, const Rect &r, const int3 &color)
  349. {
  350. CSDL_Ext::drawBorder(sur, r + pos, color);
  351. }
  352. void CIntObject::redraw()
  353. {
  354. //currently most of calls come from active objects so this check won't affect them
  355. //it should fix glitches when called by inactive elements located below active window
  356. if (active)
  357. {
  358. if (parent_m && (type & REDRAW_PARENT))
  359. {
  360. parent_m->redraw();
  361. }
  362. else
  363. {
  364. showAll(screenBuf);
  365. if(screenBuf != screen)
  366. showAll(screen);
  367. }
  368. }
  369. }
  370. const Rect & CIntObject::center( const Rect &r, bool propagate )
  371. {
  372. pos.w = r.w;
  373. pos.h = r.h;
  374. return center(Point(screen->w/2, screen->h/2), propagate);
  375. }
  376. const Rect & CIntObject::center( bool propagate )
  377. {
  378. return center(pos, propagate);
  379. }
  380. const Rect & CIntObject::center(const Point &p, bool propagate /*= true*/)
  381. {
  382. moveBy(Point(p.x - pos.w/2 - pos.x,
  383. p.y - pos.h/2 - pos.y),
  384. propagate);
  385. return pos;
  386. }
  387. bool CIntObject::captureThisEvent(const SDL_KeyboardEvent & key)
  388. {
  389. return captureAllKeys;
  390. }
  391. void CKeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
  392. {
  393. if(vstd::contains(assignedKeys,key.keysym.sym))
  394. {
  395. bool prev = pressedL;
  396. if(key.state == SDL_PRESSED)
  397. {
  398. pressedL = true;
  399. clickLeft(true, prev);
  400. }
  401. else
  402. {
  403. pressedL = false;
  404. clickLeft(false, prev);
  405. }
  406. }
  407. }