2
0

guiPopupMenuCtrl.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "gui/editor/guiPopupMenuCtrl.h"
  23. #include "gfx/gfxDrawUtil.h"
  24. #include "gfx/primBuilder.h"
  25. #include "gui/core/guiCanvas.h"
  26. GuiPopupMenuBackgroundCtrl::GuiPopupMenuBackgroundCtrl()
  27. {
  28. mMenuBarCtrl = nullptr;
  29. }
  30. void GuiPopupMenuBackgroundCtrl::onMouseDown(const GuiEvent &event)
  31. {
  32. }
  33. void GuiPopupMenuBackgroundCtrl::onMouseUp(const GuiEvent &event)
  34. {
  35. clearPopups();
  36. //Pass along the event just in case we clicked over a menu item. We don't want to eat the input for it.
  37. if (mMenuBarCtrl)
  38. mMenuBarCtrl->onMouseUp(event);
  39. close();
  40. }
  41. void GuiPopupMenuBackgroundCtrl::onMouseMove(const GuiEvent &event)
  42. {
  43. //It's possible we're trying to pan through a menubar while a popup is displayed. Pass along our event to the menubar for good measure
  44. if (mMenuBarCtrl)
  45. mMenuBarCtrl->onMouseMove(event);
  46. }
  47. void GuiPopupMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event)
  48. {
  49. }
  50. void GuiPopupMenuBackgroundCtrl::close()
  51. {
  52. if(getRoot())
  53. getRoot()->removeObject(this);
  54. mMenuBarCtrl = nullptr;
  55. }
  56. S32 GuiPopupMenuBackgroundCtrl::findPopupMenu(PopupMenu* menu)
  57. {
  58. S32 menuId = -1;
  59. for (U32 i = 0; i < mPopups.size(); i++)
  60. {
  61. if (mPopups[i]->getId() == menu->getId())
  62. return i;
  63. }
  64. return menuId;
  65. }
  66. void GuiPopupMenuBackgroundCtrl::clearPopups()
  67. {
  68. for (U32 i = 0; i < mPopups.size(); i++)
  69. {
  70. mPopups[i]->mTextList->setSelectedCell(Point2I(-1, -1));
  71. mPopups[i]->mTextList->mPopup->hidePopup();
  72. }
  73. }
  74. GuiPopupMenuTextListCtrl::GuiPopupMenuTextListCtrl()
  75. {
  76. isSubMenu = false; // Added
  77. mMenuBar = nullptr;
  78. mPopup = nullptr;
  79. mLastHighlightedMenuIdx = -1;
  80. }
  81. void GuiPopupMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver)
  82. {
  83. //check if we're a real entry, or if it's a divider
  84. if (mPopup->mMenuItems[cell.y].mIsSpacer)
  85. {
  86. S32 yp = offset.y + mCellSize.y / 2;
  87. GFX->getDrawUtil()->drawLine(offset.x + 5, yp, offset.x + mCellSize.x - 5, yp, ColorI(128, 128, 128));
  88. }
  89. else
  90. {
  91. if (dStrcmp(mList[cell.y].text + 3, "-\t")) // Was: dStrcmp(mList[cell.y].text + 2, "-\t")) but has been changed to take into account the submenu flag
  92. {
  93. Parent::onRenderCell(offset, cell, selected, mouseOver);
  94. }
  95. else
  96. {
  97. S32 yp = offset.y + mCellSize.y / 2;
  98. GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128, 128, 128));
  99. GFX->getDrawUtil()->drawLine(offset.x, yp + 1, offset.x + mCellSize.x, yp + 1, ColorI(255, 255, 255));
  100. }
  101. }
  102. // now see if there's a bitmap...
  103. U8 idx = mList[cell.y].text[0];
  104. if (idx != 1)
  105. {
  106. // there's a bitmap...
  107. U32 index = U32(idx - 2) * 3;
  108. if (!mList[cell.y].active)
  109. index += 2;
  110. else if (selected || mouseOver)
  111. index++;
  112. if (mProfile->mBitmapArrayRects.size() > index)
  113. {
  114. RectI rect = mProfile->mBitmapArrayRects[index];
  115. Point2I off = maxBitmapSize - rect.extent;
  116. off /= 2;
  117. GFX->getDrawUtil()->clearBitmapModulation();
  118. GFX->getDrawUtil()->drawBitmapSR(mProfile->mTextureObject, offset + off, rect);
  119. }
  120. }
  121. // Check if this is a submenu
  122. idx = mList[cell.y].text[1];
  123. if (idx != 1)
  124. {
  125. // This is a submenu, so draw an arrow
  126. S32 left = offset.x + mCellSize.x - 12;
  127. S32 right = left + 8;
  128. S32 top = mCellSize.y / 2 + offset.y - 4;
  129. S32 bottom = top + 8;
  130. S32 middle = top + 4;
  131. //PrimBuild::begin(GFXTriangleList, 3);
  132. ColorI color = ColorI::BLACK;
  133. if (selected || mouseOver)
  134. color = mProfile->mFontColorHL;
  135. else
  136. color = mProfile->mFontColor;
  137. GFX->getDrawUtil()->drawLine(Point2I(left, top), Point2I(right, middle), color);
  138. GFX->getDrawUtil()->drawLine(Point2I(right, middle), Point2I(left, bottom), color);
  139. GFX->getDrawUtil()->drawLine(Point2I(left, bottom), Point2I(left, top), color);
  140. /*PrimBuild::vertex2i(left, top);
  141. PrimBuild::vertex2i(right, middle);
  142. PrimBuild::vertex2i(left, bottom);
  143. PrimBuild::end();*/
  144. }
  145. }
  146. bool GuiPopupMenuTextListCtrl::onKeyDown(const GuiEvent &event)
  147. {
  148. //if the control is a dead end, don't process the input:
  149. if (!mVisible || !mActive || !mAwake)
  150. return false;
  151. //see if the key down is a <return> or not
  152. if (event.modifier == 0)
  153. {
  154. if (event.keyCode == KEY_RETURN)
  155. {
  156. mBackground->close();
  157. return true;
  158. }
  159. else if (event.keyCode == KEY_ESCAPE)
  160. {
  161. mSelectedCell.set(-1, -1);
  162. mBackground->close();
  163. return true;
  164. }
  165. }
  166. //otherwise, pass the event to it's parent
  167. return Parent::onKeyDown(event);
  168. }
  169. void GuiPopupMenuTextListCtrl::onMouseDown(const GuiEvent &event)
  170. {
  171. Parent::onMouseDown(event);
  172. }
  173. void GuiPopupMenuTextListCtrl::onMouseUp(const GuiEvent &event)
  174. {
  175. Parent::onMouseUp(event);
  176. S32 selectionIndex = getSelectedCell().y;
  177. if (selectionIndex != -1)
  178. {
  179. MenuItem *item = &mPopup->mMenuItems[selectionIndex];
  180. if (item)
  181. {
  182. if (item->mEnabled)
  183. dAtob(Con::executef(mPopup, "onSelectItem", Con::getIntArg(getSelectedCell().y), item->mText.isNotEmpty() ? item->mText : ""));
  184. }
  185. }
  186. mSelectedCell.set(-1, -1);
  187. mBackground->close();
  188. }
  189. void GuiPopupMenuTextListCtrl::onCellHighlighted(Point2I cell)
  190. {
  191. // If this text list control is part of a submenu, then don't worry about
  192. // passing this along
  193. if (!isSubMenu)
  194. {
  195. RectI globalbounds(getBounds());
  196. Point2I globalpoint = localToGlobalCoord(globalbounds.point);
  197. globalbounds.point = globalpoint;
  198. }
  199. S32 selectionIndex = cell.y;
  200. if (selectionIndex != -1 && mLastHighlightedMenuIdx != selectionIndex)
  201. {
  202. mLastHighlightedMenuIdx = selectionIndex;
  203. mPopup->hidePopupSubmenus();
  204. }
  205. if (selectionIndex != -1)
  206. {
  207. MenuItem *list = &mPopup->mMenuItems[selectionIndex];
  208. if (list->mIsSubmenu && list->mSubMenu != nullptr)
  209. {
  210. list->mSubMenu->showPopup(getRoot(), getPosition().x + mCellSize.x, getPosition().y + (selectionIndex * mCellSize.y));
  211. }
  212. }
  213. }