osxPopupMenu.mm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 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 "platformOSX/platformOSX.h"
  23. #include "platformOSX/osxCocoaUtilities.h"
  24. #include "gui/guiCanvas.h"
  25. class PlatformPopupMenuData
  26. {
  27. public:
  28. osxPopupMenuController* mController;
  29. S32 tag;
  30. PlatformPopupMenuData()
  31. {
  32. mController = NULL;
  33. tag = getTag();
  34. }
  35. ~PlatformPopupMenuData()
  36. {
  37. if (mController)
  38. [mController release];
  39. mController = NULL;
  40. }
  41. // We assign each new menu item an arbitrary integer tag.
  42. static S32 getTag()
  43. {
  44. static S32 lastTag = 'TORQ';
  45. return ++lastTag;
  46. }
  47. };
  48. //-----------------------------------------------------------------------------
  49. // Allocates the OS X specific PopupMenuData
  50. void PopupMenu::createPlatformPopupMenuData()
  51. {
  52. mData = new PlatformPopupMenuData;
  53. }
  54. //-----------------------------------------------------------------------------
  55. // Deallocates the OS X specific PopupMenuData
  56. void PopupMenu::deletePlatformPopupMenuData()
  57. {
  58. SAFE_DELETE(mData);
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Called in PopupMenu's constructor, this handles platform specific menu setup
  62. void PopupMenu::createPlatformMenu()
  63. {
  64. mData->mController = [[osxPopupMenuController alloc] init];
  65. [mData->mController setOwner:this];
  66. }
  67. //-----------------------------------------------------------------------------
  68. S32 PopupMenu::insertItem(S32 pos, const char *title, const char *accel)
  69. {
  70. NSMenuItem *newItem;
  71. newItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]]
  72. initWithTitle:[NSString stringWithUTF8String:title]
  73. action:NULL
  74. keyEquivalent:[NSString stringWithUTF8String:accel]];
  75. [newItem setTarget:mData->mController];
  76. [newItem setAction:@selector(handleSelect:)];
  77. [[mData->mController menu] insertItem:newItem atIndex:pos];
  78. [newItem release];
  79. return 0;
  80. }
  81. //-----------------------------------------------------------------------------
  82. S32 PopupMenu::insertSubMenu(S32 pos, const char *title, PopupMenu *submenu)
  83. {
  84. for(S32 i = 0;i < mSubmenus->size();i++)
  85. {
  86. if(submenu == (*mSubmenus)[i])
  87. {
  88. Con::errorf("PopupMenu::insertSubMenu - Attempting to add submenu twice");
  89. return -1;
  90. }
  91. }
  92. NSMenuItem *newItem;
  93. newItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]]
  94. initWithTitle:[NSString stringWithUTF8String:title] action:NULL
  95. keyEquivalent:[NSString stringWithUTF8String:""]];
  96. [newItem setSubmenu:[submenu->mData->mController menu]];
  97. [newItem setTarget:submenu->mData->mController];
  98. [newItem setAction:@selector(handleSelect:)];
  99. [[mData->mController menu] insertItem:newItem atIndex:pos];
  100. [newItem release];
  101. mSubmenus->addObject(submenu);
  102. return 0;
  103. }
  104. //-----------------------------------------------------------------------------
  105. void PopupMenu::removeItem(S32 itemPos)
  106. {
  107. [[mData->mController menu] removeItemAtIndex:itemPos];
  108. }
  109. //-----------------------------------------------------------------------------
  110. void PopupMenu::enableItem(S32 pos, bool enable)
  111. {
  112. [[[mData->mController menu] itemAtIndex:pos] setEnabled:enable];
  113. }
  114. //-----------------------------------------------------------------------------
  115. void PopupMenu::checkItem(S32 pos, bool checked)
  116. {
  117. [[[mData->mController menu] itemAtIndex:pos] setState:(checked ? NSOnState : NSOffState)];
  118. }
  119. //-----------------------------------------------------------------------------
  120. void PopupMenu::checkRadioItem(S32 firstPos, S32 lastPos, S32 checkPos)
  121. {
  122. for(int i = firstPos; i <= lastPos; i++)
  123. checkItem( i, false);
  124. // check the selected item
  125. checkItem( checkPos, true);
  126. }
  127. //-----------------------------------------------------------------------------
  128. bool PopupMenu::isItemChecked(S32 pos)
  129. {
  130. S32 state = (S32)[[[mData->mController menu] itemAtIndex:pos] state];
  131. return (state == NSOnState);
  132. }
  133. //-----------------------------------------------------------------------------
  134. bool PopupMenu::handleSelect(U32 command, const char *text /* = NULL */)
  135. {
  136. return dAtob(Con::executef(this, 4, "onSelectItem", Con::getIntArg(command), text ? text : ""));
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Not yet implemented or no longer necessary. Will resolve in the next platform update
  140. void PopupMenu::showPopup(S32 x /* = -1 */, S32 y /* = -1 */)
  141. {
  142. // Get the position of the cursor
  143. if(x < 0 || y < 0)
  144. {
  145. Point2I p = Canvas->getCursorPos();
  146. x = p.x;
  147. y = p.y;
  148. }
  149. // Convert to native coordinates
  150. //CGPoint native = MacCarbTorqueToNativeCoords(x, y);
  151. // Manually click the menu item
  152. //U32 result = PopUpMenuSelect(mData->mMenu, native.y, native.x, 0);
  153. }
  154. //-----------------------------------------------------------------------------
  155. void PopupMenu::attachToMenuBar(S32 pos, const char *title)
  156. {
  157. [[mData->mController menuItem] setTitle:[NSString stringWithUTF8String:title]];
  158. [[mData->mController menu] setTitle:[NSString stringWithUTF8String:title]];
  159. [[NSApp mainMenu] addItem:[mData->mController menuItem]];
  160. }
  161. //-----------------------------------------------------------------------------
  162. void PopupMenu::removeFromMenuBar()
  163. {
  164. if ([[NSApp mainMenu] indexOfItem:[mData->mController menuItem]] > -1)
  165. [[NSApp mainMenu] removeItem:[mData->mController menuItem]];
  166. }