Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / tools / 3d / object_viewer / attrib_dlg.cpp
blob6a6d48dd915815e979b97bdbd7081f951c089d05
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2010-2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
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/>.
20 // attrib_dlg.cpp : implementation file
25 #include "std_afx.h"
26 #include "object_viewer.h"
27 #include "attrib_dlg.h"
28 #include "editable_range.h"
29 #include "color_edit.h"
30 #include "basis_edit.h"
31 #include "value_blender_dlg.h"
32 #include "value_gradient_dlg.h"
33 #include "value_from_emitter_dlg.h"
34 #include "bin_op_dlg.h"
35 #include "edit_user_param.h"
36 #include "edit_spinner.h"
37 #include "edit_follow_path.h"
38 #include "scheme_bank_dlg.h"
39 #include "scheme_manager.h"
40 #include "choose_name.h"
41 #include "curve_edit.h"
44 #include "nel/3d/ps_attrib_maker.h"
45 #include "nel/3d/ps_float.h"
46 #include "nel/3d/ps_int.h"
47 #include "nel/3d/ps_color.h"
48 #include "nel/3d/ps_plane_basis.h"
49 #include "nel/3d/ps_plane_basis_maker.h"
54 /*static char trace_buf[200];
55 #define NL_TRACE sprintf(trace_buf, "%d", __LINE__); \
56 ::MessageBox(NULL, trace_buf, NULL, MB_OK);
59 /////////////////////////////////////////////////////////////////////
60 // WRAPPERS to set / retrieve the NbCycles parameter of a scheme //
61 /////////////////////////////////////////////////////////////////////
62 static float NbCyclesReader(void *lParam) { return ((CAttribDlg *) lParam)->getSchemeNbCycles(); }
63 static void NbCyclesWriter(float value, void *lParam) { ((CAttribDlg *) lParam)->setSchemeNbCycles(value); }
67 ///////////////////////////////////////////
68 // GENERAL INTERFACE FOR BLENDER EDITION //
69 ///////////////////////////////////////////
72 /** T is the type to be edited (color, float, etc..),
73 * even if it is unused
76 template <typename T>
77 class CValueBlenderDlgClientT : public IValueBlenderDlgClient
79 public:
80 std::string Id; // the Id of each of the dialog (it will be followed by %1 or %2)
81 // must be filled by the user
82 // the scheme being used. Must be set by the user
83 NL3D::CPSValueBlendFuncBase<T> *SchemeFunc;
85 protected:
86 virtual CEditAttribDlg *createDialog(uint index, CParticleWorkspace::CNode *ownerNode)
88 std::string id = Id;
89 if (index == 0) id += "%1"; else id += "%2";
90 _ValueInfos[index].ValueIndex = index;
91 _ValueInfos[index].SchemeFunc = SchemeFunc;
92 _ValueInfos[index].OwnerNode = ownerNode;
93 return newDialog(id, &_ValueInfos[index]);
97 // construct a dialog with the given wrapper and id
98 virtual CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<T> *wrapper) = 0;
100 // inherited from IPSWrapper<T>
101 struct COneValueInfo : public IPSWrapper<T>
103 // value 0 or 1 being edited
104 uint ValueIndex;
105 // the scheme being edited
106 NL3D::CPSValueBlendFuncBase<T> *SchemeFunc;
108 virtual T get(void) const
110 T t1, t2;
111 SchemeFunc->getValues(t1, t2);
112 return ValueIndex == 0 ? t1 : t2;
114 virtual void set(const T &value)
116 T t1, t2;
117 SchemeFunc->getValues(t1, t2);
118 if (ValueIndex == 0 ) t1 = value; else t2 = value;
119 SchemeFunc->setValues(t1, t2);
123 COneValueInfo _ValueInfos[2];
127 ////////////////////////////////////////////
128 // GENERAL INTERFACE FOR GRADIENT EDITION //
129 ////////////////////////////////////////////
131 /** This template generate an interface that is used with the gradient edition dialog
132 * T is the type to be edited (color, floet, etc..)
136 template <typename T>
137 class CValueGradientDlgClientT : public IValueGradientDlgClient, public IPSWrapper<T>
139 public:
141 std::string Id; // the Id of each of the dialog (it will be followed by %1 or %2)
142 // must be filled by the user
143 // the gradient being edited, must be filled by the instancier
144 NL3D::CPSValueGradientFunc<T> *Scheme;
145 // the gradient dialog, must be filled by the instancier
146 CValueGradientDlg *GradDlg;
147 // the difault value for new values creation. Must be filled by the instancier
148 T DefaultValue;
150 /// a function that can display a value in a gradient, with the given offset. Deriver must define this
151 virtual void displayValue(CDC *dc, uint index, sint x, sint y) = 0;
154 /// inherited from IPSWrapper
155 virtual T get(void) const { return Scheme->getValue(_CurrentEditedIndex); }
156 virtual void set(const T &v)
158 T *tab = new T[Scheme->getNumValues()];
159 Scheme->getValues(tab);
160 tab[_CurrentEditedIndex] = v;
161 Scheme->setValues(tab, Scheme->getNumValues(), Scheme->getNumStages());
162 delete[] tab;
163 GradDlg->invalidateGrad();
166 /** must provide a dialog for the edition of one value (only ONE exist at a time)
167 * \param index the index of the value in the dialog
168 * \grad the dlg that called this method (deriver can ask a redraw then)
170 virtual CEditAttribDlg *createDialog(uint index, CValueGradientDlg *grad, CParticleWorkspace::CNode *ownerNode)
172 OwnerNode = ownerNode;
173 _CurrentEditedIndex = index;
174 return newDialog(Id, this);
177 /// create a new dialog with given id and wrapper
178 virtual CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<T> *wrapper) = 0;
181 /// a function that can add, remove, or insert a new element in the gradient
182 virtual void modifyGradient(TAction action, uint index)
185 T *tab = new T[Scheme->getNumValues() + 1]; // +1 is for the add / insert case
186 Scheme->getValues(tab);
188 switch(action)
190 case IValueGradientDlgClient::Add:
191 tab[Scheme->getNumValues()] = DefaultValue;
192 Scheme->setValues(tab, Scheme->getNumValues() + 1, Scheme->getNumStages());
193 break;
194 case IValueGradientDlgClient::Insert:
195 ::memmove(tab + (index + 1), tab + index, sizeof(T) * (Scheme->getNumValues() - index));
196 tab[index] = DefaultValue;
197 Scheme->setValues(tab, Scheme->getNumValues() + 1, Scheme->getNumStages());
198 break;
199 case IValueGradientDlgClient::Delete:
200 ::memmove(tab + index, tab + index + 1, sizeof(T) * (Scheme->getNumValues() - index - 1));
201 Scheme->setValues(tab, Scheme->getNumValues() - 1, Scheme->getNumStages());
202 break;
203 case IValueGradientDlgClient::Up:
204 nlassert(index > 0);
205 std::swap(tab[index], tab[index - 1]);
206 Scheme->setValues(tab, Scheme->getNumValues(), Scheme->getNumStages());
207 break;
208 case IValueGradientDlgClient::Down:
209 nlassert(index < Scheme->getNumValues() - 1);
210 std::swap(tab[index], tab[index + 1]);
211 Scheme->setValues(tab, Scheme->getNumValues(), Scheme->getNumStages());
212 break;
215 delete[] tab;
217 virtual uint32 getSchemeSize(void) const { return Scheme->getNumValues(); }
219 // get the number of interpolation step
220 uint32 getNbSteps(void) const
222 return Scheme->getNumStages();
225 // set the number of interpolation steps
226 void setNbSteps(uint32 value)
228 Scheme->setNumStages(value);
231 protected:
232 // index of the value OF the current dialog that exist
233 uint32 _CurrentEditedIndex;
238 /////////////////////////////////////////////////////////////////////////////
239 // CAttribDlg dialog
242 //*************************************************************************************************************
243 CAttribDlg::CAttribDlg(const std::string &valueID, CParticleWorkspace::CNode *ownerNode, bool enableConstantValue /* = true*/)
244 : _CstValueDlg(NULL),
245 _Node(ownerNode),
246 _FirstDrawing(true),
247 _EnableConstantValue(enableConstantValue),
248 _DisableMemoryScheme(false),
249 _SchemeEditionDlg(NULL),
250 _NbCycleEnabled(true),
251 _NbCyclesDlg(NULL),
252 _ValueID(valueID),
253 _SrcInputEnabled(true)
255 //{{AFX_DATA_INIT(CAttribDlg)
256 m_AttribName = _T("");
257 m_Clamp = FALSE;
258 //}}AFX_DATA_INIT
262 //*************************************************************************************************************
263 void CAttribDlg::closeEditWindow()
265 childPopupClosed(NULL);
269 //*************************************************************************************************************
270 BOOL CAttribDlg::EnableWindow( BOOL bEnable)
272 if (_CstValueDlg)
274 _CstValueDlg->EnableWindow(bEnable);
277 if (_NbCyclesDlg)
279 _NbCyclesDlg->EnableWindow(bEnable);
281 m_UseScheme.EnableWindow(bEnable);
282 m_AttrBitmap.EnableWindow(bEnable);
284 if (useScheme())
286 m_Scheme.EnableWindow(bEnable);
287 m_SchemeInput.EnableWindow(hasSchemeCustomInput() ? bEnable : FALSE);
288 m_EditScheme.EnableWindow(bEnable);
289 m_GetScheme.EnableWindow(bEnable);
290 m_PutScheme.EnableWindow(bEnable);
291 m_ClampCtrl.EnableWindow(bEnable);
293 else
295 m_ClampCtrl.EnableWindow(FALSE);
298 UpdateData(FALSE);
300 return CDialog::EnableWindow(bEnable);
303 //*************************************************************************************************************
304 CAttribDlg::~CAttribDlg()
306 if (_NbCyclesDlg)
308 _NbCyclesDlg->DestroyWindow();
309 delete _NbCyclesDlg;
311 if (_CstValueDlg)
313 _CstValueDlg->DestroyWindow();
314 delete _CstValueDlg;
318 //*************************************************************************************************************
319 void CAttribDlg::update()
321 _FirstDrawing = true;
322 if (useScheme())
325 schemeValueUpdate();
327 else
330 nlassert(_EnableConstantValue);
331 cstValueUpdate();
335 //*************************************************************************************************************
336 void CAttribDlg::init(HBITMAP bitmap, sint x, sint y, CWnd *pParent)
339 Create(IDD_ATTRIB_DLG, pParent);
340 RECT r, ro;
341 GetClientRect(&r);
343 m_AttrBitmap.SendMessage(BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) bitmap);
344 MoveWindow(x, y, r.right, r.bottom);
346 m_NbCyclePos.GetWindowRect(&r);
347 GetWindowRect(&ro);
349 if (_NbCycleEnabled)
351 _NbCyclesDlg = new CEditableRangeFloat(_ValueID + "%%NB_CYCLE_INFO", _Node, 0.1f, 10.1f);
352 _NbCyclesDlg->init(r.left - ro.left, r.top - ro.top, this);
355 // fill the combo box with the list of available scheme
356 m_Scheme.InitStorage(getNumScheme(), 32); // 32 char per string pre-allocated
358 for (uint k = 0; k < getNumScheme(); ++k)
361 m_Scheme.InsertString(k, nlUtf8ToTStr(getSchemeName(k)));
365 update();
367 if (!_EnableConstantValue)
369 m_UseScheme.ShowWindow(SW_HIDE);
372 if (!_NbCyclesDlg)
374 GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->ShowWindow(SW_HIDE);
375 GetDlgItem(IDC_CLAMP_ATTRIB)->ShowWindow(SW_HIDE);
378 if (!_SrcInputEnabled)
380 GetDlgItem(IDC_SRC_INPUT_TXT)->ShowWindow(SW_HIDE);
381 GetDlgItem(IDC_EDIT_INPUT)->ShowWindow(SW_HIDE);
382 GetDlgItem(IDC_SCHEME_INPUT)->ShowWindow(SW_HIDE);
384 inputValueUpdate();
385 ShowWindow(SW_SHOW);
388 //*************************************************************************************************************
389 void CAttribDlg::DoDataExchange(CDataExchange* pDX)
391 CDialog::DoDataExchange(pDX);
392 //{{AFX_DATA_MAP(CAttribDlg)
393 DDX_Control(pDX, IDC_PUT_SCHEME, m_PutScheme);
394 DDX_Control(pDX, IDC_GET_SCHEME, m_GetScheme);
395 DDX_Control(pDX, IDC_EDIT_INPUT, m_EditUserParam);
396 DDX_Control(pDX, IDC_SCHEME_INPUT, m_SchemeInput);
397 DDX_Control(pDX, IDC_CONSTANT_VALUE_POS, m_CstValuePos);
398 DDX_Control(pDX, IDC_ATTRIB_NB_CYCLES, m_NbCyclePos);
399 DDX_Control(pDX, IDC_ATTR_BITMAP, m_AttrBitmap);
400 DDX_Control(pDX, IDC_CLAMP_ATTRIB, m_ClampCtrl);
401 DDX_Control(pDX, IDC_EDIT_SCHEME, m_EditScheme);
402 DDX_Control(pDX, IDC_USE_SCHEME, m_UseScheme);
403 DDX_Control(pDX, IDC_SCHEME, m_Scheme);
404 DDX_Check(pDX, IDC_CLAMP_ATTRIB, m_Clamp);
405 //}}AFX_DATA_MAP
408 //*************************************************************************************************************
409 void CAttribDlg::inputValueUpdate(void)
411 if (useScheme() && getSchemeInput().InputType == NL3D::CPSInputType::attrUserParam)
413 m_EditUserParam.EnableWindow(TRUE);
415 else
417 m_EditUserParam.EnableWindow(FALSE);
421 //*************************************************************************************************************
422 void CAttribDlg::cstValueUpdate()
424 if (!_FirstDrawing && !useScheme()) return;
426 m_ClampCtrl.EnableWindow(FALSE);
427 if (_NbCyclesDlg)
429 _NbCyclesDlg->EnableWindow(FALSE);
430 _NbCyclesDlg->emptyDialog();
432 GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->EnableWindow(FALSE);
433 m_EditScheme.EnableWindow(FALSE);
434 m_PutScheme.EnableWindow(FALSE);
435 m_GetScheme.EnableWindow(FALSE);
437 m_EditScheme.ShowWindow(SW_HIDE);
438 m_GetScheme.ShowWindow(SW_HIDE);
439 m_PutScheme.ShowWindow(SW_HIDE);
441 m_Scheme.EnableWindow(FALSE);
442 m_Scheme.ShowWindow(SW_HIDE);
443 m_SchemeInput.EnableWindow(FALSE);
444 m_SchemeInput.ShowWindow(SW_HIDE);
446 if (!_FirstDrawing) resetCstValue();
450 m_UseScheme.SetCurSel(0);
451 _CstValueDlg = createConstantValueDlg();
452 CRect r, ro;
453 m_CstValuePos.GetWindowRect(&r);
454 GetWindowRect(&ro);
455 _CstValueDlg->init(r.left - ro.left, r.top - ro.top, this);
456 UpdateData(FALSE);
458 _FirstDrawing = false;
461 //*************************************************************************************************************
462 void CAttribDlg::schemeValueUpdate()
464 //if (!_FirstDrawing && useScheme()) return;
465 if (_CstValueDlg)
467 _CstValueDlg->DestroyWindow();
468 delete _CstValueDlg;
469 _CstValueDlg = NULL;
471 m_EditScheme.EnableWindow(TRUE);
472 m_GetScheme.EnableWindow(TRUE);
473 m_PutScheme.EnableWindow(TRUE);
474 m_EditScheme.ShowWindow(SW_SHOW);
475 m_GetScheme.ShowWindow(SW_SHOW);
476 m_PutScheme.ShowWindow(SW_SHOW);
477 m_Scheme.EnableWindow(TRUE);
478 m_Scheme.ShowWindow(SW_SHOW);
479 m_SchemeInput.EnableWindow(TRUE);
480 m_SchemeInput.ShowWindow(SW_SHOW);
481 m_UseScheme.SetCurSel(1);
482 sint k = getCurrentScheme();
484 if (k == -1) // unknow scheme ...
486 setCurrentScheme(0);
487 k = 0;
489 m_Scheme.SetCurSel(k);
490 if (hasSchemeCustomInput())
492 m_SchemeInput.EnableWindow();
493 m_SchemeInput.SetCurSel((uint) getSchemeInput().InputType);
494 inputValueUpdate();
495 if (_NbCyclesDlg)
497 _NbCyclesDlg->EnableWindow(TRUE);
499 m_ClampCtrl.EnableWindow(isClampingSupported());
500 GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->EnableWindow(isClampingSupported());
502 else
504 m_SchemeInput.EnableWindow(FALSE);
505 m_SchemeInput.SetCurSel(0);
506 if (_NbCyclesDlg)
508 _NbCyclesDlg->EnableWindow(FALSE);
510 m_ClampCtrl.EnableWindow(FALSE);
511 GetDlgItem(IDC_INPUT_MULTIPLIER_TXT)->EnableWindow(FALSE);
514 if (_NbCyclesDlg)
516 _NbCyclesWrapper.OwnerNode = _Node;
517 _NbCyclesDlg->setWrapper(&_NbCyclesWrapper);
518 _NbCyclesWrapper.Dlg = this;
519 _NbCyclesDlg->updateRange();
520 _NbCyclesDlg->updateValueFromReader();
522 if (isClampingSupported())
524 m_Clamp = isSchemeClamped();
526 UpdateData(FALSE);
527 _FirstDrawing = false;
530 //*************************************************************************************************************
531 void CAttribDlg::OnSelchangeUseScheme()
533 if (m_UseScheme.GetCurSel() == 0)
535 cstValueUpdate();
537 else
539 schemeValueUpdate();
545 //*************************************************************************************************************
546 void CAttribDlg::OnSelchangeScheme()
548 UpdateData();
549 setCurrentScheme(m_Scheme.GetCurSel());
550 schemeValueUpdate();
553 //*************************************************************************************************************
554 void CAttribDlg::OnEditScheme()
556 _SchemeEditionDlg = editScheme();
557 if (_SchemeEditionDlg)
559 EnableWindow(FALSE);
563 //*************************************************************************************************************
564 void CAttribDlg::childPopupClosed(CWnd *child)
566 EnableWindow(TRUE);
567 if (!_SchemeEditionDlg) return;
568 _SchemeEditionDlg->DestroyWindow();
569 delete _SchemeEditionDlg;
570 _SchemeEditionDlg = NULL;
573 //*************************************************************************************************************
574 void CAttribDlg::OnGetScheme()
576 CSchemeBankDlg sbd(getCurrentSchemePtr()->getType(), this);
577 if (sbd.DoModal() == IDOK && sbd.getSelectedScheme())
579 setCurrentSchemePtr(sbd.getSelectedScheme()->clone());
580 _FirstDrawing = true;
581 schemeValueUpdate();
585 //*************************************************************************************************************
586 void CAttribDlg::OnPutScheme()
588 CChooseName cn("new scheme", this);
589 if (cn.DoModal() == IDOK)
591 SchemeManager.insertScheme(cn.getName(), getCurrentSchemePtr()->clone());
595 //*************************************************************************************************************
596 void CAttribDlg::OnSelchangeSchemeInput()
598 UpdateData();
599 NL3D::CPSInputType it;
600 it.InputType = (NL3D::CPSInputType::TInputType) m_SchemeInput.GetCurSel();
601 if (it.InputType == NL3D::CPSInputType::attrUserParam)
603 it.UserParamNum = 0;
605 setSchemeInput(it);
606 inputValueUpdate();
609 //*************************************************************************************************************
610 void CAttribDlg::OnClampAttrib()
612 UpdateData();
613 clampScheme(m_Clamp ? true : false /* avoid performance warning */);
616 //*************************************************************************************************************
617 void CAttribDlg::OnEditInput()
619 switch (getSchemeInput().InputType)
621 case NL3D::CPSInputType::attrUserParam:
623 CEditUserParam ep(getSchemeInput().UserParamNum);
624 if (ep.DoModal() == IDOK)
626 NL3D::CPSInputType it = getSchemeInput();
627 it.UserParamNum = ep.getUserParamIndex();
628 setSchemeInput(it);
631 break;
635 BEGIN_MESSAGE_MAP(CAttribDlg, CDialog)
636 //{{AFX_MSG_MAP(CAttribDlg)
637 ON_CBN_SELCHANGE(IDC_USE_SCHEME, OnSelchangeUseScheme)
638 ON_CBN_SELCHANGE(IDC_SCHEME, OnSelchangeScheme)
639 ON_BN_CLICKED(IDC_EDIT_SCHEME, OnEditScheme)
640 ON_CBN_SELCHANGE(IDC_SCHEME_INPUT, OnSelchangeSchemeInput)
641 ON_BN_CLICKED(IDC_CLAMP_ATTRIB, OnClampAttrib)
642 ON_BN_CLICKED(IDC_EDIT_INPUT, OnEditInput)
643 ON_BN_CLICKED(IDC_GET_SCHEME, OnGetScheme)
644 ON_BN_CLICKED(IDC_PUT_SCHEME, OnPutScheme)
645 ON_WM_DESTROY()
646 ON_WM_CLOSE()
647 //}}AFX_MSG_MAP
648 END_MESSAGE_MAP()
650 /////////////////////////////////////////////////////////////////////////////
651 // CAttribDlg message handlers
655 ////////////////////////////////////
656 // CAttribDlgFloat implementation //
657 ////////////////////////////////////
659 //////////////////////////////////////////////////////////
660 // FLOAT BLENDER EDITION INTERFACE //
661 //////////////////////////////////////////////////////////
662 class CFloatBlenderDlgClient : public CValueBlenderDlgClientT<float>
664 public:
665 CEditAttribDlg *newDialog(const std::string &id, IPSWrapperFloat *wrapper)
667 CEditableRangeFloat *erf = new CEditableRangeFloat(id, wrapper->OwnerNode, MinRange, MaxRange);
668 erf->setWrapper(wrapper);
669 BoundChecker.duplicateBoundChecker(*erf);
670 return erf;
672 CBoundCheckerFloat BoundChecker;
673 float MinRange, MaxRange;
676 //////////////////////////////////////////////////////////
677 // FLOAT GRADIENT EDITION INTERFACE //
678 //////////////////////////////////////////////////////////
680 //*************************************************************************************************************
681 class CFloatGradientDlgWrapper : public CValueGradientDlgClientT<float>
683 public:
684 /// a function that can display a value in a gradient, with the given offset. Deriver must define this
685 void displayValue(CDC *dc, uint index, sint x, sint y)
688 CString out;
689 out.Format(_T("%g"), Scheme->getValue(index) );
690 dc->TextOut(x + 10, y + 4, out);
692 CEditAttribDlg *newDialog(const std::string &id, IPSWrapperFloat *wrapper)
694 CEditableRangeFloat *erf = new CEditableRangeFloat(id, wrapper->OwnerNode, MinRange, MaxRange);
695 erf->setWrapper(wrapper);
696 BoundChecker.duplicateBoundChecker(*erf);
697 return erf;
699 CBoundCheckerFloat BoundChecker;
700 float MinRange, MaxRange;
705 //*************************************************************************************************************
706 CAttribDlgFloat::CAttribDlgFloat(const std::string &valueID, CParticleWorkspace::CNode *node, float minRange, float maxRange)
707 : CAttribDlgT<float>(valueID, node), _MinRange(minRange), _MaxRange(maxRange)
709 _CstValueId = valueID;
712 //*************************************************************************************************************
713 CEditAttribDlg *CAttribDlgFloat::createConstantValueDlg()
715 CEditableRangeFloat *erf = new CEditableRangeFloat(_CstValueId, _Node, _MinRange, _MaxRange);
716 erf->setWrapper(_Wrapper);
717 duplicateBoundChecker(*erf);
718 return erf;
721 //*************************************************************************************************************
722 uint CAttribDlgFloat::getNumScheme(void) const
724 return _DisableMemoryScheme ? 3 : 5;
727 //*************************************************************************************************************
728 std::string CAttribDlgFloat::getSchemeName(uint index) const
730 const char *types[] = { "value blender", "values gradient", "curve", "value computed from emitter", "binary operator"};
731 nlassert(index < 5);
732 return std::string(types[index]);
735 //*************************************************************************************************************
736 CWnd *CAttribDlgFloat::editScheme(void)
738 NL3D::CPSAttribMaker<float> *scheme = _SchemeWrapper->getScheme();
740 if (dynamic_cast<NL3D::CPSFloatBlender *>(scheme))
742 CFloatBlenderDlgClient *myInterface = new CFloatBlenderDlgClient;
743 this->duplicateBoundChecker(myInterface->BoundChecker);
744 myInterface->MinRange = _MinRange;
745 myInterface->MaxRange = _MaxRange;
746 myInterface->Id = _CstValueId+ std::string("%%FLOAT_BLENDER");
747 myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<float, 64> *) scheme)->_F;
748 CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
749 vb->init(this);
750 return vb;
753 if (dynamic_cast<NL3D::CPSFloatGradient *>(scheme))
755 CFloatGradientDlgWrapper *wrapper = new CFloatGradientDlgWrapper;
756 this->duplicateBoundChecker(wrapper->BoundChecker);
757 wrapper->MinRange = _MinRange;
758 wrapper->MaxRange = _MaxRange;
759 wrapper->Scheme = &(((NL3D::CPSFloatGradient *) (_SchemeWrapper->getScheme()) )->_F);
760 CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
761 wrapper->GradDlg = gd;
762 wrapper->DefaultValue = 0.f;
763 wrapper->Id = _CstValueId+ std::string("%%FLOAT GRADIENT");
764 gd->init(this);
765 return gd;
767 if (dynamic_cast<NL3D::CPSFloatMemory *>(scheme))
769 CAttribDlgFloat *adf = new CAttribDlgFloat(_CstValueId, _Node, _MinRange, _MaxRange);
770 this->duplicateBoundChecker(*adf);
771 CValueFromEmitterDlgT<float> *vfe = new CValueFromEmitterDlgT<float>( (NL3D::CPSFloatMemory *)(scheme),
772 adf,
773 this,
774 m_AttrBitmap.GetBitmap()
776 vfe->init(this);
777 return vfe;
779 if (dynamic_cast<NL3D::CPSFloatBinOp *>(scheme))
781 CAttribDlgFloat *ad[2] = { NULL, NULL};
782 for (uint k = 0; k <2; ++k)
784 ad[k] = new CAttribDlgFloat(_CstValueId, _Node, _MinRange, _MaxRange);
785 this->duplicateBoundChecker(*ad[k]);
787 CBinOpDlgT<float> *bod = new CBinOpDlgT<float>( (NL3D::CPSFloatBinOp *)(scheme),
788 (CAttribDlgT<float> **) ad,
789 this,
790 m_AttrBitmap.GetBitmap());
791 bod->init(this);
792 return bod;
795 if (dynamic_cast<NL3D::CPSFloatCurve *>(scheme))
797 CurveEdit *ce = new CurveEdit(&(dynamic_cast<NL3D::CPSFloatCurve *>(scheme)->_F), _Node, this, this);
798 ce->init(this);
799 return ce;
802 return NULL;
805 //*************************************************************************************************************
806 sint CAttribDlgFloat::getCurrentScheme(void) const
809 const NL3D::CPSAttribMaker<float> *scheme = _SchemeWrapper->getScheme();
810 if (dynamic_cast<const NL3D::CPSFloatBlender *>(scheme)) return 0;
811 if (dynamic_cast<const NL3D::CPSFloatGradient *>(scheme)) return 1;
812 if (dynamic_cast<const NL3D::CPSFloatCurve *>(scheme)) return 2;
813 if (dynamic_cast<const NL3D::CPSFloatMemory *>(scheme)) return 3;
814 if (dynamic_cast<const NL3D::CPSFloatBinOp *>(scheme)) return 4;
816 return -1;
820 //*************************************************************************************************************
821 void CAttribDlgFloat::setCurrentScheme(uint index)
823 nlassert(index < 5);
826 NL3D::CPSAttribMaker<float> *scheme = NULL;
828 switch (index)
830 case 0:
831 scheme = new NL3D::CPSFloatBlender(_MinRange, _MaxRange);
832 break;
833 case 1:
835 static const float values[2] = { 0.1f, 1.f };
836 scheme = new NL3D::CPSFloatGradient(values, 2, 16, 1.f);
838 break;
839 case 2:
841 NL3D::CPSFloatCurve *curve = new NL3D::CPSFloatCurve;
842 curve->_F.setNumSamples(128);
843 curve->_F.addControlPoint(NL3D::CPSFloatCurveFunctor::CCtrlPoint(0, 0.5f));
844 curve->_F.addControlPoint(NL3D::CPSFloatCurveFunctor::CCtrlPoint(1, 0.5f));
845 scheme = curve;
847 break;
848 case 3:
849 scheme = new NL3D::CPSFloatMemory;
850 ((NL3D::CPSAttribMakerMemory<float> *) scheme)->setScheme(new NL3D::CPSFloatBlender(_MinRange, _MaxRange));
851 break;
852 case 4 :
853 scheme = new NL3D::CPSFloatBinOp;
854 ((NL3D::CPSFloatBinOp *) scheme)->setArg(0, new NL3D::CPSFloatBlender);
855 ((NL3D::CPSFloatBinOp *) scheme)->setArg(1, new NL3D::CPSFloatBlender);
856 break;
858 default:
859 break;
862 if (scheme)
864 _SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
869 ////////////////////////////////////
870 // CAttribDlgUInt implementation //
871 ////////////////////////////////////
874 class CUIntBlenderDlgClient : public CValueBlenderDlgClientT<uint32>
876 public:
877 CEditAttribDlg *newDialog(const std::string &id, IPSWrapperUInt *wrapper)
879 CEditableRangeUInt *eru = new CEditableRangeUInt(id, wrapper->OwnerNode, MinRange, MaxRange);
880 eru->setWrapper(wrapper);
881 BoundChecker.duplicateBoundChecker(*eru);
882 return eru;
884 CBoundCheckerUInt BoundChecker;
885 uint32 MinRange, MaxRange;
888 //////////////////////////////////////////////////////////
889 // UINT GRADIENT EDITION INTERFACE //
890 //////////////////////////////////////////////////////////
893 //*************************************************************************************************************
894 class CUIntGradientDlgWrapper : public CValueGradientDlgClientT<uint32>
896 public:
897 /// a function that can display a value in a gradient, with the given offset. Deriver must define this
898 void displayValue(CDC *dc, uint index, sint x, sint y)
901 CString out;
902 out.Format(_T("%d"), Scheme->getValue(index) );
903 dc->TextOut(x + 10, y + 4, out);
905 CEditAttribDlg *newDialog(const std::string &id, IPSWrapperUInt *wrapper)
907 CEditableRangeUInt *eru = new CEditableRangeUInt(id, wrapper->OwnerNode, MinRange, MaxRange);
908 eru->setWrapper(wrapper);
909 BoundChecker.duplicateBoundChecker(*eru);
910 return eru;
912 CBoundCheckerUInt BoundChecker;
913 uint32 MinRange, MaxRange;
917 //*************************************************************************************************************
918 CAttribDlgUInt::CAttribDlgUInt(const std::string &valueID, CParticleWorkspace::CNode *node, uint32 minRange, uint32 maxRange)
919 : CAttribDlgT<uint32>(valueID, node), _MinRange(minRange), _MaxRange(maxRange)
921 _CstValueId = valueID;
924 //*************************************************************************************************************
925 CEditAttribDlg *CAttribDlgUInt::createConstantValueDlg()
927 CEditableRangeUInt *erf = new CEditableRangeUInt(_CstValueId, _Node, _MinRange, _MaxRange);
928 erf->setWrapper(_Wrapper);
929 duplicateBoundChecker(*erf);
930 return erf;
933 //*************************************************************************************************************
934 uint CAttribDlgUInt::getNumScheme(void) const
937 return _DisableMemoryScheme ? 2 : 4;
940 //*************************************************************************************************************
941 std::string CAttribDlgUInt::getSchemeName(uint index) const
943 const char *types[] = { "value blender", "values gradient", "values computed from emitter", "binary operator" };
944 nlassert(index < 4);
945 return std::string(types[index]);
948 //*************************************************************************************************************
949 CWnd *CAttribDlgUInt::editScheme(void)
951 const NL3D::CPSAttribMaker<uint32> *scheme = _SchemeWrapper->getScheme();
953 if (dynamic_cast<const NL3D::CPSUIntBlender *>(scheme))
955 CUIntBlenderDlgClient *myInterface = new CUIntBlenderDlgClient ;
956 duplicateBoundChecker(myInterface->BoundChecker);
957 myInterface->MinRange = _MinRange;
958 myInterface->MaxRange = _MaxRange;
959 myInterface->Id = _CstValueId+ std::string("%%UINT_BLENDER");
960 myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<uint32, 64> *) scheme)->_F;
962 CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
963 vb->init(this);
964 return vb;
966 if (dynamic_cast<const NL3D::CPSUIntGradient *>(scheme))
968 CUIntGradientDlgWrapper *wrapper = new CUIntGradientDlgWrapper;
969 this->duplicateBoundChecker(wrapper->BoundChecker);
970 wrapper->MinRange = _MinRange;
971 wrapper->MaxRange = _MaxRange;
972 wrapper->Scheme = &(((NL3D::CPSUIntGradient *) (_SchemeWrapper->getScheme()) )->_F);
973 CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
974 wrapper->GradDlg = gd;
975 wrapper->DefaultValue = 0;
976 wrapper->Id = _CstValueId+ std::string("%%UINT GRADIENT");
977 gd->init(this);
978 return gd;
980 if (dynamic_cast<const NL3D::CPSUIntMemory *>(scheme))
983 CAttribDlgUInt *adu = new CAttribDlgUInt(_CstValueId, _Node, _MinRange, _MaxRange);
984 this->duplicateBoundChecker(*adu);
985 CValueFromEmitterDlgT<uint32> *vfe = new CValueFromEmitterDlgT<uint32>( (NL3D::CPSUIntMemory *)(scheme),
986 adu,
987 this,
988 m_AttrBitmap.GetBitmap());
989 vfe->init(this);
990 return vfe;
992 if (dynamic_cast<const NL3D::CPSUIntBinOp *>(scheme))
994 CAttribDlgUInt *ad[2] = { NULL, NULL};
995 for (uint k = 0; k <2; ++k)
997 ad[k] = new CAttribDlgUInt(_CstValueId, _Node, _MinRange, _MaxRange);
998 this->duplicateBoundChecker(*ad[k]);
1000 CBinOpDlgT<uint32> *bod = new CBinOpDlgT<uint32>( (NL3D::CPSUIntBinOp *)(scheme),
1001 (CAttribDlgT<uint32> **) ad,
1002 this,
1003 m_AttrBitmap.GetBitmap());
1004 bod->init(this);
1005 return bod;
1007 return NULL;
1010 //*************************************************************************************************************
1011 sint CAttribDlgUInt::getCurrentScheme(void) const
1013 const NL3D::CPSAttribMaker<uint32> *scheme = _SchemeWrapper->getScheme();
1015 if (dynamic_cast<const NL3D::CPSUIntBlender *>(scheme)) return 0;
1016 if (dynamic_cast<const NL3D::CPSUIntGradient *>(scheme)) return 1;
1017 if (dynamic_cast<const NL3D::CPSUIntMemory *>(scheme)) return 2;
1018 if (dynamic_cast<const NL3D::CPSUIntBinOp *>(scheme)) return 3;
1019 return -1;
1022 //*************************************************************************************************************
1023 void CAttribDlgUInt::setCurrentScheme(uint index)
1025 nlassert(index < 4);
1028 NL3D::CPSAttribMaker<uint32> *scheme = NULL;
1030 switch (index)
1032 case 0 :
1033 scheme = new NL3D::CPSUIntBlender(_MinRange, _MaxRange);
1034 break;
1035 case 1 :
1036 scheme = new NL3D::CPSUIntGradient;
1037 break;
1038 case 2 :
1039 scheme = new NL3D::CPSUIntMemory;
1040 ((NL3D::CPSAttribMakerMemory<uint32> *) scheme)->setScheme(new NL3D::CPSUIntBlender(_MinRange, _MaxRange) );
1041 break;
1042 case 3 :
1043 scheme = new NL3D::CPSUIntBinOp;
1044 ((NL3D::CPSUIntBinOp *) scheme)->setArg(0, new NL3D::CPSUIntBlender);
1045 ((NL3D::CPSUIntBinOp *) scheme)->setArg(1, new NL3D::CPSUIntBlender);
1046 break;
1047 default:
1048 break;
1051 if (scheme)
1053 _SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
1058 ////////////////////////////////////
1059 // CAttribDlgInt implementation //
1060 ////////////////////////////////////
1062 class CIntBlenderDlgClient : public CValueBlenderDlgClientT<sint32>
1064 public:
1065 CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<sint32> *wrapper)
1067 CEditableRangeInt *eri = new CEditableRangeInt(id, wrapper->OwnerNode, MinRange, MaxRange);
1068 eri->setWrapper(wrapper);
1069 BoundChecker.duplicateBoundChecker(*eri);
1070 return eri;
1072 CBoundCheckerInt BoundChecker;
1073 sint32 MinRange, MaxRange;
1077 //////////////////////////////////////////////////////////
1078 // INT GRADIENT EDITION INTERFACE //
1079 //////////////////////////////////////////////////////////
1082 //*************************************************************************************************************
1083 class CIntGradientDlgWrapper : public CValueGradientDlgClientT<sint32>
1085 public:
1086 /// a function that can display a value in a gradient, with the given offset. Deriver must define this
1087 void displayValue(CDC *dc, uint index, sint x, sint y)
1090 CString out;
1091 out.Format(_T("%d"), Scheme->getValue(index) );
1092 dc->TextOut(x + 10, y + 4, out);
1094 CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<sint32> *wrapper)
1096 CEditableRangeInt *eri = new CEditableRangeInt(id, wrapper->OwnerNode, MinRange, MaxRange);
1097 eri->setWrapper(wrapper);
1098 BoundChecker.duplicateBoundChecker(*eri);
1099 return eri;
1101 CBoundCheckerInt BoundChecker;
1102 sint32 MinRange, MaxRange;
1106 //*************************************************************************************************************
1107 CAttribDlgInt::CAttribDlgInt(const std::string &valueID, CParticleWorkspace::CNode *node, sint32 minRange, sint32 maxRange)
1108 : CAttribDlgT<sint32>(valueID, node), _MinRange(minRange), _MaxRange(maxRange)
1110 _CstValueId = valueID;
1113 //*************************************************************************************************************
1114 CEditAttribDlg *CAttribDlgInt::createConstantValueDlg()
1116 CEditableRangeInt *erf = new CEditableRangeInt(_CstValueId, _Node, _MinRange, _MaxRange);
1117 erf->setWrapper(_Wrapper);
1118 duplicateBoundChecker(*erf);
1119 return erf;
1122 //*************************************************************************************************************
1123 uint CAttribDlgInt::getNumScheme(void) const
1125 return _DisableMemoryScheme ? 2 : 4;
1128 //*************************************************************************************************************
1129 std::string CAttribDlgInt::getSchemeName(uint index) const
1132 const char *types[] = { "value exact blender", "values gradient", "values computed from emitter", "binary operator" };
1133 nlassert(index < 4);
1134 return std::string(types[index]);
1137 //*************************************************************************************************************
1138 CWnd *CAttribDlgInt::editScheme(void)
1140 const NL3D::CPSAttribMaker<sint32> *scheme = _SchemeWrapper->getScheme();
1142 if (dynamic_cast<const NL3D::CPSIntBlender *>(scheme))
1144 CIntBlenderDlgClient *myInterface = new CIntBlenderDlgClient;
1145 this->duplicateBoundChecker(myInterface->BoundChecker);
1146 myInterface->MinRange = _MinRange;
1147 myInterface->MaxRange = _MaxRange;
1148 myInterface->Id = _CstValueId+ std::string("%%INT_BLENDER");
1149 myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<sint32, 64> *) scheme)->_F;
1151 CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
1152 vb->init(this);
1153 return vb;
1155 if (dynamic_cast<const NL3D::CPSIntGradient *>(scheme))
1157 CIntGradientDlgWrapper *wrapper = new CIntGradientDlgWrapper;
1158 this->duplicateBoundChecker(wrapper->BoundChecker);
1159 wrapper->MinRange = _MinRange;
1160 wrapper->MaxRange = _MaxRange;
1161 wrapper->Scheme = &(((NL3D::CPSIntGradient *) (_SchemeWrapper->getScheme()) )->_F);
1162 CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
1163 wrapper->GradDlg = gd;
1164 wrapper->DefaultValue = 0;
1165 wrapper->Id = _CstValueId+ std::string("%%INT GRADIENT");
1166 gd->init(this);
1167 return gd;
1169 if (dynamic_cast<const NL3D::CPSIntMemory *>(scheme))
1171 CAttribDlgInt *adi = new CAttribDlgInt(_CstValueId, _Node, _MinRange, _MaxRange);
1172 this->duplicateBoundChecker(*adi);
1173 CValueFromEmitterDlgT<sint32> *vfe = new CValueFromEmitterDlgT<sint32>((NL3D::CPSIntMemory *) _SchemeWrapper->getScheme(),
1174 adi,
1175 this,
1176 m_AttrBitmap.GetBitmap() );
1177 vfe->init(this);
1178 return vfe;
1180 /* if (dynamic_cast<const NL3D::CPSIntMemory *>(scheme))
1182 CValueFromEmitterDlgT<float, CAttribDlgFloat> vfe( (NL3D::CPSFloatMemory *)(scheme), std::string("UINT SCHEME"), m_AttrBitmap.GetBitmap());
1183 vfe.DoModal();
1185 if (dynamic_cast<const NL3D::CPSIntBinOp *>(scheme))
1187 CAttribDlgInt *ad[2] = { NULL, NULL};
1188 for (uint k = 0; k <2; ++k)
1190 ad[k] = new CAttribDlgInt(_CstValueId, _Node, _MinRange, _MaxRange);
1191 this->duplicateBoundChecker(*ad[k]);
1193 CBinOpDlgT<sint32> *bod = new CBinOpDlgT<sint32>( (NL3D::CPSIntBinOp *)(scheme),
1194 (CAttribDlgT<sint32> **) ad,
1195 this,
1196 m_AttrBitmap.GetBitmap());
1197 bod->init(this);
1198 return bod;
1200 return NULL;
1203 //*************************************************************************************************************
1204 sint CAttribDlgInt::getCurrentScheme(void) const
1206 const NL3D::CPSAttribMaker<sint32> *scheme = _SchemeWrapper->getScheme();
1208 if (dynamic_cast<const NL3D::CPSIntBlender *>(scheme)) return 0;
1209 if (dynamic_cast<const NL3D::CPSIntGradient *>(scheme)) return 1;
1210 if (dynamic_cast<const NL3D::CPSIntMemory *>(scheme)) return 2;
1211 if (dynamic_cast<const NL3D::CPSIntBinOp *>(scheme)) return 3;
1212 return -1;
1216 //*************************************************************************************************************
1217 void CAttribDlgInt::setCurrentScheme(uint index)
1219 nlassert(index < 4);
1222 NL3D::CPSAttribMaker<sint32> *scheme = NULL;
1224 switch (index)
1226 case 0 :
1227 scheme = new NL3D::CPSIntBlender;
1228 break;
1229 case 1 :
1230 scheme = new NL3D::CPSIntGradient;
1231 break;
1232 case 2 :
1233 scheme = new NL3D::CPSIntMemory;
1234 ((NL3D::CPSAttribMakerMemory<sint32> *) scheme)->setScheme(new NL3D::CPSIntBlender(_MinRange, _MaxRange));
1235 break;
1236 case 3 :
1237 scheme = new NL3D::CPSIntBinOp;
1238 ((NL3D::CPSIntBinOp *) scheme)->setArg(0, new NL3D::CPSIntBlender);
1239 ((NL3D::CPSIntBinOp *) scheme)->setArg(1, new NL3D::CPSIntBlender);
1240 break;
1241 default:
1242 break;
1245 if (scheme)
1247 _SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
1254 ///////////////////////
1255 // CRGBA attributes //
1256 ///////////////////////
1258 class CRGBABlenderDlgClient : public CValueBlenderDlgClientT<NLMISC::CRGBA>
1260 public:
1261 CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<NLMISC::CRGBA> *wrapper)
1263 CColorEdit *ce = new CColorEdit;
1264 ce->setWrapper(wrapper);
1265 return ce;
1270 //////////////////////////////////////////////////////////
1271 // COLOR GRADIENT EDITION INTERFACE //
1272 //////////////////////////////////////////////////////////
1275 //*************************************************************************************************************
1276 class CColorGradientDlgWrapper : public CValueGradientDlgClientT<CRGBA>
1278 public:
1279 /// a function that can display a value in a gradient, with the given offset. Deriver must define this
1280 void displayValue(CDC *dc, uint index, sint x, sint y)
1282 CRGBA col = Scheme->getValue(index);
1284 RECT r;
1286 r.left = x + 10;
1287 r.top = y + 10;
1288 r.right = x + 53;
1289 r.bottom = y + 29;
1291 CBrush b;
1292 b.CreateSolidBrush(RGB(col.R, col.G, col.B));
1293 dc->FillRect(&r, &b);
1294 b.DeleteObject();
1296 b.CreateSolidBrush(RGB(0, 0, 0));
1297 CGdiObject *old = dc->SelectObject(&b);
1298 r.top = y + 10; r. bottom = y + 29;
1299 r.right = x + 53; r.left = x + 10;
1300 dc->FrameRect(&r, &b);
1301 dc->SelectObject(old);
1302 b.DeleteObject();
1304 CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<NLMISC::CRGBA> *wrapper)
1306 CColorEdit *ce = new CColorEdit;
1307 ce->setWrapper(wrapper);
1308 return ce;
1314 ////////////////////////////
1316 //*************************************************************************************************************
1317 CAttribDlgRGBA::CAttribDlgRGBA(const std::string &valueID, CParticleWorkspace::CNode *node) : CAttribDlgT<CRGBA>(valueID, node)
1321 //*************************************************************************************************************
1322 uint CAttribDlgRGBA::getNumScheme(void) const
1324 return _DisableMemoryScheme ? 3 : 5;
1327 //*************************************************************************************************************
1328 std::string CAttribDlgRGBA::getSchemeName(uint index) const
1330 const char *types[] = { "color sampled blender", "color gradient", "color exact blender", "values computed from emitter", "binary operator" };
1331 nlassert(index < 5);
1332 return std::string(types[index]);
1336 //*************************************************************************************************************
1337 CWnd *CAttribDlgRGBA::editScheme(void)
1339 const NL3D::CPSAttribMaker<CRGBA> *scheme = _SchemeWrapper->getScheme();
1341 if (dynamic_cast<const NL3D::CPSColorBlender *>(scheme))
1343 CRGBABlenderDlgClient *myInterface = new CRGBABlenderDlgClient;
1344 myInterface->Id = std::string("RGBA_BLENDER");
1345 myInterface->SchemeFunc = & ((NL3D::CPSValueBlenderSample<CRGBA, 64> *) scheme)->_F;
1346 CValueBlenderDlg *vb = new CValueBlenderDlg(myInterface, true, this, this, _Node);
1347 vb->init(this);
1348 return vb;
1350 if (dynamic_cast<const NL3D::CPSColorGradient *>(scheme))
1352 CColorGradientDlgWrapper *wrapper = new CColorGradientDlgWrapper;
1353 wrapper->Scheme = &(((NL3D::CPSColorGradient *) (_SchemeWrapper->getScheme()) )->_F);
1354 CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
1355 wrapper->GradDlg = gd;
1356 wrapper->DefaultValue = CRGBA::White;
1357 wrapper->Id = std::string("RGBA_GRADIENT");
1358 gd->init(this);
1359 return gd;
1361 if (dynamic_cast<const NL3D::CPSColorBlenderExact *>(scheme))
1363 return NULL;
1366 if (dynamic_cast<const NL3D::CPSColorMemory *>(scheme))
1368 CAttribDlgRGBA *ad = new CAttribDlgRGBA(_CstValueId, _Node);
1369 CValueFromEmitterDlgT<CRGBA> *vfe = new CValueFromEmitterDlgT<CRGBA>( (NL3D::CPSColorMemory *)(scheme),
1371 this,
1372 m_AttrBitmap.GetBitmap());
1373 vfe->init(this);
1374 return vfe;
1377 if (dynamic_cast<const NL3D::CPSColorBinOp *>(scheme))
1379 CAttribDlgRGBA *ad[2] = { NULL, NULL};
1380 for (uint k = 0; k <2; ++k)
1382 ad[k] = new CAttribDlgRGBA(_CstValueId, _Node);
1384 CBinOpDlgT<CRGBA> *bod = new CBinOpDlgT<CRGBA>( (NL3D::CPSColorBinOp *)(scheme),
1385 (CAttribDlgT<CRGBA> **) ad,
1386 this,
1387 m_AttrBitmap.GetBitmap());
1388 bod->init(this);
1389 return bod;
1391 return NULL;
1394 //*************************************************************************************************************
1395 void CAttribDlgRGBA::setCurrentScheme(uint index)
1397 nlassert(index < 5);
1399 NL3D::CPSAttribMaker<CRGBA> *scheme = NULL;
1401 switch (index)
1403 case 0 :
1404 scheme = new NL3D::CPSColorBlender;
1405 break;
1406 case 1 :
1407 scheme = new NL3D::CPSColorGradient(NL3D::CPSColorGradient::_DefaultGradient, 2, 16, 1.f);
1408 break;
1409 case 2 :
1410 scheme = new NL3D::CPSColorBlenderExact;
1411 break;
1412 case 3 :
1413 scheme = new NL3D::CPSColorMemory;
1414 ((NL3D::CPSAttribMakerMemory<CRGBA> *) scheme)->setScheme(new NL3D::CPSColorBlender);
1415 break;
1416 case 4 :
1417 scheme = new NL3D::CPSColorBinOp;
1418 ((NL3D::CPSColorBinOp *) scheme)->setArg(0, new NL3D::CPSColorBlender);
1419 ((NL3D::CPSColorBinOp *) scheme)->setArg(1, new NL3D::CPSColorBlender);
1420 break;
1421 default:
1422 break;
1425 if (scheme)
1427 _SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
1431 //*************************************************************************************************************
1432 sint CAttribDlgRGBA::getCurrentScheme(void) const
1434 const NL3D::CPSAttribMaker<CRGBA> *scheme = _SchemeWrapper->getScheme();
1436 if (dynamic_cast<const NL3D::CPSColorBlender *>(scheme)) return 0;
1437 if (dynamic_cast<const NL3D::CPSColorGradient *>(scheme)) return 1;
1438 if (dynamic_cast<const NL3D::CPSColorBlenderExact *>(scheme)) return 2;
1439 if (dynamic_cast<const NL3D::CPSColorMemory *>(scheme)) return 3;
1440 if (dynamic_cast<const NL3D::CPSColorBinOp *>(scheme)) return 4;
1441 return -1;
1444 //*************************************************************************************************************
1445 CEditAttribDlg *CAttribDlgRGBA::createConstantValueDlg()
1447 CColorEdit *ce = new CColorEdit;
1448 ce->setWrapper(_Wrapper);
1450 return ce;
1455 /////////////////////////////
1456 // plane basis attributes //
1457 /////////////////////////////
1459 //////////////////////////////////////////////////////////
1460 // PLANE BASIS GRADIENT EDITION INTERFACE //
1461 //////////////////////////////////////////////////////////
1464 class CPlaneBasisGradientDlgWrapper : public CValueGradientDlgClientT<NL3D::CPlaneBasis>
1466 public:
1467 /// a function that can display a value in a gradient, with the given offset. Deriver must define this
1468 void displayValue(CDC *dc, uint index, sint x, sint y)
1471 NLMISC::CRGBA c1[] ={ NLMISC::CRGBA::Black, NLMISC::CRGBA::Black, NLMISC::CRGBA::Black };
1472 NLMISC::CRGBA c2[] ={ NLMISC::CRGBA::Green, NLMISC::CRGBA::Green, NLMISC::CRGBA::Red };
1475 // read plane basis
1476 NL3D::CPlaneBasis pb = Scheme->getValue(index);
1478 CPoint center(x + 20, y + 25);
1480 NLMISC::CMatrix m;
1481 m.setRot(pb.X, pb.Y, pb.X ^ pb.Y);
1482 DrawBasisInDC(center, 12, m, *dc, c2);
1485 CEditAttribDlg *newDialog(const std::string &id, IPSWrapper<NL3D::CPlaneBasis> *wrapper)
1487 CBasisEdit *be = new CBasisEdit;
1488 be->setWrapper(wrapper);
1489 return be;
1493 //*************************************************************************************************************
1494 CAttribDlgPlaneBasis::CAttribDlgPlaneBasis(const std::string &valueID, CParticleWorkspace::CNode *node) : CAttribDlgT<NL3D::CPlaneBasis>(valueID, node)
1498 uint CAttribDlgPlaneBasis::getNumScheme(void) const
1500 return _DisableMemoryScheme ? 3 : 5;
1503 std::string CAttribDlgPlaneBasis::getSchemeName(uint index) const
1505 const char *types[] = { "basis gradient", "follow path", "spinner", "values computed from emitter", "binary operator" };
1506 nlassert(index < 5);
1507 return std::string(types[index]);
1510 //*************************************************************************************************************
1511 CWnd *CAttribDlgPlaneBasis::editScheme(void)
1513 NL3D::CPSAttribMaker<NL3D::CPlaneBasis> *scheme = _SchemeWrapper->getScheme();
1514 if (dynamic_cast<NL3D::CPSPlaneBasisGradient *>(scheme))
1516 CPlaneBasisGradientDlgWrapper *wrapper = new CPlaneBasisGradientDlgWrapper;
1517 wrapper->Scheme = &(((NL3D::CPSPlaneBasisGradient *) (_SchemeWrapper->getScheme()) )->_F);
1518 CValueGradientDlg *gd = new CValueGradientDlg(wrapper, _Node, true, this, this);
1519 wrapper->GradDlg = gd;
1520 wrapper->DefaultValue = NL3D::CPlaneBasis(NLMISC::CVector::K);
1521 wrapper->Id = std::string("PLANE_BASIS_GRADIENT");
1522 gd->init(this);
1523 return gd;
1526 if (dynamic_cast<NL3D::CPSPlaneBasisFollowSpeed *>(scheme))
1528 CEditFollowPath *efp = new CEditFollowPath((NL3D::CPSPlaneBasisFollowSpeed *) scheme, _Node, this, this);
1529 efp->init(this);
1530 return efp;
1533 if (dynamic_cast<NL3D::CPSPlaneBasisMemory *>(scheme))
1535 CAttribDlgPlaneBasis *ad = new CAttribDlgPlaneBasis(_CstValueId, _Node);
1536 CValueFromEmitterDlgT<NL3D::CPlaneBasis> *vfe = new CValueFromEmitterDlgT<NL3D::CPlaneBasis>
1537 ( (NL3D::CPSPlaneBasisMemory *)(scheme),
1539 this,
1540 m_AttrBitmap.GetBitmap());
1541 vfe->init(this);
1542 return vfe;
1545 if (dynamic_cast<NL3D::CPSPlaneBasisBinOp *>(scheme))
1547 CAttribDlgPlaneBasis *ad[2] = { NULL, NULL};
1548 for (uint k = 0; k <2; ++k)
1550 ad[k] = new CAttribDlgPlaneBasis(_CstValueId, _Node);
1552 CBinOpDlgT<NL3D::CPlaneBasis> *bod = new CBinOpDlgT<NL3D::CPlaneBasis>( (NL3D::CPSPlaneBasisBinOp *)(scheme),
1553 (CAttribDlgT<NL3D::CPlaneBasis> **) ad,
1554 this,
1555 m_AttrBitmap.GetBitmap());
1556 bod->init(this);
1557 return bod;
1560 if (dynamic_cast<NL3D::CPSBasisSpinner *>(scheme))
1562 CEditSpinner *es = new CEditSpinner(static_cast<NL3D::CPSBasisSpinner *>(scheme), _Node, this, this);
1563 es->init(this);
1564 return es;
1566 return NULL;
1569 //*************************************************************************************************************
1570 void CAttribDlgPlaneBasis::setCurrentScheme(uint index)
1572 nlassert(index < 5);
1574 NL3D::CPSAttribMaker<NL3D::CPlaneBasis> *scheme = NULL;
1576 switch (index)
1578 case 0:
1579 scheme = new NL3D::CPSPlaneBasisGradient;
1580 break;
1581 case 1:
1582 scheme = new NL3D::CPSPlaneBasisFollowSpeed;
1583 break;
1584 case 2:
1585 scheme = new NL3D::CPSBasisSpinner;
1586 static_cast<NL3D::CPSBasisSpinner *>(scheme)->_F.setNumSamples(16);
1587 break;
1588 case 3:
1589 scheme = new NL3D::CPSPlaneBasisMemory;
1590 ((NL3D::CPSAttribMakerMemory<NL3D::CPlaneBasis> *) scheme)->setScheme(new NL3D::CPSPlaneBasisFollowSpeed);
1591 if (_Node)
1593 _Node->setModified(true);
1595 break;
1596 case 4 :
1597 scheme = new NL3D::CPSPlaneBasisBinOp;
1598 ((NL3D::CPSPlaneBasisBinOp *) scheme)->setArg(0, new NL3D::CPSPlaneBasisFollowSpeed);
1599 ((NL3D::CPSPlaneBasisBinOp *) scheme)->setArg(1, new NL3D::CPSPlaneBasisFollowSpeed);
1600 break;
1601 default:
1602 break;
1605 if (scheme)
1607 _SchemeWrapper->setSchemeAndUpdateModifiedFlag(scheme);
1611 //*************************************************************************************************************
1612 sint CAttribDlgPlaneBasis::getCurrentScheme(void) const
1614 const NL3D::CPSAttribMaker<NL3D::CPlaneBasis> *scheme = _SchemeWrapper->getScheme();
1616 if (dynamic_cast<const NL3D::CPSPlaneBasisGradient *>(scheme)) return 0;
1617 if (dynamic_cast<const NL3D::CPSPlaneBasisFollowSpeed *>(scheme)) return 1;
1618 if (dynamic_cast<const NL3D::CPSBasisSpinner *>(scheme)) return 2;
1619 if (dynamic_cast<const NL3D::CPSPlaneBasisMemory *>(scheme)) return 3;
1620 if (dynamic_cast<const NL3D::CPSPlaneBasisBinOp *>(scheme)) return 4;
1622 return -1;
1625 //*************************************************************************************************************
1626 CEditAttribDlg *CAttribDlgPlaneBasis::createConstantValueDlg()
1628 CBasisEdit *ce = new CBasisEdit;
1629 ce->setWrapper(_Wrapper);
1630 return ce;
1633 //*************************************************************************************************************
1634 void CAttribDlg::OnDestroy()
1636 if (_SchemeEditionDlg)
1638 CWnd *wnd = _SchemeEditionDlg;
1639 _SchemeEditionDlg = NULL;
1640 wnd ->DestroyWindow();
1641 delete wnd ;
1643 CDialog::OnDestroy();
1647 //*************************************************************************************************************
1648 void CAttribDlg::OnClose()
1650 CDialog::OnClose();