Skip to content

Commit

Permalink
refactor(GraphView): extract struct Selection.h
Browse files Browse the repository at this point in the history
  • Loading branch information
berdal84 committed Nov 28, 2024
1 parent f421f06 commit 3cfb476
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 76 deletions.
9 changes: 5 additions & 4 deletions src/ndbl/gui/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Event.h"
#include "FrameMode.h"
#include "SlotView.h"
#include "Selection.h"

namespace ndbl
{
Expand Down Expand Up @@ -79,12 +80,12 @@ namespace ndbl
};
using Event_ToggleFolding = tools::Event<EventID_TOGGLE_FOLDING, EventPayload_ToggleFoldingEvent>;

struct EventPayload_NodeViewSelectionChange
struct EventPayload_SelectionChange
{
std::vector<NodeView*> new_selection;
std::vector<NodeView*> old_selection;
Selection new_selection;
Selection old_selection;
};
using Event_SelectionChange = tools::Event<EventID_SELECTION_CHANGE, EventPayload_NodeViewSelectionChange>;
using Event_SelectionChange = tools::Event<EventID_SELECTION_CHANGE, EventPayload_SelectionChange>;

struct EventPayload_CreateNode
{
Expand Down
85 changes: 36 additions & 49 deletions src/ndbl/gui/GraphView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,11 @@ bool GraphView::draw(float dt)
auto low_to_high_depth = [](Scope* s1, Scope* s2) { return s1->depth() < s2->depth(); };
std::sort(scopes_to_draw.begin(), scopes_to_draw.end(), low_to_high_depth);

const ScopeView* focused_scope_view = m_focused.type == ViewItemType_SCOPE ? m_focused.scopeview : nullptr;
for( Scope* scope : scopes_to_draw )
{
if (ScopeView* view = scope->view())
{
bool highlight = view == focused_scope_view;
view->draw(dt, highlight);
view->draw(dt);
}
}

Expand Down Expand Up @@ -627,8 +625,8 @@ void GraphView::frame_nodes(FrameMode mode )

case FRAME_SELECTION_ONLY:
{
if ( !m_selected_nodeview.empty())
frame_views(m_selected_nodeview, CENTER);
if ( !m_selected.node.empty())
frame_views(m_selected.node, CENTER);
break;
}
default:
Expand All @@ -638,37 +636,33 @@ void GraphView::frame_nodes(FrameMode mode )

void GraphView::set_selected(const Selection& views, SelectionMode mode )
{
Selection curr_selection = m_selected_nodeview;
Selection curr_selection = m_selected;
if ( mode == SelectionMode_REPLACE )
{
m_selected_nodeview.clear();
for(auto& each : curr_selection )
m_selected.remove_all();
for(auto& each : curr_selection.node )
each->set_selected(false);
}

for(auto& each : views)
{
m_selected_nodeview.emplace_back(each);
each->set_selected();
}
m_selected.add( views ) ;

EventPayload_NodeViewSelectionChange event{ m_selected_nodeview, curr_selection };
EventPayload_SelectionChange event{m_selected, curr_selection };
get_event_manager()->dispatch<Event_SelectionChange>(event);
}

const GraphView::Selection& GraphView::get_selected() const
const Selection& GraphView::selected() const
{
return m_selected_nodeview;
return m_selected;
}

bool GraphView::is_selected(NodeView* view) const
{
return std::find( m_selected_nodeview.begin(), m_selected_nodeview.end(), view) != m_selected_nodeview.end();
return m_selected.has(view);
}

bool GraphView::selection_empty() const
{
return m_selected_nodeview.empty();
return m_selected.empty();
}

void GraphView::_on_graph_change()
Expand All @@ -688,8 +682,8 @@ void GraphView::reset()
Vec2 far_outside = Vec2(-1000.f, -1000.0f);

for( Node* node : graph()->nodes() )
if ( NodeView* v = node->get_component<NodeView>() )
v->spatial_node().translate( far_outside );
if ( auto* view = node->get_component<NodeView>() )
view->spatial_node().translate( far_outside );

// physics
m_physics_dirty = true;
Expand Down Expand Up @@ -735,20 +729,10 @@ void GraphView::draw_create_node_context_menu(CreateNodeCtxMenu& menu, SlotView*

void GraphView::drag_state_enter()
{
switch ( m_focused.type )
{
case ViewItemType_SCOPE:
{
m_focused.scopeview->set_pinned();
break;
}
default:
{
for ( NodeView* node_view : get_selected() )
node_view->set_pinned();
break;
}
}
for ( NodeView* view : m_selected.node )
view->set_pinned();
for ( ScopeView* view : m_selected.scope )
view->set_pinned();
}

void GraphView::drag_state_tick()
Expand All @@ -766,7 +750,7 @@ void GraphView::drag_state_tick()

default:
{
for (NodeView* view: get_selected() )
for (NodeView* view : m_selected.node )
view->spatial_node().translate( delta );
break;
}
Expand Down Expand Up @@ -836,20 +820,20 @@ void GraphView::cursor_state_tick()
Scope::get_descendent( children, m_focused.scopeview->scope(), ScopeFlags_INCLUDE_SELF );

// Extract node views from each descendent
std::set<NodeView*> views;
std::vector<NodeView*> views;
for(Scope* child : children)
{
// Include scope owner's view too
if ( NodeView* view = child->node()->get_component<NodeView>())
views.insert( view );
if ( auto* view = child->node()->get_component<NodeView>())
views.push_back( view );

// and every other child's
for(Node* child_node : child->child())
if ( NodeView* view = child_node->get_component<NodeView>())
views.insert(view);
if ( auto* view = child_node->get_component<NodeView>())
views.push_back(view);
}
// Replace selection
set_selected({views.begin(), views.end()});
set_selected(views);
}

ImGui::Separator();
Expand Down Expand Up @@ -911,6 +895,12 @@ void GraphView::cursor_state_tick()
return;
}

// TODO: handle remove!
// Add/Remove/Replace selection
SelectionMode selection_flags = SelectionMode_REPLACE;
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl))
selection_flags = SelectionMode_ADD;

switch (m_hovered.type)
{
case ViewItemType_SLOT:
Expand All @@ -937,12 +927,7 @@ void GraphView::cursor_state_tick()
}
else if (ImGui::IsMouseReleased(0) )
{
// TODO: handle remove!
// Add/Remove/Replace selection
SelectionMode flags = SelectionMode_REPLACE;
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl))
flags = SelectionMode_ADD;
set_selected({m_hovered.nodeview}, flags);
set_selected(m_hovered.nodeview, selection_flags);
m_focused = m_hovered;
}
else if (ImGui::IsMouseDoubleClicked(0))
Expand All @@ -954,7 +939,7 @@ void GraphView::cursor_state_tick()
{
m_focused = m_hovered;
if (!m_hovered.nodeview->selected())
set_selected({m_hovered.nodeview});
set_selected(m_hovered.nodeview);
m_state_machine.change_state(DRAG_STATE);
}
break;
Expand All @@ -976,8 +961,9 @@ void GraphView::cursor_state_tick()

case ViewItemType_SCOPE:
{
if (ImGui::IsMouseClicked(0))
if (ImGui::IsMouseReleased(0) )
{
set_selected(m_hovered.scopeview, selection_flags);
m_focused = m_hovered;
}
else if (ImGui::IsMouseClicked(1))
Expand All @@ -988,6 +974,7 @@ void GraphView::cursor_state_tick()
else if ( ImGui::IsMouseDragging(0) )
{
m_focused = m_hovered;
set_selected(m_hovered.scopeview);
m_state_machine.change_state(DRAG_STATE);
}
break;
Expand Down
7 changes: 3 additions & 4 deletions src/ndbl/gui/GraphView.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "ndbl/core/Scope.h"

#include "Action.h"

#include "Selection.h"
#include "NodeView.h"
#include "SlotView.h"
#include "types.h"
Expand Down Expand Up @@ -39,7 +39,6 @@ namespace ndbl
public:
DECLARE_REFLECT

typedef std::vector<NodeView*> Selection;
typedef tools::StateMachine StateMachine;

explicit GraphView(Graph* graph);
Expand All @@ -55,7 +54,7 @@ namespace ndbl
void reset(); // unfold and frame the whole graph
bool has_an_active_tool() const;
void set_selected(const Selection&, SelectionMode = SelectionMode_REPLACE);
const Selection& get_selected() const;
const Selection& selected() const;
void reset_all_properties();
Graph* graph() const;
void add_child(NodeView*);
Expand All @@ -66,7 +65,7 @@ namespace ndbl
CreateNodeCtxMenu m_create_node_menu;
ViewItem m_hovered;
ViewItem m_focused;
std::vector<NodeView*> m_selected_nodeview;
Selection m_selected;
tools::ViewState m_view_state;
Graph* m_graph;
bool m_physics_dirty = false;
Expand Down
12 changes: 6 additions & 6 deletions src/ndbl/gui/Nodable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,26 +212,26 @@ void Nodable::update()
case Event_DeleteNode::id:
{
if ( graph_view )
for(NodeView* view : graph_view->get_selected())
for(NodeView* view : graph_view->selected().node)
graph_view->graph()->destroy_next_frame(view->node());
break;
}

case Event_ArrangeNode::id:
{
if ( graph_view )
for(NodeView* view : graph_view->get_selected())
for(NodeView* view : graph_view->selected().node)
view->arrange_recursively();
break;
}

case Event_SelectNext::id:
{
if (graph_view && !graph_view->get_selected().empty())
if (graph_view && !graph_view->selected().empty())
{
std::vector<NodeView*> successors;
if (!graph_view->get_selected().empty())
for(NodeView* view : graph_view->get_selected() )
if (!graph_view->selected().empty())
for(NodeView* view : graph_view->selected().node )
for (NodeView* successor : Utils::get_components<NodeView>( view->node()->flow_outputs() ) )
successors.push_back( successor );

Expand All @@ -244,7 +244,7 @@ void Nodable::update()
case Event_ToggleFolding::id:
{
if ( graph_view && !graph_view->selection_empty() )
for(NodeView* view : graph_view->get_selected())
for(NodeView* view : graph_view->selected().node)
{
auto _event = reinterpret_cast<Event_ToggleFolding*>(event);
_event->data.mode == RECURSIVELY ? view->expand_toggle_rec()
Expand Down
2 changes: 1 addition & 1 deletion src/ndbl/gui/NodableView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ bool NodableView::draw_node_properties_window()
{
GraphView* graph_view = current_file->graph().view(); // Graph can't be null
ASSERT(graph_view != nullptr);
std::vector<NodeView*> selected_nodeviews = graph_view->get_selected();
const std::vector<NodeView*>& selected_nodeviews = graph_view->selected().node;

if (selected_nodeviews.size() == 1)
{
Expand Down
21 changes: 11 additions & 10 deletions src/ndbl/gui/ScopeView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ bool ScopeView::must_be_draw() const
}
}

void ScopeView::draw(float dt, bool highlight)
void ScopeView::draw(float dt)
{
if ( must_be_draw() )
{
Expand All @@ -142,40 +142,42 @@ void ScopeView::draw(float dt, bool highlight)
const Vec4& fill_col = m_theme == Theme_DARK ? config->ui_scope_fill_col_light
: config->ui_scope_fill_col_dark;
draw_list->AddRectFilled(r.min, r.max, ImGui::GetColorU32(fill_col), config->ui_scope_border_radius );
if ( highlight )
if ( m_state.selected )
{
draw_list->AddRect(r.min, r.max, ImGui::GetColorU32( config->ui_scope_border_col ) , config->ui_scope_border_radius, 0, config->ui_scope_border_thickness );
}

if ( ImGui::IsMouseHoveringRect(r.min, r.max) )
{
on_hover.emit(this);
}
}
}

void ScopeView::on_add_node(Node* node)
{
if( NodeView* view = node->get_component<NodeView>())
{
m_spatial_node.add_child( &view->spatial_node() );
m_state.spatial_node().add_child( &view->spatial_node() );
}
}

void ScopeView::on_remove_node(Node* node)
{
if( NodeView* view = node->get_component<NodeView>())
{
m_spatial_node.remove_child( &view->spatial_node() );
m_state.spatial_node().remove_child( &view->spatial_node() );
}
}

void ScopeView::on_reset_parent(Scope* scope)
{
if( m_spatial_node.has_parent() )
m_spatial_node.parent()->remove_child(&m_spatial_node );
if( m_state.spatial_node().has_parent() )
m_state.spatial_node().parent()->remove_child(&m_state.spatial_node() );

// this view must move when scope's owner view moves
if( scope )
scope->view()->m_spatial_node.add_child( &m_spatial_node );
scope->view()->m_state.spatial_node().add_child( &m_state.spatial_node() );
}

void ScopeView::translate(const tools::Vec2 &delta)
Expand All @@ -184,7 +186,7 @@ void ScopeView::translate(const tools::Vec2 &delta)
if ( node()->internal_scope() == m_scope )
node()->get_component<NodeView>()->spatial_node().translate( delta );
// translate view (and children...)
m_spatial_node.translate( delta );
m_state.spatial_node().translate( delta );
}

void ScopeView::set_pinned(bool b)
Expand All @@ -199,10 +201,9 @@ bool ScopeView::pinned() const

void ScopeView::set_position(const tools::Vec2& pos, tools::Space space)
{
m_spatial_node.set_position( pos, space );
m_state.spatial_node().set_position( pos, space );
}


void ScopeView::draw_scope_tree(Scope *scope)
{
if ( ImGui::TreeNode("Scope Tree" ) )
Expand Down
Loading

0 comments on commit 3cfb476

Please sign in to comment.