!XT (BREAK-16) (Sandbox) Remove double-newlines at the end of files.
[CRYENGINE.git] / Code / Sandbox / EditorQt / LensFlareEditor / LensFlareElementTree.cpp
blobdea22841e243d3e13dab84591e00931b78fd9a19
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "LensFlareElementTree.h"
5 #include "LensFlareItem.h"
6 #include "LensFlareManager.h"
7 #include "LensFlareUndo.h"
8 #include "LensFlareEditor.h"
9 #include "LensFlareLibrary.h"
10 #include "LensFlareItemTree.h"
11 #include "Util/Clipboard.h"
13 #include "QtUtil.h"
15 enum
17 ID_DB_FLARE_ADDGROUP = 1,
18 ID_DB_FLARE_COPY,
19 ID_DB_FLARE_CUT,
20 ID_DB_FLARE_PASTE,
21 ID_DB_FLARE_CLONE,
22 ID_DB_FLARE_RENAME,
23 ID_DB_FLARE_REMOVE,
24 ID_DB_FLARE_REMOVEALL,
25 ID_DB_FLARE_ITEMUP,
26 ID_DB_FLARE_ITEMDOWN
29 BEGIN_MESSAGE_MAP(CLensFlareElementTree, CXTTreeCtrl)
30 ON_NOTIFY_REFLECT(NM_RCLICK, OnNotifyTreeRClick)
31 ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnTvnSelchangedTree)
32 ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnTvnBeginlabeleditTree)
33 ON_NOTIFY_REFLECT(NM_CLICK, OnTvnItemClicked)
34 ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnTvnEndlabeleditTree)
35 ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnTvnKeydownTree)
36 ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBeginDrag)
37 ON_COMMAND(ID_DB_FLARE_ADDGROUP, OnAddGroup)
38 ON_COMMAND(ID_DB_FLARE_RENAME, OnRenameItem)
39 ON_COMMAND(ID_DB_FLARE_COPY, OnCopy)
40 ON_COMMAND(ID_DB_FLARE_CUT, OnCut)
41 ON_COMMAND(ID_DB_FLARE_PASTE, OnPaste)
42 ON_COMMAND(ID_DB_FLARE_CLONE, OnClone)
43 ON_COMMAND(ID_DB_FLARE_REMOVE, OnRemoveItem)
44 ON_COMMAND(ID_DB_FLARE_REMOVEALL, OnRemoveAll)
45 ON_COMMAND(ID_DB_FLARE_ITEMUP, OnItemUp)
46 ON_COMMAND(ID_DB_FLARE_ITEMDOWN, OnItemDown)
47 ON_WM_LBUTTONDOWN()
48 ON_WM_LBUTTONUP()
49 ON_WM_MOUSEMOVE()
50 ON_WM_KEYDOWN()
51 END_MESSAGE_MAP()
53 CLensFlareElementTree::CLensFlareElementTree()
55 CLensFlareEditor::GetLensFlareEditor()->RegisterLensFlareItemChangeListener(this);
58 CLensFlareElementTree::~CLensFlareElementTree()
60 CLensFlareEditor::GetLensFlareEditor()->UnregisterLensFlareItemChangeListener(this);
63 void CLensFlareElementTree::UpdateLensFlareItem(CLensFlareItem* pLensFlareItem)
65 ClearElementList();
67 if (pLensFlareItem == NULL)
68 return;
70 if (pLensFlareItem->GetOptics() == NULL)
71 return;
73 m_pLensFlareItem = pLensFlareItem;
74 UpdateLensFlareElementsRecusively(m_pLensFlareItem->GetOptics());
78 void CLensFlareElementTree::ClearElementList()
80 m_LensFlareElements.clear();
83 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::FindRootElement() const
85 for (int i = 0, iElementSize(m_LensFlareElements.size()); i < iElementSize; ++i)
87 if (m_LensFlareElements[i]->GetOpticsElement()->GetType() == eFT_Root)
88 return m_LensFlareElements[i];
90 return NULL;
93 int CLensFlareElementTree::FindElementIndexByOptics(IOpticsElementBasePtr pOptics) const
95 for (int i = 0, iElementSize(m_LensFlareElements.size()); i < iElementSize; ++i)
97 if (m_LensFlareElements[i]->GetOpticsElement() == pOptics)
98 return i;
100 return -1;
103 void CLensFlareElementTree::AddLensElementRecursively(HTREEITEM hParent, IOpticsElementBasePtr pOptics)
105 if (pOptics == NULL)
106 return;
108 CString shortName = LensFlareUtil::GetShortName(pOptics->GetName());
109 HTREEITEM hItem = InsertItem(shortName, 2, 3, hParent);
110 if (hItem == NULL)
111 return;
113 int nIndex = FindElementIndexByOptics(pOptics);
114 if (nIndex == -1)
115 return;
117 SetItemData(hItem, (DWORD_PTR)nIndex);
118 SetCheck(hItem, m_LensFlareElements[nIndex]->IsEnable());
120 for (int i = 0, iChildCount(pOptics->GetElementCount()); i < iChildCount; ++i)
122 IOpticsElementBasePtr pChild = pOptics->GetElementAt(i);
123 if (pChild == NULL)
124 continue;
125 AddLensElementRecursively(hItem, pChild);
129 void CLensFlareElementTree::Reload()
131 DeleteAllItems();
133 CLensFlareElement::LensFlareElementPtr pRootElement = FindRootElement();
134 if (pRootElement == NULL)
135 return;
137 IOpticsElementBasePtr pRootOptics = pRootElement->GetOpticsElement();
138 if (pRootOptics == NULL)
139 return;
141 AddLensElementRecursively(NULL, pRootOptics);
143 HTREEITEM hVisibleItem = GetFirstVisibleItem();
144 while (hVisibleItem)
146 Expand(hVisibleItem, TVE_EXPAND);
147 hVisibleItem = GetNextVisibleItem(hVisibleItem);
151 IOpticsElementBasePtr CLensFlareElementTree::GetOpticsElement() const
153 return m_pLensFlareItem->GetOptics();
156 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::AddAtomicElement(EFlareType flareType, IOpticsElementBasePtr pParent)
158 IOpticsElementBasePtr pNewOptics = gEnv->pOpticsManager->Create(flareType);
159 if (pNewOptics == NULL)
160 return NULL;
161 CLensFlareElement::LensFlareElementPtr pElement = AddElement(pNewOptics, pParent);
162 if (pElement == NULL)
163 return false;
164 pParent->AddElement(pNewOptics);
165 return pElement;
168 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::InsertAtomicElement(int nIndex, EFlareType flareType, IOpticsElementBasePtr pParent)
170 if (pParent == NULL)
171 return NULL;
173 IOpticsElementBasePtr pNewOptics = gEnv->pOpticsManager->Create(flareType);
174 if (pNewOptics == NULL)
175 return NULL;
177 if (nIndex < 0)
178 return NULL;
180 CLensFlareElement::LensFlareElementPtr pElement = AddElement(pNewOptics, pParent);
181 if (pElement == NULL)
182 return false;
184 pParent->InsertElement(nIndex, pNewOptics);
186 return pElement;
189 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::AddElement(IOpticsElementBasePtr pOptics, IOpticsElementBasePtr pParent)
191 if (pOptics == NULL)
192 return NULL;
194 CLensFlareElement::LensFlareElementPtr pLensFlareElement = NULL;
196 if (pParent == NULL)
198 if (pOptics->GetType() != eFT_Root)
200 assert(0 && "CFlareManager::AddItem() - pOptics must be a root optics if the parent doesn't exist.");
201 return NULL;
203 pLensFlareElement = CreateElement(pOptics);
205 else
207 if (!LensFlareUtil::IsGroup(pParent->GetType()))
208 return NULL;
210 CLensFlareElement::LensFlareElementPtr pParentElement = FindLensFlareElement(pParent);
211 if (pParentElement == NULL)
212 return NULL;
214 string fullElementName;
215 if (!pParentElement->GetName(fullElementName))
216 return NULL;
217 if (!fullElementName.IsEmpty())
218 fullElementName += ".";
219 fullElementName += LensFlareUtil::GetShortName(pOptics->GetName()).MakeLower();
221 string validName;
222 MakeValidElementName(fullElementName, validName);
223 pOptics->SetName(validName);
225 pLensFlareElement = CreateElement(pOptics);
228 if (LensFlareUtil::IsGroup(pOptics->GetType()))
230 for (int i = 0, iElementCount(pOptics->GetElementCount()); i < iElementCount; ++i)
231 AddElement(pOptics->GetElementAt(i), pOptics);
234 GetIEditorImpl()->GetLensFlareManager()->Modified();
235 if (m_pLensFlareItem)
236 m_pLensFlareItem->UpdateLights();
238 return pLensFlareElement;
241 bool CLensFlareElementTree::AddElement(EFlareType flareType)
243 CLensFlareElement* pSelectedElement = GetCurrentLensFlareElement();
244 if (pSelectedElement == NULL)
245 return false;
247 CLensFlareElement::LensFlareElementPtr pNewElement = NULL;
249 if (!LensFlareUtil::IsGroup(pSelectedElement->GetOpticsType()))
251 HTREEITEM hCurrentItem = GetSelectedItem();
252 if (!hCurrentItem)
253 return false;
255 HTREEITEM hParentItem = GetParentItem(hCurrentItem);
256 CLensFlareElement* pParentElement = GetLensFlareElement(hParentItem);
257 if (pParentElement == NULL)
258 return false;
260 if (!LensFlareUtil::IsGroup(pParentElement->GetOpticsType()))
261 return false;
263 IOpticsElementBasePtr pSelectedOptics = pSelectedElement->GetOpticsElement();
264 IOpticsElementBasePtr pParentOptics = pParentElement->GetOpticsElement();
265 if (!pSelectedOptics || !pParentOptics)
266 return false;
268 int nIndex = LensFlareUtil::FindOpticsIndexUnderParentOptics(pSelectedElement->GetOpticsElement(), pParentElement->GetOpticsElement());
269 if (nIndex != -1)
270 pNewElement = InsertAtomicElement(nIndex, flareType, pParentOptics);
272 else
274 IOpticsElementBasePtr pSelectedOptics = pSelectedElement->GetOpticsElement();
275 if (pSelectedOptics == NULL)
276 return false;
277 pNewElement = InsertAtomicElement(0, flareType, pSelectedOptics);
280 if (!pNewElement)
281 return false;
283 Reload();
284 SelectTreeItemByLensFlareElement(pNewElement);
285 CallChangeListeners();
286 if (m_pLensFlareItem)
287 m_pLensFlareItem->UpdateLights();
288 return true;
291 void CLensFlareElementTree::StoreUndo(const CString& undoDescription)
293 if (CUndo::IsRecording())
295 if (undoDescription.IsEmpty())
296 CUndo::Record(new CUndoLensFlareItem(GetLensFlareItem()));
297 else
298 CUndo::Record(new CUndoLensFlareItem(GetLensFlareItem(), undoDescription));
302 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::FindLensFlareElement(IOpticsElementBasePtr pElement) const
304 for (size_t i = 0, iLensElementsSize(m_LensFlareElements.size()); i < iLensElementsSize; ++i)
306 if (m_LensFlareElements[i]->GetOpticsElement() == pElement)
307 return m_LensFlareElements[i];
309 return NULL;
312 void CLensFlareElementTree::MakeValidElementName(const string& seedName, string& outValidName) const
314 if (!IsExistElement(seedName))
316 outValidName = seedName;
317 return;
320 int counter = 0;
323 string numberString;
324 numberString.Format("%d", counter);
325 string candidateName = seedName + numberString;
326 if (!IsExistElement(candidateName))
328 outValidName = candidateName;
329 return;
332 while (++counter < 100000); // prevent from infinite loop
335 bool CLensFlareElementTree::IsExistElement(const string& name) const
337 for (size_t i = 0, iLensElementSize(m_LensFlareElements.size()); i < iLensElementSize; ++i)
339 string flareName;
340 if (!m_LensFlareElements[i]->GetName(flareName))
341 continue;
342 if (!stricmp(flareName.GetString(), name.GetString()))
343 return true;
345 return false;
348 void CLensFlareElementTree::UpdateLensFlareElementsRecusively(IOpticsElementBasePtr pOptics)
350 if (pOptics == NULL)
351 return;
353 CLensFlareElement::LensFlareElementPtr pElement = CreateElement(pOptics);
354 assert(pElement);
355 pElement->SetOpticsElement(pOptics);
357 for (int i = 0, iCount(pOptics->GetElementCount()); i < iCount; i++)
358 UpdateLensFlareElementsRecusively(pOptics->GetElementAt(i));
361 HTREEITEM CLensFlareElementTree::InsertElementToTree(int nIndex, HTREEITEM hParent)
363 if (nIndex < 0 || nIndex >= m_LensFlareElements.size())
364 return NULL;
365 CLensFlareElement* pElement = m_LensFlareElements[nIndex];
366 if (pElement == NULL)
367 return NULL;
368 string shortName;
369 if (!pElement->GetShortName(shortName))
370 return NULL;
371 HTREEITEM hItem = InsertItem(CString(shortName), 2, 3, hParent);
372 if (hItem == NULL)
373 return NULL;
374 SetItemData(hItem, (DWORD_PTR)nIndex);
375 SetCheck(hItem, pElement->IsEnable());
376 return hItem;
379 void CLensFlareElementTree::OnInternalVariableChange(IVariable* pVar)
381 CLensFlareElement::LensFlareElementPtr pCurrentElement = GetCurrentLensFlareElement();
382 if (pCurrentElement == NULL)
383 return;
384 pCurrentElement->OnInternalVariableChange(pVar);
387 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::GetCurrentLensFlareElement() const
389 return GetLensFlareElement(GetSelectedItem());
392 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::GetLensFlareElement(HTREEITEM hItem) const
394 if (hItem == NULL)
395 return NULL;
396 int nItemIndex = (int)GetItemData(hItem);
397 if (nItemIndex < 0 || nItemIndex >= m_LensFlareElements.size())
398 return NULL;
399 return m_LensFlareElements[nItemIndex];
402 void CLensFlareElementTree::SelectTreeItemByLensFlareElement(const CLensFlareElement* pElement)
404 if (pElement == NULL)
405 return;
407 // Select an item in tree ctrl.
408 HTREEITEM hVisibleItem = GetFirstVisibleItem();
409 while (hVisibleItem)
411 int nItemIndex = (int)GetItemData(hVisibleItem);
412 CLensFlareElement::LensFlareElementPtr pLensFlareElement = m_LensFlareElements[nItemIndex];
413 if (pElement == pLensFlareElement)
415 SelectItem(hVisibleItem);
416 break;
418 hVisibleItem = GetNextVisibleItem(hVisibleItem);
422 void CLensFlareElementTree::StartEditItem(HTREEITEM hItem)
424 if (hItem == NULL)
425 return;
426 SetFocus();
427 EditLabel(hItem);
430 void CLensFlareElementTree::OnNotifyTreeRClick(NMHDR* pNMHDR, LRESULT* pResult)
432 CLensFlareElement* pLensFlareElement = 0;
434 HTREEITEM hItem = LensFlareUtil::GetTreeItemByHitTest(*this);
435 if (hItem)
436 pLensFlareElement = GetLensFlareElement(hItem);
438 // Copy, Cut and Clone can't be done about a Root item so those menus should be disable when the selected item is a root item.
439 int bGrayed = 0;
440 if (GetParentItem(hItem) == NULL)
441 bGrayed = MF_GRAYED;
443 SelectTreeItemByLensFlareElement(pLensFlareElement);
444 CallChangeListeners();
446 CMenu menu;
447 menu.CreatePopupMenu();
449 menu.AppendMenu(MF_STRING, ID_DB_FLARE_ADDGROUP, "Add Group");
450 menu.AppendMenu(MF_SEPARATOR, 0, "");
451 menu.AppendMenu(MF_STRING, ID_DB_FLARE_COPY, "Copy");
452 menu.AppendMenu(MF_STRING | bGrayed, ID_DB_FLARE_CUT, "Cut");
453 menu.AppendMenu(MF_STRING, ID_DB_FLARE_PASTE, "Paste");
454 menu.AppendMenu(MF_STRING, ID_DB_FLARE_CLONE, "Clone");
455 menu.AppendMenu(MF_SEPARATOR, 0, "");
456 menu.AppendMenu(MF_STRING, ID_DB_FLARE_RENAME, "Rename\tF2");
457 menu.AppendMenu(MF_STRING, ID_DB_FLARE_REMOVE, "Delete\tDel");
458 menu.AppendMenu(MF_STRING, ID_DB_FLARE_REMOVEALL, "Delete All");
459 menu.AppendMenu(MF_SEPARATOR, 0, "");
460 menu.AppendMenu(MF_STRING, ID_DB_FLARE_ITEMUP, "Up");
461 menu.AppendMenu(MF_STRING, ID_DB_FLARE_ITEMDOWN, "Down");
463 CPoint point;
464 GetCursorPos(&point);
465 menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, this);
467 // Mark message as handled and suppress default handling
468 *pResult = 1;
471 void CLensFlareElementTree::OnTvnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
473 NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)pNMHDR;
475 if (pNMTreeView->itemOld.hItem)
476 ElementChanged(GetLensFlareElement(pNMTreeView->itemOld.hItem));
478 CallChangeListeners();
480 *pResult = 1;
483 void CLensFlareElementTree::ElementChanged(CLensFlareElement* pPrevLensFlareElement)
485 if (!pPrevLensFlareElement)
486 return;
487 string itemName;
488 if (pPrevLensFlareElement->GetName(itemName))
490 if (CUndo::IsRecording())
491 CUndo::Record(new CUndoLensFlareElementSelection(GetLensFlareItem(), itemName));
495 void CLensFlareElementTree::OnTvnBeginlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult)
497 LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
499 // Mark message as handled and suppress default handling
500 *pResult = 0;
503 void CLensFlareElementTree::OnTvnItemClicked(NMHDR* pNMHDR, LRESULT* pResult)
505 TVHITTESTINFO ht = { 0 };
506 DWORD dwPos = ::GetMessagePos();
507 ht.pt.x = GET_X_LPARAM(dwPos);
508 ht.pt.y = GET_Y_LPARAM(dwPos);
510 ::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &ht.pt, 1);
511 TreeView_HitTest(pNMHDR->hwndFrom, &ht);
513 CUndo undo("Update an enable checkbox for tree ctrl.");
515 if (TVHT_ONITEMSTATEICON & ht.flags)
517 HTREEITEM hItem(ht.hItem);
518 if (hItem == NULL)
519 return;
521 CLensFlareElement* pLensFlareElement = GetLensFlareElement(hItem);
522 if (pLensFlareElement == NULL)
523 return;
525 EnableElement(pLensFlareElement, !(GetCheck(hItem)));
526 SelectItem(hItem);
528 CallChangeListeners();
531 *pResult = 0;
534 void CLensFlareElementTree::EnableElement(CLensFlareElement* pLensFlareElement, bool bEnable)
536 StoreUndo();
537 pLensFlareElement->SetEnable(bEnable);
540 void CLensFlareElementTree::OnTvnEndlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult)
542 LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
543 HTREEITEM hItem = GetSelectedItem();
545 if (hItem == NULL)
546 return;
548 if (pTVDispInfo->item.pszText == NULL)
549 return;
551 CUndo undo("Rename library item");
553 if (IsExistElement(pTVDispInfo->item.pszText))
555 MessageBox("The identical name exists in a database", "Warning", MB_OK);
556 StartEditItem(hItem);
558 else if (strstr(pTVDispInfo->item.pszText, "."))
560 MessageBox("The name must not contain \".\"", "Warning", MB_OK);
561 StartEditItem(hItem);
563 else
565 CLensFlareElement* pLensFlareElement = GetCurrentLensFlareElement();
567 string prevName;
568 if (pLensFlareElement && pLensFlareElement->GetName(prevName))
570 string parentName(prevName);
571 int offset = parentName.ReverseFind('.');
572 if (offset == -1)
573 parentName = "";
574 else
575 parentName.Delete(offset + 1, parentName.GetLength() - offset);
577 if (hItem == GetRootItem())
579 CLensFlareEditor* pLensFlareEditor = CLensFlareEditor::GetLensFlareEditor();
580 if (pLensFlareEditor)
582 CLensFlareItem* pLensFlareItem = pLensFlareEditor->GetSelectedLensFlareItem();
583 if (pLensFlareItem)
585 string candidateName = LensFlareUtil::ReplaceLastName(pLensFlareItem->GetName(), pTVDispInfo->item.pszText);
586 if (pLensFlareEditor->IsExistTreeItem(candidateName, true))
588 MessageBox("The identical name exists in a database", "Warning", MB_OK);
589 *pResult = 0;
590 return;
592 pLensFlareEditor->RenameLensFlareItem(pLensFlareItem, pLensFlareItem->GetGroupName(), pTVDispInfo->item.pszText);
595 else
597 MessageBox("Renaming is not possible.", "Warning", MB_OK);
598 *pResult = 0;
599 return;
603 SetItemText(hItem, pTVDispInfo->item.pszText);
604 RenameElement(pLensFlareElement, CString(parentName) + pTVDispInfo->item.pszText);
606 CallChangeListeners();
607 GetIEditorImpl()->GetLensFlareManager()->Modified();
611 // Mark message as handled and suppress default handling
612 *pResult = 0;
615 void CLensFlareElementTree::RenameElement(CLensFlareElement* pLensFlareElement, const CString& newName)
617 StoreUndo();
618 IOpticsElementBasePtr pOptics = pLensFlareElement->GetOpticsElement();
619 if (pOptics)
621 pOptics->SetName(newName);
622 LensFlareUtil::UpdateOpticsName(pOptics);
626 void CLensFlareElementTree::OnTvnKeydownTree(NMHDR* pNMHDR, LRESULT* pResult)
628 LPNMTVKEYDOWN pTVKeyDown = reinterpret_cast<LPNMTVKEYDOWN>(pNMHDR);
630 if (pTVKeyDown->wVKey == VK_F2)
632 OnRenameItem();
634 else if (pTVKeyDown->wVKey == VK_DELETE)
636 OnRemoveItem();
639 // Mark message as handled and suppress default handling
640 *pResult = 0;
643 XmlNodeRef CLensFlareElementTree::CreateXML(const char* type) const
645 std::vector<LensFlareUtil::SClipboardData> clipboardData;
646 if (GetClipboardList(type, clipboardData))
647 return LensFlareUtil::CreateXMLFromClipboardData(type, "", false, clipboardData);
648 return NULL;
651 void CLensFlareElementTree::UpdateClipboard(const char* type, bool bPasteAtSameLevel)
653 std::vector<LensFlareUtil::SClipboardData> clipboardData;
654 if (GetClipboardList(type, clipboardData))
655 LensFlareUtil::UpdateClipboard(type, "", bPasteAtSameLevel, clipboardData);
658 bool CLensFlareElementTree::GetClipboardList(const char* type, std::vector<LensFlareUtil::SClipboardData>& outList) const
660 CLensFlareElement::LensFlareElementPtr pElement = GetCurrentLensFlareElement();
661 if (pElement == NULL)
662 return false;
663 string name;
664 if (!pElement->GetName(name))
665 return false;
667 CLensFlareEditor* pEditor = CLensFlareEditor::GetLensFlareEditor();
668 if (pEditor == NULL)
669 return false;
671 CLensFlareItem* pLensFlareItem = pEditor->GetSelectedLensFlareItem();
672 if (pLensFlareItem == NULL)
673 return false;
675 outList.push_back(LensFlareUtil::SClipboardData(LENSFLARE_ELEMENT_TREE, pLensFlareItem->GetFullName(), name));
677 return true;
680 void CLensFlareElementTree::OnAddGroup()
682 CUndo undo("Add library item");
683 AddElement(eFT_Group);
684 GetIEditorImpl()->GetLensFlareManager()->Modified();
687 void CLensFlareElementTree::OnCopy()
689 UpdateClipboard(FLARECLIPBOARDTYPE_COPY, false);
692 void CLensFlareElementTree::OnCut()
694 Cut(false);
697 void CLensFlareElementTree::Cut(bool bPasteAtSameLevel)
699 UpdateClipboard(FLARECLIPBOARDTYPE_CUT, bPasteAtSameLevel);
702 void CLensFlareElementTree::OnPaste()
704 CClipboard clipboard;
705 if (clipboard.IsEmpty())
706 return;
708 XmlNodeRef xmlNode = clipboard.Get();
709 if (xmlNode == NULL)
710 return;
712 CUndo undo("Copy/Cut & Paste library item");
713 Paste(xmlNode);
716 void CLensFlareElementTree::Paste(XmlNodeRef xmlNode)
718 CLensFlareEditor* pEditor = CLensFlareEditor::GetLensFlareEditor();
719 if (pEditor == NULL)
720 return;
722 CString type;
723 xmlNode->getAttr("Type", type);
725 bool bPasteAtSameLevel = false;
726 xmlNode->getAttr("PasteAtSameLevel", bPasteAtSameLevel);
728 HTREEITEM hParentItem = NULL;
729 HTREEITEM hSelectedTreeItem = GetSelectedItem();
730 if (hSelectedTreeItem == NULL)
731 return;
733 IOpticsElementBasePtr pSelectedOptics = GetOpticsElementByTreeItem(hSelectedTreeItem);
734 if (pSelectedOptics == NULL)
735 return;
737 CLensFlareItem* pSelectedLensFlareItem = pEditor->GetSelectedLensFlareItem();
738 if (!pSelectedLensFlareItem)
739 return;
741 if (!LensFlareUtil::IsGroup(pSelectedOptics->GetType()))
743 HTREEITEM hParentTreeItem = GetParentItem(hSelectedTreeItem);
744 if (hParentTreeItem == NULL)
745 hParentItem = TVI_ROOT;
746 else
747 hParentItem = hParentTreeItem;
749 else
751 if (bPasteAtSameLevel)
752 hParentItem = GetParentItem(hSelectedTreeItem);
753 else
754 hParentItem = hSelectedTreeItem;
757 if (hParentItem == NULL)
758 return;
760 IOpticsElementBasePtr pParentOptics = GetOpticsElementByTreeItem(hParentItem);
761 if (pParentOptics == NULL)
762 return;
764 for (int i = 0, iChildCount(xmlNode->getChildCount()); i < iChildCount; ++i)
766 LensFlareUtil::SClipboardData clipboardData;
767 clipboardData.FillThisFromXmlNode(xmlNode->getChild(i));
769 if (clipboardData.m_LensFlareFullPath == GetLensFlareItem()->GetFullName() && clipboardData.m_From == LENSFLARE_ITEM_TREE)
771 CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "[%s] lens item can be pasted into the same item", clipboardData.m_LensFlareFullPath);
772 continue;
775 IOpticsElementBasePtr pSourceOptics = pEditor->FindOptics(clipboardData.m_LensFlareFullPath, clipboardData.m_LensOpticsPath);
776 if (pSourceOptics == NULL)
777 continue;
779 CLensFlareItem* pSourceLensFlareItem = (CLensFlareItem*)GetIEditorImpl()->GetLensFlareManager()->FindItemByName(clipboardData.m_LensFlareFullPath);
780 if (pSourceLensFlareItem == NULL)
781 continue;
783 if (type == FLARECLIPBOARDTYPE_CUT)
785 if (pSelectedLensFlareItem->GetFullName() == clipboardData.m_LensFlareFullPath && LensFlareUtil::FindOptics(pSourceOptics, pSelectedOptics->GetName()))
787 MessageBox("You can't paste this item here.", "Warning", MB_OK);
788 return;
792 // if the copied optics type is root, the type should be converted to group type.
793 bool bForceConvertType = false;
794 if (pSourceOptics->GetType() == eFT_Root)
795 bForceConvertType = true;
797 IOpticsElementBasePtr pNewOptics = LensFlareUtil::CreateOptics(pSourceOptics, bForceConvertType);
798 if (pNewOptics == NULL)
799 return;
801 if (type == FLARECLIPBOARDTYPE_CUT)
803 if (pSourceLensFlareItem == pSelectedLensFlareItem)
805 CLensFlareElement::LensFlareElementList removedElements;
806 GatherItemsRecusively(GetTreeItemByOpticsElement(pSourceOptics), removedElements);
807 DeleteOnesInElementList(removedElements);
809 else if (clipboardData.m_From == LENSFLARE_ITEM_TREE)
811 CLensFlareLibrary* pLibrary = pEditor->GetCurrentLibrary();
812 if (pLibrary)
814 string lensFlareFullName = m_pLensFlareItem ? m_pLensFlareItem->GetFullName() : "";
815 pLibrary->RemoveItem(pSourceLensFlareItem);
816 pEditor->ReloadItems();
817 pSourceLensFlareItem->UpdateLights();
818 pEditor->UpdateLensOpticsNames(pSourceLensFlareItem->GetFullName(), "");
819 if (!lensFlareFullName.IsEmpty())
820 pEditor->SelectItemByName(lensFlareFullName);
823 LensFlareUtil::RemoveOptics(pSourceOptics);
826 // The children optics items were already added in a creation phase so we don't need to update the optics object.
827 CLensFlareElement::LensFlareElementPtr pNewElement = AddElement(pNewOptics, pParentOptics);
828 assert(pNewElement);
829 if (!pNewElement)
830 return;
831 if (hParentItem == hSelectedTreeItem)
833 pParentOptics->InsertElement(0, pNewOptics);
835 else
837 int nInsertedPos = LensFlareUtil::FindOpticsIndexUnderParentOptics(pSelectedOptics, pParentOptics);
838 if (nInsertedPos >= pParentOptics->GetElementCount() || nInsertedPos == -1)
839 pParentOptics->AddElement(pNewOptics);
840 else
841 pParentOptics->InsertElement(nInsertedPos, pNewOptics);
844 LensFlareUtil::UpdateOpticsName(pNewOptics);
845 Reload();
846 SelectTreeItemByLensFlareElement(pNewElement);
847 CallChangeListeners();
848 pSelectedLensFlareItem->UpdateLights();
852 void CLensFlareElementTree::GatherItemsRecusively(HTREEITEM hItem, CLensFlareElement::LensFlareElementList& outList)
854 if (hItem == NULL)
855 return;
857 int nIndex = (int)GetItemData(hItem);
858 CLensFlareElement* pElement = GetElement(nIndex);
859 if (pElement)
860 outList.push_back(pElement);
862 HTREEITEM hChildItem = GetChildItem(hItem);
863 while (hChildItem)
865 GatherItemsRecusively(hChildItem, outList);
866 hChildItem = GetNextSiblingItem(hChildItem);
870 void CLensFlareElementTree::DeleteOnesInElementList(CLensFlareElement::LensFlareElementList& elementList)
872 CLensFlareElement::LensFlareElementList::iterator ii = m_LensFlareElements.begin();
874 for (; ii != m_LensFlareElements.end(); )
876 bool bErased(false);
877 for (int i = 0, elementListSize(elementList.size()); i < elementListSize; ++i)
879 if (elementList[i] == *ii)
881 ii = m_LensFlareElements.erase(ii);
882 bErased = true;
883 break;
886 if (bErased == false)
887 ++ii;
890 GetIEditorImpl()->GetLensFlareManager()->Modified();
891 if (m_pLensFlareItem)
892 m_pLensFlareItem->UpdateLights();
895 void CLensFlareElementTree::OnClone()
897 OnCopy();
898 OnPaste();
901 void CLensFlareElementTree::OnRenameItem()
903 StartEditItem(GetSelectedItem());
906 void CLensFlareElementTree::OnRemoveItem()
908 HTREEITEM hItem = GetSelectedItem();
909 if (hItem == NULL)
910 return;
912 // A root item must not be removed.
913 HTREEITEM hParent = GetParentItem(hItem);
914 if (hParent == NULL)
915 return;
917 CLensFlareElement::LensFlareElementPtr pCurrentElement = GetLensFlareElement(hItem);
918 if (pCurrentElement == NULL)
919 return;
921 string name;
922 pCurrentElement->GetName(name);
924 string str;
925 str.Format(_T("Delete %s?"), name.GetString());
926 if (MessageBox(str, _T("Delete Confirmation"), MB_YESNO | MB_ICONQUESTION) == IDYES)
928 CUndo undo("Remove an optics element");
929 HTREEITEM hNextItem = GetNextSiblingItem(hItem);
930 RemoveElement(hItem);
931 SelectItem(hNextItem);
932 CallChangeListeners();
933 if (m_pLensFlareItem)
934 m_pLensFlareItem->UpdateLights();
935 Reload();
939 void CLensFlareElementTree::OnRemoveAll()
941 CUndo undo("Remove All in FlareTreeCtrl");
943 if (MessageBox(_T("Do you want delete all?"), _T("Delete Confirmation"), MB_YESNO | MB_ICONQUESTION) == IDYES)
945 RemoveAllElements();
946 UpdateLensFlareItem(m_pLensFlareItem);
947 Reload();
948 if (m_pLensFlareItem)
949 m_pLensFlareItem->UpdateLights();
951 GetIEditorImpl()->GetLensFlareManager()->Modified();
955 void CLensFlareElementTree::RemoveAllElements()
957 CLensFlareElement::LensFlareElementPtr pElement = GetLensFlareElement(GetRootItem());
958 if (pElement == NULL)
959 return;
960 IOpticsElementBasePtr pOptics = pElement->GetOpticsElement();
961 if (pOptics == NULL)
962 return;
963 StoreUndo();
964 pOptics->RemoveAll();
967 void CLensFlareElementTree::OnItemUp()
969 HTREEITEM hSelectedItem = GetSelectedItem();
970 if (hSelectedItem == NULL)
971 return;
973 HTREEITEM hPrevItem = GetPrevSiblingItem(hSelectedItem);
974 if (hPrevItem == NULL)
975 return;
977 hPrevItem = GetPrevSiblingItem(hPrevItem);
979 bool bPasteAtSameLevel = true;
980 if (!hPrevItem)
982 bPasteAtSameLevel = false;
983 hPrevItem = GetParentItem(hSelectedItem);
986 if (hPrevItem)
988 Cut(bPasteAtSameLevel);
989 SelectItem(hPrevItem);
990 OnPaste();
994 void CLensFlareElementTree::OnItemDown()
996 HTREEITEM hSelectedItem = GetSelectedItem();
997 if (hSelectedItem == NULL)
998 return;
1000 HTREEITEM hNextItem = GetNextSiblingItem(hSelectedItem);
1001 if (hNextItem)
1003 Cut(true);
1004 SelectItem(hNextItem);
1005 OnPaste();
1009 IOpticsElementBasePtr CLensFlareElementTree::GetOpticsElementByTreeItem(HTREEITEM hItem) const
1011 if (hItem == NULL)
1012 return NULL;
1014 int nIndex = (int)GetItemData(hItem);
1015 CLensFlareElement::LensFlareElementPtr pElement = GetElement(nIndex);
1017 if (pElement == NULL)
1018 return NULL;
1020 return pElement->GetOpticsElement();
1023 HTREEITEM CLensFlareElementTree::GetTreeItemByOpticsElement(const IOpticsElementBasePtr pOptics) const
1025 HTREEITEM hItem = GetFirstVisibleItem();
1027 while (hItem)
1029 CLensFlareElement::LensFlareElementPtr pElement = GetElement((int)GetItemData(hItem));
1030 if (pElement)
1032 if (pElement->GetOpticsElement() == pOptics)
1033 return hItem;
1035 hItem = GetNextVisibleItem(hItem);
1038 return NULL;
1041 void CLensFlareElementTree::RemoveElement(HTREEITEM hItem)
1043 StoreUndo();
1044 IOpticsElementBasePtr pOptics = GetOpticsElementByTreeItem(hItem);
1045 if (pOptics)
1046 LensFlareUtil::RemoveOptics(pOptics);
1047 CLensFlareElement::LensFlareElementList removedElementList;
1048 GatherItemsRecusively(hItem, removedElementList);
1049 DeleteOnesInElementList(removedElementList);
1052 void CLensFlareElementTree::SelectTreeItemByName(const CString& name)
1054 HTREEITEM hVisibleItem = GetFirstVisibleItem();
1055 while (hVisibleItem)
1057 int nItemIndex = (int)GetItemData(hVisibleItem);
1058 CLensFlareElement::LensFlareElementPtr pElement = GetElement(nItemIndex);
1059 string flareName;
1060 if (pElement->GetName(flareName))
1062 if (flareName == name.GetString())
1064 SelectItem(hVisibleItem);
1065 break;
1069 hVisibleItem = GetNextVisibleItem(hVisibleItem);
1073 void CLensFlareElementTree::SelectTreeItemByCursorPos(bool* pOutChanged)
1075 HTREEITEM hOldItem = GetSelectedItem();
1076 HTREEITEM hItem = LensFlareUtil::GetTreeItemByHitTest(*this);
1077 if (hItem == NULL)
1078 return;
1079 if (pOutChanged)
1080 *pOutChanged = hOldItem != hItem;
1081 SelectItem(hItem);
1084 void CLensFlareElementTree::OnLensFlareChangeItem(CLensFlareItem* pLensFlareItem)
1086 if (pLensFlareItem)
1087 UpdateLensFlareItem(pLensFlareItem);
1088 else
1089 ClearElementList();
1090 Reload();
1093 void CLensFlareElementTree::OnLensFlareDeleteItem(CLensFlareItem* pLensFlareItem)
1097 void CLensFlareElementTree::CallChangeListeners()
1099 CLensFlareElement* pElement = GetCurrentLensFlareElement();
1100 for (int i = 0, iSize(m_LensFlaresElementListeners.size()); i < iSize; ++i)
1101 m_LensFlaresElementListeners[i]->OnLensFlareChangeElement(pElement);
1104 CLensFlareElement::LensFlareElementPtr CLensFlareElementTree::CreateElement(IOpticsElementBasePtr pOptics)
1106 StoreUndo();
1107 _smart_ptr<CLensFlareElement> pElement = new CLensFlareElement;
1108 m_LensFlareElements.push_back(pElement);
1109 pElement->SetOpticsElement(pOptics);
1110 return pElement;
1113 void CLensFlareElementTree::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
1115 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
1116 if (!pNMTreeView)
1117 return;
1119 if (!pNMTreeView->itemNew.hItem)
1120 return;
1122 SelectItem(pNMTreeView->itemNew.hItem);
1124 bool bControlPressed = QtUtil::IsModifierKeyDown(Qt::ControlModifier);
1126 XmlNodeRef XMLNode;
1127 XMLNode = CreateXML(bControlPressed ? FLARECLIPBOARDTYPE_COPY : FLARECLIPBOARDTYPE_CUT);
1128 if (XMLNode == NULL)
1129 return;
1131 LensFlareUtil::BeginDragDrop(*this, pNMTreeView->ptDrag, XMLNode);
1134 void CLensFlareElementTree::OnMouseMove(UINT nFlags, CPoint point)
1136 LensFlareUtil::MoveDragDrop(*this, point, &functor(*this, &CLensFlareElementTree::UpdateLensFlareElement));
1137 __super::OnMouseMove(nFlags, point);
1140 void CLensFlareElementTree::OnLButtonUp(UINT nFlags, CPoint point)
1142 LensFlareUtil::EndDragDrop(*this, point, &functor(*this, &CLensFlareElementTree::Drop));
1143 __super::OnLButtonUp(nFlags, point);
1146 void CLensFlareElementTree::OnLButtonDown(UINT nFlags, CPoint point)
1148 CUndo undo("Changed Lens flares element");
1149 __super::OnLButtonDown(nFlags, point);
1152 void CLensFlareElementTree::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
1154 CUndo undo("Changed Lens flares element");
1155 __super::OnKeyDown(nChar, nRepCnt, nFlags);
1158 void CLensFlareElementTree::UpdateLensFlareElement(HTREEITEM hSelectedItem, const CPoint& screenPos)
1160 CLensFlareEditor* pEditor = CLensFlareEditor::GetLensFlareEditor();
1161 if (!pEditor)
1162 return;
1164 if (pEditor->IsPointInLensFlareElementTree(screenPos))
1166 SelectTreeItemByCursorPos();
1168 else if (pEditor->IsPointInLensFlareItemTree(screenPos))
1170 pEditor->GetLensFlareItemTree()->UpdateDraggingFromOtherWindow();
1174 void CLensFlareElementTree::Drop(XmlNodeRef xmlNode, const CPoint& screenPos)
1176 if (xmlNode == NULL)
1177 return;
1179 CLensFlareEditor* pEditor = CLensFlareEditor::GetLensFlareEditor();
1180 if (!pEditor)
1181 return;
1183 if (pEditor->IsPointInLensFlareElementTree(screenPos))
1185 SelectTreeItemByCursorPos();
1186 CUndo undo("Copy/Cut & Paste library item");
1187 Paste(xmlNode);
1189 else if (pEditor->IsPointInLensFlareItemTree(screenPos))
1191 CUndo undo("Copy/Cut & Paste library item");
1192 pEditor->Paste(xmlNode);
1196 void CLensFlareElementTree::UpdateDraggingFromOtherWindow()
1198 bool bChanged(false);
1199 SelectTreeItemByCursorPos(&bChanged);
1200 if (bChanged)
1201 RedrawWindow();