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

Add auto-panning when mouse goes outside the editor while dragging stuff #120

Merged
merged 2 commits into from
Sep 12, 2021
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
81 changes: 51 additions & 30 deletions imnodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,33 @@ inline bool RectangleOverlapsLink(
return false;
}

// [SECTION] coordinate space conversion helpers

inline ImVec2 ScreenSpaceToGridSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v - GImNodes->CanvasOriginScreenSpace - editor.Panning;
}

inline ImVec2 GridSpaceToScreenSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v + GImNodes->CanvasOriginScreenSpace + editor.Panning;
}

inline ImVec2 GridSpaceToEditorSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v + editor.Panning;
}

inline ImVec2 EditorSpaceToGridSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v - editor.Panning;
}

inline ImVec2 EditorSpaceToScreenSpace(const ImVec2& v)
{
return GImNodes->CanvasOriginScreenSpace + v;
}

// [SECTION] draw list helper

void ImDrawListGrowChannels(ImDrawList* draw_list, const int num_channels)
Expand Down Expand Up @@ -664,7 +691,7 @@ void BeginCanvasInteraction(ImNodesEditorContext& editor)
else if (GImNodes->LeftMouseClicked)
{
editor.ClickInteraction.Type = ImNodesClickInteractionType_BoxSelection;
editor.ClickInteraction.BoxSelector.Rect.Min = GImNodes->MousePos;
editor.ClickInteraction.BoxSelector.Rect.Min = ScreenSpaceToGridSpace(editor, GImNodes->MousePos);
}
}
}
Expand Down Expand Up @@ -743,7 +770,7 @@ void TranslateSelectedNodes(ImNodesEditorContext& editor)
ImNodeData& node = editor.Nodes.Pool[node_idx];
if (node.Draggable)
{
node.Origin += io.MouseDelta;
node.Origin += io.MouseDelta - editor.AutoPanningDelta;
}
}
}
Expand Down Expand Up @@ -835,8 +862,11 @@ void ClickInteractionUpdate(ImNodesEditorContext& editor)
{
case ImNodesClickInteractionType_BoxSelection:
{
ImRect& box_rect = editor.ClickInteraction.BoxSelector.Rect;
box_rect.Max = GImNodes->MousePos;
editor.ClickInteraction.BoxSelector.Rect.Max = ScreenSpaceToGridSpace(editor, GImNodes->MousePos);

ImRect box_rect = editor.ClickInteraction.BoxSelector.Rect;
box_rect.Min = GridSpaceToScreenSpace(editor, box_rect.Min);
box_rect.Max = GridSpaceToScreenSpace(editor, box_rect.Max);

BoxSelectorUpdateSelection(editor, box_rect);

Expand Down Expand Up @@ -1225,31 +1255,6 @@ ImOptionalIndex ResolveHoveredLink(

// [SECTION] render helpers

inline ImVec2 ScreenSpaceToGridSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v - GImNodes->CanvasOriginScreenSpace - editor.Panning;
}

inline ImVec2 GridSpaceToScreenSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v + GImNodes->CanvasOriginScreenSpace + editor.Panning;
}

inline ImVec2 GridSpaceToEditorSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v + editor.Panning;
}

inline ImVec2 EditorSpaceToGridSpace(const ImNodesEditorContext& editor, const ImVec2& v)
{
return v - editor.Panning;
}

inline ImVec2 EditorSpaceToScreenSpace(const ImVec2& v)
{
return GImNodes->CanvasOriginScreenSpace + v;
}

inline ImRect GetItemRect() { return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); }

inline ImVec2 GetNodeTitleBarOrigin(const ImNodeData& node)
Expand Down Expand Up @@ -1926,7 +1931,7 @@ ImNodesIO::LinkDetachWithModifierClick::LinkDetachWithModifierClick() : Modifier

ImNodesIO::ImNodesIO()
: EmulateThreeButtonMouse(), LinkDetachWithModifierClick(),
AltMouseButton(ImGuiMouseButton_Middle)
AltMouseButton(ImGuiMouseButton_Middle), AutoPanningSpeed(1000.0f)
{
}

Expand Down Expand Up @@ -2125,6 +2130,7 @@ void BeginNodeEditor()
// Reset state from previous pass

ImNodesEditorContext& editor = EditorContextGet();
editor.AutoPanningDelta = ImVec2(0, 0);
ObjectPoolReset(editor.Nodes);
ObjectPoolReset(editor.Pins);
ObjectPoolReset(editor.Links);
Expand Down Expand Up @@ -2283,6 +2289,21 @@ void EndNodeEditor()
BeginCanvasInteraction(editor);
}

bool shouldAutoPan =
editor.ClickInteraction.Type == ImNodesClickInteractionType_BoxSelection ||
editor.ClickInteraction.Type == ImNodesClickInteractionType_LinkCreation ||
editor.ClickInteraction.Type == ImNodesClickInteractionType_Node;
if (shouldAutoPan && !MouseInCanvas())
{
ImVec2 mouse = ImGui::GetMousePos();
ImVec2 center = GImNodes->CanvasRectScreenSpace.GetCenter();
ImVec2 direction = (center - mouse);
direction = direction * ImInvLength(direction, 0.0);

editor.AutoPanningDelta = direction * ImGui::GetIO().DeltaTime * GImNodes->Io.AutoPanningSpeed;
editor.Panning += editor.AutoPanningDelta;
}

ClickInteractionUpdate(editor);
}

Expand Down
3 changes: 3 additions & 0 deletions imnodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ struct ImNodesIO
// Set based on ImGuiMouseButton values
int AltMouseButton;

// Panning speed when dragging an element and mouse is outside the main editor view.
float AutoPanningSpeed;

ImNodesIO();
};

Expand Down
3 changes: 2 additions & 1 deletion imnodes_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ struct ImClickInteractionState

struct
{
ImRect Rect;
ImRect Rect; // Coordinates in grid space
} BoxSelector;

ImClickInteractionState() : Type(ImNodesClickInteractionType_None) {}
Expand Down Expand Up @@ -252,6 +252,7 @@ struct ImNodesEditorContext

// ui related fields
ImVec2 Panning;
ImVec2 AutoPanningDelta;

ImVector<int> SelectedNodeIndices;
ImVector<int> SelectedLinkIndices;
Expand Down