PolyScreenEntity.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. * PolyScreenEntity.cpp
  3. * TAU
  4. *
  5. * Created by Ivan Safrin on 3/13/08.
  6. * Copyright 2008 __MyCompanyName__. All rights reserved.
  7. *
  8. */
  9. #include "PolyScreenEntity.h"
  10. using namespace Polycode;
  11. ScreenEntity::ScreenEntity() : Entity(), EventDispatcher() {
  12. color = new Color(1.0f,1.0f,1.0f,1.0f);
  13. width = 1;
  14. height = 1;
  15. hitwidth = 1;
  16. hitheight = 1;
  17. backfaceCulled = false;
  18. positionMode = POSITION_TOPLEFT;
  19. mouseOver = false;
  20. isDragged = false;
  21. dragOffsetX = 0;
  22. dragOffsetY = 0;
  23. parentEntity = NULL;
  24. zindex = 0;
  25. depthWrite = false;
  26. focusable = false;
  27. hasFocus = false;
  28. focusChildren = false;
  29. focusedChild = NULL;
  30. blockMouseInput = false;
  31. snapToPixels = false;
  32. lastClickTicks = 0;
  33. dragLimits = NULL;
  34. xmouse = 0;
  35. ymouse = 0;
  36. }
  37. void ScreenEntity::focusNextChild() {
  38. int j = 0;
  39. if(focusedChild) {
  40. for(int i=0; i < children.size(); i++) {
  41. if(children[i] == focusedChild)
  42. j = i;
  43. }
  44. }
  45. for(int i=0; i < children.size(); i++) {
  46. if(((ScreenEntity*)children[j])->isFocusable() && children[j] != focusedChild) {
  47. focusChild(((ScreenEntity*)children[j]));
  48. return;
  49. }
  50. j++;
  51. if(j == children.size())
  52. j = 0;
  53. }
  54. }
  55. float ScreenEntity::getRotation() {
  56. return this->getRoll();
  57. }
  58. void ScreenEntity::focusChild(ScreenEntity *child) {
  59. if(focusedChild != NULL) {
  60. focusedChild->onLoseFocus();
  61. focusedChild->hasFocus = false;
  62. }
  63. focusedChild = child;
  64. focusedChild->hasFocus = true;
  65. focusedChild->onGainFocus();
  66. }
  67. bool ScreenEntity::isFocusable() {
  68. return focusable;
  69. }
  70. void ScreenEntity::startDrag(float xOffset, float yOffset) {
  71. isDragged = true;
  72. dragOffsetX = xOffset;
  73. dragOffsetY = yOffset;
  74. }
  75. void ScreenEntity::stopDrag() {
  76. isDragged = false;
  77. }
  78. ScreenEntity::~ScreenEntity() {
  79. }
  80. void ScreenEntity::setBlendingMode(int newBlendingMode) {
  81. blendingMode = newBlendingMode;
  82. }
  83. void ScreenEntity::setPosition(float x, float y) {
  84. position.x = x;
  85. position.y = y;
  86. matrixDirty = true;
  87. }
  88. void ScreenEntity::setScale(float x, float y) {
  89. scale.x = x;
  90. scale.y = y;
  91. matrixDirty = true;
  92. }
  93. float ScreenEntity::getWidth() {
  94. return width;
  95. }
  96. float ScreenEntity::getHeight() {
  97. return height;
  98. }
  99. bool ScreenEntity::hitTest(float x, float y) {
  100. bool retVal = false;
  101. // Logger::log("hittest %f,%f in %f %f %f %f\n",x, y, position.x, position.y, hitwidth, hitheight);
  102. switch(positionMode) {
  103. case ScreenEntity::POSITION_TOPLEFT:
  104. if(x > position.x && x < (position.x + hitwidth)
  105. && y > position.y && y < (position.y + hitheight))
  106. retVal = true;
  107. break;
  108. case ScreenEntity::POSITION_CENTER:
  109. if(x > (position.x - hitwidth/2.0f) && x < (position.x + hitwidth/2.0f)
  110. && y > (position.y - hitheight/2.0f) && y < (position.y + hitheight/2.0f))
  111. retVal = true;
  112. break;
  113. }
  114. return retVal;
  115. }
  116. void ScreenEntity::setPositionMode(int newPositionMode) {
  117. positionMode = newPositionMode;
  118. }
  119. void ScreenEntity::_onKeyDown(TAUKey key, wchar_t charCode) {
  120. onKeyDown(key, charCode);
  121. for(int i=0;i<children.size();i++) {
  122. ((ScreenEntity*)children[i])->_onKeyDown(key, charCode);
  123. }
  124. }
  125. void ScreenEntity::_onKeyUp(TAUKey key, wchar_t charCode) {
  126. onKeyUp(key, charCode);
  127. for(int i=0;i<children.size();i++) {
  128. ((ScreenEntity*)children[i])->_onKeyUp(key, charCode);
  129. }
  130. }
  131. void ScreenEntity::setDragLimits(Polycode::Rectangle rect) {
  132. if(!dragLimits)
  133. dragLimits = new Polycode::Rectangle();
  134. dragLimits->x = rect.x;
  135. dragLimits->y = rect.y;
  136. dragLimits->w = rect.w;
  137. dragLimits->h = rect.h;
  138. }
  139. void ScreenEntity::clearDragLimits() {
  140. delete dragLimits;
  141. dragLimits = NULL;
  142. }
  143. void ScreenEntity::_onMouseMove(float x, float y, int timestamp) {
  144. if(isDragged) {
  145. setPosition(x-dragOffsetX,y-dragOffsetY);
  146. if(dragLimits) {
  147. if(position.x < dragLimits->x)
  148. position.x = dragLimits->x;
  149. if(position.x > dragLimits->x + dragLimits->w)
  150. position.x = dragLimits->x + dragLimits->w;
  151. if(position.y < dragLimits->y)
  152. position.y = dragLimits->y;
  153. if(position.y > dragLimits->y + dragLimits->h)
  154. position.y = dragLimits->y + dragLimits->h;
  155. }
  156. }
  157. xmouse = x-position.x;
  158. ymouse = y-position.y;
  159. onMouseMove(x,y);
  160. if(enabled) {
  161. if(hitTest(x,y)) {
  162. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEMOVE);
  163. if(!mouseOver) {
  164. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEOVER);
  165. mouseOver = true;
  166. }
  167. } else {
  168. if(mouseOver) {
  169. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEOUT);
  170. mouseOver = false;
  171. }
  172. }
  173. }
  174. if(enabled) {
  175. for(int i=0;i<children.size();i++) {
  176. ((ScreenEntity*)children[i])->_onMouseMove(x-position.x,y-position.y, timestamp);
  177. }
  178. }
  179. }
  180. bool ScreenEntity::_onMouseUp(float x, float y, int timestamp) {
  181. bool retVal = false;
  182. if(hitTest(x,y) && enabled) {
  183. onMouseUp(x,y);
  184. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEUP);
  185. retVal = true;
  186. } else {
  187. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEUP_OUTSIDE);
  188. }
  189. if(enabled) {
  190. for(int i=0;i<children.size();i++) {
  191. ((ScreenEntity*)children[i])->_onMouseUp(x-position.x,y-position.y, timestamp);
  192. }
  193. }
  194. return retVal;
  195. }
  196. void ScreenEntity::_onMouseWheelUp(float x, float y, int timestamp) {
  197. bool doTest = true;
  198. if(hasMask) {
  199. if(!((ScreenEntity*)maskEntity)->hitTest(x-position.x,y-position.y)) {
  200. doTest = false;
  201. }
  202. }
  203. if(doTest) {
  204. if(hitTest(x,y) && enabled) {
  205. onMouseWheelUp(x,y);
  206. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEWHEEL_UP);
  207. }
  208. if(enabled) {
  209. for(int i=children.size()-1;i>=0;i--) {
  210. ((ScreenEntity*)children[i])->_onMouseWheelUp(x-position.x,y-position.y, timestamp);
  211. if(((ScreenEntity*)children[i])->blockMouseInput && ((ScreenEntity*)children[i])->enabled) {
  212. if(((ScreenEntity*)children[i])->hitTest(x-position.x,y-position.y))
  213. break;
  214. }
  215. }
  216. }
  217. }
  218. }
  219. void ScreenEntity::_onMouseWheelDown(float x, float y, int timestamp) {
  220. bool doTest = true;
  221. if(hasMask) {
  222. if(!((ScreenEntity*)maskEntity)->hitTest(x-position.x,y-position.y)) {
  223. doTest = false;
  224. }
  225. }
  226. if(doTest) {
  227. if(hitTest(x,y) && enabled) {
  228. onMouseWheelDown(x,y);
  229. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEWHEEL_DOWN);
  230. }
  231. if(enabled) {
  232. for(int i=children.size()-1;i>=0;i--) {
  233. ((ScreenEntity*)children[i])->_onMouseWheelDown(x-position.x,y-position.y, timestamp);
  234. if(((ScreenEntity*)children[i])->blockMouseInput && ((ScreenEntity*)children[i])->enabled) {
  235. if(((ScreenEntity*)children[i])->hitTest(x-position.x,y-position.y))
  236. break;
  237. }
  238. }
  239. }
  240. }
  241. }
  242. bool ScreenEntity::_onMouseDown(float x, float y, int timestamp) {
  243. bool retVal = false;
  244. bool doTest = true;
  245. if(hasMask) {
  246. if(!((ScreenEntity*)maskEntity)->hitTest(x,y)) {
  247. doTest = false;
  248. }
  249. }
  250. if(doTest) {
  251. if(hitTest(x,y) && enabled) {
  252. onMouseDown(x,y);
  253. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEDOWN);
  254. if(timestamp - lastClickTicks < 400)
  255. dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_DOUBLECLICK);
  256. lastClickTicks = timestamp;
  257. retVal = true;
  258. }
  259. if(enabled) {
  260. for(int i=children.size()-1;i>=0;i--) {
  261. ((ScreenEntity*)children[i])->_onMouseDown(x-position.x,y-position.y, timestamp);
  262. if(((ScreenEntity*)children[i])->blockMouseInput && ((ScreenEntity*)children[i])->enabled) {
  263. if(((ScreenEntity*)children[i])->hitTest(x-position.x,y-position.y))
  264. break;
  265. }
  266. }
  267. }
  268. }
  269. return retVal;
  270. }
  271. void ScreenEntity::setRotation(float rotation) {
  272. setRoll(rotation);
  273. }
  274. Vector2 ScreenEntity::getPosition2D() {
  275. return Vector2(position.x, position.y);
  276. }
  277. Matrix4 ScreenEntity::buildPositionMatrix() {
  278. Matrix4 posMatrix;
  279. switch(positionMode) {
  280. case POSITION_TOPLEFT:
  281. // renderer->translate2D(position.x+ceil(width/2.0f)*scale->x, position.y+ceil(height/2.0f)*scale->y);
  282. posMatrix.m[3][0] = (position.x+floor(width/2.0f)*scale.x)*matrixAdj;
  283. posMatrix.m[3][1] = (position.y+floor(height/2.0f)*scale.y)*matrixAdj;
  284. posMatrix.m[3][2] = position.z*matrixAdj;
  285. break;
  286. case POSITION_CENTER:
  287. posMatrix.m[3][0] = position.x*matrixAdj;
  288. posMatrix.m[3][1] = position.y*matrixAdj;
  289. posMatrix.m[3][2] = position.z*matrixAdj;
  290. break;
  291. }
  292. if(snapToPixels) {
  293. posMatrix.m[3][0] = round(posMatrix.m[3][0]);
  294. posMatrix.m[3][1] = round(posMatrix.m[3][1]);
  295. posMatrix.m[3][2] = round(posMatrix.m[3][2]);
  296. }
  297. return posMatrix;
  298. }
  299. void ScreenEntity::adjustMatrixForChildren() {
  300. if(positionMode == POSITION_TOPLEFT)
  301. renderer->translate2D(-floor(width/2.0f)*scale.x, -floor(height/2.0f)*scale.y);
  302. }
  303. /*
  304. void ScreenEntity::transformAndRender() {
  305. Update();
  306. if(!renderer || !visible)
  307. return;
  308. renderer->pushMatrix();
  309. switch(positionMode) {
  310. case POSITION_TOPLEFT:
  311. renderer->translate2D(position.x+ceil(width/2.0f)*scale->x, position.y+ceil(height/2.0f)*scale->y);
  312. break;
  313. case POSITION_CENTER:
  314. renderer->translate2D(position.x, position.y);
  315. break;
  316. }
  317. renderer->scale2D(scale);
  318. renderer->rotate2D(rotation);
  319. if(parentEntity) {
  320. Color combined = getCombinedColor();
  321. renderer->setVertexColor(combined.r,combined.g,combined.b,combined.a);
  322. } else {
  323. renderer->setVertexColor(color.r,color.g,color.b,color.a);
  324. }
  325. renderer->setBlendingMode(blendingMode);
  326. Render();
  327. if(positionMode == POSITION_TOPLEFT)
  328. renderer->translate2D(-ceil(width/2.0f)*scale->x, -ceil(height/2.0f)*scale->y);
  329. renderChildren();
  330. renderer->popMatrix();
  331. }
  332. */