251 lines
9.6 KiB
C++
251 lines
9.6 KiB
C++
# define IMGUI_DEFINE_MATH_OPERATORS
|
|
# include <imgui.h>
|
|
# include <imgui_internal.h>
|
|
# include <imgui_canvas.h>
|
|
# include <application.h>
|
|
|
|
static void DrawScale(const ImVec2& from, const ImVec2& to, float majorUnit, float minorUnit, float labelAlignment, float sign = 1.0f)
|
|
{
|
|
auto drawList = ImGui::GetWindowDrawList();
|
|
auto direction = (to - from) * ImInvLength(to - from, 0.0f);
|
|
auto normal = ImVec2(-direction.y, direction.x);
|
|
auto distance = sqrtf(ImLengthSqr(to - from));
|
|
|
|
if (ImDot(direction, direction) < FLT_EPSILON)
|
|
return;
|
|
|
|
auto minorSize = 5.0f;
|
|
auto majorSize = 10.0f;
|
|
auto labelDistance = 8.0f;
|
|
|
|
drawList->AddLine(from, to, IM_COL32(255, 255, 255, 255));
|
|
|
|
auto p = from;
|
|
for (auto d = 0.0f; d <= distance; d += minorUnit, p += direction * minorUnit)
|
|
drawList->AddLine(p - normal * minorSize, p + normal * minorSize, IM_COL32(255, 255, 255, 255));
|
|
|
|
for (auto d = 0.0f; d <= distance + majorUnit; d += majorUnit)
|
|
{
|
|
p = from + direction * d;
|
|
|
|
drawList->AddLine(p - normal * majorSize, p + normal * majorSize, IM_COL32(255, 255, 255, 255));
|
|
|
|
if (d == 0.0f)
|
|
continue;
|
|
|
|
char label[16];
|
|
snprintf(label, 15, "%g", d * sign);
|
|
auto labelSize = ImGui::CalcTextSize(label);
|
|
|
|
auto labelPosition = p + ImVec2(fabsf(normal.x), fabsf(normal.y)) * labelDistance;
|
|
auto labelAlignedSize = ImDot(labelSize, direction);
|
|
labelPosition += direction * (-labelAlignedSize + labelAlignment * labelAlignedSize * 2.0f);
|
|
labelPosition = ImFloor(labelPosition + ImVec2(0.5f, 0.5f));
|
|
|
|
drawList->AddText(labelPosition, IM_COL32(255, 255, 255, 255), label);
|
|
}
|
|
}
|
|
|
|
static bool Splitter(bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f)
|
|
{
|
|
using namespace ImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
ImGuiID id = window->GetID("##Splitter");
|
|
ImRect bb;
|
|
bb.Min = window->DC.CursorPos + (split_vertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
|
bb.Max = bb.Min + CalcItemSize(split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), 0.0f, 0.0f);
|
|
return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f);
|
|
}
|
|
|
|
struct Example:
|
|
public Application
|
|
{
|
|
using Application::Application;
|
|
|
|
void OnFrame(float deltaTime) override
|
|
{
|
|
auto& io = ImGui::GetIO();
|
|
|
|
ImGui::Text("FPS: %.2f (%.2gms)", io.Framerate, io.Framerate ? 1000.0f / io.Framerate : 0.0f);
|
|
|
|
ImGui::Separator();
|
|
|
|
auto availableRegion = ImGui::GetContentRegionAvail();
|
|
|
|
static float s_SplitterSize = 6.0f;
|
|
static float s_SplitterArea = 0.0f;
|
|
static float s_LeftPaneSize = 0.0f;
|
|
static float s_RightPaneSize = 0.0f;
|
|
|
|
if (s_SplitterArea != availableRegion.x)
|
|
{
|
|
if (s_SplitterArea == 0.0f)
|
|
{
|
|
s_SplitterArea = availableRegion.x;
|
|
s_LeftPaneSize = ImFloor(availableRegion.x * 0.25f);
|
|
s_RightPaneSize = availableRegion.x - s_LeftPaneSize - s_SplitterSize;
|
|
}
|
|
else
|
|
{
|
|
auto ratio = availableRegion.x / s_SplitterArea;
|
|
s_SplitterArea = availableRegion.x;
|
|
s_LeftPaneSize = s_LeftPaneSize * ratio;
|
|
s_RightPaneSize = availableRegion.x - s_LeftPaneSize - s_SplitterSize;
|
|
}
|
|
}
|
|
|
|
static ImGuiEx::Canvas canvas;
|
|
static ImVec2 drawStartPoint;
|
|
static bool isDragging = false;
|
|
static ImRect panelRect;
|
|
|
|
Splitter(true, s_SplitterSize, &s_LeftPaneSize, &s_RightPaneSize, 100.0f, 100.0f);
|
|
|
|
auto canvasRect = canvas.Rect();
|
|
auto viewRect = canvas.ViewRect();
|
|
auto viewOrigin = canvas.ViewOrigin();
|
|
auto viewScale = canvas.ViewScale();
|
|
|
|
ImGui::BeginChild("##top", ImVec2(s_LeftPaneSize, -1), false, ImGuiWindowFlags_NoScrollWithMouse);
|
|
|
|
ImGui::TextUnformatted("Rect:");
|
|
ImGui::BeginColumns("rect", 2, ImGuiOldColumnFlags_NoBorder);
|
|
ImGui::SetColumnWidth(0, ImGui::CalcTextSize("\t\tL: 0000.00\t").x);
|
|
ImGui::Text("\tL: %.2f", canvasRect.Min.x); ImGui::NextColumn();
|
|
ImGui::Text("\tT: %.2f", canvasRect.Min.y); ImGui::NextColumn();
|
|
ImGui::Text("\tR: %.2f", canvasRect.Max.x); ImGui::NextColumn();
|
|
ImGui::Text("\tB: %.2f", canvasRect.Max.y); ImGui::NextColumn();
|
|
ImGui::Text("\tW: %.2f", canvasRect.GetWidth()); ImGui::NextColumn();
|
|
ImGui::Text("\tH: %.2f", canvasRect.GetHeight()); ImGui::NextColumn();
|
|
ImGui::EndColumns();
|
|
|
|
ImGui::TextUnformatted("View Rect:");
|
|
ImGui::BeginColumns("viewrect", 2, ImGuiOldColumnFlags_NoBorder);
|
|
ImGui::SetColumnWidth(0, ImGui::CalcTextSize("\t\tL: 0000.00\t").x);
|
|
ImGui::Text("\tL: %.2f", viewRect.Min.x); ImGui::NextColumn();
|
|
ImGui::Text("\tT: %.2f", viewRect.Min.y); ImGui::NextColumn();
|
|
ImGui::Text("\tR: %.2f", viewRect.Max.x); ImGui::NextColumn();
|
|
ImGui::Text("\tB: %.2f", viewRect.Max.y); ImGui::NextColumn();
|
|
ImGui::Text("\tW: %.2f", viewRect.GetWidth()); ImGui::NextColumn();
|
|
ImGui::Text("\tH: %.2f", viewRect.GetHeight()); ImGui::NextColumn();
|
|
ImGui::EndColumns();
|
|
|
|
ImGui::TextUnformatted("Origin:");
|
|
ImGui::Indent();
|
|
auto originChanged = false;
|
|
ImGui::PushItemWidth(-ImGui::GetStyle().IndentSpacing);
|
|
originChanged |= ImGui::DragFloat("##originx", &viewOrigin.x, 1.0f);
|
|
originChanged |= ImGui::DragFloat("##originy", &viewOrigin.y, 1.0f);
|
|
if (originChanged) canvas.SetView(viewOrigin, viewScale);
|
|
ImGui::PopItemWidth();
|
|
ImGui::Unindent();
|
|
|
|
ImGui::TextUnformatted("Scale:");
|
|
ImGui::Indent();
|
|
ImGui::PushItemWidth(-ImGui::GetStyle().IndentSpacing);
|
|
if (ImGui::DragFloat("##scale", &viewScale, 0.01f, 0.01f, 15.0f))
|
|
canvas.SetView(viewOrigin, viewScale);
|
|
ImGui::PopItemWidth();
|
|
ImGui::Unindent();
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::Button("Center over Panel", ImVec2(s_LeftPaneSize, 0)))
|
|
canvas.CenterView(panelRect.GetCenter());
|
|
|
|
if (ImGui::Button("Center and zoom to Panel", ImVec2(s_LeftPaneSize, 0)))
|
|
canvas.CenterView(panelRect);
|
|
|
|
ImGui::TextUnformatted("Panel Rect:");
|
|
ImGui::BeginColumns("panelrect", 2, ImGuiOldColumnFlags_NoBorder);
|
|
ImGui::SetColumnWidth(0, ImGui::CalcTextSize("\t\tL: 0000.00\t").x);
|
|
ImGui::Text("\tL: %.2f", panelRect.Min.x); ImGui::NextColumn();
|
|
ImGui::Text("\tT: %.2f", panelRect.Min.y); ImGui::NextColumn();
|
|
ImGui::Text("\tR: %.2f", panelRect.Max.x); ImGui::NextColumn();
|
|
ImGui::Text("\tB: %.2f", panelRect.Max.y); ImGui::NextColumn();
|
|
ImGui::Text("\tW: %.2f", panelRect.GetWidth()); ImGui::NextColumn();
|
|
ImGui::Text("\tH: %.2f", panelRect.GetHeight()); ImGui::NextColumn();
|
|
ImGui::EndColumns();
|
|
|
|
ImGui::EndChild();
|
|
|
|
ImGui::SameLine(0.0f, s_SplitterSize);
|
|
|
|
|
|
if (canvas.Begin("##mycanvas", ImVec2(s_RightPaneSize, 0.0f)))
|
|
{
|
|
//auto drawList = ImGui::GetWindowDrawList();
|
|
|
|
if ((isDragging || ImGui::IsItemHovered()) && ImGui::IsMouseDragging(1, 0.0f))
|
|
{
|
|
if (!isDragging)
|
|
{
|
|
isDragging = true;
|
|
drawStartPoint = viewOrigin;
|
|
}
|
|
|
|
canvas.SetView(drawStartPoint + ImGui::GetMouseDragDelta(1, 0.0f) * viewScale, viewScale);
|
|
}
|
|
else if (isDragging)
|
|
isDragging = false;
|
|
|
|
viewRect = canvas.ViewRect();
|
|
|
|
if (viewRect.Max.x > 0.0f)
|
|
DrawScale(ImVec2(0.0f, 0.0f), ImVec2(viewRect.Max.x, 0.0f), 100.0f, 10.0f, 0.6f);
|
|
if (viewRect.Min.x < 0.0f)
|
|
DrawScale(ImVec2(0.0f, 0.0f), ImVec2(viewRect.Min.x, 0.0f), 100.0f, 10.0f, 0.6f, -1.0f);
|
|
if (viewRect.Max.y > 0.0f)
|
|
DrawScale(ImVec2(0.0f, 0.0f), ImVec2(0.0f, viewRect.Max.y), 100.0f, 10.0f, 0.6f);
|
|
if (viewRect.Min.y < 0.0f)
|
|
DrawScale(ImVec2(0.0f, 0.0f), ImVec2(0.0f, viewRect.Min.y), 100.0f, 10.0f, 0.6f, -1.0f);
|
|
|
|
ImGui::Text("Hovered: %d", ImGui::IsItemHovered() ? 1 : 0);
|
|
|
|
ImGui::TextUnformatted("Hello World!");
|
|
|
|
ImGui::Bullet();
|
|
|
|
ImGui::Button("Panel", ImVec2(s_RightPaneSize * 0.75f, availableRegion.y * 0.5f) * 0.5f);
|
|
panelRect.Min = ImGui::GetItemRectMin();
|
|
panelRect.Max = ImGui::GetItemRectMax();
|
|
|
|
canvas.End();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//ed::SetCurrentEditor(g_Context);
|
|
//ed::Begin("My Editor", ImVec2(0.0, 0.0f));
|
|
//int uniqueId = 1;
|
|
//// Start drawing nodes.
|
|
//ed::BeginNode(uniqueId++);
|
|
// ImGui::Text("Node A");
|
|
// ed::BeginPin(uniqueId++, ed::PinKind::Input);
|
|
// ImGui::Text("-> In");
|
|
// ed::EndPin();
|
|
// ImGui::SameLine();
|
|
// ed::BeginPin(uniqueId++, ed::PinKind::Output);
|
|
// ImGui::Text("Out ->");
|
|
// ed::EndPin();
|
|
//ed::EndNode();
|
|
//ed::End();
|
|
//ed::SetCurrentEditor(nullptr);
|
|
|
|
//ImGui::ShowMetricsWindow();
|
|
}
|
|
};
|
|
|
|
int Main(int argc, char** argv)
|
|
{
|
|
Example exampe("Canvas", argc, argv);
|
|
|
|
if (exampe.Create())
|
|
return exampe.Run();
|
|
|
|
return 0;
|
|
} |