/*==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 "plPickNodeBase.h" #include "../MaxMain/plMaxNode.h" #include "plComponentBase.h" #include "resource.h" #include "../MaxMain/plMaxAccelerators.h" #include plPickNodeBase::plPickNodeBase(IParamBlock2* pb, int nodeParamID) : fPB(pb), fNodeParamID(nodeParamID) { } bool plPickNodeBase::DoPick() { plMaxAccelerators::Disable(); // Create Dlg BOOL ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PICK_NODE), GetCOREInterface()->GetMAXHWnd(), IDlgProc, (LPARAM)this); plMaxAccelerators::Enable(); return (ret != 0); } void plPickNodeBase::IInitDlg(HWND hDlg) { HWND hList = GetDlgItem(hDlg, IDC_NODE_LIST); // int idx = ListBox_AddString(hList, kUserTypeNone); // ListBox_SetCurSel(hList, idx); IAddUserType(hList); // LONG style = GetWindowLong(hList, GWL_STYLE); // SetWindowLong(hList, GWL_STYLE, style | LBS_MULTIPLESEL); plMaxNode* curSelNode = nil; ParamType2 type = fPB->GetParameterType(fNodeParamID); if (type == TYPE_REFTARG) curSelNode = (plMaxNode*)fPB->GetReferenceTarget(fNodeParamID); else if (type == TYPE_INODE) curSelNode = (plMaxNode*)fPB->GetINode(fNodeParamID); IGetNodesRecur((plMaxNode*)GetCOREInterface()->GetRootNode(), hList, curSelNode); } BOOL plPickNodeBase::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static plPickNodeBase* pthis = nil; switch (msg) { case WM_INITDIALOG: pthis = (plPickNodeBase*)lParam; pthis->IInitDlg(hDlg); return TRUE; case WM_COMMAND: // For 'OK' or double-click, get the selected node and exit if ((HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK) || (HIWORD(wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_NODE_LIST)) { pthis->IGetSelNode(GetDlgItem(hDlg, IDC_NODE_LIST)); EndDialog(hDlg, 1); return TRUE; } else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, 0); return TRUE; } break; } return FALSE; } void plPickNodeBase::IGetNodesRecur(plMaxNode* node, HWND hList, plMaxNode* curSelNode) { if (node) { if (ICheckNode(node)) { int idx = ListBox_AddString(hList, node->GetName()); ListBox_SetItemData(hList, idx, node); if (node == curSelNode) ListBox_SetCurSel(hList, idx); } int numChildren = node->NumberOfChildren(); for (int i = 0; i < numChildren; i++) { IGetNodesRecur((plMaxNode*)node->GetChildNode(i), hList, curSelNode); } } } void plPickNodeBase::ISetNodeValue(plMaxNode* node) { ParamType2 type = fPB->GetParameterType(fNodeParamID); if (type == TYPE_REFTARG) { fPB->SetValue(fNodeParamID, 0, (ReferenceTarget*)node); } // else if (type == TYPE_REFTARG_TAB) // { // } else if (type == TYPE_INODE) { fPB->SetValue(fNodeParamID, 0, (INode*)node); } // else if (type == TYPE_INODE_TAB) // { // } } void plPickNodeBase::IGetSelNode(HWND hList) { int sel = ListBox_GetCurSel(hList); if (sel == LB_ERR) return; plMaxNode* node = (plMaxNode*)ListBox_GetItemData(hList, sel); if (node) { ISetNodeValue(node); ISetUserType(node, nil); } else { int len = ListBox_GetTextLen(hList, sel); char* buf = TRACKED_NEW char[len+1]; ListBox_GetText(hList, sel, buf); /* if (!strcmp(buf, kUserTypeNone)) { ISetNodeValue(nil); ISetUserType(nil, nil); } else */ ISetUserType(nil, buf); delete [] buf; } } ///////////////////////////////////////////////////////////////// plPickNode::plPickNode(IParamBlock2* pb, int nodeParamID) : plPickNodeBase(pb, nodeParamID) { } bool plPickNode::ICanConvertToType(Object *obj) { for (int i = 0; i < fCIDs.size(); i++) { if (obj->CanConvertToType(fCIDs[i])) return true; } return false; } bool plPickNode::ICheckNode(plMaxNode* node) { if (node->GetObjectRef()) { // Not filtering by ClassID and node is hidden or frozen if (fCIDs.size() == 0 && (node->IsHidden() || node->IsFrozen())) return false; // We aren't filtering by ClassID or we are and we found a match if (fCIDs.size() == 0 || (fCanConvertToType && ICanConvertToType(node->GetObjectRef()) || std::find(fCIDs.begin(), fCIDs.end(), node->GetObjectRef()->ClassID()) != fCIDs.end())) { // Don't allow a ref to ourselves (a cyclical reference) if (fPB->GetOwner() == node) return false; // Approved and not in the list, add it return true; } } return false; } /////////////////////////////////////////////////////////////// plPickMtlNode::plPickMtlNode(IParamBlock2* pb, int nodeParamID, Mtl* mtl) : plPickNodeBase(pb, nodeParamID), fMtl(mtl) { } bool plPickMtlNode::ICheckNode(plMaxNode* node) { // Filtering by nodes with a specific material on them if (fMtl && node->GetMtl() == fMtl) return true; return false; } ///////////////////////////////////////////////////// plPickCompNode::plPickCompNode(IParamBlock2* pb, int nodeParamID, plComponentBase* comp) : plPickNodeBase(pb, nodeParamID), fComp(comp) { } bool plPickCompNode::ICheckNode(plMaxNode* node) { // Filtering by nodes a component is attached to if (fComp && fComp->IsTarget((plMaxNodeBase*)node)) return true; return false; }