You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
452 lines
13 KiB
452 lines
13 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
|
|
#include "HeadSpin.h" |
|
#include "pnKeyedObject/plKey.h" |
|
#include "hsTemplates.h" |
|
#include "hsWindows.h" |
|
#include "plFileSystem.h" |
|
|
|
#include <iMenuMan.h> |
|
#include <max.h> |
|
#include <notify.h> |
|
#include "resource.h" |
|
#include <vector> |
|
#pragma hdrstop |
|
|
|
#include "plMaxMenu.h" |
|
#include "plActionTableMgr.h" |
|
#include "plSaveSelected.h" |
|
#include "plComponentDlg.h" |
|
#include "plMaxCFGFile.h" |
|
#include "plResCollector.h" |
|
#include "plAgeDescInterface.h" |
|
#include "plNodeLock.h" |
|
#include "plResetXform.h" |
|
#include "plTextureSearch.h" |
|
#include "MaxExport/plExportDlg.h" |
|
|
|
// ************************* action table |
|
// |
|
|
|
// random id to identify an action table and context |
|
const ActionTableId kActionId = 0x54162b7c; |
|
|
|
|
|
enum |
|
{ |
|
kActionSaveSel, |
|
kActionMerge, |
|
kActionComponent, |
|
kActionResCollect, |
|
kActionAgeDesc, |
|
kActionCompCopy, |
|
kActionSceneViewer, // DEAD. But I don't dare remove it--don't want to break stuff :/ |
|
kActionLock, |
|
kActionUnlock, |
|
kActionTexSearch, |
|
kActionReset, |
|
kActionSelectNonRenderables, |
|
kActionExport, |
|
}; |
|
|
|
static ActionDescription spActions[] = |
|
{ |
|
{ |
|
kActionSaveSel, // ActionId identifies action for callback execution (within table) |
|
IDS_ACT1_DESC, // Action description for display in ui customization |
|
IDS_ACT1_NAME, // Action name for display on menu |
|
IDS_ACT_CAT // Action category for ui customization |
|
}, |
|
{ |
|
kActionMerge, |
|
IDS_ACT2_DESC, |
|
IDS_ACT2_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionComponent, |
|
IDS_ACT3_NAME, |
|
IDS_ACT3_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionResCollect, |
|
IDS_ACT4_NAME, |
|
IDS_ACT4_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionAgeDesc, |
|
IDS_ACT5_NAME, |
|
IDS_ACT5_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionCompCopy, |
|
IDS_ACT6_NAME, |
|
IDS_ACT6_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionSceneViewer, |
|
IDS_ACT7_NAME, |
|
IDS_ACT7_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionLock, |
|
IDS_ACT8_DESC, |
|
IDS_ACT8_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionUnlock, |
|
IDS_ACT9_DESC, |
|
IDS_ACT9_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionTexSearch, |
|
IDS_ACT10_NAME, |
|
IDS_ACT10_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionReset, |
|
IDS_ACT11_DESC, |
|
IDS_ACT11_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionSelectNonRenderables, |
|
IDS_ACT12_DESC, |
|
IDS_ACT12_NAME, |
|
IDS_ACT_CAT |
|
}, |
|
{ |
|
kActionExport, |
|
IDS_PLASMA_EXPORT, |
|
IDS_PLASMA_EXPORT, |
|
IDS_ACT_CAT |
|
} |
|
}; |
|
|
|
// callback for action exection |
|
bool DoAction(int id) |
|
{ |
|
switch(id) |
|
{ |
|
case kActionSaveSel: |
|
plSaveSelected(); |
|
return true; |
|
|
|
case kActionMerge: |
|
plMerge(); |
|
return true; |
|
|
|
case kActionComponent: |
|
plComponentDlg::Instance().Open(); |
|
return true; |
|
|
|
case kActionResCollect: |
|
plResCollector::Collect(); |
|
return true; |
|
|
|
case kActionAgeDesc: |
|
plAgeDescInterface::Instance().Open(); |
|
return true; |
|
|
|
case kActionCompCopy: |
|
CopyComponents(); |
|
return true; |
|
|
|
case kActionLock: |
|
plNodeLock().Lock(); |
|
return true; |
|
|
|
case kActionUnlock: |
|
plNodeLock().Unlock(); |
|
return true; |
|
|
|
case kActionTexSearch: |
|
plTextureSearch::Instance().Toggle(); |
|
return true; |
|
|
|
case kActionReset: |
|
plResetXform().ResetSelected(); |
|
return true; |
|
|
|
case kActionSelectNonRenderables: |
|
plSelectNonRenderables().SelectNonRenderables(); |
|
return true; |
|
|
|
case kActionExport: |
|
plExportDlg::Instance().Show(); |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
static ActionTableInfo actionInfo(kActionId, "Plasma", spActions, sizeof(spActions) / sizeof(ActionDescription)); |
|
|
|
// static or global declaration of action table manager |
|
plActionTableMgr theActionTableMgr(actionInfo, DoAction); |
|
|
|
|
|
// |
|
// ************************* end action table |
|
|
|
////////////////////////////////////////////////////////////////////////////// |
|
// Menu Creation Junk |
|
|
|
MenuContextId kMyMenuContextId=0xcff95f6c; //<random number> |
|
static char *kMenuName = "Plasma"; |
|
static int kMenuVersion = 11; // Increment this number if you add an entry to the menu |
|
|
|
extern TCHAR *GetString(int id); |
|
|
|
void AddPlasmaExportMenu() |
|
{ |
|
IMenuManager* pMenuMan = GetCOREInterface()->GetMenuManager(); |
|
IMenu* fileMenu = pMenuMan->FindMenu("&File"); |
|
|
|
int i; |
|
|
|
bool plasmaExportFound = false; |
|
|
|
// Make sure our action isn't already in the menu |
|
TSTR ourName = GetString(IDS_PLASMA_EXPORT); |
|
for (i = 0; i < fileMenu->NumItems(); i++) |
|
{ |
|
IMenuItem* fileMenuItem = fileMenu->GetItem(i); |
|
const TSTR& title = fileMenuItem->GetTitle(); |
|
if (title == ourName) |
|
plasmaExportFound = true; |
|
|
|
// KLUDGE - MaxAss didn't define the file submenu with an accelerator. |
|
// This fixes it. |
|
if (title == (CStr)"MAX File Operations") |
|
{ |
|
fileMenuItem->SetUseCustomTitle(true); |
|
bool custom = fileMenuItem->GetUseCustomTitle(); |
|
fileMenuItem->SetTitle("MAX File Opera&tions"); |
|
|
|
pMenuMan->UpdateMenuBar(); |
|
} |
|
} |
|
|
|
if (!plasmaExportFound) |
|
{ |
|
// Menu item isn't there, add it |
|
for (i = 0; i < fileMenu->NumItems(); i++) |
|
{ |
|
IMenuItem* fileMenuItem = fileMenu->GetItem(i); |
|
const TSTR& title = fileMenuItem->GetTitle(); |
|
// We want to add it after the "Export Selected" menu item |
|
if (title == (CStr)"Export Selected...") |
|
{ |
|
ActionTable* pActionTable = GetCOREInterface()->GetActionManager()->FindTable(kActionId); |
|
if (!pActionTable) |
|
{ |
|
hsAssert(0, "Action table not found"); |
|
return; |
|
} |
|
|
|
IMenuItem* menuItem = GetIMenuItem(); |
|
menuItem->SetActionItem(pActionTable->GetAction(kActionExport)); |
|
fileMenu->AddItem(menuItem, i+1); |
|
|
|
pMenuMan->UpdateMenuBar(); |
|
|
|
return; |
|
} |
|
} |
|
} |
|
} |
|
|
|
void plCreateMenu() |
|
{ |
|
#if MAX_VERSION_MAJOR <= 11 |
|
AddPlasmaExportMenu(); |
|
#endif |
|
|
|
IMenuManager* pMenuMan = GetCOREInterface()->GetMenuManager(); |
|
bool newlyRegistered = pMenuMan->RegisterMenuBarContext(kMyMenuContextId, kMenuName); |
|
|
|
// Is the Max menu version the most recent? |
|
bool wrongVersion = GetPrivateProfileIntW(L"Menu", L"Version", 0, plMaxConfig::GetPluginIni().AsString().ToWchar()) < kMenuVersion; |
|
if (wrongVersion) |
|
{ |
|
// Delete the old version of the menu |
|
IMenu *oldMenu = pMenuMan->FindMenu(kMenuName); |
|
if (oldMenu) |
|
pMenuMan->UnRegisterMenu(oldMenu); |
|
|
|
// Update the menu version |
|
wchar_t buf[12]; |
|
snwprintf(buf, arrsize(buf), L"%d", kMenuVersion); |
|
WritePrivateProfileStringW(L"Menu", L"Version", buf, plMaxConfig::GetPluginIni().AsString().ToWchar()); |
|
} |
|
|
|
if (wrongVersion || newlyRegistered) |
|
{ |
|
IMenu *pMainMenu = pMenuMan->GetMainMenuBar(); |
|
if (!pMainMenu) |
|
{ |
|
hsAssert(0, "Main menu not found"); |
|
return; |
|
} |
|
|
|
// Get our action table |
|
ActionTable* pActionTable = GetCOREInterface()->GetActionManager()->FindTable(kActionId); |
|
if (!pActionTable) |
|
{ |
|
hsAssert(0, "Action table not found"); |
|
return; |
|
} |
|
|
|
// Create the Plasma menu |
|
IMenu* pPlasmaMenu = GetIMenu(); |
|
pPlasmaMenu->SetTitle(kMenuName); |
|
|
|
// Register the new menu with the system |
|
pMenuMan->RegisterMenu(pPlasmaMenu, 0); |
|
|
|
///////////////////////////////////////////////// |
|
// Add the menu items |
|
// |
|
IMenuItem* pMenuItem; |
|
|
|
#if MAX_VERSION_MAJOR >= 12 |
|
// Add the export action to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionExport)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
#endif |
|
|
|
// Add the save selected action to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionSaveSel)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the merge action to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionMerge)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the component copy action to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionCompCopy)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add a separator |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->ActAsSeparator(); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the component manager to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionComponent)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the resource collector to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionResCollect)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the texture search to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionTexSearch)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the age description to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionAgeDesc)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add a separator |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->ActAsSeparator(); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the Lock Selected to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionLock)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the Unlock Selected to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionUnlock)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the Reset Selected to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionReset)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Add the SelectNonRenderables to the menu |
|
pMenuItem = GetIMenuItem(); |
|
pMenuItem->SetActionItem(pActionTable->GetAction(kActionSelectNonRenderables)); |
|
pPlasmaMenu->AddItem(pMenuItem); |
|
|
|
// Create a new menu item to hold the sub-menu |
|
IMenuItem* pSubMenuItem1 = GetIMenuItem(); //menu in menu bar... |
|
pSubMenuItem1->SetSubMenu(pPlasmaMenu); |
|
pMainMenu->AddItem(pSubMenuItem1); |
|
|
|
pMenuMan->UpdateMenuBar(); |
|
|
|
// Save the dang menu, in case Max crashes |
|
const char *uiDir = GetCOREInterface()->GetDir(APP_UI_DIR); |
|
char path[MAX_PATH]; |
|
sprintf(path, "%s\\%s", uiDir, "MaxMenus.mnu"); |
|
|
|
pMenuMan->SaveMenuFile(path); |
|
} |
|
|
|
} |
|
|
|
// End Menu Creation Junk |
|
////////////////////////////////////////////////////////////////////////////// |
|
|
|
|