|
@ -0,0 +1,112 @@ |
|
|
|
|
|
#pragma once |
|
|
|
|
|
|
|
|
|
|
|
#include <string> |
|
|
|
|
|
#include <vector> |
|
|
|
|
|
|
|
|
|
|
|
#define IMGUI_DEFINE_MATH_OPERATORS |
|
|
|
|
|
#include <imgui.h> |
|
|
|
|
|
#include <imgui_internal.h> |
|
|
|
|
|
|
|
|
|
|
|
#include "../geom.h" |
|
|
|
|
|
|
|
|
|
|
|
class GuiNode { |
|
|
|
|
|
public: |
|
|
|
|
|
GuiNode(std::string name, Rect bbox) |
|
|
|
|
|
: name(name), bbox(bbox) |
|
|
|
|
|
{} |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
|
friend class NodeEditor; |
|
|
|
|
|
|
|
|
|
|
|
std::string name; |
|
|
|
|
|
|
|
|
|
|
|
Rect bbox; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class NodeEditor { |
|
|
|
|
|
public: |
|
|
|
|
|
NodeEditor() { |
|
|
|
|
|
nodeList.emplace_back("hi", Rect(10, 10, 60, 60)); |
|
|
|
|
|
nodeList.emplace_back("hi2", Rect(10, 80, 60, 60)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void draw_window(const char *title, bool *opened) { |
|
|
|
|
|
ImGui::SetNextWindowSize(ImVec2(700,600), ImGuiSetCond_FirstUseEver); |
|
|
|
|
|
if (ImGui::Begin(title, opened)) { |
|
|
|
|
|
// -- Create child canvas |
|
|
|
|
|
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("nodes_region", ImVec2(0, 0), true, ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoMove); |
|
|
|
|
|
|
|
|
|
|
|
// -- Prepare to draw |
|
|
|
|
|
// Get the draw list for this canvas |
|
|
|
|
|
ImDrawList* draw_list = ImGui::GetWindowDrawList(); |
|
|
|
|
|
draw_list->ChannelsSplit(2); |
|
|
|
|
|
|
|
|
|
|
|
// this gets the offset to the upper-right corner of the child canvas. |
|
|
|
|
|
// Note: here, cursor means "draw cursor", not "mouse pointing cursor". |
|
|
|
|
|
ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); |
|
|
|
|
|
ImVec2 canvas_size = ImGui::GetWindowSize(); |
|
|
|
|
|
|
|
|
|
|
|
ImVec2 offset = canvas_pos - scrolling; // TODO: add scrolling |
|
|
|
|
|
|
|
|
|
|
|
// -- Draw the grid |
|
|
|
|
|
if (show_grid) { |
|
|
|
|
|
ImVec2 local_offset = ImGui::GetCursorPos() - scrolling; |
|
|
|
|
|
|
|
|
|
|
|
float spacing = 32.0f; ImU32 color = IM_COL32(200, 200, 200, 40); |
|
|
|
|
|
|
|
|
|
|
|
for (float x = fmodf(local_offset.x, spacing); x < canvas_size.x; x += spacing) |
|
|
|
|
|
draw_list->AddLine(ImVec2(x, 0.0f)+canvas_pos, |
|
|
|
|
|
ImVec2(x, canvas_size.y)+canvas_pos, color); |
|
|
|
|
|
for (float y = fmodf(local_offset.y, spacing); y < canvas_size.y; y += spacing) |
|
|
|
|
|
draw_list->AddLine(ImVec2(0.0f, y)+canvas_pos, |
|
|
|
|
|
ImVec2(canvas_size.x, y)+canvas_pos, color); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Rect viewportRect = Rect(scrolling, canvas_size); |
|
|
|
|
|
|
|
|
|
|
|
for (const auto &node : nodeList) { |
|
|
|
|
|
bool visible = viewportRect.intersects(node.bbox); |
|
|
|
|
|
if (visible) { |
|
|
|
|
|
// -- Draw the node boxes |
|
|
|
|
|
draw_list->ChannelsSetCurrent(0); // Switch to the background layer |
|
|
|
|
|
|
|
|
|
|
|
ImVec2 upper_left = offset + node.bbox.pos; |
|
|
|
|
|
ImVec2 lower_right = upper_left + node.bbox.size; |
|
|
|
|
|
|
|
|
|
|
|
draw_list->AddRectFilled(upper_left, lower_right, ImColor(60, 60, 60), 4.0f); |
|
|
|
|
|
draw_list->AddRect(upper_left, lower_right, ImColor(100, 100, 100), 4.0f); |
|
|
|
|
|
|
|
|
|
|
|
// for (int i=0; i<N; i++) { |
|
|
|
|
|
// auto position = node.bbox.pos; |
|
|
|
|
|
// position.y += (i+1) * (node.bbox.size.y)/(N+1); |
|
|
|
|
|
|
|
|
|
|
|
// draw_list->AddCircleFilled(offset + position, 4.0f, ImColor(150, 150, 150, 150)); |
|
|
|
|
|
// } |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// -- merge channels back together |
|
|
|
|
|
draw_list->ChannelsMerge(); |
|
|
|
|
|
|
|
|
|
|
|
// -- scrolling! |
|
|
|
|
|
// [ pointer over neditor ] [ not interacting ctrls ] [ middle mouse dragging ] |
|
|
|
|
|
if (ImGui::IsWindowHovered() && !ImGui::IsAnyItemActive() && ImGui::IsMouseDragging(2, 0.0f)) |
|
|
|
|
|
scrolling = scrolling - ImGui::GetIO().MouseDelta; |
|
|
|
|
|
|
|
|
|
|
|
// -- clean up |
|
|
|
|
|
ImGui::EndChild(); // end :nodes_region |
|
|
|
|
|
ImGui::PopStyleColor(); // pop ChildWindowBg |
|
|
|
|
|
ImGui::PopStyleVar(2); // pop FramePadding, WindowPadding |
|
|
|
|
|
} |
|
|
|
|
|
ImGui::End(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
std::vector<GuiNode> nodeList; |
|
|
|
|
|
|
|
|
|
|
|
ImVec2 scrolling = ImVec2(0.0f, 0.0f); |
|
|
|
|
|
bool show_grid = true; |
|
|
|
|
|
}; |