Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hash, selection dragging related fixes #142

Merged
merged 7 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading