AdventureMapButton.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. #pragma once
  2. #include "SDL_Extensions.h"
  3. #include "hch\CDefHandler.h"
  4. #include "CGameInfo.h"
  5. #include "hch\CLodHandler.h"
  6. #include "hch\CPreGameTextHandler.h"
  7. #include "hch/CTownHandler.h"
  8. #include "CLua.h"
  9. #include "CPlayerInterface.h"
  10. template <typename T=CAdvMapInt>
  11. class AdventureMapButton
  12. : public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
  13. {
  14. public:
  15. std::string name; //for status bar
  16. std::string helpBox; //for right-click help
  17. char key; //key shortcut
  18. T* owner;
  19. void (T::*function)(); //function in CAdvMapInt called when this button is pressed, different for each button
  20. bool colorChange,
  21. actOnDown; //runs when mouse is pressed down over it, not when up
  22. void clickRight (tribool down);
  23. void clickLeft (tribool down);
  24. virtual void hover (bool on);
  25. void keyPressed (SDL_KeyboardEvent & key);
  26. void activate(); // makes button active
  27. void deactivate(); // makes button inactive (but doesn't delete)
  28. AdventureMapButton(); //c-tor
  29. AdventureMapButton( std::string Name, std::string HelpBox, void(T::*Function)(), int x, int y, std::string defName, T* Owner, bool activ=false, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
  30. };
  31. template <typename T>
  32. AdventureMapButton<T>::AdventureMapButton ()
  33. {
  34. type=2;
  35. abs=true;
  36. active=false;
  37. ourObj=NULL;
  38. state=0;
  39. actOnDown = false;
  40. }
  41. template <typename T>
  42. AdventureMapButton<T>::AdventureMapButton
  43. ( std::string Name, std::string HelpBox, void(T::*Function)(), int x, int y, std::string defName, T* Owner, bool activ, std::vector<std::string> * add, bool playerColoredButton )
  44. {
  45. actOnDown = false;
  46. owner = Owner;
  47. type=2;
  48. abs=true;
  49. active=false;
  50. ourObj=NULL;
  51. state=0;
  52. name=Name;
  53. helpBox=HelpBox;
  54. colorChange = playerColoredButton;
  55. int est = LOCPLINT->playerID;
  56. CDefHandler * temp = CGI->spriteh->giveDef(defName);
  57. temp->notFreeImgs = true;
  58. for (int i=0;i<temp->ourImages.size();i++)
  59. {
  60. imgs.resize(1);
  61. imgs[0].push_back(temp->ourImages[i].bitmap);
  62. if(playerColoredButton)
  63. CSDL_Ext::blueToPlayersAdv(imgs[curimg][i],LOCPLINT->playerID);
  64. }
  65. delete temp;
  66. if (add)
  67. {
  68. imgs.resize(imgs.size()+add->size());
  69. for (int i=0; i<add->size();i++)
  70. {
  71. temp = CGI->spriteh->giveDef((*add)[i]);
  72. temp->notFreeImgs = true;
  73. for (int j=0;j<temp->ourImages.size();j++)
  74. {
  75. imgs[i+1].push_back(temp->ourImages[j].bitmap);
  76. if(playerColoredButton)
  77. CSDL_Ext::blueToPlayersAdv(imgs[1+i][j],LOCPLINT->playerID);
  78. }
  79. delete temp;
  80. }
  81. delete add;
  82. }
  83. function = Function;
  84. pos.x=x;
  85. pos.y=y;
  86. pos.w = imgs[curimg][0]->w;
  87. pos.h = imgs[curimg][0]->h -1;
  88. if (activ)
  89. activate();
  90. }
  91. template <typename T>
  92. void AdventureMapButton<T>::clickLeft (tribool down)
  93. {
  94. if (down)
  95. {
  96. state=1;
  97. }
  98. else
  99. {
  100. state=0;
  101. }
  102. show();
  103. if (actOnDown && down)
  104. {
  105. pressedL=state;
  106. (owner->*function)();
  107. }
  108. else if (pressedL && (down==false))
  109. {
  110. pressedL=state;
  111. (owner->*function)();
  112. }
  113. else
  114. {
  115. pressedL=state;
  116. }
  117. }
  118. template <typename T>
  119. void AdventureMapButton<T>::clickRight (tribool down)
  120. {
  121. if(helpBox.size()) //there is no point to show window with nothing inside...
  122. LOCPLINT->adventureInt->handleRightClick(helpBox,down,this);
  123. }
  124. template <typename T>
  125. void AdventureMapButton<T>::hover (bool on)
  126. {
  127. Hoverable::hover(on);
  128. if(name.size()) //if there is no name, there is nohing to display also
  129. {
  130. if (on)
  131. LOCPLINT->statusbar->print(name);
  132. else if (LOCPLINT->statusbar->getCurrent()==name)
  133. LOCPLINT->statusbar->clear();
  134. }
  135. }
  136. template <typename T>
  137. void AdventureMapButton<T>::activate()
  138. {
  139. if (active) return;
  140. active=true;
  141. ClickableL::activate();
  142. ClickableR::activate();
  143. Hoverable::activate();
  144. KeyInterested::activate();
  145. }
  146. template <typename T>
  147. void AdventureMapButton<T>::keyPressed (SDL_KeyboardEvent & key)
  148. {
  149. //TODO: check if it's shortcut
  150. }
  151. template <typename T>
  152. void AdventureMapButton<T>::deactivate()
  153. {
  154. if (!active) return;
  155. active=false;
  156. ClickableL::deactivate();
  157. ClickableR::deactivate();
  158. Hoverable::deactivate();
  159. KeyInterested::deactivate();
  160. }
  161. template <typename T>
  162. CTownList<T>::~CTownList()
  163. {
  164. delete arrup;
  165. delete arrdo;
  166. }
  167. template <typename T>
  168. CTownList<T>::CTownList(int Size, SDL_Rect * Pos, int arupx, int arupy, int ardox, int ardoy)
  169. :CList(Size)
  170. {
  171. pos = *Pos;
  172. arrup = CGI->spriteh->giveDef("IAM014.DEF");
  173. arrdo = CGI->spriteh->giveDef("IAM015.DEF");
  174. arrupp.x=arupx;
  175. arrupp.y=arupy;
  176. arrupp.w=arrup->ourImages[0].bitmap->w;
  177. arrupp.h=arrup->ourImages[0].bitmap->h;
  178. arrdop.x=ardox;
  179. arrdop.y=ardoy;
  180. arrdop.w=arrdo->ourImages[0].bitmap->w;
  181. arrdop.h=arrdo->ourImages[0].bitmap->h;
  182. posporx = arrdop.x;
  183. pospory = arrupp.y + arrupp.h;
  184. pressed = indeterminate;
  185. from = 0;
  186. }
  187. template<typename T>
  188. void CTownList<T>::genList()
  189. {
  190. int howMany = LOCPLINT->cb->howManyTowns();
  191. for (int i=0;i<howMany;i++)
  192. {
  193. items.push_back(LOCPLINT->cb->getTownInfo(i,0));
  194. }
  195. }
  196. template<typename T>
  197. void CTownList<T>::select(int which)
  198. {
  199. if (which>=items.size())
  200. return;
  201. selected = which;
  202. if(owner)
  203. (owner->*fun)();
  204. }
  205. template<typename T>
  206. void CTownList<T>::mouseMoved (SDL_MouseMotionEvent & sEvent)
  207. {
  208. if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
  209. {
  210. if (from>0)
  211. LOCPLINT->statusbar->print(CGI->preth->zelp[306].first);
  212. else
  213. LOCPLINT->statusbar->clear();
  214. return;
  215. }
  216. else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
  217. {
  218. if ((items.size()-from) > SIZE)
  219. LOCPLINT->statusbar->print(CGI->preth->zelp[307].first);
  220. else
  221. LOCPLINT->statusbar->clear();
  222. return;
  223. }
  224. //if not buttons then towns
  225. int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
  226. hx-=pos.x;
  227. hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
  228. float ny = (float)hy/(float)32;
  229. if ((ny>SIZE || ny<0) || (from+ny>=items.size()))
  230. {
  231. LOCPLINT->statusbar->clear();
  232. return;
  233. };
  234. LOCPLINT->statusbar->print(items[from+ny]->state->hoverText(const_cast<CGTownInstance*>(items[from+ny])));
  235. }
  236. template<typename T>
  237. void CTownList<T>::clickLeft(tribool down)
  238. {
  239. if (down)
  240. {
  241. /***************************ARROWS*****************************************/
  242. if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
  243. {
  244. blitAt(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
  245. pressed = true;
  246. return;
  247. }
  248. else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>SIZE))
  249. {
  250. blitAt(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
  251. pressed = false;
  252. return;
  253. }
  254. /***************************TOWNS*****************************************/
  255. int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
  256. hx-=pos.x;
  257. hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
  258. float ny = (float)hy/(float)32;
  259. if (ny>SIZE || ny<0)
  260. return;
  261. if (SIZE==5 && ((int)(ny+from))==selected && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
  262. LOCPLINT->openTownWindow(items[selected]);//print town screen
  263. else
  264. select(ny+from);
  265. }
  266. else
  267. {
  268. if (indeterminate(pressed))
  269. return;
  270. if (pressed) //up
  271. {
  272. blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
  273. pressed = indeterminate;
  274. if (!down)
  275. {
  276. from--;
  277. if (from<0)
  278. from=0;
  279. draw();
  280. }
  281. }
  282. else if (!pressed) //down
  283. {
  284. blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
  285. pressed = indeterminate;
  286. if (!down)
  287. {
  288. from++;
  289. //if (from<items.size()-5)
  290. // from=items.size()-5;
  291. draw();
  292. }
  293. }
  294. else
  295. throw 0;
  296. }
  297. }
  298. template<typename T>
  299. void CTownList<T>::clickRight(tribool down)
  300. {
  301. if (down)
  302. {
  303. /***************************ARROWS*****************************************/
  304. if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
  305. {
  306. LOCPLINT->adventureInt->handleRightClick(CGI->preth->zelp[306].second,down,this);
  307. }
  308. else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
  309. {
  310. LOCPLINT->adventureInt->handleRightClick(CGI->preth->zelp[307].second,down,this);
  311. }
  312. //if not buttons then towns
  313. int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
  314. hx-=pos.x;
  315. hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
  316. float ny = (float)hy/(float)32;
  317. if ((ny>5 || ny<0) || (from+ny>=items.size()))
  318. {
  319. return;
  320. }
  321. //show popup
  322. CInfoPopup * ip = new CInfoPopup(LOCPLINT->townWins[items[from+ny]->identifier],LOCPLINT->current->motion.x-LOCPLINT->townWins[items[from+ny]->identifier]->w,LOCPLINT->current->motion.y-LOCPLINT->townWins[items[from+ny]->identifier]->h,false);
  323. ip->activate();
  324. }
  325. else
  326. {
  327. LOCPLINT->adventureInt->handleRightClick(CGI->preth->zelp[306].second,down,this);
  328. LOCPLINT->adventureInt->handleRightClick(CGI->preth->zelp[307].second,down,this);
  329. }
  330. }
  331. template<typename T>
  332. void CTownList<T>::hover (bool on)
  333. {
  334. }
  335. template<typename T>
  336. void CTownList<T>::keyPressed (SDL_KeyboardEvent & key)
  337. {
  338. }
  339. template<typename T>
  340. void CTownList<T>::draw()
  341. {
  342. for (int iT=0+from;iT<SIZE+from;iT++)
  343. {
  344. int i = iT-from;
  345. if (iT>=items.size())
  346. {
  347. blitAt(CGI->townh->getPic(-1),posporx,pospory+i*32);
  348. continue;
  349. }
  350. blitAt(CGI->townh->getPic(items[iT]->subID,items[iT]->hasFort(),items[iT]->builded),posporx,pospory+i*32);
  351. if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
  352. {
  353. blitAt(CGI->townh->getPic(-2),posporx,pospory+i*32);
  354. }
  355. }
  356. if (from>0)
  357. blitAt(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
  358. else
  359. blitAt(arrup->ourImages[2].bitmap,arrupp.x,arrupp.y);
  360. if (items.size()-from>SIZE)
  361. blitAt(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
  362. else
  363. blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
  364. }
  365. template<typename T>
  366. class CSlider : public IShowable, public MotionInterested, public ClickableL
  367. {
  368. public:
  369. AdventureMapButton<CSlider> left, right, slider; //if vertical then left=up
  370. int capacity,//how many elements can be active at same time
  371. amount, //how many elements
  372. value; //first active element
  373. bool horizontal, moving;
  374. CDefEssential *imgs ;
  375. T* owner;
  376. void(T::*moved)(int to);
  377. void redrawSlider();
  378. void sliderClicked();
  379. void moveLeft();
  380. void clickLeft (tribool down);
  381. void mouseMoved (SDL_MouseMotionEvent & sEvent);
  382. void moveRight();
  383. void moveTo(int to);
  384. void activate(); // makes button active
  385. void deactivate(); // makes button inactive (but doesn't delete)
  386. void show(SDL_Surface * to = NULL);
  387. CSlider(int x, int y, int totalw, T*Owner,void(T::*Moved)(int to), int Capacity, int Amount,
  388. int Value=0, bool Horizontal=true);
  389. ~CSlider();
  390. };
  391. template<typename T>
  392. void CSlider<T>::sliderClicked()
  393. {
  394. if(!moving)
  395. {
  396. MotionInterested::activate();
  397. moving = true;
  398. }
  399. }
  400. template<typename T>
  401. void CSlider<T>::mouseMoved (SDL_MouseMotionEvent & sEvent)
  402. {
  403. float v = sEvent.x - pos.x - 16;
  404. v/= (pos.w - 48);
  405. v*=amount;
  406. if(v!=value)
  407. {
  408. moveTo(v);
  409. redrawSlider();
  410. }
  411. }
  412. template<typename T>
  413. void CSlider<T>::redrawSlider()
  414. {
  415. slider.show();
  416. }
  417. template<typename T>
  418. void CSlider<T>::moveLeft()
  419. {
  420. moveTo(value-1);
  421. }
  422. template<typename T>
  423. void CSlider<T>::moveRight()
  424. {
  425. moveTo(value+1);
  426. }
  427. template<typename T>
  428. void CSlider<T>::moveTo(int to)
  429. {
  430. if(to<0)
  431. to=0;
  432. else if(to>amount)
  433. to=amount;
  434. value = to;
  435. float part = (float)to/amount;
  436. part*=(pos.w-48);
  437. slider.pos.x = part + pos.x + 16;
  438. (owner->*moved)(to);
  439. }
  440. template<typename T>
  441. void CSlider<T>::activate() // makes button active
  442. {
  443. left.activate();
  444. right.activate();
  445. slider.activate();
  446. ClickableL::activate();
  447. }
  448. template<typename T>
  449. void CSlider<T>::deactivate() // makes button inactive (but doesn't delete)
  450. {
  451. left.deactivate();
  452. right.deactivate();
  453. slider.deactivate();
  454. ClickableL::deactivate();
  455. }
  456. template<typename T>
  457. void CSlider<T>::clickLeft (tribool down)
  458. {
  459. if(down)
  460. {
  461. float pw = LOCPLINT->current->motion.x-pos.x-16;
  462. float rw = pw / ((float)(pos.w-32));
  463. if (rw>1) return;
  464. if (rw<0) return;
  465. moveTo(rw*amount);
  466. return;
  467. }
  468. if(moving)
  469. {
  470. MotionInterested::deactivate();
  471. moving = false;
  472. }
  473. }
  474. template<typename T>
  475. void CSlider<T>::show(SDL_Surface * to)
  476. {
  477. left.show();
  478. right.show();
  479. slider.show();
  480. }
  481. template<typename T>
  482. CSlider<T>::CSlider(int x, int y, int totalw, T*Owner,void(T::*Moved)(int to), int Capacity, int Amount, int Value, bool Horizontal)
  483. :capacity(Capacity),amount(Amount),value(Value),horizontal(Horizontal), moved(Moved), owner(Owner)
  484. {
  485. moving = false;
  486. strongInterest = true;
  487. imgs = CGI->spriteh->giveDefEss("IGPCRDIV.DEF");
  488. left.pos.y = slider.pos.y = right.pos.y = pos.y = y;
  489. left.pos.x = pos.x = x;
  490. right.pos.x = x + totalw - 16;
  491. left.owner = right.owner = slider.owner = this;
  492. left.function = &CSlider::moveLeft;
  493. right.function = &CSlider::moveRight;
  494. slider.function = &CSlider::sliderClicked;
  495. left.pos.w = left.pos.h = right.pos.w = right.pos.h = slider.pos.w = slider.pos.h = pos.h = 16;
  496. pos.w = totalw;
  497. left.imgs.resize(1); right.imgs.resize(1); slider.imgs.resize(1);
  498. left.imgs[0].push_back(imgs->ourImages[0].bitmap); left.imgs[0].push_back(imgs->ourImages[1].bitmap);
  499. right.imgs[0].push_back(imgs->ourImages[2].bitmap); right.imgs[0].push_back(imgs->ourImages[3].bitmap);
  500. slider.imgs[0].push_back(imgs->ourImages[4].bitmap);
  501. left.notFreeButton = right.notFreeButton = slider.notFreeButton = true;
  502. slider.actOnDown = true;
  503. moveTo(value);
  504. }
  505. template<typename T>
  506. CSlider<T>::~CSlider()
  507. {
  508. delete imgs;
  509. }