guiPopupMenuCtrl.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. mBackground = NULL;
  81. }
  82. void GuiPopupMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver)
  83. {
  84. //check if we're a real entry, or if it's a divider
  85. if (mPopup->mMenuItems[cell.y].mIsSpacer)
  86. {
  87. S32 yp = offset.y + mCellSize.y / 2;
  88. GFX->getDrawUtil()->drawLine(offset.x + 5, yp, offset.x + mCellSize.x - 5, yp, ColorI(128, 128, 128));
  89. }
  90. else
  91. {
  92. if (String::compare(mList[cell.y].text + 3, "-\t")) // Was: String::compare(mList[cell.y].text + 2, "-\t")) but has been changed to take into account the submenu flag
  93. {
  94. Parent::onRenderCell(offset, cell, selected, mouseOver);
  95. }
  96. else
  97. {
  98. S32 yp = offset.y + mCellSize.y / 2;
  99. GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128, 128, 128));
  100. GFX->getDrawUtil()->drawLine(offset.x, yp + 1, offset.x + mCellSize.x, yp + 1, ColorI(255, 255, 255));
  101. }
  102. }
  103. // now see if there's a bitmap...
  104. U8 idx = mList[cell.y].text[0];
  105. if (idx != 1)
  106. {
  107. // there's a bitmap...
  108. U32 index = U32(idx - 2) * 4;
  109. if (!mList[cell.y].active)
  110. index += 3;
  111. else if (selected)
  112. index++;
  113. else if (mouseOver)
  114. index += 2;
  115. if (mProfile->mBitmapArrayRects.size() > index)
  116. {
  117. RectI rect = mProfile->mBitmapArrayRects[index];
  118. Point2I off = maxBitmapSize - rect.extent;
  119. off /= 2;
  120. Point2I bitPos = Point2I(offset.x + mCellSize.y / 2, offset.y + mCellSize.y / 2);
  121. GFX->getDrawUtil()->clearBitmapModulation();
  122. GFX->getDrawUtil()->drawBitmapSR(mProfile->getBitmapResource(), bitPos + off, rect);
  123. }
  124. }
  125. // Check if this is a submenu
  126. idx = mList[cell.y].text[1];
  127. if (idx != 1)
  128. {
  129. // This is a submenu, so draw an arrow
  130. S32 left = offset.x + mCellSize.x - 12;
  131. S32 right = left + 8;
  132. S32 top = mCellSize.y / 2 + offset.y - 4;
  133. S32 bottom = top + 8;
  134. S32 middle = top + 4;
  135. //PrimBuild::begin(GFXTriangleList, 3);
  136. ColorI color = ColorI::BLACK;
  137. if (selected || mouseOver)
  138. color = mProfile->mFontColorHL;
  139. else
  140. color = mProfile->mFontColor;
  141. GFX->getDrawUtil()->drawLine(Point2I(left, top), Point2I(right, middle), color);
  142. GFX->getDrawUtil()->drawLine(Point2I(right, middle), Point2I(left, bottom), color);
  143. GFX->getDrawUtil()->drawLine(Point2I(left, bottom), Point2I(left, top), color);
  144. /*PrimBuild::vertex2i(left, top);
  145. PrimBuild::vertex2i(right, middle);
  146. PrimBuild::vertex2i(left, bottom);
  147. PrimBuild::end();*/
  148. }
  149. //check if we're checked
  150. if (mPopup->mMenuItems[cell.y].mIsChecked)
  151. {
  152. GFX->getDrawUtil()->draw2DSquare(Point2F(offset.x + mCellSize.y / 2, offset.y + mCellSize.y / 2), 5);
  153. }
  154. }
  155. bool GuiPopupMenuTextListCtrl::onKeyDown(const GuiEvent &event)
  156. {
  157. //if the control is a dead end, don't process the input:
  158. if (!mVisible || !mActive || !mAwake)
  159. return false;
  160. //see if the key down is a <return> or not
  161. if (event.modifier == 0)
  162. {
  163. if (event.keyCode == KEY_RETURN)
  164. {
  165. mBackground->close();
  166. return true;
  167. }
  168. else if (event.keyCode == KEY_ESCAPE)
  169. {
  170. mSelectedCell.set(-1, -1);
  171. mBackground->close();
  172. return true;
  173. }
  174. }
  175. //otherwise, pass the event to it's parent
  176. return Parent::onKeyDown(event);
  177. }
  178. void GuiPopupMenuTextListCtrl::onMouseDown(const GuiEvent &event)
  179. {
  180. Parent::onMouseDown(event);
  181. }
  182. void GuiPopupMenuTextListCtrl::onMouseUp(const GuiEvent &event)
  183. {
  184. Parent::onMouseUp(event);
  185. S32 selectionIndex = getSelectedCell().y;
  186. if (selectionIndex != -1)
  187. {
  188. MenuItem *item = &mPopup->mMenuItems[selectionIndex];
  189. if (item)
  190. {
  191. if (item->mEnabled)
  192. {
  193. Con::executef(mPopup, "onSelectItem", Con::getIntArg(getSelectedCell().y), item->mText.isNotEmpty() ? item->mText : String(""));
  194. }
  195. }
  196. }
  197. mSelectedCell.set(-1, -1);
  198. mBackground->close();
  199. }
  200. void GuiPopupMenuTextListCtrl::onCellHighlighted(Point2I cell)
  201. {
  202. // If this text list control is part of a submenu, then don't worry about
  203. // passing this along
  204. if (!isSubMenu)
  205. {
  206. RectI globalbounds(getBounds());
  207. Point2I globalpoint = localToGlobalCoord(globalbounds.point);
  208. globalbounds.point = globalpoint;
  209. }
  210. S32 selectionIndex = cell.y;
  211. if (selectionIndex != -1 && mLastHighlightedMenuIdx != selectionIndex)
  212. {
  213. mLastHighlightedMenuIdx = selectionIndex;
  214. mPopup->hidePopupSubmenus();
  215. }
  216. if (selectionIndex != -1)
  217. {
  218. MenuItem *list = &mPopup->mMenuItems[selectionIndex];
  219. if (list->mIsSubmenu && list->mSubMenu != nullptr)
  220. {
  221. list->mSubMenu->showPopup(getRoot(), getPosition().x + mCellSize.x, getPosition().y + (selectionIndex * mCellSize.y));
  222. }
  223. }
  224. }