From 2ca6af8e4843a76add7094b11853a1cae9e7fc21 Mon Sep 17 00:00:00 2001 From: Areloch Date: Sat, 11 Nov 2017 01:21:48 -0600 Subject: [PATCH] Refactors the Popup menus and GuiMenuBars to remove unneeded duplication and platform-specific/deprecated code. --- Engine/source/gui/core/guiCanvas.cpp | 61 +- Engine/source/gui/core/guiCanvas.h | 1 + Engine/source/gui/editor/guiMenuBar.cpp | 912 ++--- Engine/source/gui/editor/guiMenuBar.h | 172 +- Engine/source/gui/editor/guiPopupMenuCtrl.cpp | 106 +- Engine/source/gui/editor/guiPopupMenuCtrl.h | 18 +- Engine/source/gui/editor/popupMenu.cpp | 506 +++ .../menus => gui/editor}/popupMenu.h | 119 +- Engine/source/platform/menus/menuBar.cpp | 127 - Engine/source/platform/menus/menuBar.h | 71 - Engine/source/platform/menus/popupMenu.cpp | 269 -- .../menus/PlatformSDLPopupMenuData.h | 35 - .../menus/guiPlatformGenericMenuBar.h | 51 - .../source/platformSDL/menus/menuBarSDL.cpp | 200 -- .../source/platformSDL/menus/popupMenuSDL.cpp | 393 --- .../platformWin32/menus/menuBarWin32.cpp | 177 - .../platformWin32/menus/popupMenuWin32.cpp | 746 ---- Engine/source/windowManager/sdl/sdlWindow.cpp | 1 - .../BaseGame/game/tools/gui/guiDialogs.ed.cs | 1 - .../tools/gui/guiPlatformGenericMenubar.ed.cs | 19 - .../gui/guiPlatformGenericMenubar.ed.gui | 14 - .../guiEditor/scripts/guiEditorCanvas.ed.cs | 6 +- .../tools/worldEditor/scripts/EditorGui.ed.cs | 2 +- .../tools/worldEditor/scripts/menus.ed.cs | 31 +- .../Full/game/tools/gui/guiDialogs.ed.cs | 1 - .../tools/gui/guiPlatformGenericMenubar.ed.cs | 19 - .../gui/guiPlatformGenericMenubar.ed.gui | 14 - .../guiEditor/scripts/guiEditorCanvas.ed.cs | 6 +- .../tools/worldEditor/scripts/EditorGui.ed.cs | 3135 ++--------------- 29 files changed, 1343 insertions(+), 5870 deletions(-) create mode 100644 Engine/source/gui/editor/popupMenu.cpp rename Engine/source/{platform/menus => gui/editor}/popupMenu.h (69%) delete mode 100644 Engine/source/platform/menus/menuBar.cpp delete mode 100644 Engine/source/platform/menus/menuBar.h delete mode 100644 Engine/source/platform/menus/popupMenu.cpp delete mode 100644 Engine/source/platformSDL/menus/PlatformSDLPopupMenuData.h delete mode 100644 Engine/source/platformSDL/menus/guiPlatformGenericMenuBar.h delete mode 100644 Engine/source/platformSDL/menus/menuBarSDL.cpp delete mode 100644 Engine/source/platformSDL/menus/popupMenuSDL.cpp delete mode 100644 Engine/source/platformWin32/menus/menuBarWin32.cpp delete mode 100644 Engine/source/platformWin32/menus/popupMenuWin32.cpp delete mode 100644 Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs delete mode 100644 Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui delete mode 100644 Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.cs delete mode 100644 Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.gui diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index 82c0475f0..5202e57bf 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -276,8 +276,6 @@ bool GuiCanvas::onAdd() // Define the menu bar for this canvas (if any) Con::executef(this, "onCreateMenu"); - Sim::findObject("PlatformGenericMenubar", mMenuBarCtrl); - return parentRet; } @@ -302,21 +300,39 @@ void GuiCanvas::setMenuBar(SimObject *obj) Parent::removeObject( oldMenuBar ); // set new menubar - if( mMenuBarCtrl ) - Parent::addObject(mMenuBarCtrl); + if (mMenuBarCtrl) + { + //Add a wrapper control so that the menubar sizes correctly + GuiControlProfile* profile; + Sim::findObject("GuiModelessDialogProfile", profile); + + if (!profile) + { + Con::errorf("GuiCanvas::setMenuBar: Unable to find the GuiModelessDialogProfile profile!"); + return; + } + + GuiControl* menuBackground = new GuiControl(); + menuBackground->registerObject(); + + menuBackground->setControlProfile(profile); + + menuBackground->addObject(mMenuBarCtrl); + + Parent::addObject(menuBackground); + } // update window accelerator keys if( oldMenuBar != mMenuBarCtrl ) { - StringTableEntry ste = StringTable->insert("menubar"); - GuiMenuBar* menu = NULL; - menu = !oldMenuBar ? NULL : dynamic_cast(oldMenuBar->findObjectByInternalName( ste, true)); - if( menu ) - menu->removeWindowAcceleratorMap( *getPlatformWindow()->getInputGenerator() ); + GuiMenuBar* oldMenu = dynamic_cast(oldMenuBar); + GuiMenuBar* newMenu = dynamic_cast(mMenuBarCtrl); - menu = !mMenuBarCtrl ? NULL : dynamic_cast(mMenuBarCtrl->findObjectByInternalName( ste, true)); - if( menu ) - menu->buildWindowAcceleratorMap( *getPlatformWindow()->getInputGenerator() ); + if(oldMenu) + oldMenu->removeWindowAcceleratorMap(*getPlatformWindow()->getInputGenerator()); + + if(newMenu) + newMenu->buildWindowAcceleratorMap(*getPlatformWindow()->getInputGenerator()); } } @@ -1633,27 +1649,26 @@ void GuiCanvas::maintainSizing() Point2I newPos = screenRect.point; // if menubar is active displace content gui control - if( mMenuBarCtrl && (ctrl == getContentControl()) ) - { - const SimObject *menu = mMenuBarCtrl->findObjectByInternalName( StringTable->insert("menubar"), true); + if (mMenuBarCtrl && (ctrl == getContentControl())) + { + /*const SimObject *menu = mMenuBarCtrl->findObjectByInternalName( StringTable->insert("menubar"), true); - if( !menu ) - continue; + if( !menu ) + continue; - AssertFatal( dynamic_cast(menu), ""); + AssertFatal( dynamic_cast(menu), "");*/ - const U32 yOffset = static_cast(menu)->getExtent().y; - newPos.y += yOffset; - newExt.y -= yOffset; + const U32 yOffset = static_cast(mMenuBarCtrl)->mMenubarHeight; + newPos.y += yOffset; + newExt.y -= yOffset; } - if(pos != newPos || ext != newExt) + if (pos != newPos || ext != newExt) { ctrl->resize(newPos, newExt); resetUpdateRegions(); } } - } void GuiCanvas::setupFences() diff --git a/Engine/source/gui/core/guiCanvas.h b/Engine/source/gui/core/guiCanvas.h index dfc98da38..b193bfbf1 100644 --- a/Engine/source/gui/core/guiCanvas.h +++ b/Engine/source/gui/core/guiCanvas.h @@ -210,6 +210,7 @@ public: virtual void onRemove(); void setMenuBar(SimObject *obj); + SimObject* getMenuBar() { return mMenuBarCtrl; } static void initPersistFields(); diff --git a/Engine/source/gui/editor/guiMenuBar.cpp b/Engine/source/gui/editor/guiMenuBar.cpp index 688531a87..0fe8c3c71 100644 --- a/Engine/source/gui/editor/guiMenuBar.cpp +++ b/Engine/source/gui/editor/guiMenuBar.cpp @@ -142,24 +142,11 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( S32 menuId, const char "@see GuiTickCtrl\n\n" ); -IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( S32 submenuId, const char* submenuText ),( submenuId, submenuText ), - "@brief Called whenever a submenu is selected.\n\n" - "@param submenuId Id of the selected submenu\n" - "@param submenuText Text of the selected submenu\n\n" - "@tsexample\n" - "GuiMenuBar::onSubmenuSelect(%this,%submenuId,%submenuText)\n" - "{\n" - " // Code to run when the callback occurs\n" - "}\n" - "@endtsexample\n\n" - "@see GuiTickCtrl\n\n" -); - //------------------------------------------------------------------------------ // console methods //------------------------------------------------------------------------------ -DefineEngineMethod( GuiMenuBar, clearMenus, void, (),, +/*DefineEngineMethod( GuiMenuBar, clearMenus, void, (),, "@brief Clears all the menus from the menu bar.\n\n" "@tsexample\n" "// Inform the GuiMenuBar control to clear all menus from itself.\n" @@ -818,14 +805,14 @@ GuiMenuBar::Menu *GuiMenuBar::findMenu(const char *menu) { U32 id = dAtoi(menu); for (U32 i = 0; i < mMenuList.size(); ++i) - if (id == mMenuList[i]->id) + if (id == mMenuList[i].id) return mMenuList[i]; return NULL; } else { for (U32 i = 0; i < mMenuList.size(); ++i) - if (!dStricmp(menu, mMenuList[i]->text)) + if (!dStricmp(menu, mMenuList[i].text)) return mMenuList[i]; return NULL; } @@ -1093,19 +1080,18 @@ void GuiMenuBar::clearSubmenuItems(MenuItem *menuitem) while(menuitem->submenu->firstMenuItem) removeSubmenuItem(menuitem, menuitem->submenu->firstMenuItem); } - +*/ //------------------------------------------------------------------------------ // initialization, input and render methods //------------------------------------------------------------------------------ GuiMenuBar::GuiMenuBar() { - mMenuList.clear(); + //mMenuList.clear(); menuBarDirty = true; mouseDownMenu = NULL; mouseOverMenu = NULL; mCurAcceleratorIndex = 0; - mBackground = NULL; mPadding = 0; mCheckmarkBitmapIndex = 0; // Default to the first image in the bitmap array for the check mark @@ -1114,21 +1100,28 @@ GuiMenuBar::GuiMenuBar() mVerticalMargin = 1; // Default number of pixels on the top and bottom of a menu's text mBitmapMargin = 2; // Default number of pixels between a menu's bitmap and text + mMenubarHeight = 20; + // Added: mouseDownSubmenu = NULL; mouseOverSubmenu = NULL; - mSubmenuBackground = NULL; - mSubmenuTextList = NULL; - mMouseOverCounter = 0; - mCountMouseOver = false; - mMouseHoverAmount = 30; + + mMouseInMenu = false; + setProcessTicks(false); } +void GuiMenuBar::onRemove() +{ + Parent::onRemove(); +} + void GuiMenuBar::initPersistFields() { addField("padding", TypeS32, Offset( mPadding, GuiMenuBar ),"Extra padding to add to the bounds of the control.\n"); + addField("menubarHeight", TypeS32, Offset(mMenubarHeight, GuiMenuBar), "Sets the height of the menubar when attached to the canvas.\n"); + Parent::initPersistFields(); } @@ -1153,52 +1146,75 @@ bool GuiMenuBar::onWake() return true; } -GuiMenuBar::Menu *GuiMenuBar::findHitMenu(Point2I mousePoint) +void GuiMenuBar::addObject(SimObject* object) +{ + PopupMenu* popup = dynamic_cast(object); + + if (!popup) + { + //if it's not a popup, handle it normally + Parent::addObject(object); + } + else + { + //otherwise, if it IS a popup, don't add it as a child object, but instead just insert it as a menu entry + insert(object, -1); + } +} + +GuiMenuBar::MenuEntry *GuiMenuBar::findHitMenu(Point2I mousePoint) { Point2I pos = globalToLocalCoord(mousePoint); for (U32 i = 0; i < mMenuList.size(); ++i) - if (mMenuList[i]->visible && mMenuList[i]->bounds.pointInRect(pos)) - return mMenuList[i]; + { + if (mMenuList[i].visible && mMenuList[i].bounds.pointInRect(pos)) + return &mMenuList[i]; + } + return NULL; } void GuiMenuBar::onPreRender() { + setHeight(mMenubarHeight); + Parent::onPreRender(); - if(menuBarDirty) + if (menuBarDirty) { menuBarDirty = false; U32 curX = mPadding; for (U32 i = 0; i < mMenuList.size(); ++i) { - if (!mMenuList[i]->visible) + if (!mMenuList[i].visible) continue; - // Bounds depends on if there is a bitmap to be drawn or not - if (mMenuList[i]->bitmapIndex == -1) - { - // Text only - mMenuList[i]->bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2)); - - } else - { - // Will the bitmap and text be draw? - if (!mMenuList[i]->drawBitmapOnly) + // Bounds depends on if there is a bitmap to be drawn or not + if (mMenuList[i].bitmapIndex == -1) { + // Text only + mMenuList[i].bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i].text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2)); + + } + else + { + // Will the bitmap and text be draw? + if (!mMenuList[i].drawBitmapOnly) + { // Draw the bitmap and the text RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); - mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); + mMenuList[i].bounds.set(curX, 0, bitmapBounds[mMenuList[i].bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i].text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); - } else - { + } + else + { // Only the bitmap will be drawn RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); - mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); + mMenuList[i].bounds.set(curX, 0, bitmapBounds[mMenuList[i].bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); + } } - } - curX += mMenuList[i]->bounds.extent.x; + curX += mMenuList[i].bounds.extent.x; } mouseOverMenu = NULL; mouseDownMenu = NULL; @@ -1207,12 +1223,12 @@ void GuiMenuBar::onPreRender() void GuiMenuBar::checkMenuMouseMove(const GuiEvent &event) { - Menu *hit = findHitMenu(event.mousePoint); + MenuEntry *hit = findHitMenu(event.mousePoint); if(hit && hit != mouseDownMenu) { // gotta close out the current menu... - mTextList->setSelectedCell(Point2I(-1, -1)); - closeMenu(); + mouseDownMenu->popupMenu->hidePopup(); + mouseOverMenu = mouseDownMenu = hit; setUpdate(); onAction(); @@ -1221,87 +1237,63 @@ void GuiMenuBar::checkMenuMouseMove(const GuiEvent &event) void GuiMenuBar::onMouseMove(const GuiEvent &event) { - Menu *hit = findHitMenu(event.mousePoint); - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) - mMouseOverCounter = 0; - if(!mCountMouseOver) - { - // We've never started the counter, so start it. - if(hit) - mCountMouseOver = true; - } + MenuEntry *hit = findHitMenu(event.mousePoint); - mouseOverMenu = hit; + if (mouseDownMenu != nullptr && hit != nullptr) + { + //we have a standing click, so just update and go + mouseDownMenu = mouseOverMenu = hit; setUpdate(); + onAction(); + + return; } + + mouseOverMenu = hit; + setUpdate(); +} + +void GuiMenuBar::onMouseEnter(const GuiEvent &event) +{ + onMouseInMenu_callback(true); + mMouseInMenu = true; } void GuiMenuBar::onMouseLeave(const GuiEvent &event) { if(mouseOverMenu) setUpdate(); - mouseOverMenu = NULL; - // As we've left the control, don't track how long the mouse has been - // within it. - if(mCountMouseOver && mMouseOverCounter >= mMouseHoverAmount) - { - onMouseInMenu_callback(false); // Last parameter indicates if we've entered or left the menu - } - mCountMouseOver = false; - mMouseOverCounter = 0; + mouseOverMenu = NULL; + mMouseInMenu = false; } void GuiMenuBar::onMouseDragged(const GuiEvent &event) { - Menu *hit = findHitMenu(event.mousePoint); - - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) - mMouseOverCounter = 0; - if(!mCountMouseOver) - { - // We've never started the counter, so start it. - if(hit) - mCountMouseOver = true; - } - - mouseOverMenu = hit; - mouseDownMenu = hit; - setUpdate(); - onAction(); - } } void GuiMenuBar::onMouseDown(const GuiEvent &event) +{ +} + +void GuiMenuBar::onMouseUp(const GuiEvent &event) { mouseDownMenu = mouseOverMenu = findHitMenu(event.mousePoint); setUpdate(); onAction(); } -void GuiMenuBar::onMouseUp(const GuiEvent &event) -{ - mouseDownMenu = NULL; - setUpdate(); -} - void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) { - RectI ctrlRect(offset, getExtent()); + Point2I extent = getExtent(); + + RectI ctrlRect(offset, extent); GFXDrawUtil* drawUtil = GFX->getDrawUtil(); //if opaque, fill the update rect with the fill color if (mProfile->mOpaque) - drawUtil->drawRectFill(RectI(offset, getExtent()), mProfile->mFillColor); + drawUtil->drawRectFill(RectI(offset, extent), mProfile->mFillColor); //if there's a border, draw the border if (mProfile->mBorder) @@ -1309,63 +1301,65 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) for (U32 i = 0; i < mMenuList.size(); ++i) { - if (!mMenuList[i]->visible) + if (!mMenuList[i].visible) continue; + ColorI fontColor = mProfile->mFontColor; - RectI bounds = mMenuList[i]->bounds; + RectI bounds = mMenuList[i].bounds; bounds.point += offset; - + Point2I start; - start.x = mMenuList[i]->bounds.point.x + mHorizontalMargin; - start.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - mProfile->mFont->getHeight()) / 2; + start.x = mMenuList[i].bounds.point.x + mHorizontalMargin; + start.y = mMenuList[i].bounds.point.y + (mMenuList[i].bounds.extent.y - mProfile->mFont->getHeight()) / 2; - // Draw the border - if (mMenuList[i]->drawBorder) - { - RectI highlightBounds = bounds; - highlightBounds.inset(1,1); - if (mMenuList[i] == mouseDownMenu) - renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL ); - else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) - renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); - } + // Draw the border + if (mMenuList[i].drawBorder) + { + RectI highlightBounds = bounds; + highlightBounds.inset(1, 1); + if (&mMenuList[i] == mouseDownMenu) + renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); + else if (&mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) + renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); + } - // Do we draw a bitmap? - if (mMenuList[i]->bitmapIndex != -1) - { - S32 index = mMenuList[i]->bitmapIndex * 3; - if (mMenuList[i] == mouseDownMenu) + // Do we draw a bitmap? + if (mMenuList[i].bitmapIndex != -1) + { + S32 index = mMenuList[i].bitmapIndex * 3; + if (&mMenuList[i] == mouseDownMenu) ++index; - else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) + else if (&mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) index += 2; RectI rect = mProfile->mBitmapArrayRects[index]; - Point2I bitmapstart(start); - bitmapstart.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - rect.extent.y) / 2; + Point2I bitmapstart(start); + bitmapstart.y = mMenuList[i].bounds.point.y + (mMenuList[i].bounds.extent.y - rect.extent.y) / 2; drawUtil->clearBitmapModulation(); - drawUtil->drawBitmapSR( mProfile->mTextureObject, offset + bitmapstart, rect); + drawUtil->drawBitmapSR(mProfile->mTextureObject, offset + bitmapstart, rect); - // Should we also draw the text? - if (!mMenuList[i]->drawBitmapOnly) - { + // Should we also draw the text? + if (!mMenuList[i].drawBitmapOnly) + { start.x += mBitmapMargin; - drawUtil->setBitmapModulation( fontColor ); - drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } - } else - { - drawUtil->setBitmapModulation( fontColor ); - drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } + drawUtil->setBitmapModulation(fontColor); + drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i].text, mProfile->mFontColors); + } + } + else + { + drawUtil->setBitmapModulation(fontColor); + drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i].text, mProfile->mFontColors); + } } - renderChildControls( offset, updateRect ); + renderChildControls(offset, updateRect); } -void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator ) +void GuiMenuBar::buildWindowAcceleratorMap(WindowInputGenerator &inputGenerator) { // ok, accelerator map is cleared... // add all our keys: @@ -1373,20 +1367,21 @@ void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator for (U32 i = 0; i < mMenuList.size(); ++i) { - for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem) + for (U32 item = 0; item < mMenuList[i].popupMenu->mMenuItems.size(); item++) { - if(!item->accelerator) + if (!mMenuList[i].popupMenu->mMenuItems[item].accelerator) { - item->accelerator = 0; + mMenuList[i].popupMenu->mMenuItems[item].accelerator = 0; continue; } - EventDescriptor accelEvent; - ActionMap::createEventDescriptor(item->accelerator, &accelEvent); - - //now we have a modifier, and a key, add them to the canvas - inputGenerator.addAcceleratorKey( this, item->cmd, accelEvent.eventCode, accelEvent.flags); - item->acceleratorIndex = mCurAcceleratorIndex; + EventDescriptor accelEvent; + ActionMap::createEventDescriptor(mMenuList[i].popupMenu->mMenuItems[item].accelerator, &accelEvent); + + //now we have a modifier, and a key, add them to the canvas + inputGenerator.addAcceleratorKey(this, mMenuList[i].popupMenu->mMenuItems[item].cmd, accelEvent.eventCode, accelEvent.flags); + + mMenuList[i].popupMenu->mMenuItems[item].acceleratorIndex = mCurAcceleratorIndex; mCurAcceleratorIndex++; } } @@ -1403,591 +1398,112 @@ void GuiMenuBar::acceleratorKeyPress(U32 index) // and find the item that corresponds to the accelerator index for (U32 i = 0; i < mMenuList.size(); ++i) { - if (!mMenuList[i]->visible) + if (!mMenuList[i].visible) continue; - for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem) + for(U32 item = 0; item < mMenuList[i].popupMenu->mMenuItems.size(); item++) { - if(item->acceleratorIndex == index) + if(mMenuList[i].popupMenu->mMenuItems[item].acceleratorIndex == index) { // first, call the script callback for menu selection: - onMenuSelect_callback(mMenuList[i]->id, mMenuList[i]->text); - - if(item->visible) - menuItemSelected(mMenuList[i], item); + onMenuSelect_callback(mMenuList[i].popupMenu->getId(), mMenuList[i].text); return; } } } } -//------------------------------------------------------------------------------ -// Menu display class methods -//------------------------------------------------------------------------------ - -GuiMenuBackgroundCtrl::GuiMenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl *textList) -{ - mMenuBarCtrl = ctrl; - mTextList = textList; -} - -void GuiMenuBackgroundCtrl::onMouseDown(const GuiEvent &event) -{ - mTextList->setSelectedCell(Point2I(-1,-1)); - mMenuBarCtrl->closeMenu(); -} - -void GuiMenuBackgroundCtrl::onMouseMove(const GuiEvent &event) -{ - GuiCanvas *root = getRoot(); - GuiControl *ctrlHit = root->findHitControl(event.mousePoint, mLayer - 1); - if(ctrlHit == mMenuBarCtrl) // see if the current mouse over menu is right... - mMenuBarCtrl->checkMenuMouseMove(event); -} - -void GuiMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event) -{ - GuiCanvas *root = getRoot(); - GuiControl *ctrlHit = root->findHitControl(event.mousePoint, mLayer - 1); - if(ctrlHit == mMenuBarCtrl) // see if the current mouse over menu is right... - mMenuBarCtrl->checkMenuMouseMove(event); -} - -GuiMenuTextListCtrl::GuiMenuTextListCtrl(GuiMenuBar *ctrl) -{ - mMenuBarCtrl = ctrl; - isSubMenu = false; // Added -} - -void GuiMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver) -{ - 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 - Parent::onRenderCell(offset, cell, selected, mouseOver); - else - { - S32 yp = offset.y + mCellSize.y / 2; - GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128,128,128)); - GFX->getDrawUtil()->drawLine(offset.x, yp+1, offset.x + mCellSize.x, yp+1, ColorI(255,255,255)); - } - // now see if there's a bitmap... - U8 idx = mList[cell.y].text[0]; - if(idx != 1) - { - // there's a bitmap... - U32 index = U32(idx - 2) * 3; - if(!mList[cell.y].active) - index += 2; - else if(selected || mouseOver) - index ++; - - RectI rect = mProfile->mBitmapArrayRects[index]; - Point2I off = mMenuBarCtrl->maxBitmapSize - rect.extent; - off /= 2; - - GFX->getDrawUtil()->clearBitmapModulation(); - GFX->getDrawUtil()->drawBitmapSR(mProfile->mTextureObject, offset + off, rect); - } - - // Check if this is a submenu - idx = mList[cell.y].text[1]; - if(idx != 1) - { - // This is a submenu, so draw an arrow - S32 left = offset.x + mCellSize.x - 12; - S32 right = left + 8; - S32 top = mCellSize.y / 2 + offset.y - 4; - S32 bottom = top + 8; - S32 middle = top + 4; - - PrimBuild::begin( GFXTriangleList, 3 ); - if( selected || mouseOver ) - PrimBuild::color( mProfile->mFontColorHL ); - else - PrimBuild::color( mProfile->mFontColor ); - - PrimBuild::vertex2i( left, top ); - PrimBuild::vertex2i( right, middle ); - PrimBuild::vertex2i( left, bottom ); - PrimBuild::end(); - } -} - -bool GuiMenuTextListCtrl::onKeyDown(const GuiEvent &event) -{ - //if the control is a dead end, don't process the input: - if ( !mVisible || !mActive || !mAwake ) - return false; - - //see if the key down is a or not - if ( event.modifier == 0 ) - { - if ( event.keyCode == KEY_RETURN ) - { - mMenuBarCtrl->closeMenu(); - return true; - } - else if ( event.keyCode == KEY_ESCAPE ) - { - mSelectedCell.set( -1, -1 ); - mMenuBarCtrl->closeMenu(); - return true; - } - } - - //otherwise, pass the event to it's parent - return Parent::onKeyDown(event); -} - -void GuiMenuTextListCtrl::onMouseDown(const GuiEvent &event) -{ - Parent::onMouseDown(event); -} - -void GuiMenuTextListCtrl::onMouseUp(const GuiEvent &event) -{ - Parent::onMouseUp(event); - mMenuBarCtrl->closeMenu(); -} - -void GuiMenuTextListCtrl::onCellHighlighted(Point2I cell) -{ - // If this text list control is part of a submenu, then don't worry about - // passing this along - if(!isSubMenu) - { - RectI globalbounds(getBounds()); - Point2I globalpoint = localToGlobalCoord(globalbounds.point); - globalbounds.point = globalpoint; - mMenuBarCtrl->highlightedMenuItem(cell.y, globalbounds, mCellSize); - } -} - -//------------------------------------------------------------------------------ -// Submenu display class methods -//------------------------------------------------------------------------------ - -GuiSubmenuBackgroundCtrl::GuiSubmenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl *textList) : GuiMenuBackgroundCtrl(ctrl, textList) -{ -} - -void GuiSubmenuBackgroundCtrl::onMouseDown(const GuiEvent &event) -{ - mTextList->setSelectedCell(Point2I(-1,-1)); - mMenuBarCtrl->closeMenu(); -} - -bool GuiSubmenuBackgroundCtrl::pointInControl(const Point2I& parentCoordPoint) -{ - S32 xt = parentCoordPoint.x - getLeft(); - S32 yt = parentCoordPoint.y - getTop(); - - if(findHitControl(Point2I(xt,yt)) == this) - return false; - else - return true; -// return xt >= 0 && yt >= 0 && xt < getWidth() && yt < getHeight(); -} - -//------------------------------------------------------------------------------ - -void GuiMenuBar::menuItemSelected(GuiMenuBar::Menu *menu, GuiMenuBar::MenuItem *item) -{ - if(item->enabled) - onMenuItemSelect_callback(menu->id, menu->text, item->id, item->text); -} - void GuiMenuBar::onSleep() { - if(mBackground) // a menu is up? - { - mTextList->setSelectedCell(Point2I(-1, -1)); - closeMenu(); - } Parent::onSleep(); } -void GuiMenuBar::closeMenu() -{ - // First close any open submenu - closeSubmenu(); - - // Get the selection from the text list: - S32 selectionIndex = mTextList->getSelectedCell().y; - - // Pop the background: - if( getRoot() ) - getRoot()->popDialogControl(mBackground); - else - return; - - // Kill the popup: - mBackground->deleteObject(); - mBackground = NULL; - - // Now perform the popup action: - if ( selectionIndex != -1 ) - { - MenuItem *list = mouseDownMenu->firstMenuItem; - - while(selectionIndex && list) - { - list = list->nextMenuItem; - selectionIndex--; - } - if(list) - menuItemSelected(mouseDownMenu, list); - } - mouseDownMenu = NULL; -} - -// Called when a menu item is highlighted by the mouse -void GuiMenuBar::highlightedMenuItem(S32 selectionIndex, const RectI& bounds, Point2I cellSize) -{ - S32 selstore = selectionIndex; - - // Now perform the popup action: - if ( selectionIndex != -1 ) - { - MenuItem *list = mouseDownMenu->firstMenuItem; - - while(selectionIndex && list) - { - list = list->nextMenuItem; - selectionIndex--; - } - - if(list) - { - // If the highlighted item has changed... - if(mouseOverSubmenu != list) - { - closeSubmenu(); - mouseOverSubmenu = NULL; - - // Check if this is a submenu. If so, open the submenu. - if(list->isSubmenu) - { - // If there are submenu items, then open the submenu - if(list->submenu->firstMenuItem) - { - mouseOverSubmenu = list; - onSubmenuAction(selstore, bounds, cellSize); - } - } - } - } - } -} - //------------------------------------------------------------------------------ void GuiMenuBar::onAction() { if(!mouseDownMenu) return; - // first, call the script callback for menu selection: - onMenuSelect_callback(mouseDownMenu->id, mouseDownMenu->text); - - MenuItem *visWalk = mouseDownMenu->firstMenuItem; - while(visWalk) - { - if(visWalk->visible) - break; - visWalk = visWalk->nextMenuItem; - } - if(!visWalk) - { - mouseDownMenu = NULL; - return; - } - - mTextList = new GuiMenuTextListCtrl(this); - mTextList->setControlProfile(mProfile); - - mBackground = new GuiMenuBackgroundCtrl(this, mTextList); - - GuiCanvas *root = getRoot(); - Point2I windowExt = root->getExtent(); - - mBackground->resize( Point2I(0,0), root->getExtent()); - S32 textWidth = 0, width = 0; - S32 acceleratorWidth = 0; - - GFont *font = mProfile->mFont; - - for(MenuItem *walk = mouseDownMenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - S32 iTextWidth = font->getStrWidth(walk->text); - S32 iAcceleratorWidth = walk->accelerator ? font->getStrWidth(walk->accelerator) : 0; - - if(iTextWidth > textWidth) - textWidth = iTextWidth; - if(iAcceleratorWidth > acceleratorWidth) - acceleratorWidth = iAcceleratorWidth; - } - width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; - - mTextList->setCellSize(Point2I(width, font->getHeight()+2)); - mTextList->clearColumnOffsets(); - mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index. - mTextList->addColumnOffset(maxBitmapSize.x + 1); - mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); - - U32 entryCount = 0; - - for(MenuItem *walk = mouseDownMenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - char buf[512]; - - // If this menu item is a submenu, then set the isSubmenu to 2 to indicate - // an arrow should be drawn. Otherwise set the isSubmenu normally. - char isSubmenu = 1; - if(walk->isSubmenu) - isSubmenu = 2; - - char bitmapIndex = 1; - if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) - bitmapIndex = walk->bitmapIndex + 2; - dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, walk->text, walk->accelerator ? walk->accelerator : ""); - mTextList->addEntry(entryCount, buf); - - if(!walk->enabled) - mTextList->setEntryActive(entryCount, false); - - entryCount++; - } - Point2I menuPoint = localToGlobalCoord(mouseDownMenu->bounds.point); - menuPoint.y += mouseDownMenu->bounds.extent.y; // Used to have this at the end: + 2; - - GuiControl *ctrl = new GuiControl; - RectI ctrlBounds( menuPoint, mTextList->getExtent() + Point2I(6, 6)); - - ctrl->setControlProfile(mProfile); - mTextList->setPosition( mTextList->getPosition() + Point2I(3,3) ); - - // Make sure the menu doesn't go beyond the Canvas' bottom edge. - if((ctrlBounds.point.y + ctrlBounds.extent.y) > windowExt.y) - { - // Pop the menu above the menu bar - Point2I menuBar = localToGlobalCoord(mouseDownMenu->bounds.point); - ctrlBounds.point.y = menuBar.y - ctrl->getHeight(); - } - - ctrl->resize(ctrlBounds.point, ctrlBounds.extent); - //mTextList->setPosition(Point2I(3,3)); - - mTextList->registerObject(); - mBackground->registerObject(); - ctrl->registerObject(); - - mBackground->addObject( ctrl ); - ctrl->addObject( mTextList ); - - root->pushDialogControl(mBackground, mLayer + 1); - mTextList->setFirstResponder(); -} - -//------------------------------------------------------------------------------ -// Performs an action when a menu item that is a submenu is selected/highlighted -void GuiMenuBar::onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2I cellSize) -{ - if(!mouseOverSubmenu) - return; + mouseDownMenu->popupMenu->hidePopup(); // first, call the script callback for menu selection: - onSubmenuSelect_callback(mouseOverSubmenu->id, mouseOverSubmenu->text); + onMenuSelect_callback(mouseDownMenu->popupMenu->getId(), mouseDownMenu->text); - MenuItem *visWalk = mouseOverSubmenu->submenu->firstMenuItem; - while(visWalk) - { - if(visWalk->visible) - break; - visWalk = visWalk->nextMenuItem; - } - if(!visWalk) - { - mouseOverSubmenu = NULL; - return; - } - - mSubmenuTextList = new GuiMenuTextListCtrl(this); - mSubmenuTextList->setControlProfile(mProfile); - mSubmenuTextList->isSubMenu = true; // Indicate that this text list is part of a submenu - - mSubmenuBackground = new GuiSubmenuBackgroundCtrl(this, mSubmenuTextList); + mouseDownMenu->popupMenu->mMenuBarCtrl = this; GuiCanvas *root = getRoot(); - Point2I windowExt = root->getExtent(); - - mSubmenuBackground->resize( Point2I(0,0), root->getExtent()); - S32 textWidth = 0, width = 0; - S32 acceleratorWidth = 0; - - GFont *font = mProfile->mFont; - - for(MenuItem *walk = mouseOverSubmenu->submenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - S32 iTextWidth = font->getStrWidth(walk->text); - S32 iAcceleratorWidth = walk->accelerator ? font->getStrWidth(walk->accelerator) : 0; - - if(iTextWidth > textWidth) - textWidth = iTextWidth; - if(iAcceleratorWidth > acceleratorWidth) - acceleratorWidth = iAcceleratorWidth; - } - width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; - - mSubmenuTextList->setCellSize(Point2I(width, font->getHeight()+3)); - mSubmenuTextList->clearColumnOffsets(); - mSubmenuTextList->addColumnOffset(-1); // add an empty column in for the bitmap index. - mSubmenuTextList->addColumnOffset(maxBitmapSize.x + 1); - mSubmenuTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); - - U32 entryCount = 0; - - for(MenuItem *walk = mouseOverSubmenu->submenu->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if(!walk->visible) - continue; - - char buf[512]; - - // Can't have submenus within submenus. - char isSubmenu = 1; - - char bitmapIndex = 1; - if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) - bitmapIndex = walk->bitmapIndex + 2; - dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, walk->text, walk->accelerator ? walk->accelerator : ""); - mSubmenuTextList->addEntry(entryCount, buf); - - if(!walk->enabled) - mSubmenuTextList->setEntryActive(entryCount, false); - - entryCount++; - } - Point2I menuPoint = bounds.point; //localToGlobalCoord(bounds.point); - menuPoint.x += bounds.extent.x; - menuPoint.y += cellSize.y * selectionIndex - 6; - - GuiControl *ctrl = new GuiControl; - RectI ctrlBounds(menuPoint, mSubmenuTextList->getExtent() + Point2I(6, 6)); - ctrl->setControlProfile(mProfile); - mSubmenuTextList->setPosition( getPosition() + Point2I(3,3)); - - // Make sure the menu doesn't go beyond the Canvas' bottom edge. - if((ctrlBounds.point.y + ctrlBounds.extent.y ) > windowExt.y) - { - // Pop the menu above the menu bar - ctrlBounds.point.y -= mSubmenuTextList->getHeight() - cellSize.y - 6 - 3; - } - - // And the same for the right edge - if((ctrlBounds.point.x + ctrlBounds.extent.x) > windowExt.x) - { - // Pop the submenu to the left of the menu - ctrlBounds.point.x -= mSubmenuTextList->getWidth() + cellSize.x + 6; - } - ctrl->resize(ctrlBounds.point, ctrlBounds.extent); - - //mSubmenuTextList->setPosition(Point2I(3,3)); - - mSubmenuTextList->registerObject(); - mSubmenuBackground->registerObject(); - ctrl->registerObject(); - - mSubmenuBackground->addObject( ctrl ); - ctrl->addObject( mSubmenuTextList ); - - root->pushDialogControl(mSubmenuBackground, mLayer + 1); - mSubmenuTextList->setFirstResponder(); -} - -// Close down the submenu controls -void GuiMenuBar::closeSubmenu() -{ - if(!mSubmenuBackground || !mSubmenuTextList) - return; - - // Get the selection from the text list: - S32 selectionIndex = mSubmenuTextList->getSelectedCell().y; - - // Pop the background: - if( getRoot() ) - getRoot()->popDialogControl(mSubmenuBackground); - - // Kill the popup: - mSubmenuBackground->deleteObject(); - mSubmenuBackground = NULL; - mSubmenuTextList = NULL; - - // Now perform the popup action: - if ( selectionIndex != -1 ) - { - MenuItem *list = NULL; - if(mouseOverSubmenu) - { - list = mouseOverSubmenu->submenu->firstMenuItem; - - while(selectionIndex && list) - { - list = list->nextMenuItem; - selectionIndex--; - } - } - if(list) - menuItemSelected(list->submenuParentMenu, list); - } - mouseOverSubmenu = NULL; -} - -// Find if the mouse pointer is within a menu item -GuiMenuBar::MenuItem *GuiMenuBar::findHitMenuItem(Point2I mousePoint) -{ - -// for(Menu *walk = menuList; walk; walk = walk->nextMenu) -// if(walk->visible && walk->bounds.pointInRect(pos)) -// return walk; - return NULL; -} - -// Checks if the mouse has been moved to a new menu item -void GuiMenuBar::checkSubmenuMouseMove(const GuiEvent &event) -{ - MenuItem *hit = findHitMenuItem(event.mousePoint); - if(hit && hit != mouseOverSubmenu) - { - // gotta close out the current menu... - mSubmenuTextList->setSelectedCell(Point2I(-1, -1)); -// closeSubmenu(); - setUpdate(); - } + Point2I pos = Point2I(mouseDownMenu->bounds.point.x, mouseDownMenu->bounds.point.y + mouseDownMenu->bounds.extent.y); + mouseDownMenu->popupMenu->showPopup(root, pos.x, pos.y); } // Process a tick void GuiMenuBar::processTick() { - // If we are to track a tick, then do so. - if(mCountMouseOver) - { - // If we're at a particular number of ticks, notify the script function - if(mMouseOverCounter < mMouseHoverAmount) - { - ++mMouseOverCounter; + if(mMouseInMenu) + onMouseInMenu_callback(true); +} - } else if(mMouseOverCounter == mMouseHoverAmount) - { - ++mMouseOverCounter; - onMouseInMenu_callback(true); // Last parameter indicates if we've entered or left the menu - } +void GuiMenuBar::insert(SimObject* pObject, S32 pos) +{ + PopupMenu* menu = dynamic_cast(pObject); + if (menu == nullptr) + return; + + MenuEntry newMenu; + newMenu.pos = pos >= mMenuList.size() || pos == -1 ? pos = mMenuList.size() : pos; + newMenu.drawBitmapOnly = false; + newMenu.drawBorder = true; + newMenu.bitmapIndex = -1; + newMenu.text = menu->barTitle; + newMenu.visible = true; + newMenu.popupMenu = menu; + + if (pos >= mMenuList.size() || pos == -1) + mMenuList.push_back(newMenu); + else + mMenuList.insert(pos, newMenu); +} + +PopupMenu* GuiMenuBar::getMenu(U32 index) +{ + if (index >= mMenuList.size()) + return nullptr; + + return mMenuList[index].popupMenu; +} + +//----------------------------------------------------------------------------- +// Console Methods +//----------------------------------------------------------------------------- +DefineConsoleMethod(GuiMenuBar, attachToCanvas, void, (const char *canvas, S32 pos), , "(GuiCanvas, pos)") +{ + GuiCanvas* canv = dynamic_cast(Sim::findObject(canvas)); + if (canv) + { + canv->setMenuBar(object); } } + +DefineConsoleMethod(GuiMenuBar, removeFromCanvas, void, (), , "()") +{ + GuiCanvas* canvas = object->getRoot(); + + if(canvas) + canvas->setMenuBar(nullptr); +} + +DefineConsoleMethod(GuiMenuBar, getMenuCount, S32, (), , "()") +{ + return object->getMenuListCount(); +} + +DefineConsoleMethod(GuiMenuBar, getMenu, S32, (S32 index), (0), "(Index)") +{ + return object->getMenu(index)->getId(); +} + +//----------------------------------------------------------------------------- +DefineConsoleMethod(GuiMenuBar, insert, void, (SimObject* pObject, S32 pos), (nullAsType(), -1), "(object, pos) insert object at position") +{ + object->insert(pObject, pos); +} \ No newline at end of file diff --git a/Engine/source/gui/editor/guiMenuBar.h b/Engine/source/gui/editor/guiMenuBar.h index a41455a16..d266378e3 100644 --- a/Engine/source/gui/editor/guiMenuBar.h +++ b/Engine/source/gui/editor/guiMenuBar.h @@ -23,119 +23,43 @@ #ifndef _GUIMENUBAR_H_ #define _GUIMENUBAR_H_ -#ifndef _GUITEXTLISTCTRL_H_ -#include "gui/controls/guiTextListCtrl.h" -#endif #ifndef _GUITICKCTRL_H_ #include "gui/shiny/guiTickCtrl.h" #endif +#ifndef _POPUPMENU_H_ +#include "gui/editor/popupMenu.h" +#endif + class GuiMenuBar; -class GuiMenuTextListCtrl; class WindowInputGenerator; -class GuiMenuBackgroundCtrl : public GuiControl -{ - typedef GuiControl Parent; - -protected: - GuiMenuBar *mMenuBarCtrl; - GuiMenuTextListCtrl *mTextList; -public: - GuiMenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl* textList); - void onMouseDown(const GuiEvent &event); - void onMouseMove(const GuiEvent &event); - void onMouseDragged(const GuiEvent &event); -}; - -class GuiSubmenuBackgroundCtrl : public GuiMenuBackgroundCtrl -{ - typedef GuiMenuBackgroundCtrl Parent; - -public: - GuiSubmenuBackgroundCtrl(GuiMenuBar *ctrl, GuiMenuTextListCtrl* textList); - bool pointInControl(const Point2I & parentCoordPoint); - void onMouseDown(const GuiEvent &event); -}; - //------------------------------------------------------------------------------ - -class GuiMenuTextListCtrl : public GuiTextListCtrl -{ - private: - typedef GuiTextListCtrl Parent; - - protected: - GuiMenuBar *mMenuBarCtrl; - - public: - bool isSubMenu; // Indicates that this text list is in a submenu - - GuiMenuTextListCtrl(); // for inheritance - GuiMenuTextListCtrl(GuiMenuBar *ctrl); - - // GuiControl overloads: - bool onKeyDown(const GuiEvent &event); - void onMouseDown(const GuiEvent &event); - void onMouseUp(const GuiEvent &event); - void onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver); - - virtual void onCellHighlighted(Point2I cell); // Added -}; - -//------------------------------------------------------------------------------ - class GuiMenuBar : public GuiTickCtrl // Was: GuiControl { typedef GuiTickCtrl Parent; // Was: GuiControl Parent; public: - struct Menu; + struct MenuEntry + { + U32 pos; + RectI bounds; - struct MenuItem // an individual item in a pull-down menu - { - char *text; // the text of the menu item - U32 id; // a script-assigned identifier - char *accelerator; // the keyboard accelerator shortcut for the menu item - U32 acceleratorIndex; // index of this accelerator - bool enabled; // true if the menu item is selectable - bool visible; // true if the menu item is visible - S32 bitmapIndex; // index of the bitmap in the bitmap array - S32 checkGroup; // the group index of the item visa vi check marks - - // only one item in the group can be checked. - MenuItem *nextMenuItem; // next menu item in the linked list - - bool isSubmenu; // This menu item has a submenu that will be displayed - - Menu* submenuParentMenu; // For a submenu, this is the parent menu - Menu* submenu; - String cmd; - }; - - struct Menu - { - char *text; - U32 id; - RectI bounds; bool visible; - S32 bitmapIndex; // Index of the bitmap in the bitmap array (-1 = no bitmap) - bool drawBitmapOnly; // Draw only the bitmap and not the text - bool drawBorder; // Should a border be drawn around this menu (usually if we only have a bitmap, we don't want a border) + S32 bitmapIndex; + bool drawBitmapOnly; - Menu *nextMenu; - MenuItem *firstMenuItem; - }; - - GuiMenuBackgroundCtrl *mBackground; - GuiMenuTextListCtrl *mTextList; - - GuiSubmenuBackgroundCtrl *mSubmenuBackground; // Background for a submenu - GuiMenuTextListCtrl *mSubmenuTextList; // Text list for a submenu + bool drawBorder; - Vector mMenuList; - Menu *mouseDownMenu; - Menu *mouseOverMenu; + StringTableEntry text; + PopupMenu* popupMenu; + }; + + Vector mMenuList; + + MenuEntry *mouseDownMenu; + MenuEntry *mouseOverMenu; MenuItem* mouseDownSubmenu; // Stores the menu item that is a submenu that has been selected MenuItem* mouseOverSubmenu; // Stores the menu item that is a submenu that has been highlighted @@ -151,59 +75,26 @@ public: S32 mVerticalMargin; // Top and bottom margin around the text of each menu S32 mBitmapMargin; // Margin between a menu's bitmap and text - // Used to keep track of the amount of ticks that the mouse is hovering - // over a menu. - S32 mMouseOverCounter; - bool mCountMouseOver; - S32 mMouseHoverAmount; + U32 mMenubarHeight; + + bool mMouseInMenu; GuiMenuBar(); + + void onRemove(); bool onWake(); void onSleep(); - // internal menu handling functions - // these are used by the script manipulation functions to add/remove/change menu items - static Menu* sCreateMenu(const char *menuText, U32 menuId); - void addMenu(Menu *menu, S32 pos = -1); - void addMenu(const char *menuText, U32 menuId); - Menu *findMenu(const char *menu); // takes either a menu text or a string id - static MenuItem *findMenuItem(Menu *menu, const char *menuItem); // takes either a menu text or a string id - void removeMenu(Menu *menu); - static void removeMenuItem(Menu *menu, MenuItem *menuItem); - static MenuItem* addMenuItem(Menu *menu, const char *text, U32 id, const char *accelerator, S32 checkGroup, const char *cmd); - static MenuItem* addMenuItem(Menu *menu, MenuItem *menuItem); - static void clearMenuItems(Menu *menu); - void clearMenus(); + virtual void addObject(SimObject* object); - void attachToMenuBar(Menu* menu, S32 pos = -1); - void removeFromMenuBar(Menu* menu); - - // Methods to deal with submenus - static MenuItem* findSubmenuItem(Menu *menu, const char *menuItem, const char *submenuItem); - static MenuItem* findSubmenuItem(MenuItem *menuItem, const char *submenuItem); - static void addSubmenuItem(Menu *menu, MenuItem *submenu, const char *text, U32 id, const char *accelerator, S32 checkGroup); - static void addSubmenuItem(Menu *menu, MenuItem *submenu, MenuItem *newMenuItem ); - static void removeSubmenuItem(MenuItem *menuItem, MenuItem *submenuItem); - static void clearSubmenuItems(MenuItem *menuitem); - void onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2I cellSize); - void closeSubmenu(); - void checkSubmenuMouseMove(const GuiEvent &event); - MenuItem *findHitMenuItem(Point2I mousePoint); - - void highlightedMenuItem(S32 selectionIndex, const RectI& bounds, Point2I cellSize); // Called whenever a menu item is highlighted by the mouse - - // display/mouse functions - - Menu *findHitMenu(Point2I mousePoint); - - // Called when the GUI theme changes and a bitmap arrary may need updating - // void onThemeChange(); + MenuEntry *findHitMenu(Point2I mousePoint); void onPreRender(); void onRender(Point2I offset, const RectI &updateRect); void checkMenuMouseMove(const GuiEvent &event); void onMouseMove(const GuiEvent &event); + void onMouseEnter(const GuiEvent &event); void onMouseLeave(const GuiEvent &event); void onMouseDown(const GuiEvent &event); void onMouseDragged(const GuiEvent &event); @@ -215,18 +106,21 @@ public: void removeWindowAcceleratorMap( WindowInputGenerator &inputGenerator ); void acceleratorKeyPress(U32 index); - virtual void menuItemSelected(Menu *menu, MenuItem *item); - // Added to support 'ticks' void processTick(); + void insert(SimObject* pObject, S32 pos); + static void initPersistFields(); + U32 getMenuListCount() { return mMenuList.size(); } + + PopupMenu* getMenu(U32 index); + DECLARE_CONOBJECT(GuiMenuBar); DECLARE_CALLBACK( void, onMouseInMenu, ( bool hasLeftMenu )); DECLARE_CALLBACK( void, onMenuSelect, ( S32 menuId, const char* menuText )); DECLARE_CALLBACK( void, onMenuItemSelect, ( S32 menuId, const char* menuText, S32 menuItemId, const char* menuItemText )); - DECLARE_CALLBACK( void, onSubmenuSelect, ( S32 submenuId, const char* submenuText )); }; #endif diff --git a/Engine/source/gui/editor/guiPopupMenuCtrl.cpp b/Engine/source/gui/editor/guiPopupMenuCtrl.cpp index 36e693203..99c354102 100644 --- a/Engine/source/gui/editor/guiPopupMenuCtrl.cpp +++ b/Engine/source/gui/editor/guiPopupMenuCtrl.cpp @@ -25,20 +25,32 @@ #include "gfx/primBuilder.h" #include "gui/core/guiCanvas.h" -GuiPopupMenuBackgroundCtrl::GuiPopupMenuBackgroundCtrl(GuiPopupMenuTextListCtrl *textList) +GuiPopupMenuBackgroundCtrl::GuiPopupMenuBackgroundCtrl() { - mTextList = textList; - mTextList->mBackground = this; + mMenuBarCtrl = nullptr; } void GuiPopupMenuBackgroundCtrl::onMouseDown(const GuiEvent &event) { - mTextList->setSelectedCell(Point2I(-1, -1)); + +} + +void GuiPopupMenuBackgroundCtrl::onMouseUp(const GuiEvent &event) +{ + clearPopups(); + + //Pass along the event just in case we clicked over a menu item. We don't want to eat the input for it. + if (mMenuBarCtrl) + mMenuBarCtrl->onMouseUp(event); + close(); } void GuiPopupMenuBackgroundCtrl::onMouseMove(const GuiEvent &event) { + //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 + if (mMenuBarCtrl) + mMenuBarCtrl->onMouseMove(event); } void GuiPopupMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event) @@ -48,26 +60,64 @@ void GuiPopupMenuBackgroundCtrl::onMouseDragged(const GuiEvent &event) void GuiPopupMenuBackgroundCtrl::close() { getRoot()->removeObject(this); + + mMenuBarCtrl = nullptr; +} + +S32 GuiPopupMenuBackgroundCtrl::findPopupMenu(PopupMenu* menu) +{ + S32 menuId = -1; + + for (U32 i = 0; i < mPopups.size(); i++) + { + if (mPopups[i]->getId() == menu->getId()) + return i; + } + + return menuId; +} + +void GuiPopupMenuBackgroundCtrl::clearPopups() +{ + for (U32 i = 0; i < mPopups.size(); i++) + { + mPopups[i]->mTextList->setSelectedCell(Point2I(-1, -1)); + mPopups[i]->mTextList->mPopup->hidePopup(); + } } GuiPopupMenuTextListCtrl::GuiPopupMenuTextListCtrl() { isSubMenu = false; // Added - mMenu = NULL; - mMenuBar = NULL; - mPopup = NULL; + + mMenuBar = nullptr; + mPopup = nullptr; + + mLastHighlightedMenuIdx = -1; } void GuiPopupMenuTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver) { - 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 - Parent::onRenderCell(offset, cell, selected, mouseOver); - else + //check if we're a real entry, or if it's a divider + if (mPopup->mMenuItems[cell.y].isSpacer) { S32 yp = offset.y + mCellSize.y / 2; - GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128, 128, 128)); - GFX->getDrawUtil()->drawLine(offset.x, yp + 1, offset.x + mCellSize.x, yp + 1, ColorI(255, 255, 255)); + GFX->getDrawUtil()->drawLine(offset.x + 5, yp, offset.x + mCellSize.x - 5, yp, ColorI(128, 128, 128)); } + else + { + 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 + { + Parent::onRenderCell(offset, cell, selected, mouseOver); + } + else + { + S32 yp = offset.y + mCellSize.y / 2; + GFX->getDrawUtil()->drawLine(offset.x, yp, offset.x + mCellSize.x, yp, ColorI(128, 128, 128)); + GFX->getDrawUtil()->drawLine(offset.x, yp + 1, offset.x + mCellSize.x, yp + 1, ColorI(255, 255, 255)); + } + } + // now see if there's a bitmap... U8 idx = mList[cell.y].text[0]; if (idx != 1) @@ -153,17 +203,12 @@ void GuiPopupMenuTextListCtrl::onMouseUp(const GuiEvent &event) if (selectionIndex != -1) { - GuiMenuBar::MenuItem *list = mMenu->firstMenuItem; + MenuItem *item = &mPopup->mMenuItems[selectionIndex]; - while (selectionIndex && list) + if (item) { - list = list->nextMenuItem; - selectionIndex--; - } - if (list) - { - if (list->enabled) - dAtob(Con::executef(mPopup, "onSelectItem", Con::getIntArg(getSelectedCell().y), list->text ? list->text : "")); + if (item->enabled) + dAtob(Con::executef(mPopup, "onSelectItem", Con::getIntArg(getSelectedCell().y), item->text.isNotEmpty() ? item->text : "")); } } @@ -181,4 +226,23 @@ void GuiPopupMenuTextListCtrl::onCellHighlighted(Point2I cell) Point2I globalpoint = localToGlobalCoord(globalbounds.point); globalbounds.point = globalpoint; } + + S32 selectionIndex = cell.y; + + if (selectionIndex != -1 && mLastHighlightedMenuIdx != selectionIndex) + { + mLastHighlightedMenuIdx = selectionIndex; + + mPopup->hidePopupSubmenus(); + } + + if (selectionIndex != -1) + { + MenuItem *list = &mPopup->mMenuItems[selectionIndex]; + + if (list->isSubmenu && list->subMenu != nullptr) + { + list->subMenu->showPopup(getRoot(), getPosition().x + mCellSize.x, getPosition().y + (selectionIndex * mCellSize.y)); + } + } } \ No newline at end of file diff --git a/Engine/source/gui/editor/guiPopupMenuCtrl.h b/Engine/source/gui/editor/guiPopupMenuCtrl.h index c26fa855d..54632a009 100644 --- a/Engine/source/gui/editor/guiPopupMenuCtrl.h +++ b/Engine/source/gui/editor/guiPopupMenuCtrl.h @@ -42,6 +42,7 @@ class GuiPopupMenuBackgroundCtrl; class GuiPopupMenuTextListCtrl : public GuiTextListCtrl { friend class GuiPopupMenuBackgroundCtrl; + friend class PopupMenu; private: typedef GuiTextListCtrl Parent; @@ -51,10 +52,12 @@ private: public: bool isSubMenu; // Indicates that this text list is in a submenu Point2I maxBitmapSize; - GuiMenuBar::Menu* mMenu; + GuiMenuBar* mMenuBar; PopupMenu* mPopup; + S32 mLastHighlightedMenuIdx; + GuiPopupMenuTextListCtrl(); // GuiControl overloads: @@ -70,16 +73,21 @@ class GuiPopupMenuBackgroundCtrl : public GuiControl { typedef GuiControl Parent; -protected: - GuiPopupMenuTextListCtrl *mTextList; - public: - GuiPopupMenuBackgroundCtrl(GuiPopupMenuTextListCtrl* textList); + GuiPopupMenuBackgroundCtrl(); void onMouseDown(const GuiEvent &event); + void onMouseUp(const GuiEvent &event); void onMouseMove(const GuiEvent &event); void onMouseDragged(const GuiEvent &event); void close(); + + void clearPopups(); + + S32 findPopupMenu(PopupMenu* menu); + + Vector mPopups; + GuiMenuBar* mMenuBarCtrl; }; #endif \ No newline at end of file diff --git a/Engine/source/gui/editor/popupMenu.cpp b/Engine/source/gui/editor/popupMenu.cpp new file mode 100644 index 000000000..0e5db18da --- /dev/null +++ b/Engine/source/gui/editor/popupMenu.cpp @@ -0,0 +1,506 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "gui/editor/popupMenu.h" +#include "console/consoleTypes.h" +#include "console/engineAPI.h" +#include "gui/core/guiCanvas.h" +#include "core/util/safeDelete.h" +#include "gui/editor/guiPopupMenuCtrl.h" +#include "gui/editor/guiMenuBar.h" + +static U32 sMaxPopupGUID = 0; +PopupMenuEvent PopupMenu::smPopupMenuEvent; +bool PopupMenu::smSelectionEventHandled = false; + +/// Event class used to remove popup menus from the event notification in a safe way +class PopUpNotifyRemoveEvent : public SimEvent +{ +public: + void process(SimObject *object) + { + PopupMenu::smPopupMenuEvent.remove((PopupMenu *)object, &PopupMenu::handleSelectEvent); + } +}; + +//----------------------------------------------------------------------------- +// Constructor/Destructor +//----------------------------------------------------------------------------- +PopupMenu::PopupMenu() +{ + bitmapIndex = -1; + + barTitle = StringTable->EmptyString(); + + mMenuBarCtrl = nullptr; + mTextList = nullptr; + + isSubmenu = false; +} + +PopupMenu::~PopupMenu() +{ + PopupMenu::smPopupMenuEvent.remove(this, &PopupMenu::handleSelectEvent); +} + +IMPLEMENT_CONOBJECT(PopupMenu); + +ConsoleDocClass( PopupMenu, + "@brief PopupMenu represents a system menu.\n\n" + "You can add menu items to the menu, but there is no torque object associated " + "with these menu items, they exist only in a platform specific manner.\n\n" + "@note Internal use only\n\n" + "@internal" +); + +//----------------------------------------------------------------------------- +void PopupMenu::initPersistFields() +{ + Parent::initPersistFields(); + + addField("barTitle", TypeCaseString, Offset(barTitle, PopupMenu), ""); +} + +//----------------------------------------------------------------------------- +bool PopupMenu::onAdd() +{ + if(! Parent::onAdd()) + return false; + + Con::executef(this, "onAdd"); + return true; +} + +void PopupMenu::onRemove() +{ + Con::executef(this, "onRemove"); + + Parent::onRemove(); +} + +//----------------------------------------------------------------------------- +void PopupMenu::onMenuSelect() +{ + Con::executef(this, "onMenuSelect"); +} + +//----------------------------------------------------------------------------- +void PopupMenu::handleSelectEvent(U32 popID, U32 command) +{ +} + +//----------------------------------------------------------------------------- +bool PopupMenu::onMessageReceived(StringTableEntry queue, const char* event, const char* data) +{ + return Con::executef(this, "onMessageReceived", queue, event, data); +} + +bool PopupMenu::onMessageObjectReceived(StringTableEntry queue, Message *msg ) +{ + return Con::executef(this, "onMessageReceived", queue, Con::getIntArg(msg->getId())); +} + +////////////////////////////////////////////////////////////////////////// +// Platform Menu Data +////////////////////////////////////////////////////////////////////////// +GuiMenuBar* PopupMenu::getMenuBarCtrl() +{ + return mMenuBarCtrl; +} + +////////////////////////////////////////////////////////////////////////// +// Public Methods +////////////////////////////////////////////////////////////////////////// +S32 PopupMenu::insertItem(S32 pos, const char *title, const char* accelerator, const char* cmd) +{ + String titleString = title; + + MenuItem newItem; + newItem.id = pos; + newItem.text = titleString; + newItem.cmd = cmd; + + if (titleString.isEmpty() || titleString == String("-")) + newItem.isSpacer = true; + else + newItem.isSpacer = false; + + if (accelerator[0]) + newItem.accelerator = dStrdup(accelerator); + else + newItem.accelerator = NULL; + + newItem.visible = true; + newItem.isChecked = false; + newItem.acceleratorIndex = 0; + newItem.enabled = !newItem.isSpacer; + + newItem.isSubmenu = false; + newItem.subMenu = nullptr; + newItem.subMenuParentMenu = nullptr; + + mMenuItems.push_back(newItem); + + return pos; +} + +S32 PopupMenu::insertSubMenu(S32 pos, const char *title, PopupMenu *submenu) +{ + S32 itemPos = insertItem(pos, title, "", ""); + + mMenuItems[itemPos].isSubmenu = true; + mMenuItems[itemPos].subMenu = submenu; + mMenuItems[itemPos].subMenuParentMenu = this; + + submenu->isSubmenu = true; + + return itemPos; +} + +bool PopupMenu::setItem(S32 pos, const char *title, const char* accelerator, const char* cmd) +{ + String titleString = title; + + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (mMenuItems[i].text == titleString) + { + mMenuItems[i].id = pos; + mMenuItems[i].cmd = cmd; + + if (accelerator && accelerator[0]) + mMenuItems[i].accelerator = dStrdup(accelerator); + else + mMenuItems[i].accelerator = NULL; + return true; + } + } + + return false; +} + +void PopupMenu::removeItem(S32 itemPos) +{ + if (mMenuItems.size() < itemPos || itemPos < 0) + return; + + mMenuItems.erase(itemPos); +} + +////////////////////////////////////////////////////////////////////////// +void PopupMenu::enableItem(S32 pos, bool enable) +{ + if (mMenuItems.size() < pos || pos < 0) + return; + + mMenuItems[pos].enabled = enable; +} + +void PopupMenu::checkItem(S32 pos, bool checked) +{ + if (mMenuItems.size() < pos || pos < 0) + return; + + if (checked && mMenuItems[pos].checkGroup != -1) + { + // first, uncheck everything in the group: + for (U32 i = 0; i < mMenuItems.size(); i++) + if (mMenuItems[i].checkGroup == mMenuItems[pos].checkGroup && mMenuItems[i].isChecked) + mMenuItems[i].isChecked = false; + } + + mMenuItems[pos].isChecked; +} + +void PopupMenu::checkRadioItem(S32 firstPos, S32 lastPos, S32 checkPos) +{ + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (mMenuItems[i].id >= firstPos && mMenuItems[i].id <= lastPos) + { + mMenuItems[i].isChecked = false; + } + } +} + +bool PopupMenu::isItemChecked(S32 pos) +{ + if (mMenuItems.size() < pos || pos < 0) + return false; + + return mMenuItems[pos].isChecked; +} + +U32 PopupMenu::getItemCount() +{ + return mMenuItems.size(); +} + +////////////////////////////////////////////////////////////////////////// +bool PopupMenu::canHandleID(U32 id) +{ + return true; +} + +bool PopupMenu::handleSelect(U32 command, const char *text /* = NULL */) +{ + return dAtob(Con::executef(this, "onSelectItem", Con::getIntArg(command), text ? text : "")); +} + +////////////////////////////////////////////////////////////////////////// +void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */) +{ + if (owner == NULL) + return; + + GuiControl* editorGui; + Sim::findObject("EditorGui", editorGui); + + if (editorGui) + { + GuiPopupMenuBackgroundCtrl* backgroundCtrl; + Sim::findObject("PopUpMenuControl", backgroundCtrl); + + GuiControlProfile* profile; + Sim::findObject("GuiMenubarProfile", profile); + + if (!profile) + return; + + if (mTextList == nullptr) + { + mTextList = new GuiPopupMenuTextListCtrl(); + mTextList->registerObject(); + mTextList->setControlProfile(profile); + + mTextList->mPopup = this; + mTextList->mMenuBar = getMenuBarCtrl(); + } + + if (!backgroundCtrl) + { + backgroundCtrl = new GuiPopupMenuBackgroundCtrl(); + + backgroundCtrl->registerObject("PopUpMenuControl"); + } + + if (!backgroundCtrl || !mTextList) + return; + + if (!isSubmenu) + { + //if we're a 'parent' menu, then tell the background to clear out all existing other popups + + backgroundCtrl->clearPopups(); + } + + //find out if we're doing a first-time add + S32 popupIndex = backgroundCtrl->findPopupMenu(this); + + if (popupIndex == -1) + { + backgroundCtrl->addObject(mTextList); + backgroundCtrl->mPopups.push_back(this); + } + + mTextList->mBackground = backgroundCtrl; + + owner->pushDialogControl(backgroundCtrl, 10); + + //Set the background control's menubar, if any, and if it's not already set + if(backgroundCtrl->mMenuBarCtrl == nullptr) + backgroundCtrl->mMenuBarCtrl = getMenuBarCtrl(); + + backgroundCtrl->setExtent(editorGui->getExtent()); + + mTextList->clear(); + + S32 textWidth = 0, width = 0; + S32 acceleratorWidth = 0; + GFont *font = profile->mFont; + + Point2I maxBitmapSize = Point2I(0, 0); + + S32 numBitmaps = profile->mBitmapArrayRects.size(); + if (numBitmaps) + { + RectI *bitmapBounds = profile->mBitmapArrayRects.address(); + for (S32 i = 0; i < numBitmaps; i++) + { + if (bitmapBounds[i].extent.x > maxBitmapSize.x) + maxBitmapSize.x = bitmapBounds[i].extent.x; + if (bitmapBounds[i].extent.y > maxBitmapSize.y) + maxBitmapSize.y = bitmapBounds[i].extent.y; + } + } + + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (!mMenuItems[i].visible) + continue; + + S32 iTextWidth = font->getStrWidth(mMenuItems[i].text.c_str()); + S32 iAcceleratorWidth = mMenuItems[i].accelerator ? font->getStrWidth(mMenuItems[i].accelerator) : 0; + + if (iTextWidth > textWidth) + textWidth = iTextWidth; + if (iAcceleratorWidth > acceleratorWidth) + acceleratorWidth = iAcceleratorWidth; + } + + width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; + + mTextList->setCellSize(Point2I(width, font->getHeight() + 2)); + mTextList->clearColumnOffsets(); + mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index. + mTextList->addColumnOffset(maxBitmapSize.x + 1); + mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); + + U32 entryCount = 0; + + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (!mMenuItems[i].visible) + continue; + + char buf[512]; + + // If this menu item is a submenu, then set the isSubmenu to 2 to indicate + // an arrow should be drawn. Otherwise set the isSubmenu normally. + char isSubmenu = 1; + if (mMenuItems[i].isSubmenu) + isSubmenu = 2; + + char bitmapIndex = 1; + if (mMenuItems[i].bitmapIndex >= 0 && (mMenuItems[i].bitmapIndex * 3 <= profile->mBitmapArrayRects.size())) + bitmapIndex = mMenuItems[i].bitmapIndex + 2; + + dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, mMenuItems[i].text.c_str(), mMenuItems[i].accelerator ? mMenuItems[i].accelerator : ""); + mTextList->addEntry(entryCount, buf); + + if (!mMenuItems[i].enabled) + mTextList->setEntryActive(entryCount, false); + + entryCount++; + } + + Point2I pos = Point2I::Zero; + + if (x == -1 && y == -1) + pos = owner->getCursorPos(); + else + pos = Point2I(x, y); + + mTextList->setPosition(pos); + + //nudge in if we'd overshoot the screen + S32 widthDiff = (mTextList->getPosition().x + mTextList->getExtent().x) - backgroundCtrl->getWidth(); + if (widthDiff > 0) + { + Point2I popupPos = mTextList->getPosition(); + mTextList->setPosition(popupPos.x - widthDiff, popupPos.y); + } + + mTextList->setHidden(false); + } +} + +void PopupMenu::hidePopup() +{ + if (mTextList) + { + mTextList->setHidden(true); + } + + hidePopupSubmenus(); +} + +void PopupMenu::hidePopupSubmenus() +{ + for (U32 i = 0; i < mMenuItems.size(); i++) + { + if (mMenuItems[i].subMenu != nullptr) + mMenuItems[i].subMenu->hidePopup(); + } +} + +//----------------------------------------------------------------------------- +// Console Methods +//----------------------------------------------------------------------------- +DefineConsoleMethod(PopupMenu, insertItem, S32, (S32 pos, const char * title, const char * accelerator, const char* cmd), ("", "", ""), "(pos[, title][, accelerator][, cmd])") +{ + return object->insertItem(pos, title, accelerator, cmd); +} + +DefineConsoleMethod(PopupMenu, removeItem, void, (S32 pos), , "(pos)") +{ + object->removeItem(pos); +} + +DefineConsoleMethod(PopupMenu, insertSubMenu, S32, (S32 pos, String title, String subMenu), , "(pos, title, subMenu)") +{ + PopupMenu *mnu = dynamic_cast(Sim::findObject(subMenu)); + if(mnu == NULL) + { + Con::errorf("PopupMenu::insertSubMenu - Invalid PopupMenu object specified for submenu"); + return -1; + } + return object->insertSubMenu(pos, title, mnu); +} + +DefineConsoleMethod(PopupMenu, setItem, bool, (S32 pos, const char * title, const char * accelerator, const char *cmd), (""), "(pos, title[, accelerator][, cmd])") +{ + return object->setItem(pos, title, accelerator, cmd); +} + +//----------------------------------------------------------------------------- + +DefineConsoleMethod(PopupMenu, enableItem, void, (S32 pos, bool enabled), , "(pos, enabled)") +{ + object->enableItem(pos, enabled); +} + +DefineConsoleMethod(PopupMenu, checkItem, void, (S32 pos, bool checked), , "(pos, checked)") +{ + object->checkItem(pos, checked); +} + +DefineConsoleMethod(PopupMenu, checkRadioItem, void, (S32 firstPos, S32 lastPos, S32 checkPos), , "(firstPos, lastPos, checkPos)") +{ + object->checkRadioItem(firstPos, lastPos, checkPos); +} + +DefineConsoleMethod(PopupMenu, isItemChecked, bool, (S32 pos), , "(pos)") +{ + return object->isItemChecked(pos); +} + +DefineConsoleMethod(PopupMenu, getItemCount, S32, (), , "()") +{ + return object->getItemCount(); +} + +//----------------------------------------------------------------------------- +DefineConsoleMethod(PopupMenu, showPopup, void, (const char * canvasName, S32 x, S32 y), ( -1, -1), "(Canvas,[x, y])") +{ + GuiCanvas *pCanvas = dynamic_cast(Sim::findObject(canvasName)); + object->showPopup(pCanvas, x, y); +} diff --git a/Engine/source/platform/menus/popupMenu.h b/Engine/source/gui/editor/popupMenu.h similarity index 69% rename from Engine/source/platform/menus/popupMenu.h rename to Engine/source/gui/editor/popupMenu.h index 8d1239972..9a6dd0821 100644 --- a/Engine/source/platform/menus/popupMenu.h +++ b/Engine/source/gui/editor/popupMenu.h @@ -19,17 +19,43 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#ifndef _POPUPMENU_H_ +#define _POPUPMENU_H_ + #include "console/simBase.h" #include "core/util/tVector.h" #include "util/messaging/dispatcher.h" #include "gui/core/guiCanvas.h" -#ifndef _POPUPMENU_H_ -#define _POPUPMENU_H_ +class PopupMenu; +class GuiMenuBar; +class GuiPopupMenuTextListCtrl; +class GuiPopupMenuBackgroundCtrl; -// Forward ref used by the platform code -struct PlatformPopupMenuData; -class MenuBar; +struct MenuItem // an individual item in a pull-down menu +{ + String text; // the text of the menu item + U32 id; // a script-assigned identifier + char *accelerator; // the keyboard accelerator shortcut for the menu item + U32 acceleratorIndex; // index of this accelerator + bool enabled; // true if the menu item is selectable + bool visible; // true if the menu item is visible + S32 bitmapIndex; // index of the bitmap in the bitmap array + S32 checkGroup; // the group index of the item visa vi check marks - + // only one item in the group can be checked. + + bool isSubmenu; // This menu item has a submenu that will be displayed + + bool isChecked; + + bool isSpacer; + + bool isMenubarEntry; + + PopupMenu* subMenuParentMenu; // For a submenu, this is the parent menu + PopupMenu* subMenu; + String cmd; +}; // PopupMenu represents a menu. // You can add menu items to the menu, but there is no torque object associated @@ -37,30 +63,32 @@ class MenuBar; class PopupMenu : public SimObject, public virtual Dispatcher::IMessageListener { typedef SimObject Parent; - - friend class MenuBar; - -private: - /// Used by MenuBar to attach the menu to the menu bar. Do not use anywhere else. - void attachToMenuBar(GuiCanvas *owner, S32 pos); + friend class GuiMenuBar; + friend class GuiPopupMenuTextListCtrl; + friend class GuiPopupMenuBackgroundCtrl; protected: - PlatformPopupMenuData *mData; - - SimSet *mSubmenus; - SimObjectPtr mCanvas; + Vector mMenuItems; - StringTableEntry mBarTitle; + GuiMenuBar* mMenuBarCtrl; - U32 mPopupGUID; - - bool mIsPopup; + StringTableEntry barTitle; + + RectI bounds; + bool visible; + + S32 bitmapIndex; // Index of the bitmap in the bitmap array (-1 = no bitmap) + bool drawBitmapOnly; // Draw only the bitmap and not the text + bool drawBorder; // Should a border be drawn around this menu (usually if we only have a bitmap, we don't want a border) + + bool isSubmenu; + + //This is the gui control that renders our popup + GuiPopupMenuTextListCtrl *mTextList; public: PopupMenu(); virtual ~PopupMenu(); - void createPlatformPopupMenuData(); - void deletePlatformPopupMenuData(); DECLARE_CONOBJECT(PopupMenu); @@ -72,15 +100,6 @@ public: static PopupMenuEvent smPopupMenuEvent; static bool smSelectionEventHandled; /// Set to true if any menu or submenu handles a selection event - /// Creates the platform specific menu object, a peer to this object. - /// The platform menu *must* exist before calling any method that manipulates - /// menu items or displays the menu. - /// implementd on a per-platform basis. - void createPlatformMenu(); - - void setBarTitle(const char * val) { mBarTitle = StringTable->insert(val, true); } - StringTableEntry getBarTitle() const { return mBarTitle; } - /// pass NULL for @p title to insert a separator /// returns the menu item's ID, or -1 on failure. /// implementd on a per-platform basis. @@ -118,39 +137,7 @@ public: /// Returns the number of items in the menu. U32 getItemCount(); - /// Returns the popup GUID - U32 getPopupGUID() { return mPopupGUID; } - //----------------------------------------------------------------------------- - // New code should not use these methods directly, use the menu bar instead. - // - // They remain for compatibility with old code and will be changing/going away - // once the existing code is moved over to the menu bar. - //----------------------------------------------------------------------------- - - /// Places this menu in the menu bar of the application's main window. - /// @param owner The GuiCanvas that owns the PlatformWindow that this call is associated with - /// @param pos The relative position at which to place the menu. - /// @param title The name of the menu - void attachToMenuBar(GuiCanvas *owner, S32 pos, const char *title); - - /// Removes this menu from the menu bar. - void removeFromMenuBar(); - - //----------------------------------------------------------------------------- - - /// Called when the menu has been attached to the menu bar - void onAttachToMenuBar(GuiCanvas *canvas, S32 pos, const char *title); - - /// Called when the menu has been removed from the menu bar - void onRemoveFromMenuBar(GuiCanvas *canvas); - - /// Returns the position index of this menu on the bar. - S32 getPosOnMenuBar(); - - /// Returns true if this menu is attached to the menu bar - bool isAttachedToMenuBar() { return mCanvas != NULL; } - /// Displays this menu as a popup menu and blocks until the user has selected /// an item. /// @param canvas the owner to show this popup associated with @@ -159,6 +146,9 @@ public: /// implemented on a per-platform basis. void showPopup(GuiCanvas *owner, S32 x = -1, S32 y = -1); + void hidePopup(); + void hidePopupSubmenus(); + /// Returns true iff this menu contains an item that matches @p iD. /// implemented on a per-platform basis. /// TODO: factor out common code @@ -184,6 +174,11 @@ public: virtual bool onMessageReceived(StringTableEntry queue, const char* event, const char* data ); virtual bool onMessageObjectReceived(StringTableEntry queue, Message *msg ); + + bool isVisible() { return visible; } + void setVisible(bool isVis) { visible = isVis; } + + GuiMenuBar* getMenuBarCtrl(); }; #endif // _POPUPMENU_H_ diff --git a/Engine/source/platform/menus/menuBar.cpp b/Engine/source/platform/menus/menuBar.cpp deleted file mode 100644 index cb70838a8..000000000 --- a/Engine/source/platform/menus/menuBar.cpp +++ /dev/null @@ -1,127 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "platform/menus/menuBar.h" -#include "platform/menus/popupMenu.h" -#include "gui/core/guiCanvas.h" -#include "console/engineAPI.h" - -//----------------------------------------------------------------------------- -// Constructor/Destructor -//----------------------------------------------------------------------------- - -MenuBar::MenuBar() -{ - createPlatformPopupMenuData(); - - mCanvas = NULL; -} - -MenuBar::~MenuBar() -{ - removeFromCanvas(); - - deletePlatformPopupMenuData(); -} - -IMPLEMENT_CONOBJECT(MenuBar); - -ConsoleDocClass( MenuBar, - "@brief Used for rendering platform menu bars\n\n" - "Internal use only\n\n" - "@internal" -); - -//----------------------------------------------------------------------------- -// Public Methods -//----------------------------------------------------------------------------- - -void MenuBar::addObject(SimObject *obj) -{ - Parent::addObject(obj); - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::removeObject(SimObject *obj) -{ - Parent::removeObject(obj); - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::insertObject(SimObject *obj, S32 pos) -{ - Parent::addObject(obj); - - if(pos >= size()) - pos = size() - 1; - - if(pos < size()) - { - if(pos < 0) pos = 0; - Parent::reOrder(obj, at(pos)); - } - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::pushObject(SimObject *obj) -{ - Parent::pushObject(obj); - updateMenuBar(dynamic_cast(obj)); -} - -void MenuBar::popObject() -{ - Parent::popObject(); - updateMenuBar(); -} - -bool MenuBar::reOrder(SimObject *obj, SimObject *target /*= 0*/) -{ - bool ret = Parent::reOrder(obj, target); - if(ret) - updateMenuBar(dynamic_cast(obj)); - return ret; -} - -//----------------------------------------------------------------------------- -// Console Methods -//----------------------------------------------------------------------------- - -DefineConsoleMethod(MenuBar, attachToCanvas, void, (const char *canvas, S32 pos), , "(GuiCanvas, pos)") -{ - object->attachToCanvas(dynamic_cast(Sim::findObject(canvas)), pos); -} - -DefineConsoleMethod(MenuBar, removeFromCanvas, void, (), , "()") -{ - object->removeFromCanvas(); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(MenuBar, insert, void, (SimObject* pObject, S32 pos), ,"(object, pos) insert object at position") -{ - - if(pObject) - object->insertObject(pObject, pos); -} diff --git a/Engine/source/platform/menus/menuBar.h b/Engine/source/platform/menus/menuBar.h deleted file mode 100644 index 0e0e64602..000000000 --- a/Engine/source/platform/menus/menuBar.h +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "console/simBase.h" - -#ifndef _MENUBAR_H_ -#define _MENUBAR_H_ - -// Forward Refs -class PlatformMenuBarData; -class PopupMenu; -class GuiCanvas; - -class MenuBar : public SimSet -{ - typedef SimSet Parent; - -protected: - PlatformMenuBarData *mData; - GuiCanvas *mCanvas; - - /// Update the native menu bar to ensure consistency with the set - void updateMenuBar(PopupMenu *menu = NULL); - - void createPlatformPopupMenuData(); - void deletePlatformPopupMenuData(); - -public: - MenuBar(); - virtual ~MenuBar(); - DECLARE_CONOBJECT(MenuBar); - - /// Attach this menu bar to the native menu bar - void attachToCanvas(GuiCanvas *owner, S32 pos); - /// Remove this menu bar from the native menu bar - void removeFromCanvas(); - - /// Returns true if this menu is attached to the menu bar - bool isAttachedToCanvas() { return mCanvas != NULL; } - - virtual void insertObject(SimObject *obj, S32 pos); - - // Overridden SimSet methods to ensure menu bar consistency when attached - virtual void addObject(SimObject *obj); - virtual void removeObject(SimObject *obj); - virtual void pushObject(SimObject *obj); - virtual void popObject(); - - virtual bool reOrder(SimObject *obj, SimObject *target = 0); -}; - -#endif // _MENUBAR_H_ diff --git a/Engine/source/platform/menus/popupMenu.cpp b/Engine/source/platform/menus/popupMenu.cpp deleted file mode 100644 index 7e8aad7ba..000000000 --- a/Engine/source/platform/menus/popupMenu.cpp +++ /dev/null @@ -1,269 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/menus/popupMenu.h" -#include "console/consoleTypes.h" -#include "console/engineAPI.h" -#include "gui/core/guiCanvas.h" -#include "core/util/safeDelete.h" - -static U32 sMaxPopupGUID = 0; -PopupMenuEvent PopupMenu::smPopupMenuEvent; -bool PopupMenu::smSelectionEventHandled = false; - -/// Event class used to remove popup menus from the event notification in a safe way -class PopUpNotifyRemoveEvent : public SimEvent -{ -public: - void process(SimObject *object) - { - PopupMenu::smPopupMenuEvent.remove((PopupMenu *)object, &PopupMenu::handleSelectEvent); - } -}; - -//----------------------------------------------------------------------------- -// Constructor/Destructor -//----------------------------------------------------------------------------- - -PopupMenu::PopupMenu() : mCanvas(NULL) -{ - createPlatformPopupMenuData(); - - mSubmenus = new SimSet; - mSubmenus->registerObject(); - - mBarTitle = StringTable->EmptyString(); - mIsPopup = false; - - mPopupGUID = sMaxPopupGUID++; -} - -PopupMenu::~PopupMenu() -{ - // This searches the menu bar so is safe to call for menus - // that aren't on it, since nothing will happen. - removeFromMenuBar(); - - SimSet::iterator i; - while((i = mSubmenus->begin()) != mSubmenus->end()) - { - (*i)->deleteObject(); - } - - mSubmenus->deleteObject(); - deletePlatformPopupMenuData(); - - PopupMenu::smPopupMenuEvent.remove(this, &PopupMenu::handleSelectEvent); -} - -IMPLEMENT_CONOBJECT(PopupMenu); - -ConsoleDocClass( PopupMenu, - "@brief PopupMenu represents a system menu.\n\n" - "You can add menu items to the menu, but there is no torque object associated " - "with these menu items, they exist only in a platform specific manner.\n\n" - "@note Internal use only\n\n" - "@internal" -); - - -//----------------------------------------------------------------------------- - -void PopupMenu::initPersistFields() -{ - addField("isPopup", TypeBool, Offset(mIsPopup, PopupMenu), "true if this is a pop-up/context menu. defaults to false."); - addField("barTitle", TypeCaseString, Offset(mBarTitle, PopupMenu), "the title of this menu when attached to a menu bar"); - - Parent::initPersistFields(); -} - -//----------------------------------------------------------------------------- - -bool PopupMenu::onAdd() -{ - if(! Parent::onAdd()) - return false; - - createPlatformMenu(); - - Con::executef(this, "onAdd"); - return true; -} - -void PopupMenu::onRemove() -{ - Con::executef(this, "onRemove"); - - Parent::onRemove(); -} - -//----------------------------------------------------------------------------- - -void PopupMenu::onMenuSelect() -{ - Con::executef(this, "onMenuSelect"); -} - -//----------------------------------------------------------------------------- - -void PopupMenu::handleSelectEvent(U32 popID, U32 command) -{ - if (popID == mPopupGUID && canHandleID(command)) - if (handleSelect(command)) - smSelectionEventHandled = true; -} - -//----------------------------------------------------------------------------- - -void PopupMenu::onAttachToMenuBar(GuiCanvas *canvas, S32 pos, const char *title) -{ - mCanvas = canvas; - - // Attached menus must be notified of menu events - smPopupMenuEvent.notify(this, &PopupMenu::handleSelectEvent); - - // Pass on to sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *mnu = dynamic_cast(*i); - if(mnu == NULL) - continue; - - mnu->onAttachToMenuBar(canvas, pos, title); - } - - // Call script - if(isProperlyAdded()) - Con::executef(this, "onAttachToMenuBar", Con::getIntArg(canvas ? canvas->getId() : 0), Con::getIntArg(pos), title); -} - -void PopupMenu::onRemoveFromMenuBar(GuiCanvas *canvas) -{ - mCanvas = NULL; - - // We are no longer interested in select events, remove ourselves from the notification list in a safe way - Sim::postCurrentEvent(this, new PopUpNotifyRemoveEvent()); - - // Pass on to sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *mnu = dynamic_cast(*i); - if(mnu == NULL) - continue; - - mnu->onRemoveFromMenuBar(canvas); - } - - // Call script - if(isProperlyAdded()) - Con::executef(this, "onRemoveFromMenuBar", Con::getIntArg(canvas ? canvas->getId() : 0)); -} - -//----------------------------------------------------------------------------- - -bool PopupMenu::onMessageReceived(StringTableEntry queue, const char* event, const char* data) -{ - return Con::executef(this, "onMessageReceived", queue, event, data); -} - - -bool PopupMenu::onMessageObjectReceived(StringTableEntry queue, Message *msg ) -{ - return Con::executef(this, "onMessageReceived", queue, Con::getIntArg(msg->getId())); -} - -//----------------------------------------------------------------------------- -// Console Methods -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, insertItem, S32, (S32 pos, const char * title, const char * accelerator, const char* cmd), ("", "", ""), "(pos[, title][, accelerator][, cmd])") -{ - return object->insertItem(pos, title, accelerator, cmd); -} - -DefineConsoleMethod(PopupMenu, removeItem, void, (S32 pos), , "(pos)") -{ - object->removeItem(pos); -} - -DefineConsoleMethod(PopupMenu, insertSubMenu, S32, (S32 pos, String title, String subMenu), , "(pos, title, subMenu)") -{ - PopupMenu *mnu = dynamic_cast(Sim::findObject(subMenu)); - if(mnu == NULL) - { - Con::errorf("PopupMenu::insertSubMenu - Invalid PopupMenu object specified for submenu"); - return -1; - } - return object->insertSubMenu(pos, title, mnu); -} - -DefineConsoleMethod(PopupMenu, setItem, bool, (S32 pos, const char * title, const char * accelerator, const char *cmd), (""), "(pos, title[, accelerator][, cmd])") -{ - return object->setItem(pos, title, accelerator, cmd); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, enableItem, void, (S32 pos, bool enabled), , "(pos, enabled)") -{ - object->enableItem(pos, enabled); -} - -DefineConsoleMethod(PopupMenu, checkItem, void, (S32 pos, bool checked), , "(pos, checked)") -{ - object->checkItem(pos, checked); -} - -DefineConsoleMethod(PopupMenu, checkRadioItem, void, (S32 firstPos, S32 lastPos, S32 checkPos), , "(firstPos, lastPos, checkPos)") -{ - object->checkRadioItem(firstPos, lastPos, checkPos); -} - -DefineConsoleMethod(PopupMenu, isItemChecked, bool, (S32 pos), , "(pos)") -{ - return object->isItemChecked(pos); -} - -DefineConsoleMethod(PopupMenu, getItemCount, S32, (), , "()") -{ - return object->getItemCount(); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, attachToMenuBar, void, (const char * canvasName, S32 pos, const char * title), , "(GuiCanvas, pos, title)") -{ - object->attachToMenuBar(dynamic_cast(Sim::findObject(canvasName)), pos, title); -} - -DefineConsoleMethod(PopupMenu, removeFromMenuBar, void, (), , "()") -{ - object->removeFromMenuBar(); -} - -//----------------------------------------------------------------------------- - -DefineConsoleMethod(PopupMenu, showPopup, void, (const char * canvasName, S32 x, S32 y), ( -1, -1), "(Canvas,[x, y])") -{ - GuiCanvas *pCanvas = dynamic_cast(Sim::findObject(canvasName)); - object->showPopup(pCanvas, x, y); -} diff --git a/Engine/source/platformSDL/menus/PlatformSDLPopupMenuData.h b/Engine/source/platformSDL/menus/PlatformSDLPopupMenuData.h deleted file mode 100644 index 4911f5c10..000000000 --- a/Engine/source/platformSDL/menus/PlatformSDLPopupMenuData.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef PLATFORM_SDL_POPUPMENU_DATA_H -#define PLATFORM_SDL_POPUPMENU_DATA_H - -#include "core/util/tDictionary.h" - -class GuiMenuBar; -struct EventDescriptor; -class PopupMenu; -class MenuBar; - -struct PlatformPopupMenuData -{ - MenuBar *mMenuBar; - GuiMenuBar::Menu *mMenuGui; - - static const U8 mCheckedBitmapIdx = 0; - static Map mMenuMap; - - PlatformPopupMenuData() - { - mMenuBar = NULL; - mMenuGui = NULL; - } - - ~PlatformPopupMenuData() - { - - } - - void insertAccelerator(EventDescriptor &desc, U32 id); - void removeAccelerator(U32 id); - void setAccelleratorEnabled(U32 id, bool enabled); -}; - -#endif //PLATFORM_SDL_POPUPMENU_DATA_H \ No newline at end of file diff --git a/Engine/source/platformSDL/menus/guiPlatformGenericMenuBar.h b/Engine/source/platformSDL/menus/guiPlatformGenericMenuBar.h deleted file mode 100644 index b2129a8b1..000000000 --- a/Engine/source/platformSDL/menus/guiPlatformGenericMenuBar.h +++ /dev/null @@ -1,51 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#pragma once - -#include "gui/editor/guiMenuBar.h" -#include "platformSDL/menus/PlatformSDLPopupMenuData.h" -#include "platform/menus/popupMenu.h" - -class GuiPlatformGenericMenuBar : public GuiMenuBar -{ - typedef GuiMenuBar Parent; -public: - DECLARE_CONOBJECT(GuiPlatformGenericMenuBar); - - virtual void menuItemSelected(Menu *menu, MenuItem *item) - { - AssertFatal(menu && item, ""); - - PopupMenu *popupMenu = PlatformPopupMenuData::mMenuMap[menu]; - AssertFatal(popupMenu, ""); - - popupMenu->handleSelect(item->id); - - Parent::menuItemSelected(menu, item); - } - -protected: - /// menu id / item id - Map, String> mCmds; - -}; \ No newline at end of file diff --git a/Engine/source/platformSDL/menus/menuBarSDL.cpp b/Engine/source/platformSDL/menus/menuBarSDL.cpp deleted file mode 100644 index a0ddb2370..000000000 --- a/Engine/source/platformSDL/menus/menuBarSDL.cpp +++ /dev/null @@ -1,200 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/menus/menuBar.h" -#include "platform/menus/popupMenu.h" -#include "gui/core/guiCanvas.h" -#include "windowManager/platformWindowMgr.h" -#include "core/util/safeDelete.h" - -#include "windowManager/sdl/sdlWindow.h" -#include "gui/editor/guiMenuBar.h" - -#include "platformSDL/menus/PlatformSDLPopupMenuData.h" - -#include "platformSDL/menus/guiPlatformGenericMenuBar.h" - -#ifdef TORQUE_SDL - -//----------------------------------------------------------------------------- -// Platform Data -//----------------------------------------------------------------------------- - -// class PlatformMenuBarData -// { -// -// }; - -Map PlatformPopupMenuData::mMenuMap; - -IMPLEMENT_CONOBJECT(GuiPlatformGenericMenuBar); - -//----------------------------------------------------------------------------- -// MenuBar Methods -//----------------------------------------------------------------------------- - -void MenuBar::createPlatformPopupMenuData() -{ - mData = NULL; -} - -void MenuBar::deletePlatformPopupMenuData() -{ -// SAFE_DELETE(mData); -} - -//----------------------------------------------------------------------------- - -GuiPlatformGenericMenuBar* _FindMenuBarCtrl() -{ - GuiControl* control; - Sim::findObject("PlatformGenericMenubar", control); - AssertFatal(control, ""); - if( !control ) - return NULL; - - GuiPlatformGenericMenuBar* menuBar; - menuBar = dynamic_cast( control->findObjectByInternalName( StringTable->insert("menubar"), true) ); - AssertFatal(menuBar, ""); - return menuBar; -} - - -void MenuBar::updateMenuBar(PopupMenu *popupMenu /* = NULL */) -{ - //if(! isAttachedToCanvas()) - // return; - - if(!popupMenu) - return; - - GuiPlatformGenericMenuBar* menuBarGui = _FindMenuBarCtrl(); - popupMenu->mData->mMenuBar = this; - - String menuTitle = popupMenu->getBarTitle(); - - //Next, find out if we're still in the list of entries - SimSet::iterator itr = find(begin(), end(), popupMenu); - - GuiMenuBar::Menu* menuGui = menuBarGui->findMenu(menuTitle); - if (!menuGui) - { - //This is our first time setting this particular menu up, so we'll OK it. - if (itr == end()) - menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui); - else - menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui, itr - begin()); - } - else - { - //Not our first time through, so we're really updating it. - - //So, first, remove it from the menubar - menuBarGui->removeFromMenuBar(menuGui); - - //Next, find out if we're still in the list of entries - SimSet::iterator itr = find(begin(), end(), popupMenu); - - //if we're no longer in the list, we're pretty much done here - if (itr == end()) - return; - - //We're still here, so this is a valid menu for our current bar configuration, so add us back in. - menuBarGui->attachToMenuBar(menuGui, itr - begin()); - } -} - -//----------------------------------------------------------------------------- - -void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos) -{ - if(owner == NULL || isAttachedToCanvas()) - return; - - // This is set for popup menus in the onAttachToMenuBar() callback - mCanvas = owner; - - PlatformWindowSDL *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - // Setup the native menu bar - GuiMenuBar *hWindowMenu = static_cast( pWindow->getMenuHandle() ); - if( hWindowMenu == NULL && !Journal::IsPlaying() ) - hWindowMenu = _FindMenuBarCtrl(); - - if(hWindowMenu) - { - pWindow->setMenuHandle( hWindowMenu ); - GuiControl *base = hWindowMenu->getParent(); - - while( base->getParent() ) - { - base = base->getParent(); - } - - mCanvas->setMenuBar( base ); - } - - for (S32 i = 0; i < size(); ++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if (mnu == NULL) - { - Con::warnf("MenuBar::attachToMenuBar - Non-PopupMenu object in set"); - continue; - } - - if (mnu->isAttachedToMenuBar()) - mnu->removeFromMenuBar(); - - mnu->attachToMenuBar(owner, pos + i); - } - -} - -void MenuBar::removeFromCanvas() -{ - if (mCanvas == NULL || !isAttachedToCanvas()) - return; - - //_FindMenuBarCtrl()->clearMenus(); - - // Add the items - for (S32 i = 0; i < size(); ++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if (mnu == NULL) - { - Con::warnf("MenuBar::removeFromMenuBar - Non-PopupMenu object in set"); - continue; - } - - mnu->removeFromMenuBar(); - } - - mCanvas->setMenuBar(NULL); - - mCanvas = NULL; -} - -#endif diff --git a/Engine/source/platformSDL/menus/popupMenuSDL.cpp b/Engine/source/platformSDL/menus/popupMenuSDL.cpp deleted file mode 100644 index 788d7c88e..000000000 --- a/Engine/source/platformSDL/menus/popupMenuSDL.cpp +++ /dev/null @@ -1,393 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifdef TORQUE_SDL - -#include "platform/menus/popupMenu.h" -#include "platform/menus/menuBar.h" -#include "console/consoleTypes.h" -#include "gui/core/guiCanvas.h" -#include "core/util/safeDelete.h" - -#include "sim/actionMap.h" -#include "platform/platformInput.h" - -#include "windowManager/sdl/sdlWindow.h" -#include "gui/editor/guiMenuBar.h" - -#include "platformSDL/menus/PlatformSDLPopupMenuData.h" -#include "console/engineAPI.h" - -#include "platformSDL/menus/guiPlatformGenericMenuBar.h" -#include "gui/editor/guiPopupMenuCtrl.h" - -////////////////////////////////////////////////////////////////////////// -// Platform Menu Data -////////////////////////////////////////////////////////////////////////// -GuiPlatformGenericMenuBar* findMenuBarCtrl() -{ - GuiControl* control; - Sim::findObject("PlatformGenericMenubar", control); - AssertFatal(control, ""); - if (!control) - return NULL; - - GuiPlatformGenericMenuBar* menuBar; - menuBar = dynamic_cast(control->findObjectByInternalName(StringTable->insert("menubar"), true)); - AssertFatal(menuBar, ""); - return menuBar; -} - -////////////////////////////////////////////////////////////////////////// - -void PlatformPopupMenuData::insertAccelerator(EventDescriptor &desc, U32 id) -{ - AssertFatal(0, ""); -} - -void PlatformPopupMenuData::removeAccelerator(U32 id) -{ - AssertFatal(0, ""); -} - -void PlatformPopupMenuData::setAccelleratorEnabled( U32 id, bool enabled ) -{ - AssertFatal(0, ""); -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::createPlatformPopupMenuData() -{ - mData = new PlatformPopupMenuData; -} - -void PopupMenu::deletePlatformPopupMenuData() -{ - SAFE_DELETE(mData); -} -void PopupMenu::createPlatformMenu() -{ - mData->mMenuGui = GuiMenuBar::sCreateMenu( getBarTitle(), getId() ); - PlatformPopupMenuData::mMenuMap[ mData->mMenuGui ] = this; -} - - -////////////////////////////////////////////////////////////////////////// -// Public Methods -////////////////////////////////////////////////////////////////////////// - -S32 PopupMenu::insertItem(S32 pos, const char *title, const char* accelerator, const char* cmd) -{ - GuiMenuBar::MenuItem *item = GuiMenuBar::findMenuItem( mData->mMenuGui, title ); - - //We'll make a special exception for the spacer items - if(item && dStrcmp(title, "")) - { - setItem( pos, title, accelerator, cmd); - return pos; - } - - item = GuiMenuBar::addMenuItem( mData->mMenuGui, title, pos, accelerator, -1, cmd ); - item->submenuParentMenu = this->mData->mMenuGui; - - return pos; -} - -S32 PopupMenu::insertSubMenu(S32 pos, const char *title, PopupMenu *submenu) -{ - GuiMenuBar::MenuItem *item = GuiMenuBar::addMenuItem( mData->mMenuGui, title, pos, "", -1, "" ); - item->isSubmenu = true; - item->submenu = submenu->mData->mMenuGui; - item->submenuParentMenu = this->mData->mMenuGui; - - return pos; -} - -bool PopupMenu::setItem(S32 pos, const char *title, const char* accelerator, const char* cmd) -{ - GuiMenuBar::MenuItem *item = NULL; - - item = GuiMenuBar::findMenuItem( mData->mMenuGui, title ); - - if(item) - { - item->id = pos; - item->cmd = cmd; - if( accelerator && accelerator[0] ) - item->accelerator = dStrdup( accelerator ); - else - item->accelerator = NULL; - return true; - } - - return false; -} - -void PopupMenu::removeItem(S32 itemPos) -{ - GuiMenuBar::MenuItem *item = GuiMenuBar::findMenuItem( mData->mMenuGui, String::ToString(itemPos) ); - if(item) - { - GuiMenuBar::removeMenuItem( mData->mMenuGui, item); - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::enableItem( S32 pos, bool enable ) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - { - if( item->id == pos) - item->enabled = enable; - } -} - -void PopupMenu::checkItem(S32 pos, bool checked) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - if(item->id == pos) - break; - - if( !item ) - return; - - if(checked && item->checkGroup != -1) - { - // first, uncheck everything in the group: - for( GuiMenuBar::MenuItem *itemWalk = mData->mMenuGui->firstMenuItem; itemWalk; itemWalk = itemWalk->nextMenuItem ) - if( itemWalk->checkGroup == item->checkGroup && itemWalk->bitmapIndex == mData->mCheckedBitmapIdx ) - itemWalk->bitmapIndex = -1; - } - - item->bitmapIndex = checked ? mData->mCheckedBitmapIdx : -1; -} - -void PopupMenu::checkRadioItem(S32 firstPos, S32 lastPos, S32 checkPos) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - { - if(item->id >= firstPos && item->id <= lastPos) - { - item->bitmapIndex = (item->id == checkPos) ? mData->mCheckedBitmapIdx : -1; - } - } -} - -bool PopupMenu::isItemChecked(S32 pos) -{ - GuiMenuBar::MenuItem *item = NULL; - for( item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - if(item->id == pos) - return item->bitmapIndex == mData->mCheckedBitmapIdx; - - return false; -} - -U32 PopupMenu::getItemCount() -{ - int count = 0; - for( GuiMenuBar::MenuItem *item = mData->mMenuGui->firstMenuItem; item; item = item->nextMenuItem ) - ++count; - - return count; -} - -////////////////////////////////////////////////////////////////////////// - -bool PopupMenu::canHandleID(U32 id) -{ - return true; -} - -bool PopupMenu::handleSelect(U32 command, const char *text /* = NULL */) -{ - return dAtob(Con::executef(this, "onSelectItem", Con::getIntArg(command), text ? text : "")); -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */) -{ - if(owner == NULL) - return; - - GuiControl* editorGui; - Sim::findObject("EditorGui", editorGui); - - if (editorGui) - { - GuiPopupMenuTextListCtrl* textList; - GuiPopupMenuBackgroundCtrl* backgroundCtrl; - Sim::findObject("PopUpMenuControl", backgroundCtrl); - - GuiControlProfile* profile; - Sim::findObject("GuiMenubarProfile", profile); - - if (!profile) - return; - - if (!backgroundCtrl) - { - textList = new GuiPopupMenuTextListCtrl(); - - textList->registerObject(); - - backgroundCtrl = new GuiPopupMenuBackgroundCtrl(textList); - - backgroundCtrl->registerObject("PopUpMenuControl"); - - textList->setControlProfile(profile); - - backgroundCtrl->addObject(textList); - } - else - { - textList = dynamic_cast(backgroundCtrl->first()); - } - - if (!backgroundCtrl || !textList) - return; - - owner->pushDialogControl(backgroundCtrl, 10); - - backgroundCtrl->setExtent(editorGui->getExtent()); - - textList->clear(); - textList->mMenu = mData->mMenuGui; - textList->mMenuBar = findMenuBarCtrl(); - textList->mPopup = this; - - S32 textWidth = 0, width = 0; - S32 acceleratorWidth = 0; - GFont *font = profile->mFont; - - Point2I maxBitmapSize = Point2I(0, 0); - - S32 numBitmaps = profile->mBitmapArrayRects.size(); - if (numBitmaps) - { - RectI *bitmapBounds = profile->mBitmapArrayRects.address(); - for (S32 i = 0; i < numBitmaps; i++) - { - if (bitmapBounds[i].extent.x > maxBitmapSize.x) - maxBitmapSize.x = bitmapBounds[i].extent.x; - if (bitmapBounds[i].extent.y > maxBitmapSize.y) - maxBitmapSize.y = bitmapBounds[i].extent.y; - } - } - - for (GuiMenuBar::MenuItem *walk = mData->mMenuGui->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if (!walk->visible) - continue; - - S32 iTextWidth = font->getStrWidth(walk->text); - S32 iAcceleratorWidth = walk->accelerator ? font->getStrWidth(walk->accelerator) : 0; - - if (iTextWidth > textWidth) - textWidth = iTextWidth; - if (iAcceleratorWidth > acceleratorWidth) - acceleratorWidth = iAcceleratorWidth; - } - width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4; - - textList->setCellSize(Point2I(width, font->getHeight() + 2)); - textList->clearColumnOffsets(); - textList->addColumnOffset(-1); // add an empty column in for the bitmap index. - textList->addColumnOffset(maxBitmapSize.x + 1); - textList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4); - - U32 entryCount = 0; - - for (GuiMenuBar::MenuItem *walk = mData->mMenuGui->firstMenuItem; walk; walk = walk->nextMenuItem) - { - if (!walk->visible) - continue; - - char buf[512]; - - // If this menu item is a submenu, then set the isSubmenu to 2 to indicate - // an arrow should be drawn. Otherwise set the isSubmenu normally. - char isSubmenu = 1; - if (walk->isSubmenu) - isSubmenu = 2; - - char bitmapIndex = 1; - if (walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= profile->mBitmapArrayRects.size())) - bitmapIndex = walk->bitmapIndex + 2; - dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, walk->text, walk->accelerator ? walk->accelerator : ""); - textList->addEntry(entryCount, buf); - - if (!walk->enabled) - textList->setEntryActive(entryCount, false); - - entryCount++; - } - - Point2I pos = owner->getCursorPos(); - textList->setPosition(pos); - - //nudge in if we'd overshoot the screen - S32 widthDiff = (textList->getPosition().x + textList->getExtent().x) - backgroundCtrl->getWidth(); - if (widthDiff > 0) - { - Point2I popupPos = textList->getPosition(); - textList->setPosition(popupPos.x - widthDiff, popupPos.y); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos, const char *title) -{ - if(owner == NULL || isAttachedToMenuBar()) - return; -} - -// New version of above for use by MenuBar class. Do not use yet. -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos) -{ - if(owner == NULL || isAttachedToMenuBar()) - return; - - //mData->mMenuBar = owner->setMenuBar(); -} - -void PopupMenu::removeFromMenuBar() -{ - if(isAttachedToMenuBar()) - return; -} - -S32 PopupMenu::getPosOnMenuBar() -{ - - return 0; -} - -#endif diff --git a/Engine/source/platformWin32/menus/menuBarWin32.cpp b/Engine/source/platformWin32/menus/menuBarWin32.cpp deleted file mode 100644 index dfa103161..000000000 --- a/Engine/source/platformWin32/menus/menuBarWin32.cpp +++ /dev/null @@ -1,177 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platformWin32/platformWin32.h" -#include "platform/menus/menuBar.h" -#include "platform/menus/popupMenu.h" -#include "gui/core/guiCanvas.h" -#include "windowManager/platformWindowMgr.h" -#include "windowManager/win32/win32Window.h" -#include "core/util/safeDelete.h" - -//----------------------------------------------------------------------------- -// Platform Data -//----------------------------------------------------------------------------- - -// class PlatformMenuBarData -// { -// -// }; - -//----------------------------------------------------------------------------- -// MenuBar Methods -//----------------------------------------------------------------------------- - -#ifndef TORQUE_SDL - -void MenuBar::createPlatformPopupMenuData() -{ -// mData = new PlatformMenuBarData; - - // [tom, 6/4/2007] Nothing currently needed for win32 - mData = NULL; -} - -void MenuBar::deletePlatformPopupMenuData() -{ -// SAFE_DELETE(mData); -} - -//----------------------------------------------------------------------------- - -void MenuBar::updateMenuBar(PopupMenu *menu /* = NULL */) -{ - if(! isAttachedToCanvas()) - return; - - if(menu == NULL) - { - // [tom, 6/4/2007] Kludgetastic - GuiCanvas *oldCanvas = mCanvas; - S32 pos = -1; - PopupMenu *mnu = dynamic_cast(at(0)); - if(mnu) - pos = mnu->getPosOnMenuBar(); - - removeFromCanvas(); - attachToCanvas(oldCanvas, pos); - - return; - } - - menu->removeFromMenuBar(); - SimSet::iterator itr = find(begin(), end(), menu); - if(itr == end()) - return; - - menu->attachToMenuBar(mCanvas, itr - begin()); - - Win32Window *pWindow = dynamic_cast(mCanvas->getPlatformWindow()); - if(pWindow == NULL) - return; - - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); -} - -//----------------------------------------------------------------------------- - -void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos) -{ - if(owner == NULL || isAttachedToCanvas()) - return; - - // This is set for popup menus in the onAttachToMenuBar() callback - mCanvas = owner; - - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - // Setup the native menu bar - HMENU hWindowMenu = pWindow->getMenuHandle(); - if(hWindowMenu == NULL && !Journal::IsPlaying()) - { - hWindowMenu = CreateMenu(); - if(hWindowMenu) - { - pWindow->setMenuHandle( hWindowMenu); - } - } - - // Add the items - for(S32 i = 0;i < size();++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if(mnu == NULL) - { - Con::warnf("MenuBar::attachToMenuBar - Non-PopupMenu object in set"); - continue; - } - - if(mnu->isAttachedToMenuBar()) - mnu->removeFromMenuBar(); - - mnu->attachToMenuBar(owner, pos + i); - } - - HWND hWindow = pWindow->getHWND(); - SetMenu(hWindow, hWindowMenu); - DrawMenuBar(hWindow); - -} - -void MenuBar::removeFromCanvas() -{ - if(mCanvas == NULL || ! isAttachedToCanvas()) - return; - - Win32Window *pWindow = dynamic_cast(mCanvas->getPlatformWindow()); - if(pWindow == NULL) - return; - - // Setup the native menu bar - HMENU hWindowMenu = pWindow->getMenuHandle(); - if(hWindowMenu == NULL) - return; - - // Add the items - for(S32 i = 0;i < size();++i) - { - PopupMenu *mnu = dynamic_cast(at(i)); - if(mnu == NULL) - { - Con::warnf("MenuBar::removeFromMenuBar - Non-PopupMenu object in set"); - continue; - } - - mnu->removeFromMenuBar(); - } - - HWND hWindow = pWindow->getHWND(); - SetMenu(hWindow, NULL); - DrawMenuBar(hWindow); - - mCanvas = NULL; -} - -#endif diff --git a/Engine/source/platformWin32/menus/popupMenuWin32.cpp b/Engine/source/platformWin32/menus/popupMenuWin32.cpp deleted file mode 100644 index fc3170eeb..000000000 --- a/Engine/source/platformWin32/menus/popupMenuWin32.cpp +++ /dev/null @@ -1,746 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef TORQUE_SDL - -#include "platform/menus/popupMenu.h" -#include "platformWin32/platformWin32.h" -#include "console/engineAPI.h" -#include "console/consoleTypes.h" -#include "gui/core/guiCanvas.h" -#include "windowManager/platformWindowMgr.h" -#include "windowManager/win32/win32Window.h" -#include "core/util/safeDelete.h" - -#include "sim/actionMap.h" -#include "platform/platformInput.h" - -////////////////////////////////////////////////////////////////////////// -// Platform Menu Data -////////////////////////////////////////////////////////////////////////// - -struct PlatformPopupMenuData -{ - static U32 mLastPopupMenuID; - static const U32 PopupMenuIDRange; - - HMENU mMenu; - U32 mMenuID; - U32 mLastID; - - Win32Window::AcceleratorList mAccelerators; - Win32Window::AcceleratorList mDisabledAccelerators; - - PlatformPopupMenuData() - { - mMenu = NULL; - mMenuID = mLastPopupMenuID++; - mLastID = 0; - } - - ~PlatformPopupMenuData() - { - if(mMenu) - DestroyMenu(mMenu); - } - - void insertAccelerator(EventDescriptor &desc, U32 id); - void removeAccelerator(U32 id); - void setAccelleratorEnabled(U32 id, bool enabled); -}; - -U32 PlatformPopupMenuData::mLastPopupMenuID = 0; -const U32 PlatformPopupMenuData::PopupMenuIDRange = 100; - -////////////////////////////////////////////////////////////////////////// - -void PlatformPopupMenuData::insertAccelerator(EventDescriptor &desc, U32 id) -{ - if(desc.eventType != SI_KEY) - return; - - Win32Window::AcceleratorList::iterator i; - for(i = mAccelerators.begin();i != mAccelerators.end();++i) - { - if(i->mID == id) - { - // Update existing entry - i->mDescriptor.eventType = desc.eventType; - i->mDescriptor.eventCode = desc.eventCode; - i->mDescriptor.flags = desc.flags; - return; - } - - if(i->mDescriptor.eventType == desc.eventType && i->mDescriptor.eventCode == desc.eventCode && i->mDescriptor.flags == desc.flags) - { - // Already have a matching accelerator, don't add another one - return; - } - } - - Win32Window::Accelerator accel; - accel.mDescriptor = desc; - accel.mID = id; - mAccelerators.push_back(accel); -} - -void PlatformPopupMenuData::removeAccelerator(U32 id) -{ - Win32Window::AcceleratorList::iterator i; - for(i = mAccelerators.begin();i != mAccelerators.end();++i) - { - if(i->mID == id) - { - mAccelerators.erase(i); - return; - } - } -} - -void PlatformPopupMenuData::setAccelleratorEnabled( U32 id, bool enabled ) -{ - Win32Window::AcceleratorList *src = NULL; - Win32Window::AcceleratorList *dst = NULL; - - if ( enabled ) - { - src = &mDisabledAccelerators; - dst = &mAccelerators; - } - else - { - src = &mAccelerators; - dst = &mDisabledAccelerators; - } - - Win32Window::AcceleratorList::iterator i; - for ( i = src->begin(); i != src->end(); ++i ) - { - if ( i->mID == id ) - { - Win32Window::Accelerator tmp = *i; - src->erase( i ); - dst->push_back( tmp ); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::createPlatformPopupMenuData() -{ - mData = new PlatformPopupMenuData; -} - -void PopupMenu::deletePlatformPopupMenuData() -{ - SAFE_DELETE(mData); -} -void PopupMenu::createPlatformMenu() -{ - mData->mMenu = mIsPopup ? CreatePopupMenu() : CreateMenu(); - AssertFatal(mData->mMenu, "Unable to create menu"); - - MENUINFO mi = { 0 }; - mi.cbSize = sizeof(mi); - mi.fMask = MIM_MENUDATA; - mi.dwMenuData = (ULONG_PTR)this; - SetMenuInfo(mData->mMenu, &mi); -} - -////////////////////////////////////////////////////////////////////////// -// Public Methods -////////////////////////////////////////////////////////////////////////// - -S32 PopupMenu::insertItem(S32 pos, const char *title, const char* accelerator, const char *) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return -1; - - MENUITEMINFOA mi = { 0 }; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_ID|MIIM_TYPE; - mi.wID = (mData->mMenuID * PlatformPopupMenuData::PopupMenuIDRange) + mData->mLastID + 1; - mData->mLastID++; - if(title && *title) - mi.fType = MFT_STRING; - else - mi.fType = MFT_SEPARATOR; - - char buf[1024]; - if(accelerator && *accelerator) - { - dSprintf(buf, sizeof(buf), "%s\t%s", title, accelerator); - - if(isAttached) - pWindow->removeAccelerators(mData->mAccelerators); - - // Build entry for accelerator table - EventDescriptor accelDesc; - if(ActionMap::createEventDescriptor(accelerator, &accelDesc)) - mData->insertAccelerator(accelDesc, mi.wID); - else - Con::errorf("PopupMenu::insertItem - Could not create event descriptor for accelerator \"%s\"", accelerator); - - if(isAttached) - pWindow->addAccelerators(mData->mAccelerators); - } - else - dSprintf(buf, sizeof(buf), "%s", title); - - mi.dwTypeData = (LPSTR)buf; - - if(InsertMenuItemA(mData->mMenu, pos, TRUE, &mi)) - { - if(isAttached) - { - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } - return mi.wID; - } - - return -1; -} - -S32 PopupMenu::insertSubMenu(S32 pos, const char *title, PopupMenu *submenu) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return -1; - - for(S32 i = 0;i < mSubmenus->size();i++) - { - if(submenu == (*mSubmenus)[i]) - { - Con::errorf("PopupMenu::insertSubMenu - Attempting to add submenu twice"); - return -1; - } - } - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_ID|MIIM_TYPE|MIIM_SUBMENU|MIIM_DATA; - mi.wID = (mData->mMenuID * PlatformPopupMenuData::PopupMenuIDRange) + mData->mLastID + 1; - if(title && *title) - mi.fType = MFT_STRING; - else - mi.fType = MFT_SEPARATOR; - mi.dwTypeData = (LPSTR)title; - mi.hSubMenu = submenu->mData->mMenu; - mi.dwItemData = (ULONG_PTR)submenu; - if(InsertMenuItemA(mData->mMenu, pos, TRUE, &mi)) - { - mSubmenus->addObject(submenu); - - if(isAttached) - { - pWindow->addAccelerators(submenu->mData->mAccelerators); - - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } - return mi.wID; - } - - return -1; -} - -bool PopupMenu::setItem(S32 pos, const char *title, const char* accelerator, const char *) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return false; - - // Are we out of range? - if ( pos >= getItemCount() ) - return false; - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_TYPE; - - if(title && *title) - mi.fType = MFT_STRING; - else - mi.fType = MFT_SEPARATOR; - - char buf[1024]; - if(accelerator && *accelerator) - { - dSprintf(buf, sizeof(buf), "%s\t%s", title, accelerator); - - if(isAttached) - pWindow->removeAccelerators(mData->mAccelerators); - - // Build entry for accelerator table - EventDescriptor accelDesc; - if(ActionMap::createEventDescriptor(accelerator, &accelDesc)) - mData->insertAccelerator(accelDesc, pos); - else - Con::errorf("PopupMenu::setItem - Could not create event descriptor for accelerator \"%s\"", accelerator); - - if(isAttached) - pWindow->addAccelerators(mData->mAccelerators); - } - else - dSprintf(buf, sizeof(buf), "%s", title); - - mi.dwTypeData = (LPSTR)buf; - - if(SetMenuItemInfoA(mData->mMenu, pos, TRUE, &mi)) - { - if(isAttached) - { - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } - - return true; - } - - return false; -} - -void PopupMenu::removeItem(S32 itemPos) -{ - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - bool isAttached = isAttachedToMenuBar(); - if(isAttached && pWindow == NULL) - return; - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_DATA|MIIM_ID; - if(GetMenuItemInfoA(mData->mMenu, itemPos, TRUE, &mi)) - { - bool submenu = false; - - // Update list of submenus if this is a submenu - if(mi.fMask & MIIM_DATA) - { - PopupMenu *mnu = (PopupMenu *)mi.dwItemData; - if( mnu != NULL ) - { - if(isAttached) - pWindow->removeAccelerators(mnu->mData->mAccelerators); - mSubmenus->removeObject(mnu); - - submenu = true; - } - } - - if(! submenu) - { - // Update accelerators if this has an accelerator and wasn't a sub menu - for(S32 i = 0;i < mData->mAccelerators.size();++i) - { - if(mData->mAccelerators[i].mID == mi.wID) - { - if(isAttached) - pWindow->removeAccelerators(mData->mAccelerators); - - mData->mAccelerators.erase(i); - - if(isAttached) - pWindow->addAccelerators(mData->mAccelerators); - - break; - } - } - } - } - else - return; - - RemoveMenu(mData->mMenu, itemPos, MF_BYPOSITION); - - if(isAttached) - { - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - } -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::enableItem( S32 pos, bool enable ) -{ - U32 flags = enable ? MF_ENABLED : MF_GRAYED; - EnableMenuItem( mData->mMenu, pos, MF_BYPOSITION|flags ); - - // Update accelerators. - - // NOTE: This really DOES need to happen. A disabled menu item - // should not still have an accelerator mapped to it. - // - // Unfortunately, the editors currently only set menu items - // enabled/disabled when the menu itself is selected which means our - // accelerators would be out of synch. - - /* - Win32Window *pWindow = mCanvas ? dynamic_cast( mCanvas->getPlatformWindow() ) : NULL; - bool isAttached = isAttachedToMenuBar(); - if ( isAttached && pWindow == NULL ) - return; - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_DATA|MIIM_ID; - if ( !GetMenuItemInfoA( mData->mMenu, pos, TRUE, &mi) ) - return; - - if ( isAttached ) - pWindow->removeAccelerators( mData->mAccelerators ); - - mData->setAccelleratorEnabled( mi.wID, enable ); - - if ( isAttached ) - pWindow->addAccelerators( mData->mAccelerators ); - */ -} - -void PopupMenu::checkItem(S32 pos, bool checked) -{ -// U32 flags = checked ? MF_CHECKED : MF_UNCHECKED; -// CheckMenuItem(mData->mMenu, pos, MF_BYPOSITION|flags); - - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_STATE; - mi.fState = checked ? MFS_CHECKED : MFS_UNCHECKED; - SetMenuItemInfoA(mData->mMenu, pos, TRUE, &mi); -} - -void PopupMenu::checkRadioItem(S32 firstPos, S32 lastPos, S32 checkPos) -{ - CheckMenuRadioItem(mData->mMenu, firstPos, lastPos, checkPos, MF_BYPOSITION); -} - -bool PopupMenu::isItemChecked(S32 pos) -{ - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_STATE; - if(GetMenuItemInfoA(mData->mMenu, pos, TRUE, &mi) && (mi.fState & MFS_CHECKED)) - return true; - return false; -} - -U32 PopupMenu::getItemCount() -{ - return GetMenuItemCount( mData->mMenu ); -} - -////////////////////////////////////////////////////////////////////////// - -bool PopupMenu::canHandleID(U32 id) -{ - for(S32 i = 0;i < mSubmenus->size();i++) - { - PopupMenu *subM = dynamic_cast((*mSubmenus)[i]); - if(subM == NULL) - continue; - - if(subM->canHandleID(id)) - return true; - } - - if(id >= mData->mMenuID * PlatformPopupMenuData::PopupMenuIDRange && - id < (mData->mMenuID+1) * PlatformPopupMenuData::PopupMenuIDRange) - { - return true; - } - - return false; -} - -bool PopupMenu::handleSelect(U32 command, const char *text /* = NULL */) -{ - // [tom, 8/20/2006] Pass off to a sub menu if it's for them - for(S32 i = 0;i < mSubmenus->size();i++) - { - PopupMenu *subM = dynamic_cast((*mSubmenus)[i]); - if(subM == NULL) - continue; - - if(subM->canHandleID(command)) - { - return subM->handleSelect(command, text); - } - } - - // [tom, 8/21/2006] Cheesey hack to find the position based on ID - char buf[512]; - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.dwTypeData = NULL; - - S32 numItems = GetMenuItemCount(mData->mMenu); - S32 pos = -1; - for(S32 i = 0;i < numItems;i++) - { - mi.fMask = MIIM_ID|MIIM_STRING|MIIM_STATE; - if(GetMenuItemInfoA(mData->mMenu, i, TRUE, &mi)) - { - if(mi.wID == command) - { - if(text == NULL) - { - mi.dwTypeData = buf; - mi.cch++; - GetMenuItemInfoA(mData->mMenu, i, TRUE, &mi); - - // [tom, 5/11/2007] Don't do anything if the menu item is disabled - if(mi.fState & MFS_DISABLED) - return false; - - text = StringTable->insert(mi.dwTypeData); - } - pos = i; - break; - } - } - } - - if(pos == -1) - { - Con::errorf("PopupMenu::handleSelect - Could not find menu item position for ID %d ... this shouldn't happen!", command); - return false; - } - - // [tom, 8/20/2006] Wasn't handled by a submenu, pass off to script - return dAtob(Con::executef(this, "onSelectItem", Con::getIntArg(pos), text ? text : "")); -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */) -{ - if( owner == NULL ) - { - Con::warnf("PopupMenu::showPopup - Invalid canvas supplied!"); - return; - } - - // [tom, 6/4/2007] showPopup() blocks until the menu is closed by the user, - // so the canvas pointer is not needed beyond the scope of this function - // when working with context menus. Setting mCanvas here will cause undesired - // behavior in relation to the menu bar. - - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - HWND hWindow = pWindow->getHWND(); - POINT p; - if(x == -1 && y == -1) - GetCursorPos(&p); - else - { - p.x = x; - p.y = y; - ClientToScreen(hWindow, &p); - } - - winState.renderThreadBlocked = true; - U32 opt = (int)TrackPopupMenu(mData->mMenu, TPM_NONOTIFY|TPM_RETURNCMD, p.x, p.y, 0, hWindow, NULL); - if(opt > 0) - handleSelect(opt, NULL); - winState.renderThreadBlocked = false; -} - -////////////////////////////////////////////////////////////////////////// - -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos, const char *title) -{ - if(owner == NULL || isAttachedToMenuBar()) - return; - - // This is set for sub-menus in the onAttachToMenuBar() callback - mCanvas = owner; - - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - HMENU hWindowMenu = pWindow->getMenuHandle(); - if(hWindowMenu == NULL) - { - hWindowMenu = CreateMenu(); - if(hWindowMenu) - { - pWindow->setMenuHandle( hWindowMenu); - } - } - - MENUITEMINFOA mii; - - mii.cbSize = sizeof(MENUITEMINFOA); - - mii.fMask = MIIM_STRING|MIIM_DATA; - mii.dwTypeData = (LPSTR)title; - mii.fMask |= MIIM_ID; - mii.wID = mData->mMenuID; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = mData->mMenu; - mii.dwItemData = (ULONG_PTR)this; - - InsertMenuItemA(hWindowMenu, pos, TRUE, &mii); - - HWND hWindow = pWindow->getHWND(); - DrawMenuBar(hWindow); - - pWindow->addAccelerators(mData->mAccelerators); - - // Add accelerators for sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *submenu = dynamic_cast(*i); - if(submenu == NULL) - continue; - - pWindow->addAccelerators(submenu->mData->mAccelerators); - } - - onAttachToMenuBar(owner, pos, title); -} - -// New version of above for use by MenuBar class. Do not use yet. -void PopupMenu::attachToMenuBar(GuiCanvas *owner, S32 pos) -{ - Win32Window *pWindow = dynamic_cast(owner->getPlatformWindow()); - if(pWindow == NULL) - return; - - //When playing a journal, the system menu is not actually shown - if (Journal::IsPlaying()) - { - onAttachToMenuBar(owner, pos, mBarTitle); - return; - } - - HMENU hWindowMenu = pWindow->getMenuHandle(); - - MENUITEMINFOA mii; - - mii.cbSize = sizeof(MENUITEMINFOA); - - mii.fMask = MIIM_STRING|MIIM_DATA; - mii.dwTypeData = (LPSTR)mBarTitle; - mii.fMask |= MIIM_ID; - mii.wID = mData->mMenuID; - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = mData->mMenu; - mii.dwItemData = (ULONG_PTR)this; - - InsertMenuItemA(hWindowMenu, pos, TRUE, &mii); - - pWindow->addAccelerators(mData->mAccelerators); - - // Add accelerators for sub menus (have to do this here as it's platform specific) - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *submenu = dynamic_cast(*i); - if(submenu == NULL) - continue; - - pWindow->addAccelerators(submenu->mData->mAccelerators); - } - - onAttachToMenuBar(owner, pos, mBarTitle); -} - -void PopupMenu::removeFromMenuBar() -{ - S32 pos = getPosOnMenuBar(); - if(pos == -1) - return; - - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - if(pWindow == NULL) - return; - - HMENU hMenuHandle = pWindow->getMenuHandle(); - if(!hMenuHandle) - return; - - RemoveMenu(hMenuHandle, pos, MF_BYPOSITION); - - HWND hWindow = pWindow->getHWND(); - - DrawMenuBar(hWindow); - - pWindow->removeAccelerators(mData->mAccelerators); - - // Remove accelerators for sub menus - for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) - { - PopupMenu *submenu = dynamic_cast(*i); - if(submenu == NULL) - continue; - - pWindow->removeAccelerators(submenu->mData->mAccelerators); - } - - onRemoveFromMenuBar(mCanvas); -} - -S32 PopupMenu::getPosOnMenuBar() -{ - if(mCanvas == NULL) - return -1; - - Win32Window *pWindow = mCanvas ? dynamic_cast(mCanvas->getPlatformWindow()) : NULL; - if(pWindow == NULL) - return -1; - - HMENU hMenuHandle = pWindow->getMenuHandle(); - S32 numItems = GetMenuItemCount(hMenuHandle); - S32 pos = -1; - for(S32 i = 0;i < numItems;i++) - { - MENUITEMINFOA mi; - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_DATA; - if(GetMenuItemInfoA(hMenuHandle, i, TRUE, &mi)) - { - if(mi.fMask & MIIM_DATA) - { - PopupMenu *mnu = (PopupMenu *)mi.dwItemData; - if(mnu == this) - { - pos = i; - break; - } - } - } - } - - return pos; -} - -#endif \ No newline at end of file diff --git a/Engine/source/windowManager/sdl/sdlWindow.cpp b/Engine/source/windowManager/sdl/sdlWindow.cpp index a48e3743d..149825b98 100644 --- a/Engine/source/windowManager/sdl/sdlWindow.cpp +++ b/Engine/source/windowManager/sdl/sdlWindow.cpp @@ -27,7 +27,6 @@ #include "windowManager/sdl/sdlWindowMgr.h" #include "windowManager/sdl/sdlCursorController.h" #include "platformSDL/sdlInput.h" -#include "platform/menus/popupMenu.h" #include "platform/platformInput.h" #include "gfx/gfxDevice.h" diff --git a/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs index 696b98975..f2de82d96 100644 --- a/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs +++ b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs @@ -35,5 +35,4 @@ exec("./GuiEaseEditDlg.ed.cs"); exec("./guiObjectInspector.ed.cs"); exec("./uvEditor.ed.gui"); exec("./objectSelection.ed.cs"); -exec("./guiPlatformGenericMenubar.ed.cs"); exec("./postFxManager.gui"); \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs deleted file mode 100644 index 089b0b8fa..000000000 --- a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs +++ /dev/null @@ -1,19 +0,0 @@ -if(isClass(GuiPlatformGenericMenuBar)) -{ - exec("./guiPlatformGenericMenubar.ed.gui"); -} -else -{ - %guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiControl() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; - }; -} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui deleted file mode 100644 index 8d2cbcd74..000000000 --- a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui +++ /dev/null @@ -1,14 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -%guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiPlatformGenericMenuBar() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; -}; -//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs index 1305ae170..83317d0d8 100644 --- a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs @@ -66,9 +66,13 @@ function GuiEditCanvas::onCreateMenu(%this) } // Menu bar - %this.menuBar = new MenuBar() + %this.menuBar = new GuiMenuBar(GuiEditorMenubar) { dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; new PopupMenu() { diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs index bc1905292..535d00880 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -2017,7 +2017,7 @@ function EWorldEditor::syncGui( %this ) %this.syncToolPalette(); EditorTree.update(); - Editor.getUndoManager().updateUndoMenu( EditorGui.menuBar-->EditMenu ); + Editor.getUndoManager().updateUndoMenu( EditorGui.findMenu("Edit") ); EditorGuiStatusBar.setSelectionObjectsByCount( %this.getSelectionSize() ); EWTreeWindow-->LockSelection.setStateOn( %this.getSelectionLockCount() > 0 ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs index dbe978cab..b225d3534 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs @@ -110,9 +110,13 @@ function EditorGui::buildMenus(%this) }; // Menu bar - %this.menuBar = new MenuBar(WorldEditorMenubar) + %this.menuBar = new GuiMenuBar(WorldEditorMenubar) { dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; }; // File Menu @@ -158,7 +162,7 @@ function EditorGui::buildMenus(%this) %fileMenu.appendItem("Exit Level" TAB "" TAB "EditorExitMission();"); %fileMenu.appendItem("Quit" TAB %quitShortcut TAB "EditorQuitGame();"); - %this.menuBar.insert(%fileMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%fileMenu); // Edit Menu %editMenu = new PopupMenu() @@ -187,7 +191,7 @@ function EditorGui::buildMenus(%this) item[15] = "Game Options..." TAB "" TAB "Canvas.pushDialog(optionsDlg);"; item[16] = "PostEffect Manager" TAB "" TAB "Canvas.pushDialog(PostFXManager);"; }; - %this.menuBar.insert(%editMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%editMenu); // View Menu %viewMenu = new PopupMenu() @@ -201,7 +205,7 @@ function EditorGui::buildMenus(%this) item[ 0 ] = "Visibility Layers" TAB "Alt V" TAB "VisibilityDropdownToggle();"; item[ 1 ] = "Show Grid in Ortho Views" TAB %cmdCtrl @ "-Shift-Alt G" TAB "EditorGui.toggleOrthoGrid();"; }; - %this.menuBar.insert(%viewMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%viewMenu); // Camera Menu %cameraMenu = new PopupMenu() @@ -229,7 +233,7 @@ function EditorGui::buildMenus(%this) Item[15] = "Manage Bookmarks..." TAB "Ctrl-Shift B" TAB "EditorGui.toggleCameraBookmarkWindow();"; item[16] = "Jump to Bookmark" TAB %this.cameraBookmarksMenu; }; - %this.menuBar.insert(%cameraMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%cameraMenu); // Editors Menu %editorsMenu = new PopupMenu() @@ -246,7 +250,7 @@ function EditorGui::buildMenus(%this) //item[4] = "Terrain Painter" TAB "F4" TAB TerrainPainterPlugin; //item[5] = "-"; }; - %this.menuBar.insert(%editorsMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%editorsMenu); // Lighting Menu %lightingMenu = new PopupMenu() @@ -263,7 +267,7 @@ function EditorGui::buildMenus(%this) // NOTE: The light managers will be inserted as the // last menu items in EditorLightingMenu::onAdd(). }; - %this.menuBar.insert(%lightingMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%lightingMenu); // Tools Menu %toolsMenu = new PopupMenu() @@ -278,7 +282,7 @@ function EditorGui::buildMenus(%this) item[2] = "Torque SimView" TAB "" TAB "tree();"; item[3] = "Make Selected a Mesh" TAB "" TAB "makeSelectedAMesh();"; }; - %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%toolsMenu); // Help Menu %helpMenu = new PopupMenu() @@ -293,7 +297,7 @@ function EditorGui::buildMenus(%this) item[2] = "Offline Reference Guide..." TAB "" TAB "shellexecute(EWorldEditor.documentationReference);"; item[3] = "Torque 3D Forums..." TAB "" TAB "gotoWebPage(EWorldEditor.forumURL);"; }; - %this.menuBar.insert(%helpMenu, %this.menuBar.getCount()); + %this.menuBar.insert(%helpMenu); // Menus that are added/removed dynamically (temporary) @@ -398,9 +402,9 @@ function EditorGui::setMenuDefaultState(%this) if(! isObject(%this.menuBar)) return 0; - for(%i = 0;%i < %this.menuBar.getCount();%i++) + for(%i = 0;%i < %this.menuBar.getMenuCount();%i++) { - %menu = %this.menuBar.getObject(%i); + %menu = %this.menuBar.getMenu(%i); %menu.setupDefaultState(); } @@ -414,9 +418,10 @@ function EditorGui::findMenu(%this, %name) if(! isObject(%this.menuBar)) return 0; - for(%i = 0;%i < %this.menuBar.getCount();%i++) + + for(%i = 0; %i < %this.menuBar.getMenuCount(); %i++) { - %menu = %this.menuBar.getObject(%i); + %menu = %this.menuBar.getMenu(%i); if(%name $= %menu.barTitle) return %menu; diff --git a/Templates/Full/game/tools/gui/guiDialogs.ed.cs b/Templates/Full/game/tools/gui/guiDialogs.ed.cs index db09e8570..dc6b4e3a3 100644 --- a/Templates/Full/game/tools/gui/guiDialogs.ed.cs +++ b/Templates/Full/game/tools/gui/guiDialogs.ed.cs @@ -35,4 +35,3 @@ exec("./GuiEaseEditDlg.ed.cs"); exec("./guiObjectInspector.ed.cs"); exec("./uvEditor.ed.gui"); exec("./objectSelection.ed.cs"); -exec("./guiPlatformGenericMenubar.ed.cs"); diff --git a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.cs b/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.cs deleted file mode 100644 index 089b0b8fa..000000000 --- a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.cs +++ /dev/null @@ -1,19 +0,0 @@ -if(isClass(GuiPlatformGenericMenuBar)) -{ - exec("./guiPlatformGenericMenubar.ed.gui"); -} -else -{ - %guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiControl() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; - }; -} \ No newline at end of file diff --git a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.gui b/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.gui deleted file mode 100644 index 8d2cbcd74..000000000 --- a/Templates/Full/game/tools/gui/guiPlatformGenericMenubar.ed.gui +++ /dev/null @@ -1,14 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -%guiContent = new GuiControl(PlatformGenericMenubar) { - profile = "GuiModelessDialogProfile"; - - new GuiPlatformGenericMenuBar() - { - internalName = "menubar"; - extent = "1024 20"; - minExtent = "320 20"; - horizSizing = "width"; - profile = "GuiMenuBarProfile"; - }; -}; -//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs b/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs index 1305ae170..83317d0d8 100644 --- a/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs +++ b/Templates/Full/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs @@ -66,9 +66,13 @@ function GuiEditCanvas::onCreateMenu(%this) } // Menu bar - %this.menuBar = new MenuBar() + %this.menuBar = new GuiMenuBar(GuiEditorMenubar) { dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; new PopupMenu() { diff --git a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs index bc1905292..b225d3534 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -20,2813 +20,412 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -function EditorGui::init(%this) +function EditorGui::buildMenus(%this) { - EWorldEditor.isDirty = false; - ETerrainEditor.isDirty = false; - ETerrainEditor.isMissionDirty = false; - - if( %this.isInitialized ) + if(isObject(%this.menuBar)) return; - - %this.readWorldEditorSettings(); - - $SelectedOperation = -1; - $NextOperationId = 1; - $HeightfieldDirtyRow = -1; - - if( !isObject( %this-->ToolsPaletteWindow ) ) - { - // Load Creator/Inspector GUI - exec("~/worldEditor/gui/ToolsPaletteGroups/init.cs"); - exec("~/worldEditor/gui/ToolsPaletteWindow.ed.gui"); - - if( isObject( EWToolsPaletteWindow ) ) - { - %this.add( EWToolsPaletteWindow ); - EWToolsPaletteWindow.init(); - EWToolsPaletteWindow.setVisible( false ); - } + + //set up %cmdctrl variable so that it matches OS standards + if( $platform $= "macos" ) + { + %cmdCtrl = "Cmd"; + %menuCmdCtrl = "Cmd"; + %quitShortcut = "Cmd Q"; + %redoShortcut = "Cmd-Shift Z"; } - - if( !isObject( %this-->TreeWindow ) ) - { - // Load Creator/Inspector GUI - exec("~/worldEditor/gui/WorldEditorTreeWindow.ed.gui"); - if( isObject( EWTreeWindow ) ) - { - %this.add( EWTreeWindow ); - EWTreeWindow-->EditorTree.selectPage( 0 ); - EWTreeWindow.setVisible( false ); - } - } - - if( !isObject( %this-->InspectorWindow ) ) - { - // Load Creator/Inspector GUI - exec("~/worldEditor/gui/WorldEditorInspectorWindow.ed.gui"); - //EWInspectorWindow.resize(getWord(EWInspectorWindow.Position, 0), getWord(EWInspectorWindow.Position, 1), getWord(EWInspectorWindow.extent, 0), getWord(EWInspectorWindow.extent, 1)); - if( isObject( EWInspectorWindow ) ) - { - %this.add( EWInspectorWindow ); - EWInspectorWindow.setVisible( false ); - } - } - - if( !isObject( %this-->WorldEditorToolbar ) ) - { - // Load Creator/Inspector GUI - exec("~/worldEditor/gui/WorldEditorToolbar.ed.gui"); - if( isObject( EWorldEditorToolbar ) ) - { - %this.add( EWorldEditorToolbar ); - EWorldEditorToolbar.setVisible( false ); - } - } - - if ( !isObject( %this-->TerrainEditToolbar ) ) - { - // Load Terrain Edit GUI - exec("~/worldEditor/gui/TerrainEditToolbar.ed.gui"); - if( isObject( EWTerrainEditToolbar ) ) - { - %this.add( EWTerrainEditToolbar ); - EWTerrainEditToolbar.setVisible( false ); - } - } - - if( !isObject( %this-->TerrainPainter ) ) - { - // Load Terrain Painter GUI - exec("~/worldEditor/gui/TerrainPainterWindow.ed.gui"); - if( isObject( %guiContent ) ){ - %this.add( %guiContent->TerrainPainter ); - %this.add( %guiContent->TerrainPainterPreview ); - } - - exec("~/worldEditor/gui/guiTerrainMaterialDlg.ed.gui"); - exec("~/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui"); - } - if ( !isObject( %this-->TerrainPainterToolbar) ) - { - // Load Terrain Edit GUI - exec("~/worldEditor/gui/TerrainPainterToolbar.ed.gui"); - if( isObject( EWTerrainPainterToolbar ) ) - { - %this.add( EWTerrainPainterToolbar ); - EWTerrainPainterToolbar.setVisible( false ); - } - } - - if( !isObject( %this-->ToolsToolbar ) ) - { - // Load Creator/Inspector GUI - exec("~/worldEditor/gui/ToolsToolbar.ed.gui"); - if( isObject( EWToolsToolbar ) ) - { - %this.add( EWToolsToolbar ); - EWToolsToolbar.setVisible( true ); - - } - } - - // Visibility Layer Window - if( !isObject( %this-->VisibilityLayerWindow ) ) - { - %this.add( EVisibility ); - EVisibility.setVisible(false); - EVisibilityTabBook.selectPage(0); - } - - // Editor Settings Window - if( !isObject( %this-->EditorSettingsWindow ) ) - { - exec("~/worldEditor/gui/EditorSettingsWindow.ed.gui"); - exec("~/worldEditor/scripts/editorSettingsWindow.ed.cs"); - %this.add( ESettingsWindow ); - ESettingsWindow.setVisible(false); - - // Start the standard settings tabs pages - exec( "~/worldEditor/gui/GeneralSettingsTab.ed.gui" ); - ESettingsWindow.addTabPage( EGeneralSettingsPage ); - exec("~/worldEditor/gui/ObjectEditorSettingsTab.ed.gui"); - ESettingsWindow.addTabPage( EObjectEditorSettingsPage ); - exec("~/worldEditor/gui/AxisGizmoSettingsTab.ed.gui"); - ESettingsWindow.addTabPage( EAxisGizmoSettingsPage ); - exec("~/worldEditor/gui/TerrainEditorSettingsTab.ed.gui"); - ESettingsWindow.addTabPage( ETerrainEditorSettingsPage ); - exec("~/worldEditor/gui/CameraSettingsTab.ed.gui"); - ESettingsWindow.addTabPage( ECameraSettingsPage ); - } - - // Object Snap Options Window - if( !isObject( %this-->SnapOptionsWindow ) ) - { - exec("~/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui"); - exec("~/worldEditor/scripts/objectSnapOptions.ed.cs"); - %this.add( ESnapOptions ); - ESnapOptions.setVisible(false); - ESnapOptionsTabBook.selectPage(0); - } - - // Transform Selection Window - if( !isObject( %this-->TransformSelectionWindow ) ) - { - exec("~/worldEditor/gui/TransformSelectionWindow.ed.gui"); - exec("~/worldEditor/scripts/transformSelection.ed.cs"); - %this.add( ETransformSelection ); - ETransformSelection.setVisible(false); - } - - // Manage Bookmarks Window - if( !isObject( %this-->ManageBookmarksWindow ) ) - { - %this.add( EManageBookmarks ); - EManageBookmarks.setVisible(false); - } - - // Manage SFXParameters Window - if( !isObject( %this-->ManageSFXParametersWindow ) ) - { - %this.add( EManageSFXParameters ); - EManageSFXParameters.setVisible( false ); - } - - // Select Objects Window - if( !isObject( %this->SelectObjectsWindow ) ) - { - %this.add( ESelectObjectsWindow ); - ESelectObjectsWindow.setVisible( false ); - } - - EWorldEditor.init(); - ETerrainEditor.init(); - - //Creator.init(); - EWCreatorWindow.init(); - ObjectBuilderGui.init(); - - %this.setMenuDefaultState(); - - EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/player"); - - /* - EWorldEditorCameraSpeed.clear(); - EWorldEditorCameraSpeed.add("Slowest - Camera 1",0); - EWorldEditorCameraSpeed.add("Slow - Camera 2",1); - EWorldEditorCameraSpeed.add("Slower - Camera 3",2); - EWorldEditorCameraSpeed.add("Normal - Camera 4",3); - EWorldEditorCameraSpeed.add("Faster - Camera 5",4); - EWorldEditorCameraSpeed.add("Fast - Camera 6",5); - EWorldEditorCameraSpeed.add("Fastest - Camera 7",6); - EWorldEditorCameraSpeed.setSelected(3); - */ - - EWorldEditorAlignPopup.clear(); - EWorldEditorAlignPopup.add("World",0); - EWorldEditorAlignPopup.add("Object",1); - EWorldEditorAlignPopup.setSelected(0); - - - // sync camera gui - EditorGui.syncCameraGui(); - - // this will brind CameraTypesDropdown to front so that it goes over the menubar - EditorGui.pushToBack(CameraTypesDropdown); - EditorGui.pushToBack(VisibilityDropdown); - - // dropdowns out so that they display correctly in editor gui - objectTransformDropdown.parentGroup = editorGui; - objectCenterDropdown.parentGroup = editorGui; - objectSnapDropdown.parentGroup = editorGui; - - // make sure to show the default world editor guis - EditorGui.bringToFront( EWorldEditor ); - EWorldEditor.setVisible( false ); - - // Call the startup callback on the editor plugins. - for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) - { - %obj = EditorPluginSet.getObject( %i ); - %obj.onWorldEditorStartup(); - } - - // With everything loaded, start up the settings window - ESettingsWindow.startup(); - - // Start up initial editor plugin. - - %initialEditor = %this.currentEditor; // Read from prefs. - %this.currentEditor = ""; - - if( %initialEditor $= "" ) - %initialEditor = "WorldEditorInspectorPlugin"; - %this.setEditor( %initialEditor, true, true ); - - // Done. - - %this.isInitialized = true; -} - -//------------------------------------------------------------------------------ -// Editor Gui's interactions with Camera Settings - -function EditorGui::setupDefaultCameraSettings( %this ) -{ - EditorSettings.beginGroup( "LevelInformation/levels/" @ %this.levelName ); - - EditorSettings.setDefaultValue( "cameraSpeedMin", "5" ); - EditorSettings.setDefaultValue( "cameraSpeedMax", "200" ); - - EditorSettings.endGroup(); -} - -function EditorGui::readCameraSettings( %this, %levelName ) -{ - if( %levelName !$= %this.levelName ) - return; - - EditorCameraSpeedOptions.setupGuiControls(); -} - -function EditorGui::writeCameraSettings( %this ) -{ - EditorSettings.beginGroup( "LevelInformation/levels/" @ %this.levelName ); - - EditorSettings.setValue( "cameraSpeed", $Camera::movementSpeed ); - - EditorSettings.endGroup(); -} - -//------------------------------------------------------------------------------ - -function EditorGui::shutdown( %this ) -{ - // Store settings. - %this.writeWorldEditorSettings(); - - // Deactivate current editor. - %this.setEditor( "" ); - - // Call the shutdown callback on the editor plugins. - foreach( %plugin in EditorPluginSet ) - %plugin.onWorldEditorShutdown(); -} - -/// This is used to add an editor to the Editors menu which -/// will take over the default world editor window. -function EditorGui::addToEditorsMenu( %this, %displayName, %accel, %newPlugin ) -{ - %windowMenu = %this.findMenu( "Editors" ); - %count = %windowMenu.getItemCount(); - - - %alreadyExists = false; - for ( %i = 0; %i < %count; %i++ ) - { - %existingPlugins = getField(%windowMenu.Item[%i], 2); - - if(%newPlugin $= %existingPlugins) - %alreadyExists = true; - } - - if( %accel $= "" && %count < 9 ) - %accel = "F" @ %count + 1; else - %accel = ""; - - if(!%alreadyExists) - %windowMenu.addItem( %count, %displayName TAB %accel TAB %newPlugin ); - - return %accel; -} - -function EditorGui::addToToolsToolbar( %this, %pluginName, %internalName, %bitmap, %tooltip ) -{ - %count = ToolsToolbarArray.getCount(); - - %alreadyExists = false; - for ( %i = 0; %i < %count; %i++ ) - { - %existingInternalName = ToolsToolbarArray.getObject(%i).getFieldValue("internalName"); - - if(%internalName $= %existingInternalName) - { - %alreadyExists = true; - break; - } - } - - if(!%alreadyExists) { - %button = new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - internalName = %internalName; - Enabled = "1"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "180 0"; - Extent = "25 19"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "EditorGui.setEditor(" @ %pluginName @ ");"; - tooltipprofile = "ToolsGuiToolTipProfile"; - ToolTip = %tooltip; - hovertime = "750"; - bitmap = %bitmap; - buttonType = "RadioButton"; - groupNum = "0"; - useMouseEvents = "0"; + %cmdCtrl = "Ctrl"; + %menuCmdCtrl = "Alt"; + %quitShortcut = "Alt F4"; + %redoShortcut = "Ctrl Y"; + } + + // Sub menus (temporary, until MenuBuilder gets updated) + // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState. + // The new min/max for the editor camera speed range can be set in each level's levelInfo object. + if(!isObject(EditorCameraSpeedOptions)) + { + %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions) + { + superClass = "MenuBuilder"; + class = "EditorCameraSpeedMenu"; + + item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5"; + item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35"; + item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70"; + item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100"; + item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130"; + item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165"; + item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200"; }; - ToolsToolbarArray.add(%button); - EWToolsToolbar.setExtent((25 + 8) * (%count + 1) + 12 SPC "33"); } -} - -//----------------------------------------------------------------------------- - -function EditorGui::setDisplayType( %this, %type ) -{ - %gui = %this.currentEditor.editorGui; - if( !isObject( %gui ) ) - return; - - %this.viewTypeMenu.checkRadioItem( 0, 7, %type ); - - // Store the current camera rotation so we can restore it correctly when - // switching back to perspective view - if ( %gui.getDisplayType() == $EditTSCtrl::DisplayTypePerspective ) - %this.lastPerspectiveCamRotation = LocalClientConnection.camera.getRotation(); - - %gui.setDisplayType( %type ); - - if ( %gui.getDisplayType() == $EditTSCtrl::DisplayTypePerspective ) - LocalClientConnection.camera.setRotation( %this.lastPerspectiveCamRotation ); - - %this.currentDisplayType = %type; -} - -//----------------------------------------------------------------------------- - -function EditorGui::setEditor( %this, %newEditor, %dontActivate ) -{ - if ( isObject( %this.currentEditor ) ) + if(!isObject(EditorFreeCameraTypeOptions)) { - if( isObject( %newEditor ) && %this.currentEditor.getId() == %newEditor.getId() ) - return; - - if( %this.currentEditor.isActivated ) - %this.currentEditor.onDeactivated(); + %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorFreeCameraTypeMenu"; - if( isObject( %this.currentEditor.editorGui ) ) - %this.currentOrthoFOV = %this.currentEditor.editorGui.getOrthoFOV(); + item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; + Item[2] = "-"; + item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; + item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; + }; } - - if( !isObject( %newEditor ) ) + if(!isObject(EditorPlayerCameraTypeOptions)) { - %this.currentEditor = ""; - return; - } - - // If we have a special set editor function, run that instead - if( %newEditor.isMethod( "setEditorFunction" ) ) - { - if( %newEditor.setEditorFunction() ) + %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions) { - %this.syncEditor( %newEditor ); - %this.currentEditor = %newEditor; + superClass = "MenuBuilder"; + class = "EditorPlayerCameraTypeMenu"; - if (!%dontActivate) - %this.currentEditor.onActivated(); - } - else + Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; + Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; + }; + } + if(!isObject(EditorCameraBookmarks)) + { + %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks) { - // if were falling back and were the same editor, why are we going to just shove ourself - // into the editor position again? opt for a fallback - if( !isObject( %this.currentEditor ) ) - %this.currentEditor = "WorldEditorInspectorPlugin"; - else if( %this.currentEditor.getId() == %newEditor.getId() ) - %this.currentEditor = "WorldEditorInspectorPlugin"; - - %this.syncEditor( %this.currentEditor, true ); + superClass = "MenuBuilder"; + class = "EditorCameraBookmarksMenu"; - if( !%dontActivate ) - %this.currentEditor.onActivated(); - } + //item[0] = "None"; + }; } - else - { - %this.syncEditor( %newEditor ); - %this.currentEditor = %newEditor; - - if( !%dontActivate ) - %this.currentEditor.onActivated(); - } - - // Sync display type. - - %gui = %this.currentEditor.editorGui; - if( isObject( %gui ) ) - { - %gui.setDisplayType( %this.currentDisplayType ); - %gui.setOrthoFOV( %this.currentOrthoFOV ); - EditorGui.syncCameraGui(); - } -} - -function EditorGui::syncEditor( %this, %newEditor, %newEditorFailed ) -{ - // Sync with menu bar - %menu = %this.findMenu( "Editors" ); - %count = %menu.getItemCount(); - for ( %i = 0; %i < %count; %i++ ) - { - %pluginObj = getField( %menu.item[%i], 2 ); - if ( %pluginObj $= %newEditor ) - { - %menu.checkRadioItem( 0, %count, %i ); - break; - } - } - - // In order to hook up a palette, the word Palette must be able to be - // switched out in order to read correctly, if not, no palette will be used - %paletteName = strreplace(%newEditor, "Plugin", "Palette"); - - // Sync with ToolsToolbar - for ( %i = 0; %i < ToolsToolbarArray.getCount(); %i++ ) - { - %toolbarButton = ToolsToolbarArray.getObject(%i).internalName; - if( %paletteName $= %toolbarButton ) - { - ToolsToolbarArray.getObject(%i).setStateOn(1); - break; - } - } - - // Handles quit game and gui editor changes in wierd scenarios - if( %newEditorFailed && EWToolsToolbar.isDynamic ) - { - if( EWToolsToolbar.isClosed ) - EWToolsToolbar.reset(); - EWToolsToolbar.toggleSize(); - } - - // Toggle the editor specific palette; we define special cases here - switch$ ( %paletteName ) - { - case "MaterialEditorPalette": - %paletteName = "WorldEditorInspectorPalette"; - case "DatablockEditorPalette": - %paletteName = "WorldEditorInspectorPalette"; - case "ParticleEditorPalette": - %paletteName = "WorldEditorInspectorPalette"; - } - - %this-->ToolsPaletteWindow.togglePalette(%paletteName); -} - -function EditorGui::onWake( %this ) -{ - EHWorldEditor.setStateOn( 1 ); - - // Notify the editor plugins that the editor has started. - - foreach( %plugin in EditorPluginSet ) - %plugin.onEditorWake(); - - // Push the ActionMaps in the order that we want to have them - // before activating an editor plugin, so that if the plugin - // installs an ActionMap, it will be highest on the stack. - - MoveMap.push(); - EditorMap.push(); - - // Active the current editor plugin. - - if( !%this.currentEditor.isActivated ) - %this.currentEditor.onActivated(); - - %slashPos = 0; - while( strpos( $Server::MissionFile, "/", %slashPos ) != -1 ) - { - %slashPos = strpos( $Server::MissionFile, "/", %slashPos ) + 1; - } - %levelName = getSubStr( $Server::MissionFile , %slashPos , 99 ); - - if( %levelName !$= %this.levelName ) - %this.onNewLevelLoaded( %levelName ); -} - -function EditorGui::onSleep( %this ) -{ - // Deactivate the current editor plugin. - - if( %this.currentEditor.isActivated ) - %this.currentEditor.onDeactivated(); - - // Remove the editor's ActionMaps. - - EditorMap.pop(); - MoveMap.pop(); - - // Notify the editor plugins that the editor will be closing. - - foreach( %plugin in EditorPluginSet ) - %plugin.onEditorSleep(); - - if(isObject($Server::CurrentScene)) - $Server::CurrentScene.open(); -} - -function EditorGui::onNewLevelLoaded( %this, %levelName ) -{ - %this.levelName = %levelName; - %this.setupDefaultCameraSettings(); - ECameraSettingsPage.init(); - EditorCameraSpeedOptions.setupDefaultState(); - - new ScriptObject( EditorMissionCleanup ) - { - parentGroup = "MissionCleanup"; - }; -} - -function EditorMissionCleanup::onRemove( %this ) -{ - EditorGui.levelName = ""; - foreach( %plugin in EditorPluginSet ) - %plugin.onExitMission(); -} - -//----------------------------------------------------------------------------- - -// Called when we have been set as the content and onWake has been called -function EditorGui::onSetContent(%this, %oldContent) -{ - %this.attachMenus(); -} - -// Called before onSleep when the canvas content is changed -function EditorGui::onUnsetContent(%this, %newContent) -{ - %this.detachMenus(); -} - -//------------------------------------------------------------------------------ - -function EditorGui::toggleSFXParametersWindow( %this ) -{ - %window = %this-->ManageSFXParametersWindow; - %window.setVisible( !%window.isVisible() ); -} - -//------------------------------------------------------------------------------ - -function EditorGui::addCameraBookmark( %this, %name ) -{ - %obj = new CameraBookmark() { - datablock = CameraBookmarkMarker; - internalName = %name; - }; - - // Place into correct group - if( !isObject(CameraBookmarks) ) - { - %grp = new SimGroup(CameraBookmarks); - MissionGroup.add(%grp); - } - CameraBookmarks.add( %obj ); - - %cam = LocalClientConnection.camera.getTransform(); - %obj.setTransform( %cam ); - - EWorldEditor.isDirty = true; - EditorTree.buildVisibleTree(true); -} - -function EditorGui::removeCameraBookmark( %this, %name ) -{ - if( !isObject(CameraBookmarks) ) - return; - - %mark = CameraBookmarks.findObjectByInternalName( %name, true ); - if( %mark == 0 ) - return; - - MEDeleteUndoAction::submit( %mark ); - EWorldEditor.isDirty = true; - EditorTree.buildVisibleTree(true); -} - -function EditorGui::removeCameraBookmarkIndex( %this, %index ) -{ - if( !isObject(CameraBookmarks) ) - return; - - if( %index < 0 || %index >= CameraBookmarks.getCount() ) - return; - - %obj = CameraBookmarks.getObject( %index ); - MEDeleteUndoAction::submit( %obj ); - EWorldEditor.isDirty = true; - EditorTree.buildVisibleTree(true); -} - -function EditorGui::jumpToBookmark( %this, %name ) -{ - if( !isObject(CameraBookmarks) ) - return; - - %mark = CameraBookmarks.findObjectByInternalName( %name, true ); - if( %mark == 0 ) - return; - - LocalClientConnection.camera.setTransform( %mark.getTransform() ); - return; -} - -function EditorGui::jumpToBookmarkIndex( %this, %index ) -{ - if( !isObject(CameraBookmarks) ) - return; - - if( %index < 0 || %index >= CameraBookmarks.getCount() ) - return; - - %trans = CameraBookmarks.getObject( %index ).getTransform(); - LocalClientConnection.camera.setTransform( %trans ); -} - -function EditorGui::addCameraBookmarkByGui( %this ) -{ - // look for a NewCamera name to grab - for(%i = 0; ; %i++){ - %name = "NewCamera_" @ %i; - if( !CameraBookmarks.findObjectByInternalName(%name) ){ - break; - } - } - EditorGui.addCameraBookmark( %name ); -} - -function EditorGui::toggleCameraBookmarkWindow( %this ) -{ - EManageBookmarks.ToggleVisibility(); -} - -function EditorGui::toggleObjectSelectionsWindow( %this ) -{ - ESelectObjectsWindow.toggleVisibility(); -} - -function EditorGui::toggleOrthoGrid( %this ) -{ - EWorldEditor.renderOrthoGrid = !EWorldEditor.renderOrthoGrid; -} - -//------------------------------------------------------------------------------ - -function EditorGui::syncCameraGui( %this ) -{ - if( !EditorIsActive() ) - return; - - // Sync projection type - %displayType = %this.currentEditor.editorGui.getDisplayType(); - %this.viewTypeMenu.checkRadioItem( 0, 7, %displayType ); - - // Set the camera object's mode and rotation so that it moves correctly - // based on the current editor mode - if( %displayType != $EditTSCtrl::DisplayTypePerspective ) - { - switch( %displayType ) - { - case $EditTSCtrl::DisplayTypeTop: %name = "Top View"; %camRot = "0 0 0"; - case $EditTSCtrl::DisplayTypeBottom: %name = "Bottom View"; %camRot = "3.14159 0 0"; - case $EditTSCtrl::DisplayTypeLeft: %name = "Left View"; %camRot = "-1.571 0 1.571"; - case $EditTSCtrl::DisplayTypeRight: %name = "Right View"; %camRot = "-1.571 0 -1.571"; - case $EditTSCtrl::DisplayTypeFront: %name = "Front View"; %camRot = "-1.571 0 3.14159"; - case $EditTSCtrl::DisplayTypeBack: %name = "Back View"; %camRot = "-1.571 0 0"; - case $EditTSCtrl::DisplayTypeIsometric: %name = "Isometric View"; %camRot = "0 0 0"; - } - - LocalClientConnection.camera.controlMode = "Fly"; - LocalClientConnection.camera.setRotation( %camRot ); - EditorGuiStatusBar.setCamera( %name ); - return; - } - - // Sync camera settings. - %flyModeRadioItem = -1; - if(LocalClientConnection.getControlObject() != LocalClientConnection.player) - { - %mode = LocalClientConnection.camera.getMode(); - - if(%mode $= "Fly" && LocalClientConnection.camera.newtonMode) - { - if(LocalClientConnection.camera.newtonRotation == true) - { - EditorGui-->NewtonianRotationCamera.setStateOn(true); - EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/smooth-cam-rot"); - %flyModeRadioItem = 4; - EditorGuiStatusBar.setCamera("Smooth Rot Camera"); - } - else - { - EditorGui-->NewtonianCamera.setStateOn(true); - EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/smooth-cam"); - %flyModeRadioItem = 3; - EditorGuiStatusBar.setCamera("Smooth Camera"); - } - } - else if(%mode $= "EditOrbit") - { - EditorGui-->OrbitCamera.setStateOn(true); - EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/orbit-cam"); - %flyModeRadioItem = 1; - EditorGuiStatusBar.setCamera("Orbit Camera"); - } - else // default camera mode - { - EditorGui-->StandardCamera.setStateOn(true); - EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/camera"); - %flyModeRadioItem = 0; - EditorGuiStatusBar.setCamera("Standard Camera"); - } - - //quick way select menu bar options - %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 0 ); - EditorFreeCameraTypeOptions.checkRadioItem( 0, 4, %flyModeRadioItem); - EditorPlayerCameraTypeOptions.checkRadioItem( 0, 4, -1); - } - else if (!$isFirstPersonVar) // if 3rd person - { - EditorGui-->trdPersonCamera.setStateOn(true); - EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/3rd-person-camera"); - %flyModeRadioItem = 1; - //quick way select menu bar options - %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 1 ); - EditorPlayerCameraTypeOptions.checkRadioItem( 0, 2, %flyModeRadioItem); - EditorGuiStatusBar.setCamera("3rd Person Camera"); - } - else if ($isFirstPersonVar) // if 1st Person - { - EditorGui-->PlayerCamera.setStateOn(true); - EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/player"); - %flyModeRadioItem = 0; - //quick way select menu bar options - %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 1 ); - EditorPlayerCameraTypeOptions.checkRadioItem( 0, 2, %flyModeRadioItem); - EditorFreeCameraTypeOptions.checkRadioItem( 0, 4, -1); - EditorGuiStatusBar.setCamera("1st Person Camera"); - } - } - -/// @name EditorPlugin Methods -/// @{ - -//------------------------------------------------------------------------------ -// WorldEditorPlugin -//------------------------------------------------------------------------------ - -function WorldEditorPlugin::onActivated( %this ) -{ - EditorGui.bringToFront( EWorldEditor ); - EWorldEditor.setVisible(true); - EditorGui.menuBar.insert( EditorGui.worldMenu, EditorGui.menuBar.dynamicItemInsertPos ); - EWorldEditor.makeFirstResponder(true); - EditorTree.open(MissionGroup,true); - EWCreatorWindow.setNewObjectGroup(MissionGroup); - - EWorldEditor.syncGui(); - - EditorGuiStatusBar.setSelectionObjectsByCount(EWorldEditor.getSelectionSize()); - - // Should the Transform Selection window open? - if( EWorldEditor.ETransformSelectionDisplayed ) - { - ETransformSelection.setVisible(true); - } - - Parent::onActivated(%this); -} - -function WorldEditorPlugin::onDeactivated( %this ) -{ - // Hide the Transform Selection window from other editors - ETransformSelection.setVisible(false); - - EWorldEditor.setVisible( false ); - EditorGui.menuBar.remove( EditorGui.worldMenu ); - - Parent::onDeactivated(%this); -} - -//------------------------------------------------------------------------------ -// WorldEditorInspectorPlugin -//------------------------------------------------------------------------------ - -function WorldEditorInspectorPlugin::onWorldEditorStartup( %this ) -{ - Parent::onWorldEditorStartup( %this ); - - // Add ourselves to the window menu. - %accel = EditorGui.addToEditorsMenu( "Object Editor", "", WorldEditorInspectorPlugin ); - - // Add ourselves to the ToolsToolbar - %tooltip = "Object Editor (" @ %accel @ ")"; - EditorGui.addToToolsToolbar( "WorldEditorInspectorPlugin", "WorldEditorInspectorPalette", expandFilename("tools/worldEditor/images/toolbar/transform-objects"), %tooltip ); - - //connect editor windows - GuiWindowCtrl::attach( EWInspectorWindow, EWTreeWindow); - - %map = new ActionMap(); - %map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select - %map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move - %map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate - %map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale - %map.bindCmd( keyboard, "f", "FitToSelectionBtn.performClick();", "" );// Fit Camera to Selection - %map.bindCmd( keyboard, "z", "EditorGuiStatusBar.setCamera(\"Standard Camera\");", "" );// Free camera - %map.bindCmd( keyboard, "n", "ToggleNodeBar->renderHandleBtn.performClick();", "" );// Render Node - %map.bindCmd( keyboard, "shift n", "ToggleNodeBar->renderTextBtn.performClick();", "" );// Render Node Text - %map.bindCmd( keyboard, "g", "ESnapOptions-->GridSnapButton.performClick();" ); // Grid Snappping - %map.bindCmd( keyboard, "t", "SnapToBar->objectSnapDownBtn.performClick();", "" );// Terrain Snapping - %map.bindCmd( keyboard, "b", "SnapToBar-->objectSnapBtn.performClick();" ); // Soft Snappping - %map.bindCmd( keyboard, "v", "EWorldEditorToolbar->boundingBoxColBtn.performClick();", "" );// Bounds Selection - %map.bindCmd( keyboard, "o", "objectCenterDropdown->objectBoxBtn.performClick(); objectCenterDropdown.toggle();", "" );// Object Center - %map.bindCmd( keyboard, "p", "objectCenterDropdown->objectBoundsBtn.performClick(); objectCenterDropdown.toggle();", "" );// Bounds Center - %map.bindCmd( keyboard, "k", "objectTransformDropdown->objectTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// Object Transform - %map.bindCmd( keyboard, "l", "objectTransformDropdown->worldTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// World Transform - - WorldEditorInspectorPlugin.map = %map; -} - -function WorldEditorInspectorPlugin::onActivated( %this ) -{ - Parent::onActivated( %this ); - - EditorGui-->InspectorWindow.setVisible( true ); - EditorGui-->TreeWindow.setVisible( true ); - EditorGui-->WorldEditorToolbar.setVisible( true ); - %this.map.push(); -} - -function WorldEditorInspectorPlugin::onDeactivated( %this ) -{ - Parent::onDeactivated( %this ); - - EditorGui-->InspectorWindow.setVisible( false ); - EditorGui-->TreeWindow.setVisible( false ); - EditorGui-->WorldEditorToolbar.setVisible( false ); - %this.map.pop(); -} - -function WorldEditorInspectorPlugin::onEditMenuSelect( %this, %editMenu ) -{ - %canCutCopy = EWorldEditor.getSelectionSize() > 0; - %editMenu.enableItem( 3, %canCutCopy ); // Cut - %editMenu.enableItem( 4, %canCutCopy ); // Copy - %editMenu.enableItem( 5, EWorldEditor.canPasteSelection() ); // Paste - - %selSize = EWorldEditor.getSelectionSize(); - %lockCount = EWorldEditor.getSelectionLockCount(); - %hideCount = EWorldEditor.getSelectionHiddenCount(); - %editMenu.enableItem( 6, %selSize > 0 && %lockCount != %selSize ); // Delete Selection - - %editMenu.enableItem( 8, %canCutCopy ); // Deselect -} - -function WorldEditorInspectorPlugin::handleDelete( %this ) -{ - // The tree handles deletion and notifies the - // world editor to clear its selection. - // - // This is because non-SceneObject elements like - // SimGroups also need to be destroyed. - // - // See EditorTree::onObjectDeleteCompleted(). - %selSize = EWorldEditor.getSelectionSize(); - if( %selSize > 0 ) - EditorTree.deleteSelection(); -} - -function WorldEditorInspectorPlugin::handleDeselect() -{ - EWorldEditor.clearSelection(); -} - -function WorldEditorInspectorPlugin::handleCut() -{ - EWorldEditor.cutSelection(); -} - -function WorldEditorInspectorPlugin::handleCopy() -{ - EWorldEditor.copySelection(); -} - -function WorldEditorInspectorPlugin::handlePaste() -{ - EWorldEditor.pasteSelection(); -} - -//------------------------------------------------------------------------------ -// TerrainEditorPlugin -//------------------------------------------------------------------------------ - -function TerrainEditorPlugin::onWorldEditorStartup( %this ) -{ - Parent::onWorldEditorStartup( %this ); - - // Add ourselves to the window menu. - %accel = EditorGui.addToEditorsMenu( "Terrain Editor", "", TerrainEditorPlugin ); - - // Add ourselves to the ToolsToolbar - %tooltip = "Terrain Editor (" @ %accel @ ")"; - EditorGui.addToToolsToolbar( "TerrainEditorPlugin", "TerrainEditorPalette", expandFilename("tools/worldEditor/images/toolbar/sculpt-terrain"), %tooltip ); - - %map = new ActionMap(); - %map.bindCmd( keyboard, "1", "ToolsPaletteArray->brushAdjustHeight.performClick();", "" ); //Grab Terrain - %map.bindCmd( keyboard, "2", "ToolsPaletteArray->raiseHeight.performClick();", "" ); // Raise Height - %map.bindCmd( keyboard, "3", "ToolsPaletteArray->lowerHeight.performClick();", "" ); // Lower Height - %map.bindCmd( keyboard, "4", "ToolsPaletteArray->smoothHeight.performClick();", "" ); // Average Height - %map.bindCmd( keyboard, "5", "ToolsPaletteArray->smoothSlope.performClick();", "" ); // Smooth Slope - %map.bindCmd( keyboard, "6", "ToolsPaletteArray->paintNoise.performClick();", "" ); // Noise - %map.bindCmd( keyboard, "7", "ToolsPaletteArray->flattenHeight.performClick();", "" ); // Flatten - %map.bindCmd( keyboard, "8", "ToolsPaletteArray->setHeight.performClick();", "" ); // Set Height - %map.bindCmd( keyboard, "9", "ToolsPaletteArray->setEmpty.performClick();", "" ); // Clear Terrain - %map.bindCmd( keyboard, "0", "ToolsPaletteArray->clearEmpty.performClick();", "" ); // Restore Terrain - %map.bindCmd( keyboard, "v", "EWTerrainEditToolbarBrushType->ellipse.performClick();", "" );// Circle Brush - %map.bindCmd( keyboard, "b", "EWTerrainEditToolbarBrushType->box.performClick();", "" );// Box Brush - %map.bindCmd( keyboard, "=", "TerrainEditorPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size - %map.bindCmd( keyboard, "+", "TerrainEditorPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size - %map.bindCmd( keyboard, "-", "TerrainEditorPlugin.keyboardModifyBrushSize(-1);", "" );// -1 Brush Size - %map.bindCmd( keyboard, "[", "TerrainEditorPlugin.keyboardModifyBrushSize(-5);", "" );// -5 Brush Size - %map.bindCmd( keyboard, "]", "TerrainEditorPlugin.keyboardModifyBrushSize(5);", "" );// +5 Brush Size - /*%map.bindCmd( keyboard, "]", "TerrainBrushPressureTextEditContainer->textEdit.text += 5", "" );// +5 Pressure - %map.bindCmd( keyboard, "[", "TerrainBrushPressureTextEditContainer->textEdit.text -= 5", "" );// -5 Pressure - %map.bindCmd( keyboard, "'", "TerrainBrushSoftnessTextEditContainer->textEdit.text += 5", "" );// +5 Softness - %map.bindCmd( keyboard, ";", "TerrainBrushSoftnessTextEditContainer->textEdit.text -= 5", "" );// -5 Softness*/ - - TerrainEditorPlugin.map = %map; - - %this.terrainMenu = new PopupMenu() + %this.viewTypeMenu = new PopupMenu() { superClass = "MenuBuilder"; - - barTitle = "Terrain"; - - item[0] = "Smooth Heightmap" TAB "" TAB "ETerrainEditor.onSmoothHeightmap();"; - }; -} - -function TerrainEditorPlugin::onActivated( %this ) -{ - Parent::onActivated( %this ); - - EditorGui.readTerrainEditorSettings(); - - %action = EditorSettings.value("TerrainEditor/currentAction"); - ETerrainEditor.switchAction( %action ); - ToolsPaletteArray.findObjectByInternalName( %action, true ).setStateOn( true ); - - EWTerrainEditToolbarBrushType->ellipse.performClick(); // Circle Brush - - EditorGui.menuBar.insert( %this.terrainMenu, EditorGui.menuBar.dynamicItemInsertPos ); - - EditorGui.bringToFront( ETerrainEditor ); - ETerrainEditor.setVisible( true ); - ETerrainEditor.attachTerrain(); - ETerrainEditor.makeFirstResponder( true ); - - EWTerrainEditToolbar.setVisible( true ); - ETerrainEditor.onBrushChanged(); - ETerrainEditor.setup(); - TerrainEditorPlugin.syncBrushInfo(); - - EditorGuiStatusBar.setSelection(""); - %this.map.push(); -} - -function TerrainEditorPlugin::onDeactivated( %this ) -{ - Parent::onDeactivated( %this ); - - endToolTime("TerrainEditor"); - EditorGui.writeTerrainEditorSettings(); - - EWTerrainEditToolbar.setVisible( false ); - ETerrainEditor.setVisible( false ); - - EditorGui.menuBar.remove( %this.terrainMenu ); - - %this.map.pop(); -} - -function TerrainEditorPlugin::syncBrushInfo( %this ) -{ - // Update gui brush info - TerrainBrushSizeTextEditContainer-->textEdit.text = getWord(ETerrainEditor.getBrushSize(), 0); - TerrainBrushPressureTextEditContainer-->textEdit.text = ETerrainEditor.getBrushPressure()*100; - TerrainBrushSoftnessTextEditContainer-->textEdit.text = ETerrainEditor.getBrushSoftness()*100; - TerrainSetHeightTextEditContainer-->textEdit.text = ETerrainEditor.setHeightVal; - - %brushType = ETerrainEditor.getBrushType(); - eval( "EWTerrainEditToolbar-->" @ %brushType @ ".setStateOn(1);" ); -} - -function TerrainEditorPlugin::validateBrushSize( %this ) -{ - %minBrushSize = 1; - %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); - - %val = $ThisControl.getText(); - if(%val < %minBrushSize) - $ThisControl.setValue(%minBrushSize); - else if(%val > %maxBrushSize) - $ThisControl.setValue(%maxBrushSize); -} - -function TerrainEditorPlugin::keyboardModifyBrushSize( %this, %amt) -{ - %val = TerrainBrushSizeTextEditContainer-->textEdit.getText(); - %val += %amt; - TerrainBrushSizeTextEditContainer-->textEdit.setValue(%val); - TerrainBrushSizeTextEditContainer-->textEdit.forceValidateText(); - ETerrainEditor.setBrushSize( TerrainBrushSizeTextEditContainer-->textEdit.getText() ); -} - -//------------------------------------------------------------------------------ -// TerrainTextureEditorTool -//------------------------------------------------------------------------------ - -function TerrainTextureEditorTool::onActivated( %this ) -{ - EditorGui.bringToFront( ETerrainEditor ); - ETerrainEditor.setVisible( true ); - ETerrainEditor.attachTerrain(); - ETerrainEditor.makeFirstResponder( true ); - - EditorGui-->TextureEditor.setVisible(true); - - EditorGuiStatusBar.setSelection(""); -} - -function TerrainTextureEditorTool::onDeactivated( %this ) -{ - EditorGui-->TextureEditor.setVisible(false); - - ETerrainEditor.setVisible( false ); -} - -//------------------------------------------------------------------------------ -// TerrainPainterPlugin -//------------------------------------------------------------------------------ - -function TerrainPainterPlugin::onWorldEditorStartup( %this ) -{ - Parent::onWorldEditorStartup( %this ); - - // Add ourselves to the window menu. - %accel = EditorGui.addToEditorsMenu( "Terrain Painter", "", TerrainPainterPlugin ); - - // Add ourselves to the ToolsToolbar - %tooltip = "Terrain Painter (" @ %accel @ ")"; - EditorGui.addToToolsToolbar( "TerrainPainterPlugin", "TerrainPainterPalette", expandFilename("tools/worldEditor/images/toolbar/paint-terrain"), %tooltip ); - - %map = new ActionMap(); - %map.bindCmd( keyboard, "v", "EWTerrainPainterToolbarBrushType->ellipse.performClick();", "" );// Circle Brush - %map.bindCmd( keyboard, "b", "EWTerrainPainterToolbarBrushType->box.performClick();", "" );// Box Brush - %map.bindCmd( keyboard, "=", "TerrainPainterPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size - %map.bindCmd( keyboard, "+", "TerrainPainterPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size - %map.bindCmd( keyboard, "-", "TerrainPainterPlugin.keyboardModifyBrushSize(-1);", "" );// -1 Brush Size - %map.bindCmd( keyboard, "[", "TerrainPainterPlugin.keyboardModifyBrushSize(-5);", "" );// -5 Brush Size - %map.bindCmd( keyboard, "]", "TerrainPainterPlugin.keyboardModifyBrushSize(5);", "" );// +5 Brush Size - /*%map.bindCmd( keyboard, "]", "PaintBrushSlopeControl->SlopeMinAngle.text += 5", "" );// +5 SlopeMinAngle - %map.bindCmd( keyboard, "[", "PaintBrushSlopeControl->SlopeMinAngle.text -= 5", "" );// -5 SlopeMinAngle - %map.bindCmd( keyboard, "'", "PaintBrushSlopeControl->SlopeMaxAngle.text += 5", "" );// +5 SlopeMaxAngle - %map.bindCmd( keyboard, ";", "PaintBrushSlopeControl->SlopeMaxAngle.text -= 5", "" );// -5 Softness*/ - - for(%i=1; %i<10; %i++) - { - %map.bindCmd( keyboard, %i, "TerrainPainterPlugin.keyboardSetMaterial(" @ (%i-1) @ ");", "" ); - } - %map.bindCmd( keyboard, 0, "TerrainPainterPlugin.keyboardSetMaterial(10);", "" ); - - TerrainPainterPlugin.map = %map; - GuiWindowCtrl::attach( EPainter, EPainterPreview); -} - -function TerrainPainterPlugin::onActivated( %this ) -{ - Parent::onActivated( %this ); - - EditorGui.readTerrainEditorSettings(); - - EWTerrainPainterToolbarBrushType->ellipse.performClick();// Circle Brush - %this.map.push(); - - EditorGui.bringToFront( ETerrainEditor ); - ETerrainEditor.setVisible( true ); - ETerrainEditor.attachTerrain(); - ETerrainEditor.makeFirstResponder( true ); - - EditorGui-->TerrainPainter.setVisible(true); - EditorGui-->TerrainPainterPreview.setVisible(true); - EWTerrainPainterToolbar.setVisible(true); - ETerrainEditor.onBrushChanged(); - EPainter.setup(); - TerrainPainterPlugin.syncBrushInfo(); - - EditorGuiStatusBar.setSelection(""); -} - -function TerrainPainterPlugin::onDeactivated( %this ) -{ - Parent::onDeactivated( %this ); - - EditorGui.writeTerrainEditorSettings(); - - %this.map.pop(); - EditorGui-->TerrainPainter.setVisible(false); - EditorGui-->TerrainPainterPreview.setVisible(false); - EWTerrainPainterToolbar.setVisible(false); - ETerrainEditor.setVisible( false ); -} - -function TerrainPainterPlugin::syncBrushInfo( %this ) -{ - // Update gui brush info - PaintBrushSizeTextEditContainer-->textEdit.text = getWord(ETerrainEditor.getBrushSize(), 0); - PaintBrushSlopeControl-->SlopeMinAngle.text = ETerrainEditor.getSlopeLimitMinAngle(); - PaintBrushSlopeControl-->SlopeMaxAngle.text = ETerrainEditor.getSlopeLimitMaxAngle(); - PaintBrushPressureTextEditContainer-->textEdit.text = ETerrainEditor.getBrushPressure()*100; - %brushType = ETerrainEditor.getBrushType(); - eval( "EWTerrainPainterToolbar-->" @ %brushType @ ".setStateOn(1);" ); -} - -function TerrainPainterPlugin::validateBrushSize( %this ) -{ - %minBrushSize = 1; - %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); - - %val = $ThisControl.getText(); - if(%val < %minBrushSize) - $ThisControl.setValue(%minBrushSize); - else if(%val > %maxBrushSize) - $ThisControl.setValue(%maxBrushSize); -} - -function TerrainPainterPlugin::validateSlopeMaxAngle( %this ) -{ - %maxval = ETerrainEditor.getSlopeLimitMaxAngle(); - PaintBrushSlopeControl-->SlopeMaxAngle.setText(%maxval); -} - -function TerrainPainterPlugin::validateSlopeMinAngle( %this ) -{ - %minval = ETerrainEditor.getSlopeLimitMinAngle(); - PaintBrushSlopeControl-->SlopeMinAngle.setText(%minval); -} - -function TerrainPainterPlugin::keyboardModifyBrushSize( %this, %amt) -{ - %val = PaintBrushSizeTextEditContainer-->textEdit.getText(); - %val += %amt; - PaintBrushSizeTextEditContainer-->textEdit.setValue(%val); - PaintBrushSizeTextEditContainer-->textEdit.forceValidateText(); - ETerrainEditor.setBrushSize( PaintBrushSizeTextEditContainer-->textEdit.getText() ); -} - -function TerrainPainterPlugin::keyboardSetMaterial( %this, %mat) -{ - %name = "EPainterMaterialButton" @ %mat; - %ctrl = EPainter.findObjectByInternalName(%name, true); - if(%ctrl) - { - %ctrl.performClick(); - } -} - -/// @} End of EditorPlugin Methods - - -function objectTransformDropdown::toggle() -{ - if ( objectTransformDropdown.visible ) - { - EWorldEditorToolbar-->objectTransform.setStateOn(false); - objectTransformDropdownDecoy.setVisible(false); - objectTransformDropdownDecoy.setActive(false); - objectTransformDropdown.setVisible(false); - } - else - { - EWorldEditorToolbar-->objectTransform.setStateOn(true); - objectTransformDropdown.setVisible(true); - objectTransformDropdownDecoy.setActive(true); - objectTransformDropdownDecoy.setVisible(true); - } -} - -function CameraTypesDropdownToggle() -{ - if ( CameraTypesDropdown.visible ) - { - EWorldEditorToggleCamera.setStateOn(0); - CameraTypesDropdownDecoy.setVisible(false); - CameraTypesDropdownDecoy.setActive(false); - CameraTypesDropdown.setVisible(false); - } - else - { - CameraTypesDropdown.setVisible(true); - CameraTypesDropdownDecoy.setVisible(true); - CameraTypesDropdownDecoy.setActive(true); - EWorldEditorToggleCamera.setStateOn(1); - } -} - -function VisibilityDropdownToggle() -{ - if ( EVisibility.visible ) - { - EVisibility.setVisible(false); - visibilityToggleBtn.setStateOn(0); - } - else - { - EVisibility.setVisible(true); - visibilityToggleBtn.setStateOn(1); - } -} - -function CameraTypesDropdownDecoy::onMouseLeave() -{ - CameraTypesDropdownToggle(); -} - -//----------------------------------------------------------------------------- - -function EWorldEditor::getGridSnap( %this ) -{ - return %this.gridSnap; -} - -function EWorldEditor::setGridSnap( %this, %value ) -{ - %this.gridSnap = %value; - GlobalGizmoProfile.snapToGrid = %value; - %this.syncGui(); -} - -function EWorldEditor::getGridSize( %this ) -{ - return %this.gridSize; -} - -function EWorldEditor::setGridSize( %this, %value ) -{ - GlobalGizmoProfile.gridSize = %value SPC %value SPC %value; - %this.gridSize = %value; - - %this.syncGui(); -} - -//----------------------------------------------------------------------------- - -function EWorldEditor::areAllSelectedObjectsOfType( %this, %className ) -{ - %activeSelection = %this.getActiveSelection(); - if( !isObject( %activeSelection ) ) - return false; - %count = %activeSelection.getCount(); - for( %i = 0; %i < %count; %i ++ ) - { - %obj = %activeSelection.getObject( %i ); - if( !%obj.isMemberOfClass( %className ) ) - return false; - } - - return true; -} - -//----------------------------------------------------------------------------- -function EWorldEditorToggleCamera::toggleBitmap(%this) -{ - %currentImage = %this.bitmap; - - if ( %currentImage $= "tools/worldEditor/images/toolbar/player" ) - %image = "tools/worldEditor/images/toolbar/camera"; - else - %image = "tools/worldEditor/images/toolbar/player"; - - %this.setBitmap( %image ); -} - -function EWorldEditorCameraSpeed::updateMenuBar(%this, %editorBarCtrl) -{ - // Update Toolbar TextEdit - if( %editorBarCtrl.getId() == CameraSpeedDropdownCtrlContainer-->slider.getId() ) - { - %value = %editorBarCtrl.getValue(); - EWorldEditorCameraSpeed.setText( %value ); - $Camera::movementSpeed = %value; - } - - // Update Toolbar Slider - if( %editorBarCtrl.getId() == EWorldEditorCameraSpeed.getId() ) - { - %value = %editorBarCtrl.getText(); - if ( %value !$= "" ) - { - if ( %value <= 0 ) // camera speed must be >= 0 - { - %value = 1; - %editorBarCtrl.setText( %value ); - } - CameraSpeedDropdownCtrlContainer-->slider.setValue( %value ); - $Camera::movementSpeed = %value; - } - } - - // Update Editor - EditorCameraSpeedOptions.checkRadioItem(0, 6, -1); -} - -//----------------------------------------------------------------------------- - -function EWorldEditorAlignPopup::onSelect(%this, %id, %text) -{ - if ( GlobalGizmoProfile.mode $= "Scale" && %text $= "World" ) - { - EWorldEditorAlignPopup.setSelected(1); - return; - } - - GlobalGizmoProfile.alignment = %text; -} - -//----------------------------------------------------------------------------- - - -//----------------------------------------------------------------------------- - -function EWorldEditorNoneModeBtn::onClick(%this) -{ - GlobalGizmoProfile.mode = "None"; - - EditorGuiStatusBar.setInfo("Selection arrow."); -} - -function EWorldEditorMoveModeBtn::onClick(%this) -{ - GlobalGizmoProfile.mode = "Move"; - - %cmdCtrl = "CTRL"; - if( $platform $= "macos" ) - %cmdCtrl = "CMD"; - - EditorGuiStatusBar.setInfo( "Move selection. SHIFT while dragging duplicates objects. " @ %cmdCtrl @ " to toggle soft snap. ALT to toggle grid snap." ); -} - -function EWorldEditorRotateModeBtn::onClick(%this) -{ - GlobalGizmoProfile.mode = "Rotate"; - - EditorGuiStatusBar.setInfo("Rotate selection."); -} - -function EWorldEditorScaleModeBtn::onClick(%this) -{ - GlobalGizmoProfile.mode = "Scale"; - - EditorGuiStatusBar.setInfo("Scale selection."); -} - -//----------------------------------------------------------------------------- - -function EditorTree::onDeleteSelection( %this ) -{ - %this.undoDeleteList = ""; -} - -function EditorTree::onDeleteObject( %this, %object ) -{ - // Don't delete locked objects - if( %object.locked ) - return true; - - if( %object == EWCreatorWindow.objectGroup ) - EWCreatorWindow.setNewObjectGroup( MissionGroup ); - - // Append it to our list. - %this.undoDeleteList = %this.undoDeleteList TAB %object; - - // We're gonna delete this ourselves in the - // completion callback. - return true; -} - -function EditorTree::onObjectDeleteCompleted( %this ) -{ - // This can be called when a deletion is attempted but nothing was - // actually deleted ( cannot delete the root of the tree ) so only submit - // the undo if we really deleted something. - if ( %this.undoDeleteList !$= "" ) - MEDeleteUndoAction::submit( %this.undoDeleteList ); - - // Let the world editor know to - // clear its selection. - EWorldEditor.clearSelection(); - EWorldEditor.isDirty = true; -} - -function EditorTree::onClearSelected(%this) -{ - WorldEditor.clearSelection(); -} - -function EditorTree::onInspect(%this, %obj) -{ - Inspector.inspect(%obj); -} - -function EditorTree::toggleLock( %this ) -{ - if( EWTreeWindow-->LockSelection.command $= "EWorldEditor.lockSelection(true); EditorTree.toggleLock();" ) - { - EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(false); EditorTree.toggleLock();"; - EWTreeWindow-->DeleteSelection.command = ""; - } - else - { - EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; - EWTreeWindow-->DeleteSelection.command = "EditorMenuEditDelete();"; - } -} - -function EditorTree::onAddSelection(%this, %obj, %isLastSelection) -{ - EWorldEditor.selectObject( %obj ); - - %selSize = EWorldEditor.getSelectionSize(); - %lockCount = EWorldEditor.getSelectionLockCount(); - - if( %lockCount < %selSize ) - { - EWTreeWindow-->LockSelection.setStateOn(0); - EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; - } - else if ( %lockCount > 0 ) - { - EWTreeWindow-->LockSelection.setStateOn(1); - EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(false); EditorTree.toggleLock();"; - } - - if( %selSize > 0 && %lockCount == 0 ) - EWTreeWindow-->DeleteSelection.command = "EditorMenuEditDelete();"; - else - EWTreeWindow-->DeleteSelection.command = ""; - - if( %isLastSelection ) - Inspector.addInspect( %obj ); - else - Inspector.addInspect( %obj, false ); - -} -function EditorTree::onRemoveSelection(%this, %obj) -{ - EWorldEditor.unselectObject(%obj); - Inspector.removeInspect( %obj ); -} -function EditorTree::onSelect(%this, %obj) -{ -} - -function EditorTree::onUnselect(%this, %obj) -{ - EWorldEditor.unselectObject(%obj); -} - -function EditorTree::onDragDropped(%this) -{ - EWorldEditor.isDirty = true; -} - -function EditorTree::onAddGroupSelected(%this, %group) -{ - EWCreatorWindow.setNewObjectGroup(%group); -} - -function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) -{ - %haveObjectEntries = false; - %haveLockAndHideEntries = true; - - // Handle multi-selection. - if( %this.getSelectedItemsCount() > 1 ) - { - %popup = ETMultiSelectionContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETMultiSelectionContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 0 ] = "Delete" TAB "" TAB "EditorMenuEditDelete();"; - item[ 1 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; - }; - } - - // Open context menu if this is a CameraBookmark - else if( %obj.isMemberOfClass( "CameraBookmark" ) ) - { - %popup = ETCameraBookmarkContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETCameraBookmarkContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 0 ] = "Go To Bookmark" TAB "" TAB "EditorGui.jumpToBookmark( %this.bookmark.getInternalName() );"; - - bookmark = -1; - }; - - ETCameraBookmarkContextPopup.bookmark = %obj; - } - - // Open context menu if this is set CameraBookmarks group. - else if( %obj.name $= "CameraBookmarks" ) - { - %popup = ETCameraBookmarksGroupContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETCameraBookmarksGroupContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 0 ] = "Add Camera Bookmark" TAB "" TAB "EditorGui.addCameraBookmarkByGui();"; - }; - } - - // Open context menu if this is a SimGroup - else if( !%obj.isMemberOfClass( "SceneObject" ) ) - { - %popup = ETSimGroupContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETSimGroupContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; - item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; - item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; - item[ 3 ] = "-"; - item[ 4 ] = "Toggle Lock Children" TAB "" TAB "EWorldEditor.toggleLockChildren( %this.object );"; - item[ 5 ] = "Toggle Hide Children" TAB "" TAB "EWorldEditor.toggleHideChildren( %this.object );"; - item[ 6 ] = "-"; - item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; - item[ 8 ] = "-"; - item[ 9 ] = "Add New Objects Here" TAB "" TAB "EWCreatorWindow.setNewObjectGroup( %this.object );"; - item[ 10 ] = "Add Children to Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, false );"; - item[ 11 ] = "Remove Children from Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, true );"; - - object = -1; - }; - - %popup.object = %obj; - - %hasChildren = %obj.getCount() > 0; - %popup.enableItem( 10, %hasChildren ); - %popup.enableItem( 11, %hasChildren ); - - %haveObjectEntries = true; - %haveLockAndHideEntries = false; - } - - // Open generic context menu. - else - { - %popup = ETContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; - item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; - item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; - item[ 3 ] = "-"; - item[ 4 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); EWorldEditor.syncGui();"; - item[ 5 ] = "Hidden" TAB "" TAB "EWorldEditor.hideObject( %this.object, !%this.object.hidden ); EWorldEditor.syncGui();"; - item[ 6 ] = "-"; - item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; - - object = -1; - }; - - if(%obj.isMemberOfClass("Entity")) - { - %popup = ETEntityContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETEntityContextPopup : ETSimGroupContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 12 ] = "-"; - item[ 13 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; - }; - } - - // Specialized version for ConvexShapes. - else if( %obj.isMemberOfClass( "ConvexShape" ) ) - { - %popup = ETConvexShapeContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETConvexShapeContextPopup : ETContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 8 ] = "-"; - item[ 9 ] = "Convert to Zone" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Zone\" );"; - item[ 10 ] = "Convert to Portal" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Portal\" );"; - item[ 11 ] = "Convert to Occluder" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"OcclusionVolume\" );"; - item[ 12 ] = "Convert to Sound Space" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"SFXSpace\" );"; - }; - } - - // Specialized version for polyhedral objects. - else if( %obj.isMemberOfClass( "Zone" ) || - %obj.isMemberOfClass( "Portal" ) || - %obj.isMemberOfClass( "OcclusionVolume" ) || - %obj.isMemberOfClass( "SFXSpace" ) ) - { - %popup = ETPolyObjectContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETPolyObjectContextPopup : ETContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 8 ] = "-"; - item[ 9 ] = "Convert to ConvexShape" TAB "" TAB "EWorldEditor.convertSelectionToConvexShape();"; - }; - } - - %popup.object = %obj; - %haveObjectEntries = true; - } - - if( %haveObjectEntries ) - { - %popup.enableItem( 0, %obj.isNameChangeAllowed() && %obj.getName() !$= "MissionGroup" ); - %popup.enableItem( 1, %obj.getName() !$= "MissionGroup" ); - if( %haveLockAndHideEntries ) - { - %popup.checkItem( 4, %obj.locked ); - %popup.checkItem( 5, %obj.hidden ); - } - %popup.enableItem( 7, %this.isItemSelected( %itemId ) ); - } - - %popup.showPopup( Canvas ); -} - -function EditorTree::positionContextMenu( %this, %menu ) -{ - if( (getWord(%menu.position, 0) + getWord(%menu.extent, 0)) > getWord(EWorldEditor.extent, 0) ) - { - %posx = getWord(%menu.position, 0); - %offset = getWord(EWorldEditor.extent, 0) - (%posx + getWord(%menu.extent, 0)) - 5; - %posx += %offset; - %menu.position = %posx @ " " @ getWord(%menu.position, 1); - } -} - -function EditorTree::isValidDragTarget( %this, %id, %obj ) -{ - if( %obj.isMemberOfClass( "Path" ) ) - return EWorldEditor.areAllSelectedObjectsOfType( "Marker" ); - if( %obj.name $= "CameraBookmarks" ) - return EWorldEditor.areAllSelectedObjectsOfType( "CameraBookmark" ); - else - return ( %obj.getClassName() $= "SimGroup" ); -} - -function EditorTree::onBeginReparenting( %this ) -{ - if( isObject( %this.reparentUndoAction ) ) - %this.reparentUndoAction.delete(); - - %action = UndoActionReparentObjects::create( %this ); - - %this.reparentUndoAction = %action; -} - -function EditorTree::onReparent( %this, %obj, %oldParent, %newParent ) -{ - %this.reparentUndoAction.add( %obj, %oldParent, %newParent ); -} - -function EditorTree::onEndReparenting( %this ) -{ - %action = %this.reparentUndoAction; - %this.reparentUndoAction = ""; - - if( %action.numObjects > 0 ) - { - if( %action.numObjects == 1 ) - %action.actionName = "Reparent Object"; - else - %action.actionName = "Reparent Objects"; - - %action.addToManager( Editor.getUndoManager() ); - - EWorldEditor.syncGui(); - } - else - %action.delete(); -} - -function EditorTree::update( %this ) -{ - %this.buildVisibleTree( false ); -} - -//------------------------------------------------------------------------------ - -// Tooltip for TSStatic -function EditorTree::GetTooltipTSStatic( %this, %obj ) -{ - return "Shape: " @ %obj.shapeName; -} - -// Tooltip for ShapeBase -function EditorTree::GetTooltipShapeBase( %this, %obj ) -{ - return "Datablock: " @ %obj.dataBlock; -} - -// Tooltip for StaticShape -function EditorTree::GetTooltipStaticShape( %this, %obj ) -{ - return "Datablock: " @ %obj.dataBlock; -} - -// Tooltip for Item -function EditorTree::GetTooltipItem( %this, %obj ) -{ - return "Datablock: " @ %obj.dataBlock; -} - -// Tooltip for RigidShape -function EditorTree::GetTooltipRigidShape( %this, %obj ) -{ - return "Datablock: " @ %obj.dataBlock; -} - -// Tooltip for Prefab -function EditorTree::GetTooltipPrefab( %this, %obj ) -{ - return "File: " @ %obj.filename; -} - -// Tooltip for GroundCover -function EditorTree::GetTooltipGroundCover( %this, %obj ) -{ - %text = "Material: " @ %obj.material; - for(%i=0; %i<8; %i++) - { - if(%obj.probability[%i] > 0 && %obj.shapeFilename[%i] !$= "") - { - %text = %text NL "Shape " @ %i @ ": " @ %obj.shapeFilename[%i]; - } - } - return %text; -} - -// Tooltip for SFXEmitter -function EditorTree::GetTooltipSFXEmitter( %this, %obj ) -{ - if(%obj.fileName $= "") - return "Track: " @ %obj.track; - else - return "File: " @ %obj.fileName; -} - -// Tooltip for ParticleEmitterNode -function EditorTree::GetTooltipParticleEmitterNode( %this, %obj ) -{ - %text = "Datablock: " @ %obj.dataBlock; - %text = %text NL "Emitter: " @ %obj.emitter; - return %text; -} - -// Tooltip for WorldEditorSelection -function EditorTree::GetTooltipWorldEditorSelection( %this, %obj ) -{ - %text = "Objects: " @ %obj.getCount(); - - if( !%obj.getCanSave() ) - %text = %text NL "Persistent: No"; - else - %text = %text NL "Persistent: Yes"; - - return %text; -} - -//------------------------------------------------------------------------------ - -function EditorTreeTabBook::onTabSelected( %this ) -{ - if( EditorTreeTabBook.getSelectedPage() == 0) - { - EWTreeWindow-->DeleteSelection.visible = true; - EWTreeWindow-->LockSelection.visible = true; - EWTreeWindow-->AddSimGroup.visible = true; - } - else - { - EWTreeWindow-->DeleteSelection.visible = false; - EWTreeWindow-->LockSelection.visible = false; - EWTreeWindow-->AddSimGroup.visible = false; - } -} - -//------------------------------------------------------------------------------ - -function Editor::open(%this) -{ - // prevent the mission editor from opening while the GuiEditor is open. - if(Canvas.getContent() == GuiEditorGui.getId()) - return; - - EditorGui.buildMenus(); - - if( !EditorGui.isInitialized ) - EditorGui.init(); - - %this.editorEnabled(); - Canvas.setContent(EditorGui); - EditorGui.syncCameraGui(); -} - -function Editor::close(%this, %gui) -{ - %this.editorDisabled(); - Canvas.setContent(%gui); - if(isObject(MessageHud)) - MessageHud.close(); - EditorGui.writeCameraSettings(); - - EditorGui.onDestroyMenu(); -} - -function EditorGui::onDestroyMenu(%this) -{ - if( !isObject( %this.menuBar ) ) - return; - - // Destroy menus - while( %this.menuBar.getCount() != 0 ) - %this.menuBar.getObject( 0 ).delete(); - - %this.menuBar.removeFromCanvas(); - %this.menuBar.delete(); -} - -$RelightCallback = ""; - -function EditorLightingComplete() -{ - $lightingMission = false; - RelightStatus.visible = false; - - if ($RelightCallback !$= "") - { - eval($RelightCallback); - } - - $RelightCallback = ""; -} - -function updateEditorLightingProgress() -{ - RelightProgress.setValue(($SceneLighting::lightingProgress)); - if ($lightingMission) - $lightingProgressThread = schedule(1, 0, "updateEditorLightingProgress"); -} - -function Editor::lightScene(%this, %callback, %forceAlways) -{ - if ($lightingMission) - return; - - $lightingMission = true; - $RelightCallback = %callback; - RelightStatus.visible = true; - RelightProgress.setValue(0); - Canvas.repaint(); - lightScene("EditorLightingComplete", %forceAlways); - updateEditorLightingProgress(); -} - -//------------------------------------------------------------------------------ - -function EditorGui::handleEscape( %this ) -{ - %result = false; - if ( isObject( %this.currentEditor ) ) - %result = %this.currentEditor.handleEscape(); - - if ( !%result ) - { - Editor.close("PlayGui"); - } -} - -function EditTSCtrl::updateGizmoMode( %this, %mode ) -{ - // Called when the gizmo mode is changed from C++ - - if ( %mode $= "None" ) - EditorGuiToolbar->NoneModeBtn.performClick(); - else if ( %mode $= "Move" ) - EditorGuiToolbar->MoveModeBtn.performClick(); - else if ( %mode $= "Rotate" ) - EditorGuiToolbar->RotateModeBtn.performClick(); - else if ( %mode $= "Scale" ) - EditorGuiToolbar->ScaleModeBtn.performClick(); -} - -//------------------------------------------------------------------------------ - -function EWorldEditor::syncGui( %this ) -{ - %this.syncToolPalette(); - - EditorTree.update(); - Editor.getUndoManager().updateUndoMenu( EditorGui.menuBar-->EditMenu ); - EditorGuiStatusBar.setSelectionObjectsByCount( %this.getSelectionSize() ); - - EWTreeWindow-->LockSelection.setStateOn( %this.getSelectionLockCount() > 0 ); - - EWorldEditorToolbar-->boundingBoxColBtn.setStateOn( EWorldEditor.boundingBoxCollision ); - - if( EWorldEditor.objectsUseBoxCenter ) - { - EWorldEditorToolbar-->centerObject.setBitmap("tools/gui/images/menubar/bounds-center"); - objectCenterDropdown-->objectBoundsBtn.setStateOn( 1 ); - } - else - { - EWorldEditorToolbar-->centerObject.setBitmap("tools/gui/images/menubar/object-center"); - objectCenterDropdown-->objectBoxBtn.setStateOn( 1 ); - } - - if( GlobalGizmoProfile.getFieldValue(alignment) $= "Object" ) - { - EWorldEditorToolbar-->objectTransform.setBitmap("tools/gui/images/menubar/object-transform"); - objectTransformDropdown-->objectTransformBtn.setStateOn( 1 ); - - } - else - { - EWorldEditorToolbar-->objectTransform.setBitmap("tools/gui/images/menubar/world-transform"); - objectTransformDropdown-->worldTransformBtn.setStateOn( 1 ); - } - - EWorldEditorToolbar-->renderHandleBtn.setStateOn( EWorldEditor.renderObjHandle ); - EWorldEditorToolbar-->renderTextBtn.setStateOn( EWorldEditor.renderObjText ); - - EWorldEditorToolbar-->objectSnapDownBtn.setStateOn( %this.stickToGround ); - SnapToBar-->objectSnapBtn.setStateOn( EWorldEditor.getSoftSnap() ); - EWorldEditorToolbar-->softSnapSizeTextEdit.setText( EWorldEditor.getSoftSnapSize() ); - ESnapOptions-->SnapSize.setText( EWorldEditor.getSoftSnapSize() ); - ESnapOptions-->GridSize.setText( EWorldEditor.getGridSize() ); - - ESnapOptions-->GridSnapButton.setStateOn( %this.getGridSnap() ); - ESnapOptions-->GroupSnapButton.setStateOn( %this.UseGroupCenter ); - SnapToBar-->objectGridSnapBtn.setStateOn( %this.getGridSnap() ); - ESnapOptions-->NoSnapButton.setStateOn( !%this.stickToGround && !%this.getSoftSnap() && !%this.getGridSnap() ); -} - -function EWorldEditor::syncToolPalette( %this ) -{ - switch$ ( GlobalGizmoProfile.mode ) - { - case "None": - EWorldEditorNoneModeBtn.performClick(); - case "Move": - EWorldEditorMoveModeBtn.performClick(); - case "Rotate": - EWorldEditorRotateModeBtn.performClick(); - case "Scale": - EWorldEditorScaleModeBtn.performClick(); - } -} - -function EWorldEditor::addSimGroup( %this, %groupCurrentSelection ) -{ - %activeSelection = %this.getActiveSelection(); - if ( %activeSelection.getObjectIndex( MissionGroup ) != -1 ) - { - MessageBoxOK( "Error", "Cannot add MissionGroup to a new SimGroup" ); - return; - } - - // Find our parent. - - %parent = MissionGroup; - if( !%groupCurrentSelection && isObject( %activeSelection ) && %activeSelection.getCount() > 0 ) - { - %firstSelectedObject = %activeSelection.getObject( 0 ); - if( %firstSelectedObject.isMemberOfClass( "SimGroup" ) ) - %parent = %firstSelectedObject; - else if( %firstSelectedObject.getId() != MissionGroup.getId() ) - %parent = %firstSelectedObject.parentGroup; - } - - // If we are about to do a group-selected as well, - // starting recording an undo compound. - - if( %groupCurrentSelection ) - Editor.getUndoManager().pushCompound( "Group Selected" ); - - // Create the SimGroup. - - %object = new SimGroup() - { - parentGroup = %parent; + item[ 0 ] = "Top" TAB "Alt 2" TAB "EditorGuiStatusBar.setCamera(\"Top View\");"; + item[ 1 ] = "Bottom" TAB "Alt 5" TAB "EditorGuiStatusBar.setCamera(\"Bottom View\");"; + item[ 2 ] = "Front" TAB "Alt 3" TAB "EditorGuiStatusBar.setCamera(\"Front View\");"; + item[ 3 ] = "Back" TAB "Alt 6" TAB "EditorGuiStatusBar.setCamera(\"Back View\");"; + item[ 4 ] = "Left" TAB "Alt 4" TAB "EditorGuiStatusBar.setCamera(\"Left View\");"; + item[ 5 ] = "Right" TAB "Alt 7" TAB "EditorGuiStatusBar.setCamera(\"Right View\");"; + item[ 6 ] = "Perspective" TAB "Alt 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[ 7 ] = "Isometric" TAB "Alt 8" TAB "EditorGuiStatusBar.setCamera(\"Isometric View\");"; }; - MECreateUndoAction::submit( %object ); - - // Put selected objects into the group, if requested. - - if( %groupCurrentSelection && isObject( %activeSelection ) ) - { - %undo = UndoActionReparentObjects::create( EditorTree ); - %numObjects = %activeSelection.getCount(); - for( %i = 0; %i < %numObjects; %i ++ ) - { - %sel = %activeSelection.getObject( %i ); - %undo.add( %sel, %sel.parentGroup, %object ); - %object.add( %sel ); - } + // Menu bar + %this.menuBar = new GuiMenuBar(WorldEditorMenubar) + { + dynamicItemInsertPos = 3; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; + }; + + // File Menu + %fileMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorFileMenu"; + + barTitle = "File"; + }; + + + %fileMenu.appendItem("New Level" TAB "" TAB "schedule( 1, 0, \"EditorNewLevel\" );"); + %fileMenu.appendItem("Open Level..." TAB %cmdCtrl SPC "O" TAB "schedule( 1, 0, \"EditorOpenMission\" );"); + %fileMenu.appendItem("Save Level" TAB %cmdCtrl SPC "S" TAB "EditorSaveMissionMenu();"); + %fileMenu.appendItem("Save Level As..." TAB "" TAB "EditorSaveMissionAs();"); + %fileMenu.appendItem("-"); + + if( $platform $= "windows" ) + { + %fileMenu.appendItem( "Open Project in Torsion" TAB "" TAB "EditorOpenTorsionProject();" ); + %fileMenu.appendItem( "Open Level File in Torsion" TAB "" TAB "EditorOpenFileInTorsion();" ); + %fileMenu.appendItem( "-" ); + } + + %fileMenu.appendItem("Create Blank Terrain" TAB "" TAB "Canvas.pushDialog( CreateNewTerrainGui );"); + %fileMenu.appendItem("Import Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainImportGui );"); + + %fileMenu.appendItem("Export Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainExportGui );"); + %fileMenu.appendItem("-"); + %fileMenu.appendItem("Export To COLLADA..." TAB "" TAB "EditorExportToCollada();"); + //item[5] = "Import Terraform Data..." TAB "" TAB "Heightfield::import();"; + //item[6] = "Import Texture Data..." TAB "" TAB "Texture::import();"; + //item[7] = "-"; + //item[8] = "Export Terraform Data..." TAB "" TAB "Heightfield::saveBitmap(\"\");"; + + %fileMenu.appendItem( "-" ); + %fileMenu.appendItem( "Add FMOD Designer Audio..." TAB "" TAB "AddFMODProjectDlg.show();" ); + + %fileMenu.appendItem("-"); + %fileMenu.appendItem("Play Level" TAB "F11" TAB "Editor.close(\"PlayGui\");"); - %undo.addToManager( Editor.getUndoManager() ); - } + %fileMenu.appendItem("Exit Level" TAB "" TAB "EditorExitMission();"); + %fileMenu.appendItem("Quit" TAB %quitShortcut TAB "EditorQuitGame();"); + + %this.menuBar.insert(%fileMenu); + + // Edit Menu + %editMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorEditMenu"; + internalName = "EditMenu"; + + barTitle = "Edit"; + + item[0] = "Undo" TAB %cmdCtrl SPC "Z" TAB "Editor.getUndoManager().undo();"; + item[1] = "Redo" TAB %redoShortcut TAB "Editor.getUndoManager().redo();"; + item[2] = "-"; + item[3] = "Cut" TAB %cmdCtrl SPC "X" TAB "EditorMenuEditCut();"; + item[4] = "Copy" TAB %cmdCtrl SPC "C" TAB "EditorMenuEditCopy();"; + item[5] = "Paste" TAB %cmdCtrl SPC "V" TAB "EditorMenuEditPaste();"; + item[6] = "Delete" TAB "Delete" TAB "EditorMenuEditDelete();"; + item[7] = "-"; + item[8] = "Deselect" TAB "X" TAB "EditorMenuEditDeselect();"; + Item[9] = "Select..." TAB "" TAB "EditorGui.toggleObjectSelectionsWindow();"; + item[10] = "-"; + item[11] = "Audio Parameters..." TAB "" TAB "EditorGui.toggleSFXParametersWindow();"; + item[12] = "Editor Settings..." TAB "" TAB "ESettingsWindow.ToggleVisibility();"; + item[13] = "Snap Options..." TAB "" TAB "ESnapOptions.ToggleVisibility();"; + item[14] = "-"; + item[15] = "Game Options..." TAB "" TAB "Canvas.pushDialog(optionsDlg);"; + item[16] = "PostEffect Manager" TAB "" TAB "Canvas.pushDialog(PostFXManager);"; + }; + %this.menuBar.insert(%editMenu); - // Stop recording for group-selected. - - if( %groupCurrentSelection ) - Editor.getUndoManager().popCompound(); - - // When not grouping selection, make the newly created SimGroup the - // current selection. - - if( !%groupCurrentSelection ) + // View Menu + %viewMenu = new PopupMenu() { - EWorldEditor.clearSelection(); - EWorldEditor.selectObject( %object ); - } + superClass = "MenuBuilder"; + class = "EditorViewMenu"; + internalName = "viewMenu"; - // Refresh the Gui. - - %this.syncGui(); -} - -function EWorldEditor::toggleLockChildren( %this, %simGroup ) -{ - foreach( %child in %simGroup ) - { - if( %child.class $= "SimGroup" ) - { - %this.toggleHideChildren( %child ); - } - if( %child.isMemberOfClass( "SimGroup" ) ) - { - %this.toggleHideChildren( %child ); - %child.setLocked( !%child.locked ); - } - else - { - %child.setLocked( !%child.locked ); - } - } - - EWorldEditor.syncGui(); -} - -function EWorldEditor::toggleHideChildren( %this, %simGroup ) -{ - foreach( %child in %simGroup ) - { - if( %child.class $= "SimGroup" ) - { - %this.toggleHideChildren( %child ); - } - if( %child.isMemberOfClass( "SimGroup" ) ) - { - %this.toggleHideChildren( %child ); - %this.hideObject( %child, !%child.hidden ); - } - else - { - %this.hideObject( %child, !%child.hidden ); - } - } - - EWorldEditor.syncGui(); -} - -function EWorldEditor::convertSelectionToPolyhedralObjects( %this, %className ) -{ - %group = %this.getNewObjectGroup(); - %undoManager = Editor.getUndoManager(); - - %activeSelection = %this.getActiveSelection(); - while( %activeSelection.getCount() != 0 ) - { - %oldObject = %activeSelection.getObject( 0 ); - %newObject = %this.createPolyhedralObject( %className, %oldObject ); - if( isObject( %newObject ) ) - { - %undoManager.pushCompound( "Convert ConvexShape to " @ %className ); - %newObject.parentGroup = %oldObject.parentGroup; - MECreateUndoAction::submit( %newObject ); - MEDeleteUndoAction::submit( %oldObject ); - %undoManager.popCompound(); - } - } -} - -function EWorldEditor::convertSelectionToConvexShape( %this ) -{ - %group = %this.getNewObjectGroup(); - %undoManager = Editor.getUndoManager(); - - %activeSelection = %this.getActiveSelection(); - while( %activeSelection.getCount() != 0 ) - { - %oldObject = %activeSelection.getObject( 0 ); - %newObject = %this.createConvexShapeFrom( %oldObject ); - if( isObject( %newObject ) ) - { - %undoManager.pushCompound( "Convert " @ %oldObject.getClassName() @ " to ConvexShape" ); - %newObject.parentGroup = %oldObject.parentGroup; - MECreateUndoAction::submit( %newObject ); - MEDeleteUndoAction::submit( %oldObject ); - %undoManager.popCompound(); - } - } -} - -function EWorldEditor::getNewObjectGroup( %this ) -{ - return EWCreatorWindow.getNewObjectGroup(); -} - -function EWorldEditor::deleteMissionObject( %this, %object ) -{ - // Unselect in editor tree. - - %id = EditorTree.findItemByObjectId( %object ); - EditorTree.selectItem( %id, false ); - - // Delete object. - - MEDeleteUndoAction::submit( %object ); - EWorldEditor.isDirty = true; - EditorTree.buildVisibleTree( true ); -} - -function EWorldEditor::createGameObject( %this, %entity ) -{ - if(!isObject(GameObjectBuilder)) - { - new GuiControl(GameObjectBuilder, EditorGuiGroup) { - profile = "ToolsGuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "800 600"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; + barTitle = "View"; + + item[ 0 ] = "Visibility Layers" TAB "Alt V" TAB "VisibilityDropdownToggle();"; + item[ 1 ] = "Show Grid in Ortho Views" TAB %cmdCtrl @ "-Shift-Alt G" TAB "EditorGui.toggleOrthoGrid();"; + }; + %this.menuBar.insert(%viewMenu); - new GuiWindowCtrl(GameObjectBuilderTargetWindow) { - profile = "ToolsGuiWindowProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "384 205"; - extent = "256 102"; - minExtent = "256 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - resizeWidth = "1"; - resizeHeight = "1"; - canMove = "1"; - canClose = "0"; - canMinimize = "0"; - canMaximize = "0"; - minSize = "50 50"; - text = "Create Object"; + // Camera Menu + %cameraMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorCameraMenu"; + + barTitle = "Camera"; + + item[0] = "World Camera" TAB %this.freeCameraTypeMenu; + item[1] = "Player Camera" TAB %this.playerCameraTypeMenu; + item[2] = "-"; + Item[3] = "Toggle Camera" TAB %menuCmdCtrl SPC "C" TAB "commandToServer('ToggleCamera');"; + item[4] = "Place Camera at Selection" TAB "Ctrl Q" TAB "EWorldEditor.dropCameraToSelection();"; + item[5] = "Place Camera at Player" TAB "Alt Q" TAB "commandToServer('dropCameraAtPlayer');"; + item[6] = "Place Player at Camera" TAB "Alt W" TAB "commandToServer('DropPlayerAtCamera');"; + item[7] = "-"; + item[8] = "Fit View to Selection" TAB "F" TAB "commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + item[9] = "Fit View To Selection and Orbit" TAB "Alt F" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\"); commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + item[10] = "-"; + item[11] = "Speed" TAB %this.cameraSpeedMenu; + item[12] = "View" TAB %this.viewTypeMenu; + item[13] = "-"; + Item[14] = "Add Bookmark..." TAB "Ctrl B" TAB "EditorGui.addCameraBookmarkByGui();"; + Item[15] = "Manage Bookmarks..." TAB "Ctrl-Shift B" TAB "EditorGui.toggleCameraBookmarkWindow();"; + item[16] = "Jump to Bookmark" TAB %this.cameraBookmarksMenu; + }; + %this.menuBar.insert(%cameraMenu); - new GuiTextCtrl() { - profile = "GuiCenterTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 26"; - extent = "84 16"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = "Object Name:"; - }; - new GuiTextEditCtrl(GameObjectBuilderObjectName) { - class = ObjectBuilderGuiTextEditCtrl; - profile = "ToolsGuiTextEditProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "78 26"; - extent = "172 18"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - historySize = "0"; - }; - new GuiButtonCtrl(GameObjectBuilderOKButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "7 250"; - extent = "156 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "EWorldEditor.buildGameObject();"; - helpTag = "0"; - text = "Create New"; - Accelerator = "return"; - }; - new GuiButtonCtrl(GameObjectBuilderCancelButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "170 250"; - extent = "80 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "Canvas.popDialog(GameObjectBuilder);"; - helpTag = "0"; - text = "Cancel"; - Accelerator = "escape"; - }; - }; + // Editors Menu + %editorsMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorToolsMenu"; + + barTitle = "Editors"; + + //item[0] = "Object Editor" TAB "F1" TAB WorldEditorInspectorPlugin; + //item[1] = "Material Editor" TAB "F2" TAB MaterialEditorPlugin; + //item[2] = "-"; + //item[3] = "Terrain Editor" TAB "F3" TAB TerrainEditorPlugin; + //item[4] = "Terrain Painter" TAB "F4" TAB TerrainPainterPlugin; + //item[5] = "-"; + }; + %this.menuBar.insert(%editorsMenu); + + // Lighting Menu + %lightingMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorLightingMenu"; + + barTitle = "Lighting"; + + item[0] = "Full Relight" TAB "Alt L" TAB "Editor.lightScene(\"\", forceAlways);"; + item[1] = "Toggle ShadowViz" TAB "" TAB "toggleShadowViz();"; + item[2] = "-"; + + // NOTE: The light managers will be inserted as the + // last menu items in EditorLightingMenu::onAdd(). + }; + %this.menuBar.insert(%lightingMenu); + + // Tools Menu + %toolsMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorUtilitiesMenu"; + + barTitle = "Tools"; + + item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();"; + item[1] = "Profiler" TAB "ctrl F2" TAB "showMetrics(true);"; + item[2] = "Torque SimView" TAB "" TAB "tree();"; + item[3] = "Make Selected a Mesh" TAB "" TAB "makeSelectedAMesh();"; + }; + %this.menuBar.insert(%toolsMenu); + + // Help Menu + %helpMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorHelpMenu"; + + barTitle = "Help"; + + item[0] = "Online Documentation..." TAB "Alt F1" TAB "gotoWebPage(EWorldEditor.documentationURL);"; + item[1] = "Offline User Guide..." TAB "" TAB "gotoWebPage(EWorldEditor.documentationLocal);"; + item[2] = "Offline Reference Guide..." TAB "" TAB "shellexecute(EWorldEditor.documentationReference);"; + item[3] = "Torque 3D Forums..." TAB "" TAB "gotoWebPage(EWorldEditor.forumURL);"; + }; + %this.menuBar.insert(%helpMenu); + + // Menus that are added/removed dynamically (temporary) + + // World Menu + if(! isObject(%this.worldMenu)) + { + %this.dropTypeMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorDropTypeMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "at Origin" TAB "" TAB "atOrigin"; + item[1] = "at Camera" TAB "" TAB "atCamera"; + item[2] = "at Camera w/Rotation" TAB "" TAB "atCameraRot"; + item[3] = "Below Camera" TAB "" TAB "belowCamera"; + item[4] = "Screen Center" TAB "" TAB "screenCenter"; + item[5] = "at Centroid" TAB "" TAB "atCentroid"; + item[6] = "to Terrain" TAB "" TAB "toTerrain"; + item[7] = "Below Selection" TAB "" TAB "belowSelection"; + item[8] = "At Gizmo" TAB "" TAB "atGizmo"; }; - GameObjectBuilderTargetWindow.extent = getWord(GameObjectBuilderTargetWindow.extent, 0) SPC 88; - GameObjectBuilderOKButton.position = getWord(GameObjectBuilderOKButton.position, 0) SPC 57; - GameObjectBuilderCancelButton.position = getWord(GameObjectBuilderCancelButton.position, 0) SPC 57; - } - - GameObjectBuilderObjectName.text = ""; - GameObjectBuilder.selectedEntity = %entity; - - Canvas.pushDialog(GameObjectBuilder); -} - -function EWorldEditor::buildGameObject(%this) -{ - if(GameObjectBuilderObjectName.getText() $= "") - { - error("Attempted to make a new Game Object with no name!"); - Canvas.popDialog(GameObjectBuilder); - return; - } - - %path = EditorSettings.value( "WorldEditor/newGameObjectDir" ); - %className = GameObjectBuilderObjectName.getText(); - GameObjectBuilder.selectedEntity.class = %className; - Inspector.inspect(GameObjectBuilder.selectedEntity); - - %file = new FileObject(); - - if(%file.openForWrite(%path @ "\\" @ %className @ ".cs")) - { - %file.writeline("function " @ %className @ "::onAdd(%this)\n{\n\n}\n"); - %file.writeline("function " @ %className @ "::onRemove(%this)\n{\n\n}\n"); - - //todo, pre-write any event functions of interest - - %file.close(); - } - - //set up the paths - %tamlPath = %path @ "/" @ %className @ ".taml"; - %scriptPath = %path @ "/" @ %className @ ".cs"; - saveGameObject(%className, %tamlPath, %scriptPath); - - //reload it - execGameObjects(); - - //now, add the script file and a ref to the taml into our SGO manifest so we can readily spawn it later. - TamlWrite(GameObjectBuilder.selectedEntity, %tamlpath); - - GameObjectBuilder.selectedEntity = ""; - - Canvas.popDialog(GameObjectBuilder); -} - -function EWorldEditor::selectAllObjectsInSet( %this, %set, %deselect ) -{ - if( !isObject( %set ) ) - return; - - foreach( %obj in %set ) - { - if( %deselect ) - %this.unselectObject( %obj ); - else - %this.selectObject( %obj ); - } -} - -function toggleSnappingOptions( %var ) -{ - if( SnapToBar->objectSnapDownBtn.getValue() && SnapToBar->objectSnapBtn.getValue() ) - { - if( %var $= "terrain" ) + %this.alignBoundsMenu = new PopupMenu() { - EWorldEditor.stickToGround = 1; - EWorldEditor.setSoftSnap(false); - ESnapOptionsTabBook.selectPage(0); - SnapToBar->objectSnapBtn.setStateOn(0); - } - else - { - // soft snapping - EWorldEditor.stickToGround = 0; - EWorldEditor.setSoftSnap(true); - ESnapOptionsTabBook.selectPage(1); - SnapToBar->objectSnapDownBtn.setStateOn(0); - } + superClass = "MenuBuilder"; + class = "EditorAlignBoundsMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "+X Axis" TAB "" TAB "0"; + item[1] = "+Y Axis" TAB "" TAB "1"; + item[2] = "+Z Axis" TAB "" TAB "2"; + item[3] = "-X Axis" TAB "" TAB "3"; + item[4] = "-Y Axis" TAB "" TAB "4"; + item[5] = "-Z Axis" TAB "" TAB "5"; + }; + + %this.alignCenterMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorAlignCenterMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "X Axis" TAB "" TAB "0"; + item[1] = "Y Axis" TAB "" TAB "1"; + item[2] = "Z Axis" TAB "" TAB "2"; + }; + + %this.worldMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + + barTitle = "Object"; + + item[0] = "Lock Selection" TAB %cmdCtrl @ " L" TAB "EWorldEditor.lockSelection(true); EWorldEditor.syncGui();"; + item[1] = "Unlock Selection" TAB %cmdCtrl @ "-Shift L" TAB "EWorldEditor.lockSelection(false); EWorldEditor.syncGui();"; + item[2] = "-"; + item[3] = "Hide Selection" TAB %cmdCtrl @ " H" TAB "EWorldEditor.hideSelection(true); EWorldEditor.syncGui();"; + item[4] = "Show Selection" TAB %cmdCtrl @ "-Shift H" TAB "EWorldEditor.hideSelection(false); EWorldEditor.syncGui();"; + item[5] = "-"; + item[6] = "Align Bounds" TAB %this.alignBoundsMenu; + item[7] = "Align Center" TAB %this.alignCenterMenu; + item[8] = "-"; + item[9] = "Reset Transforms" TAB "Ctrl R" TAB "EWorldEditor.resetTransforms();"; + item[10] = "Reset Selected Rotation" TAB "" TAB "EWorldEditor.resetSelectedRotation();"; + item[11] = "Reset Selected Scale" TAB "" TAB "EWorldEditor.resetSelectedScale();"; + item[12] = "Transform Selection..." TAB "Ctrl T" TAB "ETransformSelection.ToggleVisibility();"; + item[13] = "-"; + //item[13] = "Drop Camera to Selection" TAB "Ctrl Q" TAB "EWorldEditor.dropCameraToSelection();"; + //item[14] = "Add Selection to Instant Group" TAB "" TAB "EWorldEditor.addSelectionToAddGroup();"; + item[14] = "Drop Selection" TAB "Ctrl D" TAB "EWorldEditor.dropSelection();"; + //item[15] = "-"; + item[15] = "Drop Location" TAB %this.dropTypeMenu; + Item[16] = "-"; + Item[17] = "Make Selection Prefab" TAB "" TAB "EditorMakePrefab();"; + Item[18] = "Explode Selected Prefab" TAB "" TAB "EditorExplodePrefab();"; + Item[19] = "-"; + Item[20] = "Mount Selection A to B" TAB "" TAB "EditorMount();"; + Item[21] = "Unmount Selected Object" TAB "" TAB "EditorUnmount();"; + }; } - else if( %var $= "terrain" && EWorldEditor.stickToGround == 0 ) +} + +////////////////////////////////////////////////////////////////////////// + +function EditorGui::attachMenus(%this) +{ + %this.menuBar.attachToCanvas(Canvas, 0); +} + +function EditorGui::detachMenus(%this) +{ + %this.menuBar.removeFromCanvas(); +} + +function EditorGui::setMenuDefaultState(%this) +{ + if(! isObject(%this.menuBar)) + return 0; + + for(%i = 0;%i < %this.menuBar.getMenuCount();%i++) { - // Terrain Snapping - EWorldEditor.stickToGround = 1; - EWorldEditor.setSoftSnap(false); - ESnapOptionsTabBook.selectPage(0); - SnapToBar->objectSnapDownBtn.setStateOn(1); - SnapToBar->objectSnapBtn.setStateOn(0); - - } - else if( %var $= "soft" && EWorldEditor.getSoftSnap() == false ) - { - // Object Snapping - EWorldEditor.stickToGround = 0; - EWorldEditor.setSoftSnap(true); - ESnapOptionsTabBook.selectPage(1); - SnapToBar->objectSnapBtn.setStateOn(1); - SnapToBar->objectSnapDownBtn.setStateOn(0); - - } - else if( %var $= "grid" ) - { - EWorldEditor.setGridSnap( !EWorldEditor.getGridSnap() ); - } - else if( %var $= "byGroup" ) - { - EWorldEditor.UseGroupCenter = !EWorldEditor.UseGroupCenter; - ESnapOptions->GroupSnapButton.setStateOn(EWorldEditor.UseGroupCenter); - } - else - { - // No snapping. - - EWorldEditor.stickToGround = false; - EWorldEditor.setGridSnap( false ); - EWorldEditor.setSoftSnap( false ); - - SnapToBar->objectSnapDownBtn.setStateOn(0); - SnapToBar->objectSnapBtn.setStateOn(0); + %menu = %this.menuBar.getMenu(%i); + %menu.setupDefaultState(); } - EWorldEditor.syncGui(); + %this.worldMenu.setupDefaultState(); } -function objectCenterDropdown::toggle() +////////////////////////////////////////////////////////////////////////// + +function EditorGui::findMenu(%this, %name) { - if ( objectCenterDropdown.visible ) - { - EWorldEditorToolbar-->centerObject.setStateOn(false); - objectCenterDropdownDecoy.setVisible(false); - objectCenterDropdownDecoy.setActive(false); - objectCenterDropdown.setVisible(false); - } - else - { - EWorldEditorToolbar-->centerObject.setStateOn(true); - objectCenterDropdown.setVisible(true); - objectCenterDropdownDecoy.setActive(true); - objectCenterDropdownDecoy.setVisible(true); - } -} - -function objectTransformDropdown::toggle() -{ - if ( objectTransformDropdown.visible ) - { - EWorldEditorToolbar-->objectTransform.setStateOn(false); - objectTransformDropdownDecoy.setVisible(false); - objectTransformDropdownDecoy.setActive(false); - objectTransformDropdown.setVisible(false); - } - else - { - EWorldEditorToolbar-->objectTransform.setStateOn(true); - objectTransformDropdown.setVisible(true); - objectTransformDropdownDecoy.setActive(true); - objectTransformDropdownDecoy.setVisible(true); - } -} - -function objectSnapDropdownDecoy::onMouseLeave() -{ - objectSnapDropdown.toggle(); -} - -function objectCenterDropdownDecoy::onMouseLeave() -{ - objectCenterDropdown.toggle(); -} - -function objectTransformDropdownDecoy::onMouseLeave() -{ - objectTransformDropdown.toggle(); -} - -//------------------------------------------------------------------------------ - -function EWAddSimGroupButton::onDefaultClick( %this ) -{ - EWorldEditor.addSimGroup(); -} - -function EWAddSimGroupButton::onCtrlClick( %this ) -{ - EWorldEditor.addSimGroup( true ); -} - -//------------------------------------------------------------------------------ - -function EWToolsToolbar::reset( %this ) -{ - %count = ToolsToolbarArray.getCount(); - for( %i = 0 ; %i < %count; %i++ ) - ToolsToolbarArray.getObject(%i).setVisible(true); - - %this.setExtent((29 + 4) * %count + 12, 33); - %this.isClosed = 0; - EWToolsToolbar.isDynamic = 0; + if(! isObject(%this.menuBar)) + return 0; - EWToolsToolbarDecoy.setVisible(false); - EWToolsToolbarDecoy.setExtent((29 + 4) * %count + 4, 31); - - %this-->resizeArrow.setBitmap( "tools/gui/images/collapse-toolbar" ); -} - -function EWToolsToolbar::toggleSize( %this, %useDynamics ) -{ - // toggles the size of the tooltoolbar. also goes through - // and hides each control not currently selected. we hide the controls - // in a very neat, spiffy way - - if ( %this.isClosed == 0 ) + + for(%i = 0; %i < %this.menuBar.getMenuCount(); %i++) { - %image = "tools/gui/images/expand-toolbar"; + %menu = %this.menuBar.getMenu(%i); - for( %i = 0 ; %i < ToolsToolbarArray.getCount(); %i++ ) - { - if( ToolsToolbarArray.getObject(%i).getValue() != 1 ) - ToolsToolbarArray.getObject(%i).setVisible(false); - } - - %this.setExtent(43, 33); - %this.isClosed = 1; - - if(!%useDynamics) - { - EWToolsToolbarDecoy.setVisible(true); - EWToolsToolbar.isDynamic = 1; - } - - EWToolsToolbarDecoy.setExtent(35, 31); + if(%name $= %menu.barTitle) + return %menu; } - else - { - %image = "tools/gui/images/collapse-toolbar"; - - %count = ToolsToolbarArray.getCount(); - for( %i = 0 ; %i < %count; %i++ ) - ToolsToolbarArray.getObject(%i).setVisible(true); - - %this.setExtent((29 + 4) * %count + 12, 33); - %this.isClosed = 0; - - if(!%useDynamics) - { - EWToolsToolbarDecoy.setVisible(false); - EWToolsToolbar.isDynamic = 0; - } - - EWToolsToolbarDecoy.setExtent((29 + 4) * %count + 4, 32); - } - - %this-->resizeArrow.setBitmap( %image ); - + + return 0; } - -function EWToolsToolbarDecoy::onMouseEnter( %this ) -{ - EWToolsToolbar.toggleSize(true); -} - -function EWToolsToolbarDecoy::onMouseLeave( %this ) -{ - EWToolsToolbar.toggleSize(true); -} - -//------------------------------------------------------------------------------ - -function EditorGuiStatusBar::reset( %this ) -{ - EWorldEditorStatusBarInfo.clearInfo(); -} - -function EditorGuiStatusBar::getInfo( %this ) -{ - return EWorldEditorStatusBarInfo.getValue(); -} - -function EditorGuiStatusBar::setInfo( %this, %text ) -{ - EWorldEditorStatusBarInfo.setText(%text); -} - -function EditorGuiStatusBar::clearInfo( %this ) -{ - EWorldEditorStatusBarInfo.setText(""); -} - -function EditorGuiStatusBar::getSelection( %this ) -{ - return EWorldEditorStatusBarSelection.getValue(); -} - -function EditorGuiStatusBar::setSelection( %this, %text ) -{ - EWorldEditorStatusBarSelection.setText(%text); -} - -function EditorGuiStatusBar::setSelectionObjectsByCount( %this, %count ) -{ - %text = " objects selected"; - if(%count == 1) - %text = " object selected"; - - EWorldEditorStatusBarSelection.setText(%count @ %text); -} - -function EditorGuiStatusBar::clearSelection( %this ) -{ - EWorldEditorStatusBarSelection.setText(""); -} - -function EditorGuiStatusBar::getCamera( %this ) -{ - return EWorldEditorStatusBarCamera.getText(); -} - -function EditorGuiStatusBar::setCamera( %this, %text ) -{ - %id = EWorldEditorStatusBarCamera.findText( %text ); - if( %id != -1 ) - { - if ( EWorldEditorStatusBarCamera.getSelected() != %id ) - EWorldEditorStatusBarCamera.setSelected( %id, true ); - } -} - -function EWorldEditorStatusBarCamera::onWake( %this ) -{ - %this.add( "Standard Camera" ); - %this.add( "1st Person Camera" ); - %this.add( "3rd Person Camera" ); - %this.add( "Orbit Camera" ); - %this.add( "Top View" ); - %this.add( "Bottom View" ); - %this.add( "Left View" ); - %this.add( "Right View" ); - %this.add( "Front View" ); - %this.add( "Back View" ); - %this.add( "Isometric View" ); - %this.add( "Smooth Camera" ); - %this.add( "Smooth Rot Camera" ); -} - -function EWorldEditorStatusBarCamera::onSelect( %this, %id, %text ) -{ - switch$( %text ) - { - case "Top View": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeTop ); - - case "Bottom View": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeBottom ); - - case "Left View": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeLeft ); - - case "Right View": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeRight ); - - case "Front View": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeFront ); - - case "Back View": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeBack ); - - case "Isometric View": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeIsometric ); - - case "Standard Camera": - commandToServer( 'SetEditorCameraStandard' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); - - case "1st Person Camera": - commandToServer( 'SetEditorCameraPlayer' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); - - case "3rd Person Camera": - commandToServer( 'SetEditorCameraPlayerThird' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); - - case "Orbit Camera": - commandToServer( 'SetEditorOrbitCamera' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); - - case "Smooth Camera": - commandToServer( 'SetEditorCameraNewton' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); - - case "Smooth Rot Camera": - commandToServer( 'SetEditorCameraNewtonDamped' ); - EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); - } -} - -//------------------------------------------------------------------------------------ -// Each a gui slider bar is pushed on the editor gui, it maps itself with value -// located in its connected text control -//------------------------------------------------------------------------------------ -function softSnapSizeSliderCtrlContainer::onWake(%this) -{ - %this-->slider.setValue(EWorldEditorToolbar-->softSnapSizeTextEdit.getValue()); -} -function softSnapSizeSliderCtrlContainer::onSliderChanged(%this) -{ - EWorldEditor.setSoftSnapSize( %this-->slider.value ); - EWorldEditor.syncGui(); -} -//------------------------------------------------------------------------------------ - -function PaintBrushSizeSliderCtrlContainer::onWake(%this) -{ - %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); - %this-->slider.setValue(PaintBrushSizeTextEditContainer-->textEdit.getValue()); -} - -function PaintBrushPressureSliderCtrlContainer::onWake(%this) -{ - %this-->slider.setValue(PaintBrushPressureTextEditContainer-->textEdit.getValue() / 100); -} - -function PaintBrushSoftnessSliderCtrlContainer::onWake(%this) -{ - %this-->slider.setValue(PaintBrushSoftnessTextEditContainer-->textEdit.getValue() / 100); -} - -//------------------------------------------------------------------------------------ - -function TerrainBrushSizeSliderCtrlContainer::onWake(%this) -{ - %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); - %this-->slider.setValue(TerrainBrushSizeTextEditContainer-->textEdit.getValue()); -} - -function TerrainBrushPressureSliderCtrlContainer::onWake(%this) -{ - %this-->slider.setValue(TerrainBrushPressureTextEditContainer-->textEdit.getValue() / 100.0); -} - -function TerrainBrushSoftnessSliderCtrlContainer::onWake(%this) -{ - %this-->slider.setValue(TerrainBrushSoftnessTextEditContainer-->textEdit.getValue() / 100.0); -} - -function TerrainSetHeightSliderCtrlContainer::onWake(%this) -{ - %this-->slider.setValue(TerrainSetHeightTextEditContainer-->textEdit.getValue()); -} -//------------------------------------------------------------------------------------ -function CameraSpeedDropdownCtrlContainer::onWake(%this) -{ - %this-->slider.setValue(CameraSpeedDropdownContainer-->textEdit.getText()); -} - -//------------------------------------------------------------------------------------ -// Callbacks to close the dropdown slider controls like the camera speed, -// that are marked with this class name. - -function EditorDropdownSliderContainer::onMouseDown(%this) -{ - Canvas.popDialog(%this); -} - -function EditorDropdownSliderContainer::onRightMouseDown(%this) -{ - Canvas.popDialog(%this); -} \ No newline at end of file