/*==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 . 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 "plAnimCompProc.h" #include "../MaxMain/plMaxNode.h" #include "plComponentBase.h" #include "plPickNode.h" #include "plAnimComponent.h" #include "../../PubUtilLib/plInterp/plAnimEaseTypes.h" plAnimCompProc::plAnimCompProc() : fCompButtonID(0), fCompParamID(0), fNodeButtonID(0), fNodeParamID(0) { } BOOL plAnimCompProc::DlgProc(TimeValue t, IParamMap2* pm, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { IParamBlock2* pb = pm->GetParamBlock(); IUpdateNodeButton(hWnd, pb); IUpdateCompButton(hWnd, pb); ILoadUser(hWnd, pb); } return TRUE; case WM_COMMAND: { int cmd = HIWORD(wParam); int resID = LOWORD(wParam); if (cmd == BN_CLICKED && resID == fCompButtonID) { ICompButtonPress(hWnd, pm->GetParamBlock()); return TRUE; } else if (cmd == BN_CLICKED && resID == fNodeButtonID) { INodeButtonPress(hWnd, pm->GetParamBlock()); return TRUE; } else if (IUserCommand(hWnd, pm->GetParamBlock(), cmd, resID)) return TRUE; } break; } return FALSE; } void plAnimCompProc::ICompButtonPress(HWND hWnd, IParamBlock2* pb) { IPickComponent(pb); IUpdateCompButton(hWnd, pb); IUpdateNodeButton(hWnd, pb); ILoadUser(hWnd, pb); } void plAnimCompProc::IPickNode(IParamBlock2* pb, plComponentBase* comp) { plPick::CompTargets(pb, fNodeParamID, comp); } void plAnimCompProc::INodeButtonPress(HWND hWnd, IParamBlock2* pb) { plComponentBase* comp = IGetComp(pb); if (comp) IPickNode(pb, comp); IUpdateNodeButton(hWnd, pb); ILoadUser(hWnd, pb); } void plAnimCompProc::IUpdateNodeButton(HWND hWnd, IParamBlock2* pb) { HWND hButton = GetDlgItem(hWnd, fNodeButtonID); plComponentBase* comp = IGetComp(pb); if (!comp) { SetWindowText(hButton, "(none)"); EnableWindow(hButton, FALSE); return; } // If this is an anim grouped component you can't pick a target if (comp->ClassID() == ANIM_GROUP_COMP_CID) { IClearNode(pb); SetWindowText(hButton, "(none)"); EnableWindow(hButton, FALSE); return; } EnableWindow(hButton, TRUE); // Make sure the node is actually in the components target list plMaxNode* node = IGetNode(pb); if (comp->IsTarget((plMaxNodeBase*)node)) SetWindowText(hButton, node->GetName()); else SetWindowText(hButton, "(none)"); } void plAnimCompProc::IUpdateCompButton(HWND hWnd, IParamBlock2* pb) { HWND hAnim = GetDlgItem(hWnd, fCompButtonID); plComponentBase* comp = IGetComp(pb); if (comp) SetWindowText(hAnim, comp->GetINode()->GetName()); else SetWindowText(hAnim, "(none)"); } plComponentBase* plAnimCompProc::IGetComp(IParamBlock2* pb) { plMaxNode* node = nil; if (pb->GetParameterType(fCompParamID) == TYPE_REFTARG) node = (plMaxNode*)pb->GetReferenceTarget(fCompParamID); else node = (plMaxNode*)pb->GetINode(fCompParamID); if (node) return node->ConvertToComponent(); return nil; } plMaxNode* plAnimCompProc::IGetNode(IParamBlock2* pb) { if (pb->GetParameterType(fNodeParamID) == TYPE_REFTARG) return (plMaxNode*)pb->GetReferenceTarget(fNodeParamID); else return (plMaxNode*)pb->GetINode(fNodeParamID); } void plAnimCompProc::IClearNode(IParamBlock2* pb) { if (pb->GetParameterType(fNodeParamID) == TYPE_REFTARG) pb->SetValue(fNodeParamID, 0, (ReferenceTarget*)nil); else pb->SetValue(fNodeParamID, 0, (INode*)nil); } bool plAnimCompProc::GetCompAndNode(IParamBlock2* pb, plComponentBase*& comp, plMaxNode*& node) { comp = IGetComp(pb); if (comp) { node = IGetNode(pb); // If it's an anim group component (don't need a node), or we have a node // and the component is attached to it, we're ok. if (comp->ClassID() == ANIM_GROUP_COMP_CID || (node && comp->IsTarget((plMaxNodeBase*)node))) return true; } return false; } /////////////////////////////////////////////////////////////////////////////////////////// plMtlAnimProc::plMtlAnimProc() : fMtlButtonID(0), fMtlParamID(0), fNodeButtonID(0), fNodeParamID(0), fAnimComboID(0), fAnimParamID(0) { } BOOL plMtlAnimProc::DlgProc(TimeValue t, IParamMap2* pm, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { IParamBlock2* pb = pm->GetParamBlock(); IOnInitDlg(hWnd, pb); IUpdateMtlButton(hWnd, pb); } return TRUE; case WM_COMMAND: { int cmd = HIWORD(wParam); int resID = LOWORD(wParam); IParamBlock2* pb = pm->GetParamBlock(); if (cmd == BN_CLICKED && resID == fMtlButtonID) { IMtlButtonPress(hWnd, pb); return TRUE; } else if (cmd == BN_CLICKED && resID == fNodeButtonID) { INodeButtonPress(hWnd, pb); return TRUE; } else if (cmd == CBN_SELCHANGE && resID == fAnimComboID) { IAnimComboChanged(hWnd, pb); return TRUE; } else if (IUserCommand(hWnd, pb, cmd, resID)) return TRUE; } break; } return FALSE; } void plMtlAnimProc::IUpdateMtlButton(HWND hWnd, IParamBlock2* pb) { HWND hMtl = GetDlgItem(hWnd, fMtlButtonID); // Get the saved material Mtl *savedMtl = IGetMtl(pb); if (savedMtl) SetWindowText(hMtl, savedMtl->GetName()); else SetWindowText(hMtl, "(none)"); // Enable the node button if a material is selected EnableWindow(GetDlgItem(hWnd, fNodeButtonID), (savedMtl != nil)); // Update the dependencies of this IUpdateNodeButton(hWnd, pb); } void plMtlAnimProc::IUpdateNodeButton(HWND hWnd, IParamBlock2* pb) { ISetNodeButtonText(hWnd, pb); // Update the dependencies of this ILoadAnimCombo(hWnd, pb); } #include "plNotetrackAnim.h" void plMtlAnimProc::ILoadAnimCombo(HWND hWnd, IParamBlock2* pb) { HWND hAnim = GetDlgItem(hWnd, fAnimComboID); ComboBox_ResetContent(hAnim); int sel = ComboBox_AddString(hAnim, ENTIRE_ANIMATION_NAME); ComboBox_SetCurSel(hAnim, sel); const char* savedName = pb->GetStr(fAnimParamID); if (!savedName) savedName = ""; Mtl* mtl = IGetMtl(pb); if (mtl) { plNotetrackAnim anim(mtl, nil); while (const char* animName = anim.GetNextAnimName()) { int idx = ComboBox_AddString(hAnim, animName); ComboBox_SetItemData(hAnim, idx, 1); if (!strcmp(animName, savedName)) ComboBox_SetCurSel(hAnim, idx); } EnableWindow(hAnim, TRUE); } else EnableWindow(hAnim, FALSE); // Update the dependencies of this ILoadUser(hWnd, pb); } #include "plPickMaterialMap.h" #include "../MaxMain/plMtlCollector.h" void plMtlAnimProc::IMtlButtonPress(HWND hWnd, IParamBlock2* pb) { // Let the user pick a new material Mtl* pickedMtl = plPickMaterialMap::PickMaterial(plMtlCollector::kUsedOnly | plMtlCollector::kPlasmaOnly); // Save the mtl in the pb and update the interface if (pickedMtl != nil) { if (pb->GetParameterType(fMtlParamID) == TYPE_REFTARG) pb->SetValue(fMtlParamID, 0, (ReferenceTarget*)pickedMtl); else pb->SetValue(fMtlParamID, 0, pickedMtl); } // Make sure the current node has the selected material on it (clear it otherwise) INode* node = pb->GetINode(fNodeParamID); if (!pickedMtl || !node || node->GetMtl() != pickedMtl) pb->SetValue(fNodeParamID, 0, (INode*)nil); IUpdateMtlButton(hWnd, pb); } void plMtlAnimProc::INodeButtonPress(HWND hWnd, IParamBlock2* pb) { IPickNode(pb); IUpdateNodeButton(hWnd, pb); } void plMtlAnimProc::IAnimComboChanged(HWND hWnd, IParamBlock2* pb) { HWND hCombo = GetDlgItem(hWnd, fAnimComboID); int idx = ComboBox_GetCurSel(hCombo); if (idx != CB_ERR) { if (ComboBox_GetItemData(hCombo, idx) == 0) pb->SetValue(fAnimParamID, 0, ""); else { // Get the name of the animation and save it char buf[256]; ComboBox_GetText(hCombo, buf, sizeof(buf)); pb->SetValue(fAnimParamID, 0, buf); } } // Update the dependencies of this ILoadUser(hWnd, pb); } Mtl* plMtlAnimProc::IGetMtl(IParamBlock2* pb) { if (pb->GetParameterType(fMtlParamID) == TYPE_REFTARG) return (Mtl*)pb->GetReferenceTarget(fMtlParamID); else return pb->GetMtl(fMtlParamID); } #include "plPickNodeBase.h" static const char* kUserTypeAll = "(All)"; class plPickAllMtlNode : public plPickMtlNode { protected: void IAddUserType(HWND hList) { int idx = ListBox_AddString(hList, kUserTypeAll); if (!fPB->GetINode(fNodeParamID)) ListBox_SetCurSel(hList, idx); } void ISetUserType(plMaxNode* node, const char* userType) { if (hsStrEQ(userType, kUserTypeAll)) ISetNodeValue(nil); } public: plPickAllMtlNode(IParamBlock2* pb, int nodeParamID, Mtl* mtl) : plPickMtlNode(pb, nodeParamID, mtl) { } }; void plMtlAnimProc::IPickNode(IParamBlock2* pb) { plPickAllMtlNode pick(pb, fNodeParamID, IGetMtl(pb)); pick.DoPick(); } void plMtlAnimProc::ISetNodeButtonText(HWND hWnd, IParamBlock2* pb) { HWND hNode = GetDlgItem(hWnd, fNodeButtonID); INode* node = pb->GetINode(fNodeParamID); if (node) SetWindowText(hNode, node->GetName()); else SetWindowText(hNode, kUserTypeAll); }