Skip to content

Commit

Permalink
Merge pull request #142 from berdal84/feat/scope-ui-ux 2/N
Browse files Browse the repository at this point in the history
hash, selection dragging related fixes
  • Loading branch information
berdal84 authored Dec 2, 2024
2 parents 146b87a + a5ee68a commit a944938
Show file tree
Hide file tree
Showing 23 changed files with 566 additions and 352 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ target_link_libraries(

add_executable(
test-tools
src/tools/core/UniqueOrderedList.specs.cpp
src/tools/core/Variant.specs.cpp
src/tools/core/UniqueOrderedVariantList.specs.cpp
src/tools/core/Delegate.specs.cpp
src/tools/core/reflection/reflection.specs.cpp
src/tools/core/reflection/Type.specs.cpp
Expand Down
9 changes: 4 additions & 5 deletions src/ndbl/core/language/Nodlang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ Nodlang::Nodlang(bool _strict)

for( auto [keyword, token_t] : m_definition.keywords)
{
m_token_t_by_keyword.insert({Hash::hash32(keyword), token_t});
m_token_t_by_keyword.insert({Hash::hash(keyword), token_t});
m_keyword_by_token_t.insert({token_t, keyword});
}

for( auto [keyword, token_t, type] : m_definition.types)
{
m_keyword_by_token_t.insert({token_t, keyword});
m_keyword_by_type_id.insert({type->id(), keyword});
m_token_t_by_keyword.insert({Hash::hash32(keyword), token_t});
m_token_t_by_keyword.insert({Hash::hash(keyword), token_t});
m_token_t_by_type_id.insert({type->id(), token_t});
m_type_by_token_t.insert({token_t, type});
}
Expand Down Expand Up @@ -1029,7 +1029,7 @@ Token Nodlang::parse_token(const char* buffer, size_t buffer_size, size_t& globa

Token_t type = Token_t::identifier;

const u32_t key = Hash::hash32( buffer + start_pos, cursor - start_pos );
const auto key = Hash::hash( buffer + start_pos, cursor - start_pos );
auto keyword_found = m_token_t_by_keyword.find( key );
if (keyword_found != m_token_t_by_keyword.end())
{
Expand Down Expand Up @@ -1813,8 +1813,7 @@ const IInvokable* Nodlang::find_function(const char* _signature_hint) const
return nullptr;
}

const u32_t key = Hash::hash32(_signature_hint);
return find_function( key );
return find_function( Hash::hash(_signature_hint) );
}

const tools::IInvokable* Nodlang::find_function(u32_t _hash) const
Expand Down
104 changes: 51 additions & 53 deletions src/ndbl/gui/GraphView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ bool GraphView::draw(float dt)
{
bool changed = false;

if ( !m_view_state.visible )
if ( !m_view_state.visible() )
return false;

// Ensure view state fit with content region
Expand Down Expand Up @@ -234,9 +234,9 @@ bool GraphView::draw(float dt)

if ( each_successor_view == nullptr )
continue;
if ( each_view->visible() == false )
if ( !each_view->state().visible() )
continue;
if ( each_successor_view->visible() == false )
if ( !each_successor_view->state().visible() )
continue;

SlotView* tail = slot->view;
Expand Down Expand Up @@ -280,9 +280,9 @@ bool GraphView::draw(float dt)
auto *node_view_out = slot_out->node->get_component<NodeView>();
auto *node_view_in = slot_in->node->get_component<NodeView>();

if ( !node_view_out->visible() )
if ( !node_view_out->state().visible() )
continue;
if ( !node_view_in->visible() )
if ( !node_view_in->state().visible() )
continue;

Vec2 p1, cp1, cp2, p2; // BezierCurveSegment's points
Expand Down Expand Up @@ -316,7 +316,7 @@ bool GraphView::draw(float dt)
{
auto variable = static_cast<VariableNode*>( node_out );
if (slot_out == variable->ref_out() ) // from a reference slot (can't be a declaration link)
if (!node_view_out->selected() && !node_view_in->selected() )
if (!node_view_out->state().selected() && !node_view_in->state().selected() )
style.color.w *= 0.25f;
}

Expand Down Expand Up @@ -350,12 +350,12 @@ bool GraphView::draw(float dt)

if ( !nodeview)
continue;
if ( nodeview->visible() == false )
if ( !nodeview->state().visible() )
continue;

changed |= nodeview->draw();

if ( nodeview->hovered() ) // no check if something else is hovered, last node always win against an edge
if ( nodeview->state().hovered() ) // no check if something else is hovered, last node always win against an edge
{
if ( nodeview->m_hovered_slotview != nullptr)
{
Expand Down Expand Up @@ -646,23 +646,23 @@ void GraphView::_on_graph_change()
m_physics_dirty = true;
}

void GraphView::_on_selection_change(Selection::EventT type, Element elem)
void GraphView::_on_selection_change(Selection::EventType type, Selection::ElemType elem)
{
bool selected = type == Selection::EventT_Append;
bool selected = type == Selection::EventType::Append;

switch ( elem.index() )
{
case Element::index_of<ScopeView*>():
case Selectable::index_of<ScopeView*>():
{
elem.get<ScopeView*>()->state().selected = selected;
elem.get<ScopeView*>()->state().set_selected( selected );
break;
}
case Element::index_of<NodeView*>():
case Selectable::index_of<NodeView*>():
{
elem.get<NodeView*>()->set_selected( selected );
elem.get<NodeView*>()->state().set_selected( selected );
break;
}
case Element::index_of<EdgeView>():
case Selectable::index_of<EdgeView>():
{
break;
}
Expand Down Expand Up @@ -732,12 +732,12 @@ void GraphView::draw_create_node_context_menu(CreateNodeCtxMenu& menu, SlotView*

void GraphView::drag_state_enter()
{
for( const Element& elem : m_selection.data() )
for( const Selectable& elem : m_selection.data() )
{
if ( auto* nodeview = elem.get_if<NodeView*>() )
nodeview->set_pinned();
nodeview->state().set_pinned();
else if ( auto* scopeview = elem.get_if<ScopeView*>() )
scopeview->set_pinned();
scopeview->state().set_pinned();
}
}

Expand All @@ -746,7 +746,7 @@ void GraphView::drag_state_tick()
const Vec2 delta = ImGui::GetMouseDragDelta();
ImGui::ResetMouseDragDelta();

for ( const Selection::element_t& elem : m_selection.data() )
for ( const Selectable& elem : m_selection.data() )
{
if ( auto* nodeview = elem.get_if<NodeView*>() )
nodeview->spatial_node().translate(delta);
Expand Down Expand Up @@ -790,13 +790,13 @@ void GraphView::cursor_state_tick()

switch ( m_focused.index() )
{
case Element::index_null:
case Selectable::index_null:
{
draw_create_node_context_menu(m_create_node_menu);
break;
}

case Element::index_of<ScopeView*>():
case Selectable::index_of<ScopeView*>():
{
auto scopeview = m_focused.get<ScopeView*>();
Node* node = scopeview->scope()->node();
Expand Down Expand Up @@ -842,7 +842,7 @@ void GraphView::cursor_state_tick()
break;
}

case Element::index_of<EdgeView>():
case Selectable::index_of<EdgeView>():
{
auto edge = m_focused.get<EdgeView>();
if ( ImGui::MenuItem(ICON_FA_TRASH " Delete Edge") )
Expand All @@ -856,7 +856,7 @@ void GraphView::cursor_state_tick()
break;
}

case Element::index_of<SlotView*>():
case Selectable::index_of<SlotView*>():
{
if ( ImGui::MenuItem(ICON_FA_TRASH " Disconnect Edges") )
{
Expand All @@ -868,7 +868,7 @@ void GraphView::cursor_state_tick()
break;
}

case Element::index_of<NodeView*>():
case Selectable::index_of<NodeView*>():
{
auto nodeview = m_focused.get<NodeView*>();

Expand All @@ -881,7 +881,8 @@ void GraphView::cursor_state_tick()

if ( ImGui::MenuItem(ICON_FA_MAP_PIN " Pin/Unpin Node") )
{
nodeview->set_pinned( !nodeview->pinned() );
const bool pinned = nodeview->state().pinned();
nodeview->state().set_pinned( !pinned );
}

if ( ImGui::MenuItem(ICON_FA_WINDOW_RESTORE " Arrange Node") )
Expand All @@ -902,7 +903,7 @@ void GraphView::cursor_state_tick()

switch ( m_hovered.index() )
{
case Element::index_of<SlotView*>():
case Selectable::index_of<SlotView*>():
{
if ( ImGui::IsMouseClicked(1) )
{
Expand All @@ -917,7 +918,7 @@ void GraphView::cursor_state_tick()
break;
}

case Element::index_of<EdgeView>():
case Selectable::index_of<EdgeView>():
{
if (ImGui::IsMouseDragging(0, 0.1f))
{
Expand All @@ -931,37 +932,31 @@ void GraphView::cursor_state_tick()
break;
}

case Element::index_of<NodeView*>():
case Element::index_of<ScopeView*>():
case Selectable::index_of<NodeView*>():
case Selectable::index_of<ScopeView*>():
{
const bool ctrl_pressed = ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl);
auto handle_selection = [&](Element& hovered_elem, bool want_selected, bool allow_multi_selection )

if ( ImGui::IsMouseReleased(0) )
{
if ( want_selected )
{
if ( !allow_multi_selection )
m_selection.clear();
m_selection.append( hovered_elem );
}
else if ( !allow_multi_selection )
if ( ctrl_pressed )
{
m_selection.remove( hovered_elem );
if ( !m_selection.contains( m_hovered ) )
{
m_selection.append( m_hovered );
m_focused = m_hovered;
}
else
{
m_selection.remove( m_hovered );
}
}
else
{
m_selection.clear();
m_selection.append( m_hovered );
m_focused = m_hovered;
}
};

if (ImGui::IsMouseReleased(0) )
{
bool want_selected = true;
if ( ctrl_pressed )
{
want_selected = !m_selection.contains( m_hovered );
}
handle_selection( m_hovered, want_selected, ctrl_pressed );
m_focused = m_hovered;
}
else if (ImGui::IsMouseClicked(1))
{
Expand All @@ -970,15 +965,18 @@ void GraphView::cursor_state_tick()
}
else if ( ImGui::IsMouseDragging(0) )
{
if ( bool wants_selection = !m_selection.contains( m_hovered ) )
handle_selection( m_hovered, wants_selection, ctrl_pressed ); // always allow multi selection in that case
m_focused = m_hovered;
if ( !m_selection.contains( m_hovered) )
{
if ( !ctrl_pressed )
m_selection.clear();
m_selection.append( m_hovered );
}
m_state_machine.change_state(DRAG_STATE);
}
break;
}

case Element::index_null:
case Selectable::index_null:
{
if ( ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows) )
{
Expand Down
31 changes: 23 additions & 8 deletions src/ndbl/gui/GraphView.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#include <vector>

#include "tools/core/reflection/reflection"
#include "tools/core/VariantVector.h"
#include "tools/core/Variant.h"
#include "tools/core/UniqueOrderedVariantList.h"
#include "tools/gui/ViewState.h"
#include "tools/gui/geometry/Pivots.h"

Expand All @@ -28,10 +29,16 @@ namespace ndbl
class Graph;
using tools::Vec2;

struct EdgeView { SlotView* tail = nullptr; SlotView* head = nullptr; } ;
using Selection = tools::VariantVector<NodeView*, ScopeView*, SlotView*, EdgeView> ;
using Element = Selection::element_t;
struct EdgeView
{
SlotView* tail = nullptr;
SlotView* head = nullptr;
bool operator==(const EdgeView& other) const // required to compare tools::Variant<..., EdgeView>
{ return tail == other.tail && head == other.head; }
};

using Selectable = tools::Variant<NodeView*, ScopeView*, SlotView*, EdgeView> ;
using Selection = tools::UniqueOrderedVariantList<Selectable> ;

class GraphView
{
Expand Down Expand Up @@ -61,8 +68,8 @@ namespace ndbl
static void draw_wire_from_slot_to_pos(SlotView *from, const Vec2 &end_pos);
private:
CreateNodeCtxMenu m_create_node_menu;
Element m_hovered;
Element m_focused;
Selectable m_hovered;
Selectable m_focused;
Selection m_selection;
tools::ViewState m_view_state;
Graph* m_graph;
Expand All @@ -73,7 +80,7 @@ namespace ndbl
void _update(float dt, u16_t iterations);
void _update(float dt);
void _on_graph_change();
void _on_selection_change(Selection::EventT, Element);
void _on_selection_change(Selection::EventType, Selection::ElemType );
void frame_views(const std::vector<NodeView*>&, const Vec2& pivot );
void draw_create_node_context_menu(CreateNodeCtxMenu& menu, SlotView* dragged_slotview = nullptr );
void create_constraints__align_top_recursively(const std::vector<Node*>& unfiltered_follower, ndbl::Node *leader);
Expand Down Expand Up @@ -102,4 +109,12 @@ namespace ndbl
void line_state_leave();

};
}
}

// Custom hash provided to work in std::hash<std::variant<EdgeView, ...>>
template<>
struct std::hash<ndbl::EdgeView>
{
std::size_t operator()(const ndbl::EdgeView& edge) const noexcept
{ return tools::Hash::hash(edge); }
};
8 changes: 4 additions & 4 deletions src/ndbl/gui/Nodable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void Nodable::update()
{
if ( graph_view )
{
for(const Element& elem : graph_view->selection().data() )
for(const Selectable& elem : graph_view->selection().data() )
{
if ( auto nodeview = elem.get_if<NodeView*>() )
graph_view->graph()->destroy_next_frame( nodeview->node() );
Expand All @@ -217,14 +217,14 @@ void Nodable::update()
{
if ( graph_view )
{
for(const Element& elem : graph_view->selection().data() )
for(const Selectable& elem : graph_view->selection().data() )
{
switch ( elem.index() )
{
case Element::index_of<NodeView*>():
case Selectable::index_of<NodeView*>():
elem.get<NodeView*>()->arrange_recursively();
break;
case Element::index_of<ScopeView*>():
case Selectable::index_of<ScopeView*>():
elem.get<ScopeView*>()->arrange_content();
break;
}
Expand Down
Loading

0 comments on commit a944938

Please sign in to comment.