1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "object_viewer.h"
22 #include "ps_mover_dlg.h"
23 #include "particle_tree_ctrl.h"
24 #include "particle_dlg.h"
25 #include "main_frame.h"
26 #include "nel/3d/ps_located.h"
27 #include "nel/3d/particle_system.h"
30 #include "editable_range.h"
31 #include "direction_attr.h"
33 /////////////////////////////////////////////////////////////////////////////
37 CPSMoverDlg::CPSMoverDlg(CParticleWorkspace::CNode
*ownerNode
, CWnd
*parent
, NL3D::CEvent3dMouseListener
*ml
, NL3D::CPSLocated
*editedLocated
, uint32 editedLocatedIndex
) // standard constructor
38 : CDialog(CPSMoverDlg::IDD
, parent
),
40 _EditedLocated(editedLocated
),
41 _EditedLocatedIndex(editedLocatedIndex
),
44 _Scale(NULL
), _XScale(NULL
), _YScale(NULL
), _ZScale(NULL
),
45 _ScaleText(NULL
), _XScaleText(NULL
), _YScaleText(NULL
), _ZScaleText(NULL
)
50 const NLMISC::CVector
&pos
= _EditedLocated
->getPos()[_EditedLocatedIndex
];
52 m_X
.Format(_T("%.3g"), pos
.x
);
53 m_Y
.Format(_T("%.3g"), pos
.y
);
54 m_Z
.Format(_T("%.3g"), pos
.z
);
56 //{{AFX_DATA_INIT(CPSMoverDlg)
62 CPSMoverDlg::~CPSMoverDlg()
67 _DirectionDlg
->DestroyWindow();
72 void CPSMoverDlg::updateListener(void)
74 if(_ParticleDlg
->MainFrame
->isMoveElement())
76 const NLMISC::CVector
&pos
= _EditedLocated
->getPos()[_EditedLocatedIndex
];
78 m
= _MouseListener
->getModelMatrix();
80 _MouseListener
->setModelMatrix(m
);
81 _Node
->setModified(true);
85 void CPSMoverDlg::updatePosition(void)
88 const NLMISC::CVector
&pos
= _EditedLocated
->getPos()[_EditedLocatedIndex
];
90 m_X
.Format(_T("%.3g"), pos
.x
);
91 m_Y
.Format(_T("%.3g"), pos
.y
);
92 m_Z
.Format(_T("%.3g"), pos
.z
);
97 void CPSMoverDlg::DoDataExchange(CDataExchange
* pDX
)
99 CDialog::DoDataExchange(pDX
);
100 //{{AFX_DATA_MAP(CPSMoverDlg)
101 DDX_Control(pDX
, IDC_SUB_COMPONENT
, m_SubComponentCtrl
);
102 DDX_Text(pDX
, IDC_XPOS
, m_X
);
103 DDX_Text(pDX
, IDC_YPOS
, m_Y
);
104 DDX_Text(pDX
, IDC_ZPOS
, m_Z
);
109 BEGIN_MESSAGE_MAP(CPSMoverDlg
, CDialog
)
110 //{{AFX_MSG_MAP(CPSMoverDlg)
111 ON_BN_CLICKED(IDC_UPDATE_XPOS
, OnUpdateXpos
)
112 ON_BN_CLICKED(IDC_UPDATE_YPOS
, OnUpdateYpos
)
113 ON_BN_CLICKED(IDC_UPDATE_ZPOS
, OnUpdateZpos
)
114 ON_LBN_SELCHANGE(IDC_SUB_COMPONENT
, OnSelchangeSubComponent
)
118 /////////////////////////////////////////////////////////////////////////////
119 // CPSMoverDlg message handlers
121 void CPSMoverDlg::OnUpdateXpos()
124 NLMISC::CVector
&pos
= _EditedLocated
->getPos()[_EditedLocatedIndex
];
126 if (NLMISC::fromString(NLMISC::tStrToUtf8(m_X
), x
))
133 MessageBox(_T("invalid entry"), _T("error"));
138 void CPSMoverDlg::OnUpdateYpos()
141 NLMISC::CVector
&pos
= _EditedLocated
->getPos()[_EditedLocatedIndex
];
143 if (NLMISC::fromString(NLMISC::tStrToUtf8(m_Y
), y
))
150 MessageBox(_T("invalid entry"), _T("error"));
155 void CPSMoverDlg::OnUpdateZpos()
158 NLMISC::CVector
&pos
= _EditedLocated
->getPos()[_EditedLocatedIndex
];
160 if (NLMISC::fromString(NLMISC::tStrToUtf8(m_Z
), z
))
167 MessageBox(_T("invalid entry"), _T("error"));
172 BOOL
CPSMoverDlg::OnInitDialog()
174 CDialog::OnInitDialog();
176 uint numBound
= _EditedLocated
->getNbBoundObjects();
178 uint nbCandidates
= 0;
180 for (uint k
= 0; k
< numBound
; ++k
)
182 if (dynamic_cast<NL3D::IPSMover
*>(_EditedLocated
->getBoundObject(k
)))
184 uint insertedLine
= m_SubComponentCtrl
.AddString(nlUtf8ToTStr(_EditedLocated
->getBoundObject(k
)->getName()));
185 m_SubComponentCtrl
.SetItemData(insertedLine
, (DWORD_PTR
) _EditedLocated
->getBoundObject(k
));
190 if (nbCandidates
> 0)
192 m_SubComponentCtrl
.SetCurSel(0);
193 _EditedLocated
->getOwner()->setCurrentEditedElement(_EditedLocated
, _EditedLocatedIndex
, (NL3D::CPSLocatedBindable
*) m_SubComponentCtrl
.GetItemData(0));
196 return TRUE
; // return TRUE unless you set the focus to a control
197 // EXCEPTION: OCX Property Pages should return FALSE
200 void CPSMoverDlg::cleanScaleCtrl(void)
202 #define REMOVE_WINDOW(w) if (w) { w->DestroyWindow(); delete w; w = NULL; }
204 REMOVE_WINDOW(_Scale
);
205 REMOVE_WINDOW(_XScale
);
206 REMOVE_WINDOW(_YScale
);
207 REMOVE_WINDOW(_ZScale
);
209 REMOVE_WINDOW(_ScaleText
);
210 REMOVE_WINDOW(_XScaleText
);
211 REMOVE_WINDOW(_YScaleText
);
212 REMOVE_WINDOW(_ZScaleText
);
213 REMOVE_WINDOW(_DirectionDlg
);
216 void CPSMoverDlg::createScaleControls(void)
221 NL3D::IPSMover
*m
= getMoverInterface();
224 const sint xPos
= 10;
231 if (m
->supportUniformScaling() && ! m
->supportNonUniformScaling() )
233 _Scale
= new CEditableRangeFloat("UNIFORM SCALE", _Node
, 0.f
, 4.f
);
234 _UniformScaleWrapper
.M
= m
;
235 _UniformScaleWrapper
.Index
= _EditedLocatedIndex
;
237 _Scale
->setWrapper(&_UniformScaleWrapper
);
238 _Scale
->init(100 + xPos
, yPos
, this);
240 _ScaleText
= new CStatic
;
241 _ScaleText
->Create(_T("Scale : "), SS_LEFT
, CRect(xPos
, yPos
+ 10, xPos
+ 60, yPos
+ 32), this);
242 _ScaleText
->ShowWindow(SW_SHOW
);
244 _Scale
->GetClientRect(&r
);
247 else if (m
->supportNonUniformScaling())
251 // dialog for edition of x scale
252 _XScale
= new CEditableRangeFloat("X SCALE", _Node
, 0.f
, 4.f
);
253 _XScaleWrapper
.M
= m
;
254 _XScaleWrapper
.Index
= _EditedLocatedIndex
;
255 _XScale
->setWrapper(&_XScaleWrapper
);
256 _XScale
->init(xPos
+ 70, yPos
, this);
257 _XScale
->GetClientRect(&r
);
259 _XScaleText
= new CStatic
;
260 _XScaleText
->Create(_T("x Scale : "), SS_LEFT
, CRect(xPos
, yPos
+ 10, xPos
+ 60, yPos
+ 32), this);
261 _XScaleText
->ShowWindow(SW_SHOW
);
265 // dialog for edition of y scale
266 _YScale
= new CEditableRangeFloat("Y SCALE", _Node
, 0.f
, 4.f
);
267 _YScaleWrapper
.M
= m
;
268 _YScaleWrapper
.Index
= _EditedLocatedIndex
;
269 _YScale
->setWrapper(&_YScaleWrapper
);
270 _YScale
->init(xPos
+ 70, yPos
, this);
271 _YScale
->GetClientRect(&r
);
274 _YScaleText
= new CStatic
;
275 _YScaleText
->Create(_T("y Scale : "), SS_LEFT
, CRect(xPos
, yPos
+ 10, xPos
+ 60, yPos
+ 32), this);
276 _YScaleText
->ShowWindow(SW_SHOW
);
280 // dialog for edition of x scale
281 _ZScale
= new CEditableRangeFloat("Z SCALE", _Node
, 0.f
, 4.f
);
282 _ZScaleWrapper
.M
= m
;
283 _ZScaleWrapper
.Index
= _EditedLocatedIndex
;
284 _ZScale
->setWrapper(&_ZScaleWrapper
);
285 _ZScale
->init(xPos
+ 70, yPos
, this);
286 _ZScale
->GetClientRect(&r
);
288 _ZScaleText
= new CStatic
;
289 _ZScaleText
->Create(_T("z Scale : "), SS_LEFT
, CRect(xPos
, yPos
+ 10, xPos
+ 60, yPos
+ 32), this);
290 _ZScaleText
->ShowWindow(SW_SHOW
);
294 if (m
->onlyStoreNormal())
296 _DirectionDlg
= new CDirectionAttr(" ELEMENT DIRECTION");
297 _DirectionDlg
->init(xPos
, yPos
, this);
298 _DirectionWrapper
.M
= m
;
299 _DirectionWrapper
.Index
= _EditedLocatedIndex
;
300 _DirectionDlg
->setWrapper(&_DirectionWrapper
);
306 void CPSMoverDlg::OnSelchangeSubComponent()
309 createScaleControls();
310 _EditedLocated
->getOwner()->setCurrentEditedElement(_EditedLocated
, _EditedLocatedIndex
, getLocatedBindable());
315 NL3D::IPSMover
*CPSMoverDlg::getMoverInterface(void)
318 nlassert(_EditedLocated
);
319 sint currIndex
= m_SubComponentCtrl
.GetCurSel();
320 if (currIndex
== -1) return NULL
;
321 return dynamic_cast<NL3D::IPSMover
*>((NL3D::CPSLocatedBindable
*)(m_SubComponentCtrl
.GetItemData(currIndex
)));
324 void CPSMoverDlg::init(CParticleDlg
*parent
)
326 _ParticleDlg
= parent
;
328 Create(CPSMoverDlg::IDD
, parent
);
330 createScaleControls();
334 NL3D::CPSLocatedBindable
*CPSMoverDlg::getLocatedBindable(void)
337 nlassert(_EditedLocated
);
338 sint currIndex
= m_SubComponentCtrl
.GetCurSel();
339 if (currIndex
== -1) return NULL
;
341 return (NL3D::CPSLocatedBindable
*) m_SubComponentCtrl
.GetItemData(currIndex
);