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.

342 lines
9.8 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/>.
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 <algorithm>
#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;
}