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

[Example] Add example of Canva Editor #126

Merged
merged 4 commits into from
May 5, 2022
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
144 changes: 144 additions & 0 deletions example/src/main/java/ExampleCanvasEditor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import imgui.*;
import imgui.flag.ImGuiButtonFlags;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiMouseButton;
import imgui.flag.ImGuiPopupFlags;
import imgui.type.ImBoolean;

import java.util.ArrayList;
import java.util.List;

public class ExampleCanvasEditor {
private static final List<ImVec2> pointList = new ArrayList<>();
private static final ImVec2 scrolling = new ImVec2();

private static boolean addingLine = false;
public static float thickness = 2.0f;

/**
* Computes the floating-point remainder of a / b.
*
* @param a float
* @param b float
* @return computed floating-point remainder of a / b
*/
private static float fmodf(float a, float b) {
int result = (int) Math.floor(a / b);
return a - result * b;
}

public static void show(final ImBoolean showCanvaWindow) {
ImGui.setNextWindowSize(700, 400, ImGuiCond.Once);
ImGui.setNextWindowPos(ImGui.getMainViewport().getPosX() + 200, ImGui.getMainViewport().getPosY() + 200, ImGuiCond.Once);

if (ImGui.begin("Canvas Demo Window", showCanvaWindow)) {
ImGui.text("This a demo for ImGui Canvas editor");
ImGui.sameLine();
ImGui.text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu.");

// Typically, you would use a BeginChild()/EndChild() pair to benefit from a clipping region + own scrolling.
// Here we demonstrate that this can be replaced by simple offsetting + custom drawing + PushClipRect/PopClipRect() calls.
// To use a child window instead we could use, e.g:
// ImGui.pushStyleVar(ImGuiStyleVar.WindowPadding, 0, 0); // Disable padding
// ImGui.pushStyleColor(ImGuiCol.ChildBg, ImColor.intToColor(50, 50, 50, 255)); // Set a background color
// ImGui.beginChild("canvas", new ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags.NoMove);
// ImGui.popStyleColor();
// ImGui.popStyleVar();
// [...]
// ImGui.endChild();

// Using InvisibleButton() as a convenience 1) it will advance the layout cursor and 2) allows us to use IsItemHovered()/IsItemActive()
ImVec2 canvasP0 = ImGui.getCursorScreenPos(); // ImDrawList API uses screen coordinates!
ImVec2 canvasSize = ImGui.getContentRegionAvail(); // Resize canvas to what's available

if (canvasSize.x < 50.0f) {
canvasSize.x = 50.0f;
}

if (canvasSize.y < 50.0f) {
canvasSize.y = 50.0f;
}

ImVec2 canvasP1 = new ImVec2(canvasP0.x + canvasSize.x, canvasP0.y + canvasSize.y);

// Draw border and background color
ImGuiIO io = ImGui.getIO();
ImDrawList drawList = ImGui.getWindowDrawList();
drawList.addRectFilled(canvasP0.x, canvasP0.y, canvasP1.x, canvasP1.y,
ImColor.intToColor(50, 50, 50, 255));
drawList.addRect(canvasP0.x, canvasP0.y, canvasP1.x, canvasP1.y,
ImColor.intToColor(255, 255, 255, 255));

// This will catch our interactions
ImGui.invisibleButton("canvas", canvasSize.x, canvasSize.y,
ImGuiButtonFlags.MouseButtonLeft | ImGuiButtonFlags.MouseButtonRight);

boolean isHovered = ImGui.isItemHovered(); // Hovered
boolean isActive = ImGui.isItemActive(); // Held

ImVec2 origin = new ImVec2(canvasP0.x + scrolling.x, canvasP0.y + scrolling.y); // Lock scrolled origin

ImVec2 mousePosInCanvas = new ImVec2(io.getMousePos().x - origin.x, io.getMousePos().y - origin.y);

// Add first and second point
if (isHovered && !addingLine && ImGui.isMouseClicked(ImGuiMouseButton.Left)) {
pointList.add(mousePosInCanvas);
pointList.add(mousePosInCanvas);
addingLine = true;
}
if (addingLine) {
pointList.set(pointList.size() - 1, mousePosInCanvas);
if (!ImGui.isMouseDown(ImGuiMouseButton.Left)) {
addingLine = false;
}
}

// Pan (we use a zero mouse threshold when there's no context menu)
// You may decide to make that threshold dynamic based on whether the mouse is hovering something etc.
float mouseThresholdForPan = -1.0f;
if (isActive && ImGui.isMouseDragging(ImGuiMouseButton.Right, mouseThresholdForPan)) {
scrolling.x += io.getMouseDelta().x;
scrolling.y += io.getMouseDelta().y;
}

// Context menu (under default mouse threshold)
ImVec2 dragDelta = ImGui.getMouseDragDelta(ImGuiMouseButton.Right);
if (dragDelta.x == 0.0f && dragDelta.y == 0.0f) {
ImGui.openPopupOnItemClick("context", ImGuiPopupFlags.MouseButtonRight);
}

// Draw grid + all lines in the canvas
drawList.pushClipRect(canvasP0.x, canvasP0.y, canvasP1.x, canvasP1.y, false);
float GRID_STEP = 64.0f;
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvasSize.x; x += GRID_STEP) {
drawList.addLine(canvasP0.x + x, canvasP0.y, canvasP0.x + x, canvasP1.y,
ImColor.intToColor(200, 200, 200, 40));
}
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvasSize.y; y += GRID_STEP) {
drawList.addLine(canvasP0.x, canvasP0.y + y, canvasP1.x, canvasP0.y + y,
ImColor.intToColor(200, 200, 200, 40));
}
for (int n = 0; n < pointList.size(); n += 2) {
drawList.addLine(origin.x + pointList.get(n).x, origin.y + pointList.get(n).y,
origin.x + pointList.get(n + 1).x, origin.y + pointList.get(n + 1).y,
ImColor.intToColor(255, 255, 0, 255), thickness);
}
drawList.popClipRect();

// Menu properties
if (ImGui.beginPopup("context")) {
addingLine = false;
if (ImGui.menuItem("Remove one", "", false, pointList.size() > 0)) {
pointList.remove(pointList.size() - 1);
pointList.remove(pointList.size() - 1);
}
if (ImGui.menuItem("Remove all", "", false, pointList.size() > 0)) {
pointList.clear();
}
ImGui.endPopup();
}
}

