!B (Sandbox) (CE-21795) Importing models with multisubmaterials via fbx switches...
[CRYENGINE.git] / Code / Sandbox / Plugins / EditorSchematyc2 / Editor / TreeCtrl.cpp
blob7c6b30aad501b1fe3ef52a5626673258d38c19a5
1 // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "TreeCtrl.h"
5 #include "BrowserIcons.h"
7 #pragma warning(disable: 4355)
9 namespace Schematyc2
11 namespace
13 // Temporary (and very hacky) workaround for poor sorting in browser. This can be fixed properly when we port the browsers to QT.
14 bool SortCustomTreeCtrlItems(const CCustomTreeCtrlItemPtr& t1, const CCustomTreeCtrlItemPtr& t2)
16 static const int BROWSER_ICON_PRIORITIES[] =
18 0, // FOLDER
19 1, // DOC
20 0, // BRANCH
21 21, // FUNCTION_GRAPH
22 5, // ENV_ACTION
23 1, // ENV_SIGNAL
24 2, // ENV_GLOBAL_FUNCTION
25 3, // ENV_COMPONENT
26 4, // ENV_COMPONENT_FUNCTION
27 4, // ENUMERATION
28 15, // VARIABLE
29 3, // USER_GROUP
30 1, // FOR_LOOP
31 6, // SIGNAL
32 10, // CLASS
33 20, // COMPONENT
34 22, // ACTION_INSTANCE
35 13, // STATE
36 12, // STATE_MACHINE
37 17, // TIMER
38 26, // SIGNAL_RECEIVER
39 24, // CONSTRUCTOR
40 23, // CONDITION_GRAPH
41 2, // RETURN
42 6, // ENV_ACTION_FUNCTION
43 18, // ABSTRACT_INTERFACE_IMPLEMENTATION
44 19, // ABSTRACT_INTERFACE_FUNCTION_IMPLEMENTATION
45 2, // INCLUDE
46 27, // INPUT
47 28, // OUTPUT
48 5, // STRUCTURE
49 25, // DESTRUCTOR
50 0, // SETTINGS_FOLDER
51 1, // SETTINGS_DOC
52 16, // CONTAINER
53 7, // ABSTRACT_INTERFACE
54 9, // ABSTRACT_INTERFACE_FUNCTION
55 8, // ABSTRACT_INTERFACE_TASK
56 14, // PROPERTY
57 11, // BASE_CLASS
60 static_assert(CRY_ARRAY_COUNT(BROWSER_ICON_PRIORITIES) == BrowserIcon::COUNT, "Size of array does not match number of constants in BrowserIcon enumeration!");
62 int lhsImage = t1->GetIcon();
63 int rhsImage = t2->GetIcon();
65 if (lhsImage == rhsImage)
67 return strcmp(t1->GetText(), t2->GetText()) < 0;
69 else if (std::max(lhsImage, rhsImage) < CRY_ARRAY_COUNT(BROWSER_ICON_PRIORITIES) && BROWSER_ICON_PRIORITIES[lhsImage] != BROWSER_ICON_PRIORITIES[rhsImage])
71 return BROWSER_ICON_PRIORITIES[lhsImage] < BROWSER_ICON_PRIORITIES[rhsImage];
73 else
75 return lhsImage < rhsImage;
80 //////////////////////////////////////////////////////////////////////////
81 CCustomTreeCtrlItem::CCustomTreeCtrlItem(const char* text, size_t icon, const CCustomTreeCtrlItemPtr& pParent, const SGUID& guid)
82 : m_text(text)
83 , m_icon(icon)
84 , m_pParent(pParent)
85 , m_hTreeItem(NULL)
86 , m_guid(guid)
89 //////////////////////////////////////////////////////////////////////////
90 CCustomTreeCtrlItem::~CCustomTreeCtrlItem() {}
92 //////////////////////////////////////////////////////////////////////////
93 const char* CCustomTreeCtrlItem::GetText() const
95 return m_text.c_str();
98 //////////////////////////////////////////////////////////////////////////
99 size_t CCustomTreeCtrlItem::GetIcon() const
101 return m_icon;
104 //////////////////////////////////////////////////////////////////////////
105 CCustomTreeCtrlItemPtr CCustomTreeCtrlItem::GetParent() const
107 return m_pParent;
110 //////////////////////////////////////////////////////////////////////////
111 CCustomTreeCtrlItemPtr CCustomTreeCtrlItem::FindAncestor(const char* text) const
113 CRY_ASSERT(text);
114 if(text)
116 for(CCustomTreeCtrlItemPtr pAncestor = m_pParent; pAncestor; pAncestor = pAncestor->GetParent())
118 if(pAncestor->GetText() == text)
120 return pAncestor;
124 return CCustomTreeCtrlItemPtr();
127 //////////////////////////////////////////////////////////////////////////
128 CCustomTreeCtrlItemPtr CCustomTreeCtrlItem::FindAncestor(size_t icon) const
130 for(CCustomTreeCtrlItemPtr pAncestor = m_pParent; pAncestor; pAncestor = pAncestor->GetParent())
132 if(pAncestor->GetIcon() == icon)
134 return pAncestor;
137 return CCustomTreeCtrlItemPtr();
140 //////////////////////////////////////////////////////////////////////////
141 CCustomTreeCtrlItemPtr CCustomTreeCtrlItem::FindAncestor(const TSizeTConstArray& icons) const
143 const size_t *pBeginIcon = icons.begin();
144 const size_t *pEndIcon = icons.end();
145 for(CCustomTreeCtrlItemPtr pAncestor = m_pParent; pAncestor; pAncestor = pAncestor->GetParent())
147 const size_t ancestorIcon = pAncestor->GetIcon();
148 for(const size_t* pIcon = pBeginIcon; pIcon != pEndIcon; ++ pIcon)
150 if(*pIcon == ancestorIcon)
152 return pAncestor;
156 return CCustomTreeCtrlItemPtr();
159 //////////////////////////////////////////////////////////////////////////
160 void CCustomTreeCtrlItem::SetHTreeItem(HTREEITEM hTreeItem)
162 m_hTreeItem = hTreeItem;
165 //////////////////////////////////////////////////////////////////////////
166 HTREEITEM CCustomTreeCtrlItem::GetHTreeItem() const
168 return m_hTreeItem;
171 //////////////////////////////////////////////////////////////////////////
172 const SGUID& CCustomTreeCtrlItem::GetGUID() const
174 return m_guid;
177 void CCustomTreeCtrlItem::AddChild(CCustomTreeCtrlItemPtr pItem)
179 m_children.push_back(pItem);
182 const TCustomTreeCtrlItemPtrVector& CCustomTreeCtrlItem::GetChildren()
184 return m_children;
187 void CCustomTreeCtrlItem::RemoveChild(CCustomTreeCtrlItemPtr pItem)
189 TCustomTreeCtrlItemPtrVector::iterator it = std::find(m_children.begin(), m_children.end(), pItem);
190 if (it != m_children.end())
192 m_children.erase(it);
196 //////////////////////////////////////////////////////////////////////////
197 void CCustomTreeCtrlItem::SetText(const char* text)
199 m_text = text;
202 //////////////////////////////////////////////////////////////////////////
203 BOOL CCustomTreeCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
205 LOADING_TIME_PROFILE_SECTION;
206 if(__super::Create(dwStyle | WS_BORDER | TVS_HASBUTTONS | TVS_NOTOOLTIPS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS, rect, pParentWnd, nID))
208 // Register drop target.
209 m_dropTarget.Register(this);
210 // Load image list.
211 LoadImageList(m_imageList);
212 return true;
214 else
216 return false;
220 //////////////////////////////////////////////////////////////////////////
221 void CCustomTreeCtrl::ExpandItem(const CCustomTreeCtrlItemPtr& pItem)
223 CRY_ASSERT(pItem);
224 if(pItem)
226 CXTTreeCtrl::Expand(pItem->GetHTreeItem(), TVE_EXPAND);
230 //////////////////////////////////////////////////////////////////////////
231 void CCustomTreeCtrl::EnsureVisible(const CCustomTreeCtrlItemPtr& pItem)
233 CRY_ASSERT(pItem);
234 if(pItem)
236 CXTTreeCtrl::EnsureVisible(pItem->GetHTreeItem());
240 CCustomTreeCtrl::CCustomTreeCtrl(TCustomTreeCtrlItemCompFunc itemCompare /* = NULL */)
241 : m_itemCompare(itemCompare ? itemCompare : SortCustomTreeCtrlItems)
242 , m_dropTarget(*this)
243 , m_root(new CCustomTreeCtrlItem("", (size_t)-1, NULL, SGUID()))
246 //////////////////////////////////////////////////////////////////////////
247 CCustomTreeCtrl::~CCustomTreeCtrl() {}
249 //////////////////////////////////////////////////////////////////////////
250 void CCustomTreeCtrl::AddItem(const CCustomTreeCtrlItemPtr& pItem)
252 CRY_ASSERT(pItem);
253 if(pItem)
255 CCustomTreeCtrlItemPtr pParentItem = pItem->GetParent();
256 if (!pParentItem)
258 pParentItem = m_root;
260 HTREEITEM hParentTreeItem = pParentItem ? pParentItem->GetHTreeItem() : NULL;
262 //Find correct place to insert node
263 const TCustomTreeCtrlItemPtrVector& children = pParentItem->GetChildren();
264 auto it = std::lower_bound(children.begin(), children.end(), pItem, m_itemCompare);
266 HTREEITEM hTreeItem = CXTTreeCtrl::InsertItem(pItem->GetText(), pItem->GetIcon(), pItem->GetIcon(), hParentTreeItem, !hParentTreeItem || it == children.end() ? TVI_LAST : (*it)->GetHTreeItem());
267 CXTTreeCtrl::SetItemData(hTreeItem, (DWORD_PTR)hTreeItem);
268 pItem->SetHTreeItem(hTreeItem);
269 m_items.push_back(pItem);
270 const SGUID& guid = pItem->GetGUID();
271 if (guid)
273 m_guid_map[guid] = pItem;
275 m_htreeitem_map[hTreeItem] = pItem;
276 pParentItem->AddChild(pItem);
280 //////////////////////////////////////////////////////////////////////////
281 void CCustomTreeCtrl::SetItemText(const CCustomTreeCtrlItemPtr& pItem, const char* text)
283 CRY_ASSERT(pItem);
284 if(pItem)
286 CXTTreeCtrl::SetItemText(pItem->GetHTreeItem(), text);
287 pItem->SetText(text);
291 //////////////////////////////////////////////////////////////////////////
292 void CCustomTreeCtrl::SetItemColor(const CCustomTreeCtrlItemPtr& pItem, COLORREF color)
294 CRY_ASSERT(pItem);
295 if(pItem)
297 CXTTreeCtrl::SetItemColor(pItem->GetHTreeItem(), color);
301 //////////////////////////////////////////////////////////////////////////
302 void CCustomTreeCtrl::SetItemBold(const CCustomTreeCtrlItemPtr& pItem, bool bBold)
304 CRY_ASSERT(pItem);
305 if(pItem)
307 CXTTreeCtrl::SetItemBold(pItem->GetHTreeItem(), bBold);
311 //////////////////////////////////////////////////////////////////////////
312 void CCustomTreeCtrl::RemoveItem(const CCustomTreeCtrlItemPtr& pItem)
314 for(TCustomTreeCtrlItemPtrVector::iterator iItem = m_items.begin(), iEndItem = m_items.end(); iItem != iEndItem; ++ iItem)
316 const CCustomTreeCtrlItemPtr& _pItem = *iItem;
317 if (_pItem == pItem)
319 HTREEITEM hTreeItem = _pItem->GetHTreeItem();
320 CXTTreeCtrl::DeleteItem(hTreeItem);
321 const SGUID& guid = _pItem->GetGUID();
322 if (guid)
324 m_guid_map.erase(guid);
326 m_htreeitem_map.erase(hTreeItem);
327 CCustomTreeCtrlItemPtr pParentItem = _pItem->GetParent();
328 if (!pParentItem)
330 pParentItem = m_root;
332 pParentItem->RemoveChild(_pItem);
333 if(iItem != (iEndItem - 1))
335 *iItem = m_items.back();
337 m_items.pop_back();
338 break;
343 //////////////////////////////////////////////////////////////////////////
344 void CCustomTreeCtrl::RemoveItemChildren(const CCustomTreeCtrlItemPtr& pItem)
346 TCustomTreeCtrlItemPtrVector children = pItem->GetChildren();
347 for (CCustomTreeCtrlItemPtr pChild : children)
349 RemoveItemChildren(pChild);
350 RemoveItem(pChild);
354 //////////////////////////////////////////////////////////////////////////
355 CCustomTreeCtrlItemPtr CCustomTreeCtrl::FindItem(const char* text, const CCustomTreeCtrlItemPtr& pParentItem)
357 TCustomTreeCtrlItemPtrVector children;
358 if (pParentItem)
360 children = pParentItem->GetChildren();
362 else
364 children = m_root->GetChildren();
366 for(TCustomTreeCtrlItemPtrVector::iterator iItem = children.begin(), iEndItem = children.end(); iItem != iEndItem; ++ iItem)
368 const CCustomTreeCtrlItemPtr& pItem = *iItem;
369 if(strcmp(pItem->GetText(), text) == 0)
371 return pItem;
374 return CCustomTreeCtrlItemPtr();
377 //////////////////////////////////////////////////////////////////////////
378 CCustomTreeCtrlItemPtr CCustomTreeCtrl::FindItem(CPoint pos)
380 UINT flags = 0;
381 HTREEITEM hTreeItem = CXTTreeCtrl::HitTest(pos, &flags);
382 if(hTreeItem && (flags & TVHT_ONITEM))
384 return FindItem(hTreeItem);
386 return CCustomTreeCtrlItemPtr();
389 ///////////////////////////////////////////////////////////////////////
390 CCustomTreeCtrlItemPtr CCustomTreeCtrl::FindItem(HTREEITEM hTreeItem)
392 auto it = m_htreeitem_map.find(hTreeItem);
393 if (it != m_htreeitem_map.end())
394 return it->second;
395 return CCustomTreeCtrlItemPtr();
398 ///////////////////////////////////////////////////////////////////////
399 CCustomTreeCtrlItemPtr CCustomTreeCtrl::FindItem(SGUID guid)
401 auto it = m_guid_map.find(guid);
402 if (it != m_guid_map.end())
403 return it->second;
404 return CCustomTreeCtrlItemPtr();
407 //////////////////////////////////////////////////////////////////////////
408 TCustomTreeCtrlItemPtrVector& CCustomTreeCtrl::GetItems()
410 return m_items;
413 //////////////////////////////////////////////////////////////////////////
414 const TCustomTreeCtrlItemPtrVector& CCustomTreeCtrl::GetItems() const
416 return m_items;
419 //////////////////////////////////////////////////////////////////////////
420 void CCustomTreeCtrl::GetChildItems(CCustomTreeCtrlItem& item, TCustomTreeCtrlItemPtrVector &childItems)
422 auto children = item.GetChildren();
423 childItems.insert(childItems.begin(), children.begin(), children.end());
426 //////////////////////////////////////////////////////////////////////////
427 void CCustomTreeCtrl::Reset()
429 m_items.clear();
430 m_htreeitem_map.clear();
431 m_guid_map.clear();
432 CXTTreeCtrl::DeleteAllItems();
435 //////////////////////////////////////////////////////////////////////////
436 void CCustomTreeCtrl::LoadImageList(CImageList& imageList) {}
438 //////////////////////////////////////////////////////////////////////////
439 DROPEFFECT CCustomTreeCtrl::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
441 return DROPEFFECT_NONE;
444 //////////////////////////////////////////////////////////////////////////
445 BOOL CCustomTreeCtrl::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
447 return false;
450 //////////////////////////////////////////////////////////////////////////
451 CCustomTreeCtrl::CDropTarget::CDropTarget(CCustomTreeCtrl& customTreeCtrl)
452 : m_customTreeCtrl(customTreeCtrl)
455 //////////////////////////////////////////////////////////////////////////
456 DROPEFFECT CCustomTreeCtrl::CDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
458 return m_customTreeCtrl.OnDragOver(pWnd, pDataObject, dwKeyState, point);
461 //////////////////////////////////////////////////////////////////////////
462 BOOL CCustomTreeCtrl::CDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
464 return m_customTreeCtrl.OnDrop(pWnd, pDataObject, dropEffect, point);