Skip to content

Commit c9851fa

Browse files
author
Adrien GIVRY
committed
Implementing a simple hierarchy finder
We can now search for an actor by name with the hierarchy search bar. Actors that matches the input string are shown in the hierarchy and other actors are hidden. I also noticed m_widgetActorLink was never cleared so I added it. It seems to be fixing the duplication crash that we had.
1 parent e3249b8 commit c9851fa

3 files changed

Lines changed: 98 additions & 16 deletions

File tree

Sources/Overload/OvEditor/src/OvEditor/Panels/Hierarchy.cpp

Lines changed: 88 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,90 @@ class HierarchyActorContextualMenu : public OvUI::Plugins::ContextualMenu
174174
OvUI::Widgets::Layout::TreeNode& m_treeNode;
175175
};
176176

177+
void ExpandTreeNode(OvUI::Widgets::Layout::TreeNode& p_toExpand, const OvUI::Widgets::Layout::TreeNode* p_root)
178+
{
179+
p_toExpand.Open();
180+
181+
if (&p_toExpand != p_root && p_toExpand.HasParent())
182+
{
183+
ExpandTreeNode(*static_cast<OvUI::Widgets::Layout::TreeNode*>(p_toExpand.GetParent()), p_root);
184+
}
185+
}
186+
187+
std::vector<OvUI::Widgets::Layout::TreeNode*> nodesToCollapse;
188+
std::vector<OvUI::Widgets::Layout::TreeNode*> founds;
189+
190+
void ExpandTreeNodeAndEnable(OvUI::Widgets::Layout::TreeNode& p_toExpand, const OvUI::Widgets::Layout::TreeNode* p_root)
191+
{
192+
if (!p_toExpand.IsOpened())
193+
{
194+
p_toExpand.Open();
195+
nodesToCollapse.push_back(&p_toExpand);
196+
}
197+
198+
p_toExpand.enabled = true;
199+
200+
if (&p_toExpand != p_root && p_toExpand.HasParent())
201+
{
202+
ExpandTreeNodeAndEnable(*static_cast<OvUI::Widgets::Layout::TreeNode*>(p_toExpand.GetParent()), p_root);
203+
}
204+
}
205+
177206
OvEditor::Panels::Hierarchy::Hierarchy
178207
(
179208
const std::string & p_title,
180209
bool p_opened,
181210
const OvUI::Settings::PanelWindowSettings& p_windowSettings
182211
) : PanelWindow(p_title, p_opened, p_windowSettings)
183212
{
213+
auto& searchBar = CreateWidget<OvUI::Widgets::InputFields::InputText>();
214+
searchBar.ContentChangedEvent += [this](const std::string& p_content)
215+
{
216+
founds.clear();
217+
auto content = p_content;
218+
std::transform(content.begin(), content.end(), content.begin(), ::tolower);
219+
220+
for (auto& [actor, item] : m_widgetActorLink)
221+
{
222+
if (!p_content.empty())
223+
{
224+
auto itemName = item->name;
225+
std::transform(itemName.begin(), itemName.end(), itemName.begin(), ::tolower);
226+
227+
if (itemName.find(content) != std::string::npos)
228+
{
229+
founds.push_back(item);
230+
}
231+
232+
item->enabled = false;
233+
}
234+
else
235+
{
236+
item->enabled = true;
237+
}
238+
}
239+
240+
for (auto node : founds)
241+
{
242+
node->enabled = true;
243+
244+
if (node->HasParent())
245+
{
246+
ExpandTreeNodeAndEnable(*static_cast<OvUI::Widgets::Layout::TreeNode*>(node->GetParent()), m_sceneRoot);
247+
}
248+
}
249+
250+
if (p_content.empty())
251+
{
252+
for (auto node : nodesToCollapse)
253+
{
254+
node->Close();
255+
}
256+
257+
nodesToCollapse.clear();
258+
}
259+
};
260+
184261
m_sceneRoot = &CreateWidget<OvUI::Widgets::Layout::TreeNode>("Root", true);
185262
static_cast<OvUI::Widgets::Layout::TreeNode*>(m_sceneRoot)->Open();
186263
m_sceneRoot->AddPlugin<OvUI::Plugins::DDTarget<std::pair<OvCore::ECS::Actor*, OvUI::Widgets::Layout::TreeNode*>>>("Actor").DataReceivedEvent += [this](std::pair<OvCore::ECS::Actor*, OvUI::Widgets::Layout::TreeNode*> p_element)
@@ -223,16 +300,6 @@ void OvEditor::Panels::Hierarchy::SelectActorByInstance(OvCore::ECS::Actor& p_ac
223300
SelectActorByWidget(*result->second);
224301
}
225302

226-
void ExpandTreeNode(OvUI::Widgets::Layout::TreeNode& p_toExpand, const OvUI::Widgets::Layout::TreeNode* p_root)
227-
{
228-
p_toExpand.Open();
229-
230-
if (&p_toExpand != p_root && p_toExpand.HasParent())
231-
{
232-
ExpandTreeNode(*static_cast<OvUI::Widgets::Layout::TreeNode*>(p_toExpand.GetParent()), p_root);
233-
}
234-
}
235-
236303
void OvEditor::Panels::Hierarchy::SelectActorByWidget(OvUI::Widgets::Layout::TreeNode & p_widget)
237304
{
238305
UnselectActorsWidgets();
@@ -267,15 +334,14 @@ void OvEditor::Panels::Hierarchy::AttachActorToParent(OvCore::ECS::Actor & p_act
267334

268335
void OvEditor::Panels::Hierarchy::DetachFromParent(OvCore::ECS::Actor & p_actor)
269336
{
270-
auto actorWidget = m_widgetActorLink.find(&p_actor);
271-
272-
if (actorWidget != m_widgetActorLink.end())
337+
if (auto actorWidget = m_widgetActorLink.find(&p_actor); actorWidget != m_widgetActorLink.end())
273338
{
274339
if (p_actor.HasParent() && p_actor.GetParent()->GetChildren().size() == 1)
275340
{
276-
auto parentWidget = m_widgetActorLink.at(p_actor.GetParent());
277-
if (parentWidget)
278-
parentWidget->leaf = true;
341+
if (auto parentWidget = m_widgetActorLink.find(p_actor.GetParent()); parentWidget != m_widgetActorLink.end())
342+
{
343+
parentWidget->second->leaf = true;
344+
}
279345
}
280346

281347
auto widget = actorWidget->second;
@@ -290,8 +356,14 @@ void OvEditor::Panels::Hierarchy::DetachFromParent(OvCore::ECS::Actor & p_actor)
290356
void OvEditor::Panels::Hierarchy::DeleteActorByInstance(OvCore::ECS::Actor& p_actor)
291357
{
292358
if (auto result = m_widgetActorLink.find(&p_actor); result != m_widgetActorLink.end())
359+
{
293360
if (result->second)
361+
{
294362
result->second->Destroy();
363+
}
364+
365+
m_widgetActorLink.erase(result);
366+
}
295367
}
296368

297369
void OvEditor::Panels::Hierarchy::AddActorByInstance(OvCore::ECS::Actor & p_actor)

Sources/Overload/OvUI/include/OvUI/Widgets/Layout/TreeNode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ namespace OvUI::Widgets::Layout
3838
*/
3939
void Close();
4040

41+
/**
42+
* Returns true if the TreeNode is currently opened
43+
*/
44+
bool IsOpened() const;
45+
4146
protected:
4247
virtual void _Draw_Impl() override;
4348

Sources/Overload/OvUI/src/OvUI/Widgets/Layout/TreeNode.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ void OvUI::Widgets::Layout::TreeNode::Close()
2626
m_shouldOpen = false;
2727
}
2828

29+
bool OvUI::Widgets::Layout::TreeNode::IsOpened() const
30+
{
31+
return m_opened;
32+
}
33+
2934
void OvUI::Widgets::Layout::TreeNode::_Draw_Impl()
3035
{
3136
bool prevOpened = m_opened;

0 commit comments

Comments
 (0)