// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/> // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "std_afx.h" #include "object_viewer.h" #include "ps_mover_dlg.h" #include "particle_tree_ctrl.h" #include "particle_dlg.h" #include "main_frame.h" #include "nel/3d/ps_located.h" #include "nel/3d/particle_system.h" #include "editable_range.h" #include "direction_attr.h" ///////////////////////////////////////////////////////////////////////////// // CPSMoverDlg dialog CPSMoverDlg::CPSMoverDlg(CParticleWorkspace::CNode *ownerNode, CWnd *parent, NL3D::CEvent3dMouseListener *ml, NL3D::CPSLocated *editedLocated, uint32 editedLocatedIndex) // standard constructor : CDialog(CPSMoverDlg::IDD, parent), _Node(ownerNode), _EditedLocated(editedLocated), _EditedLocatedIndex(editedLocatedIndex), _DirectionDlg(NULL), _MouseListener(ml), _Scale(NULL), _XScale(NULL), _YScale(NULL), _ZScale(NULL), _ScaleText(NULL), _XScaleText(NULL), _YScaleText(NULL), _ZScaleText(NULL) { const NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex]; m_X.Format("%.3g", pos.x); m_Y.Format("%.3g", pos.y); m_Z.Format("%.3g", pos.z); //{{AFX_DATA_INIT(CPSMoverDlg) //}}AFX_DATA_INIT } CPSMoverDlg::~CPSMoverDlg() { cleanScaleCtrl(); if (_DirectionDlg) { _DirectionDlg->DestroyWindow(); delete _DirectionDlg; } } void CPSMoverDlg::updateListener(void) { if(_ParticleDlg->MainFrame->isMoveElement()) { const NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex]; NLMISC::CMatrix m; m = _MouseListener->getModelMatrix(); m.setPos(pos); _MouseListener->setModelMatrix(m); _Node->setModified(true); } } void CPSMoverDlg::updatePosition(void) { UpdateData(); const NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex]; m_X.Format("%.3g", pos.x); m_Y.Format("%.3g", pos.y); m_Z.Format("%.3g", pos.z); UpdateData(FALSE); } void CPSMoverDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPSMoverDlg) DDX_Control(pDX, IDC_SUB_COMPONENT, m_SubComponentCtrl); DDX_Text(pDX, IDC_XPOS, m_X); DDX_Text(pDX, IDC_YPOS, m_Y); DDX_Text(pDX, IDC_ZPOS, m_Z); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CPSMoverDlg, CDialog) //{{AFX_MSG_MAP(CPSMoverDlg) ON_BN_CLICKED(IDC_UPDATE_XPOS, OnUpdateXpos) ON_BN_CLICKED(IDC_UPDATE_YPOS, OnUpdateYpos) ON_BN_CLICKED(IDC_UPDATE_ZPOS, OnUpdateZpos) ON_LBN_SELCHANGE(IDC_SUB_COMPONENT, OnSelchangeSubComponent) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPSMoverDlg message handlers void CPSMoverDlg::OnUpdateXpos() { UpdateData(); NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex]; float x; if (::sscanf(m_X, "%f", &x) == 1) { pos.x = x; updateListener(); } else { MessageBox("invalid entry", "error"); } UpdateData(FALSE); } void CPSMoverDlg::OnUpdateYpos() { UpdateData(); NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex]; float y; if (::sscanf(m_Y, "%f", &y) == 1) { pos.y = y; updateListener(); } else { MessageBox("invalid entry", "error"); } UpdateData(FALSE); } void CPSMoverDlg::OnUpdateZpos() { UpdateData(); NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex]; float z; if (::sscanf(m_Z, "%f", &z) == 1) { pos.z = z; updateListener(); } else { MessageBox("invalid entry", "error"); } UpdateData(FALSE); } BOOL CPSMoverDlg::OnInitDialog() { CDialog::OnInitDialog(); uint numBound = _EditedLocated->getNbBoundObjects(); uint nbCandidates = 0; for (uint k = 0; k < numBound; ++k) { if (dynamic_cast<NL3D::IPSMover *>(_EditedLocated->getBoundObject(k))) { uint insertedLine = m_SubComponentCtrl.AddString(_EditedLocated->getBoundObject(k)->getName().c_str()); m_SubComponentCtrl.SetItemData(insertedLine, (DWORD) _EditedLocated->getBoundObject(k)); ++nbCandidates; } } if (nbCandidates > 0) { m_SubComponentCtrl.SetCurSel(0); _EditedLocated->getOwner()->setCurrentEditedElement(_EditedLocated, _EditedLocatedIndex, (NL3D::CPSLocatedBindable *) m_SubComponentCtrl.GetItemData(0)); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CPSMoverDlg::cleanScaleCtrl(void) { #define REMOVE_WINDOW(w) if (w) { w->DestroyWindow(); delete w; w = NULL; } REMOVE_WINDOW(_Scale); REMOVE_WINDOW(_XScale); REMOVE_WINDOW(_YScale); REMOVE_WINDOW(_ZScale); REMOVE_WINDOW(_ScaleText); REMOVE_WINDOW(_XScaleText); REMOVE_WINDOW(_YScaleText); REMOVE_WINDOW(_ZScaleText); REMOVE_WINDOW(_DirectionDlg); } void CPSMoverDlg::createScaleControls(void) { cleanScaleCtrl(); NL3D::IPSMover *m = getMoverInterface(); if (!m) return; const sint xPos = 10; sint yPos = 330; RECT r; if (m->supportUniformScaling() && ! m->supportNonUniformScaling() ) { _Scale = new CEditableRangeFloat("UNIFORM SCALE", _Node, 0.f, 4.f); _UniformScaleWrapper.M = m; _UniformScaleWrapper.Index = _EditedLocatedIndex; _Scale->setWrapper(&_UniformScaleWrapper); _Scale->init(100 + xPos, yPos, this); _ScaleText = new CStatic; _ScaleText ->Create("Scale : ", SS_LEFT, CRect(xPos, yPos + 10, xPos + 60, yPos + 32), this); _ScaleText ->ShowWindow(SW_SHOW); _Scale->GetClientRect(&r); yPos += r.bottom; } else if (m->supportNonUniformScaling()) { // dialog for edition of x scale _XScale = new CEditableRangeFloat("X SCALE", _Node, 0.f, 4.f); _XScaleWrapper.M = m; _XScaleWrapper.Index = _EditedLocatedIndex; _XScale->setWrapper(&_XScaleWrapper); _XScale->init(xPos + 70, yPos, this); _XScale->GetClientRect(&r); _XScaleText = new CStatic; _XScaleText ->Create("x Scale : ", SS_LEFT, CRect(xPos, yPos + 10, xPos + 60, yPos + 32), this); _XScaleText ->ShowWindow(SW_SHOW); yPos += r.bottom; // dialog for edition of y scale _YScale = new CEditableRangeFloat("Y SCALE", _Node, 0.f, 4.f); _YScaleWrapper.M = m; _YScaleWrapper.Index = _EditedLocatedIndex; _YScale->setWrapper(&_YScaleWrapper); _YScale->init(xPos + 70, yPos, this); _YScale->GetClientRect(&r); _YScaleText = new CStatic; _YScaleText ->Create("y Scale : ", SS_LEFT, CRect(xPos, yPos + 10, xPos + 60, yPos + 32), this); _YScaleText ->ShowWindow(SW_SHOW); yPos += r.bottom; // dialog for edition of x scale _ZScale = new CEditableRangeFloat("Z SCALE", _Node, 0.f, 4.f); _ZScaleWrapper.M = m; _ZScaleWrapper.Index = _EditedLocatedIndex; _ZScale->setWrapper(&_ZScaleWrapper); _ZScale->init(xPos + 70, yPos, this); _ZScale->GetClientRect(&r); _ZScaleText = new CStatic; _ZScaleText ->Create("z Scale : ", SS_LEFT, CRect(xPos, yPos + 10, xPos + 60, yPos + 32), this); _ZScaleText ->ShowWindow(SW_SHOW); } if (m->onlyStoreNormal()) { _DirectionDlg = new CDirectionAttr(" ELEMENT DIRECTION"); _DirectionDlg->init(xPos, yPos, this); _DirectionWrapper.M = m; _DirectionWrapper.Index = _EditedLocatedIndex; _DirectionDlg->setWrapper(&_DirectionWrapper); } } void CPSMoverDlg::OnSelchangeSubComponent() { UpdateData(); createScaleControls(); _EditedLocated->getOwner()->setCurrentEditedElement(_EditedLocated, _EditedLocatedIndex, getLocatedBindable()); UpdateData(FALSE); } NL3D::IPSMover *CPSMoverDlg::getMoverInterface(void) { UpdateData(); nlassert(_EditedLocated); sint currIndex = m_SubComponentCtrl.GetCurSel(); if (currIndex == -1) return NULL; return dynamic_cast<NL3D::IPSMover *>((NL3D::CPSLocatedBindable *)(m_SubComponentCtrl.GetItemData(currIndex))); } void CPSMoverDlg::init(CParticleDlg *parent) { _ParticleDlg= parent; Create(CPSMoverDlg::IDD, parent); ShowWindow(SW_SHOW); createScaleControls(); } NL3D::CPSLocatedBindable *CPSMoverDlg::getLocatedBindable(void) { UpdateData(); nlassert(_EditedLocated); sint currIndex = m_SubComponentCtrl.GetCurSel(); if (currIndex == -1) return NULL; return (NL3D::CPSLocatedBindable *) m_SubComponentCtrl.GetItemData(currIndex); }