ImGui.end();
}
}
6 changes: 6 additions & 0 deletions example/src/main/java/Extra.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class Extra {
private static final ImBoolean SHOW_IMGUI_COLOR_TEXT_EDIT_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMGUI_FILE_DIALOG_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMGUI_MEMORY_EDITOR_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMGUI_CANVAS_EDITOR_WINDOW = new ImBoolean(false);

private static final Graph GRAPH = new Graph();

Expand All @@ -26,6 +27,7 @@ public static void show(final Application app) {
ImGui.checkbox("Show ImGuiColorTextEdit Demo Window", SHOW_IMGUI_COLOR_TEXT_EDIT_WINDOW);
ImGui.checkbox("Show ImGuiFileDialog Demo Window", SHOW_IMGUI_FILE_DIALOG_WINDOW);
ImGui.checkbox("Show ImGui MemoryEditor Demo Window", SHOW_IMGUI_MEMORY_EDITOR_WINDOW);
ImGui.checkbox("Show ImGui Canvas Demo Window", SHOW_IMGUI_CANVAS_EDITOR_WINDOW);

if (SHOW_DEMO_WINDOW.get()) {
ImGui.showDemoWindow(SHOW_DEMO_WINDOW);
Expand Down Expand Up @@ -62,5 +64,9 @@ public static void show(final Application app) {
if (SHOW_IMGUI_MEMORY_EDITOR_WINDOW.get()) {
ExampleImGuiMemoryEditor.show(SHOW_IMGUI_MEMORY_EDITOR_WINDOW);
}

if (SHOW_IMGUI_CANVAS_EDITOR_WINDOW.get()) {
ExampleCanvasEditor.show(SHOW_IMGUI_CANVAS_EDITOR_WINDOW);
}
}
}
26 changes: 15 additions & 11 deletions example/src/main/java/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import imgui.app.Configuration;
import imgui.flag.ImGuiConfigFlags;
import imgui.flag.ImGuiInputTextFlags;
import imgui.flag.ImGuiWindowFlags;
import imgui.type.ImString;

import java.io.IOException;
Expand Down Expand Up @@ -70,18 +71,21 @@ private void initFonts(final ImGuiIO io) {

@Override
public void process() {
ImGui.text("Hello, World! " + FontAwesomeIcons.Smile);
if (ImGui.button(FontAwesomeIcons.Save + " Save")) {
count++;
if (ImGui.begin("Demo", ImGuiWindowFlags.AlwaysAutoResize)) {
ImGui.text("Hello, World! " + FontAwesomeIcons.Smile);
if (ImGui.button(FontAwesomeIcons.Save + " Save")) {
count++;
}
ImGui.sameLine();
ImGui.text(String.valueOf(count));
ImGui.inputText("string", str, ImGuiInputTextFlags.CallbackResize);
ImGui.text("Result: " + str.get());
ImGui.sliderFloat("float", flt, 0, 1);
ImGui.separator();
ImGui.text("Extra");
Extra.show(this);
}
ImGui.sameLine();
ImGui.text(String.valueOf(count));
ImGui.inputText("string", str, ImGuiInputTextFlags.CallbackResize);
ImGui.text("Result: " + str.get());
ImGui.sliderFloat("float", flt, 0, 1);
ImGui.separator();
ImGui.text("Extra");
Extra.show(this);
ImGui.end();
}

private static byte[] loadFromResources(String name) {
Expand Down