-
-
Save MSylvia/202b90b6a0677dcf31ef3b2b23f35d29 to your computer and use it in GitHub Desktop.
Revisions
-
ocornut revised this gist
Mar 6, 2020 . 1 changed file with 32 additions and 23 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,9 +1,11 @@ // Creating a node graph editor for Dear ImGui // Quick sample, not production code! This is more of a demo of how to use Dear ImGui to create custom stuff. // See https://github.com/ocornut/imgui/issues/306 for details // And more fancy node editors: https://github.com/ocornut/imgui/wiki#Useful-widgets--references // Changelog // - v0.04 (2020-03): minor tweaks // - v0.03 (2018-03): fixed grid offset issue, inverted sign of 'scrolling' #include <math.h> // fmodf @@ -12,11 +14,11 @@ static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } // Dummy data structure provided for the example. // Note that we storing links as indices (not ID) to make example code shorter. static void ShowExampleAppCustomNodeGraph(bool* opened) { ImGui::SetNextWindowSize(ImVec2(700, 600), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Example: Custom Node Graph", opened)) { ImGui::End(); @@ -33,7 +35,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImVec4 Color; int InputsCount, OutputsCount; Node(int id, const char* name, const ImVec2& pos, float value, const ImVec4& color, int inputs_count, int outputs_count) { ID = id; strcpy(Name, name); Pos = pos; Value = value; Color = color; InputsCount = inputs_count; OutputsCount = outputs_count; } ImVec2 GetInputSlotPos(int slot_no) const { return ImVec2(Pos.x, Pos.y + Size.y * ((float)slot_no + 1) / ((float)InputsCount + 1)); } ImVec2 GetOutputSlotPos(int slot_no) const { return ImVec2(Pos.x + Size.x, Pos.y + Size.y * ((float)slot_no + 1) / ((float)OutputsCount + 1)); } @@ -45,12 +47,16 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) NodeLink(int input_idx, int input_slot, int output_idx, int output_slot) { InputIdx = input_idx; InputSlot = input_slot; OutputIdx = output_idx; OutputSlot = output_slot; } }; // State static ImVector<Node> nodes; static ImVector<NodeLink> links; static ImVec2 scrolling = ImVec2(0.0f, 0.0f); static bool inited = false; static bool show_grid = true; static int node_selected = -1; // Initialization ImGuiIO& io = ImGui::GetIO(); if (!inited) { nodes.push_back(Node(0, "MainTex", ImVec2(40, 50), 0.5f, ImColor(255, 100, 100), 1, 1)); @@ -95,12 +101,14 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImGui::Checkbox("Show grid", &show_grid); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1, 1)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(60, 60, 70, 200)); ImGui::BeginChild("scrolling_region", ImVec2(0, 0), true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove); ImGui::PopStyleVar(); // WindowPadding ImGui::PushItemWidth(120.0f); const ImVec2 offset = ImGui::GetCursorScreenPos() + scrolling; ImDrawList* draw_list = ImGui::GetWindowDrawList(); // Display grid if (show_grid) { @@ -161,8 +169,8 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) bool node_moving_active = ImGui::IsItemActive(); if (node_widgets_active || node_moving_active) node_selected = node->ID; if (node_moving_active && ImGui::IsMouseDragging(ImGuiMouseButton_Left)) node->Pos = node->Pos + io.MouseDelta; ImU32 node_bg_color = (node_hovered_in_list == node->ID || node_hovered_in_scene == node->ID || (node_hovered_in_list == -1 && node_selected == node->ID)) ? IM_COL32(75, 75, 75, 255) : IM_COL32(60, 60, 60, 255); draw_list->AddRectFilled(node_rect_min, node_rect_max, node_bg_color, 4.0f); @@ -177,11 +185,12 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) draw_list->ChannelsMerge(); // Open context menu if (ImGui::IsMouseReleased(ImGuiMouseButton_Right)) if (ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) || !ImGui::IsAnyItemHovered()) { node_selected = node_hovered_in_list = node_hovered_in_scene = -1; open_context_menu = true; } if (open_context_menu) { ImGui::OpenPopup("context_menu"); @@ -215,13 +224,13 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImGui::PopStyleVar(); // Scrolling if (ImGui::IsWindowHovered() && !ImGui::IsAnyItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Middle, 0.0f)) scrolling = scrolling + io.MouseDelta; ImGui::PopItemWidth(); ImGui::EndChild(); ImGui::PopStyleColor(); ImGui::PopStyleVar(); ImGui::EndGroup(); ImGui::End(); -
ocornut revised this gist
Mar 21, 2018 . 1 changed file with 1 addition and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -101,8 +101,6 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImVec2 offset = ImGui::GetCursorScreenPos() + scrolling; ImDrawList* draw_list = ImGui::GetWindowDrawList(); // Display grid if (show_grid) { @@ -117,6 +115,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) } // Display links draw_list->ChannelsSplit(2); draw_list->ChannelsSetCurrent(0); // Background for (int link_idx = 0; link_idx < links.Size; link_idx++) { -
ocornut revised this gist
Mar 21, 2018 . 1 changed file with 33 additions and 31 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,19 +2,21 @@ // Quick demo, not production code! This is more of a demo of how to use ImGui to create custom stuff. // Better version by @daniel_collin here https://gist.github.com/emoon/b8ff4b4ce4f1b43e79f2 // See https://github.com/ocornut/imgui/issues/306 // v0.03: fixed grid offset issue, inverted sign of 'scrolling' // Animated gif: https://cloud.githubusercontent.com/assets/8225057/9472357/c0263c04-4b4c-11e5-9fdf-2cd4f33f6582.gif #include <math.h> // fmodf // NB: You can use math functions/operators on ImVec2 if you #define IMGUI_DEFINE_MATH_OPERATORS and #include "imgui_internal.h" // Here we only declare simple +/- operators so others don't leak into the demo code. static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } // Really dumb data structure provided for the example. // Note that we storing links are INDICES (not ID) to make example code shorter, obviously a bad idea for any general purpose code. static void ShowExampleAppCustomNodeGraph(bool* opened) { ImGui::SetNextWindowSize(ImVec2(700, 600), ImGuiSetCond_FirstUseEver); if (!ImGui::Begin("Example: Custom Node Graph", opened)) { ImGui::End(); @@ -33,8 +35,8 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) Node(int id, const char* name, const ImVec2& pos, float value, const ImVec4& color, int inputs_count, int outputs_count) { ID = id; strncpy(Name, name, 31); Name[31] = 0; Pos = pos; Value = value; Color = color; InputsCount = inputs_count; OutputsCount = outputs_count; } ImVec2 GetInputSlotPos(int slot_no) const { return ImVec2(Pos.x, Pos.y + Size.y * ((float)slot_no + 1) / ((float)InputsCount + 1)); } ImVec2 GetOutputSlotPos(int slot_no) const { return ImVec2(Pos.x + Size.x, Pos.y + Size.y * ((float)slot_no + 1) / ((float)OutputsCount + 1)); } }; struct NodeLink { @@ -51,9 +53,9 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) static int node_selected = -1; if (!inited) { nodes.push_back(Node(0, "MainTex", ImVec2(40, 50), 0.5f, ImColor(255, 100, 100), 1, 1)); nodes.push_back(Node(1, "BumpMap", ImVec2(40, 150), 0.42f, ImColor(200, 100, 200), 1, 1)); nodes.push_back(Node(2, "Combine", ImVec2(270, 80), 1.0f, ImColor(0, 200, 100), 2, 2)); links.push_back(NodeLink(0, 0, 2, 0)); links.push_back(NodeLink(1, 0, 2, 1)); inited = true; @@ -63,7 +65,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) bool open_context_menu = false; int node_hovered_in_list = -1; int node_hovered_in_scene = -1; ImGui::BeginChild("node_list", ImVec2(100, 0)); ImGui::Text("Nodes"); ImGui::Separator(); for (int node_idx = 0; node_idx < nodes.Size; node_idx++) @@ -89,29 +91,29 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) // Create our child canvas ImGui::Text("Hold middle mouse button to scroll (%.2f,%.2f)", scrolling.x, scrolling.y); ImGui::SameLine(ImGui::GetWindowWidth() - 100); ImGui::Checkbox("Show grid", &show_grid); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1, 1)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, IM_COL32(60, 60, 70, 200)); ImGui::BeginChild("scrolling_region", ImVec2(0, 0), true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove); ImGui::PushItemWidth(120.0f); ImVec2 offset = ImGui::GetCursorScreenPos() + scrolling; ImDrawList* draw_list = ImGui::GetWindowDrawList(); draw_list->ChannelsSplit(2); // Display grid if (show_grid) { ImU32 GRID_COLOR = IM_COL32(200, 200, 200, 40); float GRID_SZ = 64.0f; ImVec2 win_pos = ImGui::GetCursorScreenPos(); ImVec2 canvas_sz = ImGui::GetWindowSize(); for (float x = fmodf(scrolling.x, GRID_SZ); x < canvas_sz.x; x += GRID_SZ) draw_list->AddLine(ImVec2(x, 0.0f) + win_pos, ImVec2(x, canvas_sz.y) + win_pos, GRID_COLOR); for (float y = fmodf(scrolling.y, GRID_SZ); y < canvas_sz.y; y += GRID_SZ) draw_list->AddLine(ImVec2(0.0f, y) + win_pos, ImVec2(canvas_sz.x, y) + win_pos, GRID_COLOR); } // Display links @@ -122,8 +124,8 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) Node* node_inp = &nodes[link->InputIdx]; Node* node_out = &nodes[link->OutputIdx]; ImVec2 p1 = offset + node_inp->GetOutputSlotPos(link->InputSlot); ImVec2 p2 = offset + node_out->GetInputSlotPos(link->OutputSlot); draw_list->AddBezierCurve(p1, p1 + ImVec2(+50, 0), p2 + ImVec2(-50, 0), p2, IM_COL32(200, 200, 100, 255), 3.0f); } // Display nodes @@ -163,13 +165,13 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) if (node_moving_active && ImGui::IsMouseDragging(0)) node->Pos = node->Pos + ImGui::GetIO().MouseDelta; ImU32 node_bg_color = (node_hovered_in_list == node->ID || node_hovered_in_scene == node->ID || (node_hovered_in_list == -1 && node_selected == node->ID)) ? IM_COL32(75, 75, 75, 255) : IM_COL32(60, 60, 60, 255); draw_list->AddRectFilled(node_rect_min, node_rect_max, node_bg_color, 4.0f); draw_list->AddRect(node_rect_min, node_rect_max, IM_COL32(100, 100, 100, 255), 4.0f); for (int slot_idx = 0; slot_idx < node->InputsCount; slot_idx++) draw_list->AddCircleFilled(offset + node->GetInputSlotPos(slot_idx), NODE_SLOT_RADIUS, IM_COL32(150, 150, 150, 150)); for (int slot_idx = 0; slot_idx < node->OutputsCount; slot_idx++) draw_list->AddCircleFilled(offset + node->GetOutputSlotPos(slot_idx), NODE_SLOT_RADIUS, IM_COL32(150, 150, 150, 150)); ImGui::PopID(); } @@ -191,7 +193,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) } // Draw context menu ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8)); if (ImGui::BeginPopup("context_menu")) { Node* node = node_selected != -1 ? &nodes[node_selected] : NULL; @@ -206,7 +208,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) } else { if (ImGui::MenuItem("Add")) { nodes.push_back(Node(nodes.Size, "New node", scene_pos, 0.5f, ImColor(100, 100, 200), 2, 2)); } if (ImGui::MenuItem("Paste", NULL, false, false)) {} } ImGui::EndPopup(); @@ -215,7 +217,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) // Scrolling if (ImGui::IsWindowHovered() && !ImGui::IsAnyItemActive() && ImGui::IsMouseDragging(2, 0.0f)) scrolling = scrolling + ImGui::GetIO().MouseDelta; ImGui::PopItemWidth(); ImGui::EndChild(); -
ocornut revised this gist
Jan 11, 2018 . 1 changed file with 7 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -93,7 +93,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImGui::Checkbox("Show grid", &show_grid); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1,1)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0)); ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, IM_COL32(60,60,70,200)); ImGui::BeginChild("scrolling_region", ImVec2(0,0), true, ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoMove); ImGui::PushItemWidth(120.0f); @@ -104,7 +104,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) // Display grid if (show_grid) { ImU32 GRID_COLOR = IM_COL32(200,200,200,40); float GRID_SZ = 64.0f; ImVec2 win_pos = ImGui::GetCursorScreenPos(); ImVec2 canvas_sz = ImGui::GetWindowSize(); @@ -123,7 +123,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) Node* node_out = &nodes[link->OutputIdx]; ImVec2 p1 = offset + node_inp->GetOutputSlotPos(link->InputSlot); ImVec2 p2 = offset + node_out->GetInputSlotPos(link->OutputSlot); draw_list->AddBezierCurve(p1, p1+ImVec2(+50,0), p2+ImVec2(-50,0), p2, IM_COL32(200,200,100,255), 3.0f); } // Display nodes @@ -163,13 +163,13 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) if (node_moving_active && ImGui::IsMouseDragging(0)) node->Pos = node->Pos + ImGui::GetIO().MouseDelta; ImU32 node_bg_color = (node_hovered_in_list == node->ID || node_hovered_in_scene == node->ID || (node_hovered_in_list == -1 && node_selected == node->ID)) ? IM_COL32(75,75,75,255) : IM_COL32(60,60,60,255); draw_list->AddRectFilled(node_rect_min, node_rect_max, node_bg_color, 4.0f); draw_list->AddRect(node_rect_min, node_rect_max, IM_COL32(100,100,100,255), 4.0f); for (int slot_idx = 0; slot_idx < node->InputsCount; slot_idx++) draw_list->AddCircleFilled(offset + node->GetInputSlotPos(slot_idx), NODE_SLOT_RADIUS, IM_COL32(150,150,150,150)); for (int slot_idx = 0; slot_idx < node->OutputsCount; slot_idx++) draw_list->AddCircleFilled(offset + node->GetOutputSlotPos(slot_idx), NODE_SLOT_RADIUS, IM_COL32(150,150,150,150)); ImGui::PopID(); } -
ocornut revised this gist
Sep 11, 2015 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,6 @@ // Creating a node graph editor for ImGui // Quick demo, not production code! This is more of a demo of how to use ImGui to create custom stuff. // Better version by @daniel_collin here https://gist.github.com/emoon/b8ff4b4ce4f1b43e79f2 // See https://github.com/ocornut/imgui/issues/306 // v0.02 // Animated gif: https://cloud.githubusercontent.com/assets/8225057/9472357/c0263c04-4b4c-11e5-9fdf-2cd4f33f6582.gif -
ocornut revised this gist
Aug 28, 2015 . 1 changed file with 28 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,15 +20,17 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) return; } // Dummy struct Node { int ID; char Name[32]; ImVec2 Pos, Size; float Value; ImVec4 Color; int InputsCount, OutputsCount; Node(int id, const char* name, const ImVec2& pos, float value, const ImVec4& color, int inputs_count, int outputs_count) { ID = id; strncpy(Name, name, 31); Name[31] = 0; Pos = pos; Value = value; Color = color; InputsCount = inputs_count; OutputsCount = outputs_count; } ImVec2 GetInputSlotPos(int slot_no) const { return ImVec2(Pos.x, Pos.y + Size.y * ((float)slot_no+1) / ((float)InputsCount+1)); } ImVec2 GetOutputSlotPos(int slot_no) const { return ImVec2(Pos.x + Size.x, Pos.y + Size.y * ((float)slot_no+1) / ((float)OutputsCount+1)); } @@ -44,12 +46,13 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) static ImVector<NodeLink> links; static bool inited = false; static ImVec2 scrolling = ImVec2(0.0f, 0.0f); static bool show_grid = true; static int node_selected = -1; if (!inited) { nodes.push_back(Node(0, "MainTex", ImVec2(40,50), 0.5f, ImColor(255,100,100), 1, 1)); nodes.push_back(Node(1, "BumpMap", ImVec2(40,150), 0.42f, ImColor(200,100,200), 1, 1)); nodes.push_back(Node(2, "Combine", ImVec2(270,80), 1.0f, ImColor(0,200,100), 2, 2)); links.push_back(NodeLink(0, 0, 2, 0)); links.push_back(NodeLink(1, 0, 2, 1)); inited = true; @@ -85,15 +88,30 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) // Create our child canvas ImGui::Text("Hold middle mouse button to scroll (%.2f,%.2f)", scrolling.x, scrolling.y); ImGui::SameLine(ImGui::GetWindowWidth()-100); ImGui::Checkbox("Show grid", &show_grid); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1,1)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0)); ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, ImColor(60,60,70,200)); ImGui::BeginChild("scrolling_region", ImVec2(0,0), true, ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoMove); ImGui::PushItemWidth(120.0f); ImVec2 offset = ImGui::GetCursorScreenPos() - scrolling; ImDrawList* draw_list = ImGui::GetWindowDrawList(); draw_list->ChannelsSplit(2); // Display grid if (show_grid) { ImU32 GRID_COLOR = ImColor(200,200,200,40); float GRID_SZ = 64.0f; ImVec2 win_pos = ImGui::GetCursorScreenPos(); ImVec2 canvas_sz = ImGui::GetWindowSize(); for (float x = fmodf(offset.x,GRID_SZ); x < canvas_sz.x; x += GRID_SZ) draw_list->AddLine(ImVec2(x,0.0f)+win_pos, ImVec2(x,canvas_sz.y)+win_pos, GRID_COLOR); for (float y = fmodf(offset.y,GRID_SZ); y < canvas_sz.y; y += GRID_SZ) draw_list->AddLine(ImVec2(0.0f,y)+win_pos, ImVec2(canvas_sz.x,y)+win_pos, GRID_COLOR); } // Display links draw_list->ChannelsSetCurrent(0); // Background @@ -104,7 +122,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) Node* node_out = &nodes[link->OutputIdx]; ImVec2 p1 = offset + node_inp->GetOutputSlotPos(link->InputSlot); ImVec2 p2 = offset + node_out->GetInputSlotPos(link->OutputSlot); draw_list->AddBezierCurve(p1, p1+ImVec2(+50,0), p2+ImVec2(-50,0), p2, ImColor(200,200,100), 3.0f); } // Display nodes @@ -121,8 +139,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImGui::BeginGroup(); // Lock horizontal position ImGui::Text("%s", node->Name); ImGui::SliderFloat("##value", &node->Value, 0.0f, 1.0f, "Alpha %.2f"); ImGui::ColorEdit3("##color", &node->Color.x); ImGui::EndGroup(); // Save the size of what we have emitted and whether any of the widgets are being used @@ -188,7 +205,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) } else { if (ImGui::MenuItem("Add")) { nodes.push_back(Node(nodes.Size, "New node", scene_pos, 0.5f, ImColor(100,100,200), 2, 2)); } if (ImGui::MenuItem("Paste", NULL, false, false)) {} } ImGui::EndPopup(); @@ -206,4 +223,4 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImGui::EndGroup(); ImGui::End(); } -
ocornut revised this gist
Aug 28, 2015 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -104,7 +104,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) Node* node_out = &nodes[link->OutputIdx]; ImVec2 p1 = offset + node_inp->GetOutputSlotPos(link->InputSlot); ImVec2 p2 = offset + node_out->GetInputSlotPos(link->OutputSlot); draw_list->AddBezier(p1, p1+ImVec2(+50,0), p2+ImVec2(-50,0), p2, ImColor(200,200,100), 3.0f); } // Display nodes @@ -125,7 +125,7 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) ImGui::ColorEdit3("##color", &dummy_color[0]); ImGui::EndGroup(); // Save the size of what we have emitted and whether any of the widgets are being used bool node_widgets_active = (!old_any_active && ImGui::IsAnyItemActive()); node->Size = ImGui::GetItemRectSize() + NODE_WINDOW_PADDING + NODE_WINDOW_PADDING; ImVec2 node_rect_max = node_rect_min + node->Size; -
ocornut revised this gist
Aug 28, 2015 . 1 changed file with 4 additions and 23 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ // Creating a node graph editor for ImGui // Quick demo, not production code! // See https://github.com/ocornut/imgui/issues/306 // v0.02 // Animated gif: https://cloud.githubusercontent.com/assets/8225057/9472357/c0263c04-4b4c-11e5-9fdf-2cd4f33f6582.gif // NB: You can use math functions/operators on ImVec2 if you #define IMGUI_DEFINE_MATH_OPERATORS and #include "imgui_internal.h" @@ -102,28 +102,9 @@ static void ShowExampleAppCustomNodeGraph(bool* opened) NodeLink* link = &links[link_idx]; Node* node_inp = &nodes[link->InputIdx]; Node* node_out = &nodes[link->OutputIdx]; ImVec2 p1 = offset + node_inp->GetOutputSlotPos(link->InputSlot); ImVec2 p2 = offset + node_out->GetInputSlotPos(link->OutputSlot); draw_list->AddBezier(p1, p1+ImVec2(+50,0), p2+ImVec2(-50,0), p2, ImColor(200,100,100), 3.0f); } // Display nodes -
ocornut revised this gist
Aug 25, 2015 . 1 changed file with 5 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,11 +1,13 @@ // Creating a node graph editor for ImGui // Quick demo, not production code! // See https://github.com/ocornut/imgui/issues/306 // v0.01 // Animated gif: https://cloud.githubusercontent.com/assets/8225057/9472357/c0263c04-4b4c-11e5-9fdf-2cd4f33f6582.gif // NB: You can use math functions/operators on ImVec2 if you #define IMGUI_DEFINE_MATH_OPERATORS and #include "imgui_internal.h" // Here we only declare simple +/- operators so others don't leak into the demo code. static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); } static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); } // Really dumb data structure provided for the example. // Note that we storing links are INDICES (not ID) to make example code shorter, obviously a bad idea for any general purpose code. -
ocornut revised this gist
Aug 25, 2015 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ // Animation: https://cloud.githubusercontent.com/assets/8225057/9472357/c0263c04-4b4c-11e5-9fdf-2cd4f33f6582.gif // See https://github.com/ocornut/imgui/issues/306 // v0.01 -
ocornut renamed this gist
Aug 25, 2015 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
ocornut created this gist
Aug 25, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,225 @@ // See https://github.com/ocornut/imgui/issues/306 // v0.01 // NB: You can use math functions/operators on ImVec2 if you #define IMGUI_DEFINE_MATH_OPERATORS and #include "imgui_internal.h" // Here we only declare simple +/- operators so others don't leak into the demo code. static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); } static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); } // Really dumb data structure provided for the example. // Note that we storing links are INDICES (not ID) to make example code shorter, obviously a bad idea for any general purpose code. static void ShowExampleAppCustomNodeGraph(bool* opened) { ImGui::SetNextWindowSize(ImVec2(700,600), ImGuiSetCond_FirstUseEver); if (!ImGui::Begin("Example: Custom Node Graph", opened)) { ImGui::End(); return; } struct Node { int ID; char Name[32]; ImVec2 Pos, Size; float Value; int InputsCount, OutputsCount; Node(int id, const char* name, const ImVec2& pos, float value, int inputs_count, int outputs_count) { ID = id; strncpy(Name, name, 31); Name[31] = 0; Pos = pos; Value = value; InputsCount = inputs_count; OutputsCount = outputs_count; } ImVec2 GetInputSlotPos(int slot_no) const { return ImVec2(Pos.x, Pos.y + Size.y * ((float)slot_no+1) / ((float)InputsCount+1)); } ImVec2 GetOutputSlotPos(int slot_no) const { return ImVec2(Pos.x + Size.x, Pos.y + Size.y * ((float)slot_no+1) / ((float)OutputsCount+1)); } }; struct NodeLink { int InputIdx, InputSlot, OutputIdx, OutputSlot; NodeLink(int input_idx, int input_slot, int output_idx, int output_slot) { InputIdx = input_idx; InputSlot = input_slot; OutputIdx = output_idx; OutputSlot = output_slot; } }; static ImVector<Node> nodes; static ImVector<NodeLink> links; static bool inited = false; static ImVec2 scrolling = ImVec2(0.0f, 0.0f); static int node_selected = -1; if (!inited) { nodes.push_back(Node(0, "MainTex", ImVec2(40,50), 0.5f, 1, 1)); nodes.push_back(Node(1, "BumpMap", ImVec2(40,150), 0.42f, 1, 1)); nodes.push_back(Node(2, "Combine", ImVec2(270,80), 1.0f, 2, 2)); links.push_back(NodeLink(0, 0, 2, 0)); links.push_back(NodeLink(1, 0, 2, 1)); inited = true; } // Draw a list of nodes on the left side bool open_context_menu = false; int node_hovered_in_list = -1; int node_hovered_in_scene = -1; ImGui::BeginChild("node_list", ImVec2(100,0)); ImGui::Text("Nodes"); ImGui::Separator(); for (int node_idx = 0; node_idx < nodes.Size; node_idx++) { Node* node = &nodes[node_idx]; ImGui::PushID(node->ID); if (ImGui::Selectable(node->Name, node->ID == node_selected)) node_selected = node->ID; if (ImGui::IsItemHovered()) { node_hovered_in_list = node->ID; open_context_menu |= ImGui::IsMouseClicked(1); } ImGui::PopID(); } ImGui::EndChild(); ImGui::SameLine(); ImGui::BeginGroup(); const float NODE_SLOT_RADIUS = 4.0f; const ImVec2 NODE_WINDOW_PADDING(8.0f, 8.0f); // Create our child canvas ImGui::Text("Hold middle mouse button to scroll (%.2f,%.2f)", scrolling.x, scrolling.y); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1,1)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0)); ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, ImColor(40,40,40,200)); ImGui::BeginChild("scrolling_region", ImVec2(0,0), true, ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoMove); ImGui::PushItemWidth(120.0f); ImDrawList* draw_list = ImGui::GetWindowDrawList(); draw_list->ChannelsSplit(2); ImVec2 offset = ImGui::GetCursorScreenPos() - scrolling; // Display links draw_list->ChannelsSetCurrent(0); // Background for (int link_idx = 0; link_idx < links.Size; link_idx++) { NodeLink* link = &links[link_idx]; Node* node_inp = &nodes[link->InputIdx]; Node* node_out = &nodes[link->OutputIdx]; #if 1 // Hermite spline // TODO: move to ImDrawList path API ImVec2 p1 = offset+node_inp->GetOutputSlotPos(link->InputSlot); ImVec2 t1 = ImVec2(+80.0f, 0.0f); ImVec2 p2 = offset+node_out->GetInputSlotPos(link->OutputSlot); ImVec2 t2 = ImVec2(+80.0f, 0.0f); const int STEPS = 12; for (int step = 0; step <= STEPS; step++) { float t = (float)step / (float)STEPS; float h1 = +2*t*t*t - 3*t*t + 1.0f; float h2 = -2*t*t*t + 3*t*t; float h3 = t*t*t - 2*t*t + t; float h4 = t*t*t - t*t; draw_list->PathLineTo(ImVec2(h1*p1.x + h2*p2.x + h3*t1.x + h4*t2.x, h1*p1.y + h2*p2.y + h3*t1.y + h4*t2.y)); } draw_list->PathStroke(ImColor(200,200,100), false, 3.0f); #else draw_list->AddLine(offset+node_inp->GetOutputSlotPos(link->InputSlot), offset+node_out->GetInputSlotPos(link->OutputSlot), ImColor(200,200,100), 3.0f); #endif } // Display nodes for (int node_idx = 0; node_idx < nodes.Size; node_idx++) { Node* node = &nodes[node_idx]; ImGui::PushID(node->ID); ImVec2 node_rect_min = offset + node->Pos; // Display node contents first draw_list->ChannelsSetCurrent(1); // Foreground bool old_any_active = ImGui::IsAnyItemActive(); ImGui::SetCursorScreenPos(node_rect_min + NODE_WINDOW_PADDING); ImGui::BeginGroup(); // Lock horizontal position ImGui::Text("%s", node->Name); ImGui::SliderFloat("##value", &node->Value, 0.0f, 1.0f, "Alpha %.2f"); float dummy_color[3] = { node->Pos.x / ImGui::GetWindowWidth(), node->Pos.y / ImGui::GetWindowHeight(), fmodf((float)node->ID * 0.5f, 1.0f) }; ImGui::ColorEdit3("##color", &dummy_color[0]); ImGui::EndGroup(); // Save the size of what we have emitted and weither any of the widgets are being used bool node_widgets_active = (!old_any_active && ImGui::IsAnyItemActive()); node->Size = ImGui::GetItemRectSize() + NODE_WINDOW_PADDING + NODE_WINDOW_PADDING; ImVec2 node_rect_max = node_rect_min + node->Size; // Display node box draw_list->ChannelsSetCurrent(0); // Background ImGui::SetCursorScreenPos(node_rect_min); ImGui::InvisibleButton("node", node->Size); if (ImGui::IsItemHovered()) { node_hovered_in_scene = node->ID; open_context_menu |= ImGui::IsMouseClicked(1); } bool node_moving_active = ImGui::IsItemActive(); if (node_widgets_active || node_moving_active) node_selected = node->ID; if (node_moving_active && ImGui::IsMouseDragging(0)) node->Pos = node->Pos + ImGui::GetIO().MouseDelta; ImU32 node_bg_color = (node_hovered_in_list == node->ID || node_hovered_in_scene == node->ID || (node_hovered_in_list == -1 && node_selected == node->ID)) ? ImColor(75,75,75) : ImColor(60,60,60); draw_list->AddRectFilled(node_rect_min, node_rect_max, node_bg_color, 4.0f); draw_list->AddRect(node_rect_min, node_rect_max, ImColor(100,100,100), 4.0f); for (int slot_idx = 0; slot_idx < node->InputsCount; slot_idx++) draw_list->AddCircleFilled(offset + node->GetInputSlotPos(slot_idx), NODE_SLOT_RADIUS, ImColor(150,150,150,150)); for (int slot_idx = 0; slot_idx < node->OutputsCount; slot_idx++) draw_list->AddCircleFilled(offset + node->GetOutputSlotPos(slot_idx), NODE_SLOT_RADIUS, ImColor(150,150,150,150)); ImGui::PopID(); } draw_list->ChannelsMerge(); // Open context menu if (!ImGui::IsAnyItemHovered() && ImGui::IsMouseHoveringWindow() && ImGui::IsMouseClicked(1)) { node_selected = node_hovered_in_list = node_hovered_in_scene = -1; open_context_menu = true; } if (open_context_menu) { ImGui::OpenPopup("context_menu"); if (node_hovered_in_list != -1) node_selected = node_hovered_in_list; if (node_hovered_in_scene != -1) node_selected = node_hovered_in_scene; } // Draw context menu ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8,8)); if (ImGui::BeginPopup("context_menu")) { Node* node = node_selected != -1 ? &nodes[node_selected] : NULL; ImVec2 scene_pos = ImGui::GetMousePosOnOpeningCurrentPopup() - offset; if (node) { ImGui::Text("Node '%s'", node->Name); ImGui::Separator(); if (ImGui::MenuItem("Rename..", NULL, false, false)) {} if (ImGui::MenuItem("Delete", NULL, false, false)) {} if (ImGui::MenuItem("Copy", NULL, false, false)) {} } else { if (ImGui::MenuItem("Add")) { nodes.push_back(Node(nodes.Size, "New node", scene_pos, 0.5f, 2, 2)); } if (ImGui::MenuItem("Paste", NULL, false, false)) {} } ImGui::EndPopup(); } ImGui::PopStyleVar(); // Scrolling if (ImGui::IsWindowHovered() && !ImGui::IsAnyItemActive() && ImGui::IsMouseDragging(2, 0.0f)) scrolling = scrolling - ImGui::GetIO().MouseDelta; ImGui::PopItemWidth(); ImGui::EndChild(); ImGui::PopStyleColor(); ImGui::PopStyleVar(2); ImGui::EndGroup(); ImGui::End(); }