/*==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 "plResponderGetComp.h" #include #include "../MaxMain/plMaxNodeBase.h" #include "resource.h" #include "plComponentBase.h" #include "../MaxMain/plMaxAccelerators.h" plResponderGetComp& plResponderGetComp::Instance() { static plResponderGetComp theInstance; return theInstance; } bool plResponderGetComp::GetComp(IParamBlock2 *pb, int nodeID, int compID, ClassIDs *classIDs) { fPB = pb; fNodeID = nodeID; fCompID = compID; fClassIDs = classIDs; plMaxAccelerators::Disable(); int ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_COMP_RESPOND_ANIMPICK), GetCOREInterface()->GetMAXHWnd(), ForwardDlgProc); plMaxAccelerators::Enable(); return (ret != 0); } plComponentBase *plResponderGetComp::GetSavedComp(IParamBlock2 *pb, int nodeID, int compID, bool convertTime) { plMaxNodeBase *node = (plMaxNodeBase*)pb->GetReferenceTarget(nodeID); // This value could be whack, only use if node is valid plMaxNodeBase *comp = (plMaxNodeBase*)pb->GetReferenceTarget(compID); if (!node || (convertTime && !node->CanConvert()) || !comp) return nil; int numComps = node->NumAttachedComponents(); for (int i = 0; i < numComps; i++) { plComponentBase *thisComp = node->GetAttachedComponent(i); if (thisComp->GetINode() == comp) return thisComp; } return nil; } void plResponderGetComp::IFindCompsRecur(plMaxNodeBase *node, NodeSet& nodes) { plComponentBase *comp = node->ConvertToComponent(); if (comp) { // If we're not filtering, or we are and this component is in our accepted list, add it if (!fClassIDs || std::find(fClassIDs->begin(), fClassIDs->end(), comp->ClassID()) != fClassIDs->end()) { nodes.insert(node); } } for (int i = 0; i < node->NumberOfChildren(); i++) IFindCompsRecur((plMaxNodeBase*)node->GetChildNode(i), nodes); } void plResponderGetComp::ILoadNodes(plMaxNodeBase *compNode, HWND hDlg) { HWND hNodes = GetDlgItem(hDlg, IDC_OBJ_LIST); ListBox_ResetContent(hNodes); plComponentBase *comp = compNode ? compNode->ConvertToComponent() : nil; if (!comp) return; plMaxNodeBase *savedNode = (plMaxNodeBase*)fPB->GetReferenceTarget(fNodeID); for (int i = 0; i < comp->NumTargets(); i++) { plMaxNodeBase *node = comp->GetTarget(i); if (node) { int idx = ListBox_AddString(hNodes, node->GetName()); ListBox_SetItemData(hNodes, idx, node); if (savedNode == node) ListBox_SetCurSel(hNodes, idx); } } } BOOL CALLBACK plResponderGetComp::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { return Instance().DlgProc(hDlg, msg, wParam, lParam); } BOOL plResponderGetComp::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { NodeSet nodes; IFindCompsRecur((plMaxNodeBase*)GetCOREInterface()->GetRootNode(), nodes); HWND hComps = GetDlgItem(hDlg, IDC_COMP_LIST); plMaxNodeBase *node = (plMaxNodeBase*)fPB->GetReferenceTarget(fCompID); for (NodeSet::iterator it = nodes.begin(); it != nodes.end(); it++) { int idx = ListBox_AddString(hComps, (*it)->GetName()); ListBox_SetItemData(hComps, idx, *it); if (*it == node) ListBox_SetCurSel(hComps, idx); } ILoadNodes(node, hDlg); } return TRUE; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, 0); return TRUE; } else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK) { // Get the selected node HWND hNode = GetDlgItem(hDlg, IDC_OBJ_LIST); int idx = ListBox_GetCurSel(hNode); plMaxNodeBase *node = nil; if (idx != LB_ERR) node = (plMaxNodeBase*)ListBox_GetItemData(hNode, idx); // Get the selected component HWND hComp = GetDlgItem(hDlg, IDC_COMP_LIST); idx = ListBox_GetCurSel(hComp); plMaxNodeBase *comp = nil; if (idx != LB_ERR) comp = (plMaxNodeBase*)ListBox_GetItemData(hComp, idx); // If both were selected, save them in the PB and as the last setting if (node && comp) { #if 0 if (fType == kFindAnim) { fLastAnimObj = obj->GetHandle(); fLastAnimComp = comp->GetHandle(); } else if (fType == kFindSound) { fLastSoundObj = obj->GetHandle(); fLastSoundComp = comp->GetHandle(); } #endif fPB->SetValue(fNodeID, 0, (ReferenceTarget*)node); fPB->SetValue(fCompID, 0, (ReferenceTarget*)comp); EndDialog(hDlg, 1); } else EndDialog(hDlg, 0); return TRUE; } else if (HIWORD(wParam) == LBN_SELCHANGE) { if (LOWORD(wParam) == IDC_COMP_LIST) { int idx = ListBox_GetCurSel((HWND)lParam); plMaxNodeBase *node = (plMaxNodeBase*)ListBox_GetItemData((HWND)lParam, idx); ILoadNodes(node, hDlg); } } break; } return FALSE; } /////////////////////////////////////////////////////////////////////////// #include "plPickNode.h" void plResponderCompNode::Init(IParamBlock2 *pb, int compID, int nodeID, int compResID, int nodeResID, ClassIDs *compCIDs) { fPB = pb; fCompID = compID; fNodeID = nodeID; fCompResID = compResID; fNodeResID = nodeResID; if (compCIDs) fCompCIDs = *compCIDs; } void plResponderCompNode::InitDlg(HWND hWnd) { IValidate(); IUpdateNodeButton(hWnd); IUpdateCompButton(hWnd); } bool plResponderCompNode::IValidate() { plMaxNodeBase *savedComp = (plMaxNodeBase*)fPB->GetReferenceTarget(fCompID); plComponentBase *comp = savedComp ? savedComp->ConvertToComponent() : nil; plMaxNodeBase *node = (plMaxNodeBase*)fPB->GetReferenceTarget(fNodeID); if (comp && node) { // Make sure the selected comp has the correct CID if (fCompCIDs.size() > 0) { Class_ID compCID = comp->ClassID(); bool foundCID = false; for (int i = 0; i < fCompCIDs.size(); i++) { if (fCompCIDs[i] == compCID) foundCID = true; } if (!foundCID) { fPB->SetValue(fCompID, 0, (INode*)nil); fPB->SetValue(fNodeID, 0, (INode*)nil); return false; } } // Make sure the comp is really attached to the node if (comp->IsTarget(node)) return true; else fPB->SetValue(fNodeID, 0, (INode*)nil); } return false; } void plResponderCompNode::CompButtonPress(HWND hWnd) { plPick::Node(fPB, fCompID, &fCompCIDs, true, false); IUpdateCompButton(hWnd); IUpdateNodeButton(hWnd); } void plResponderCompNode::NodeButtonPress(HWND hWnd) { plMaxNodeBase *node = (plMaxNodeBase*)fPB->GetReferenceTarget(fCompID); plComponentBase *comp = node ? node->ConvertToComponent() : nil; if (comp) plPick::CompTargets(fPB, fNodeID, comp); IUpdateNodeButton(hWnd); } void plResponderCompNode::IUpdateCompButton(HWND hWnd) { HWND hComp = GetDlgItem(hWnd, fCompResID); plMaxNodeBase *savedComp = (plMaxNodeBase*)fPB->GetReferenceTarget(fCompID); if (savedComp) SetWindowText(hComp, savedComp->GetName()); else SetWindowText(hComp, "(none)"); } void plResponderCompNode::IUpdateNodeButton(HWND hWnd) { HWND hNode = GetDlgItem(hWnd, fNodeResID); // If there is no component, disable the node button plMaxNodeBase *node = (plMaxNodeBase*)fPB->GetReferenceTarget(fCompID); plComponentBase *comp = node ? node->ConvertToComponent() : nil; if (!comp) { EnableWindow(hNode, FALSE); SetWindowText(hNode, "(none)"); return; } EnableWindow(hNode, TRUE); plMaxNodeBase *objNode = (plMaxNodeBase*)fPB->GetReferenceTarget(fNodeID); if (objNode && comp->IsTarget(objNode)) SetWindowText(hNode, objNode->GetName()); else SetWindowText(hNode, "(none)"); } bool plResponderCompNode::GetCompAndNode(plComponentBase*& comp, plMaxNodeBase*& node) { if (!IValidate()) { comp = nil; node = nil; return false; } plMaxNodeBase *savedComp = (plMaxNodeBase*)fPB->GetReferenceTarget(fCompID); comp = savedComp ? savedComp->ConvertToComponent() : nil; node = (plMaxNodeBase*)fPB->GetReferenceTarget(fNodeID); return true; }