aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ui.cpp90
1 files changed, 64 insertions, 26 deletions
diff --git a/src/ui.cpp b/src/ui.cpp
index aa72ac9..8e4e275 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -18,34 +18,76 @@ struct ImRect {
ImVec2 bottom_right;
};
-struct SandboxCfg {
- int width = 40, height = 100;
- float tile_size = 4.0f;
+/// Helpers for displaying and coordinate space tracking of the sandbox image display.
+struct SandboxDisplay {
+ float tile_size;
+ int sandbox_width = 40;
+ int sandbox_height = 100;
- ImVec2 tr_sandbox2screen(ImVec2 origin, Pt pt) const {
+ ImVec2 size_screenspace;
+ ImVec2 origin;
+
+ SandboxDisplay(float tile_size, const Sandbox& sb)
+ : tile_size(tile_size)
+ , sandbox_width{ sb.width }
+ , sandbox_height{ sb.height }
+ , size_screenspace(sandbox_width * tile_size, sandbox_height * tile_size) {}
+
+ ImVec2 tr_sandbox2screen(Pt pt) const {
return ImVec2(origin.x + tile_size * pt.x, origin.y - tile_size * pt.y);
}
// Assuming inclusive-inclusive rectangle
- ImRect tr_sandbox2screen(ImVec2 origin, Rect r) const {
+ ImRect tr_sandbox2screen(Rect r) const {
return {
ImVec2(origin.x + tile_size * r.bl.x, origin.y - tile_size * (r.tr.y + 1)),
ImVec2(origin.x + tile_size * (r.tr.x + 1), origin.y - tile_size * r.bl.y),
};
}
- std::unique_ptr<Sandbox> make_sandbox() const {
- return std::make_unique<Sandbox>(width, height);
+ void show_image(ImTextureID texid) {
+ auto img_topleft = ImGui::GetCursorScreenPos();
+ ImGui::Image(texid, size_screenspace, ImVec2(0, 1), ImVec2(1, 0));
+ // bottom-left corner of the sandbox, in screen space
+ origin = img_topleft;
+ origin.y += size_screenspace.y;
}
};
void ShowEverything() {
- ImGui::Begin("Sandbox");
+ ImGui::Begin("Options");
- static SandboxCfg cfg;
- static std::unique_ptr<Sandbox> sandbox = cfg.make_sandbox();
+ static float tile_size = 4.0f;
+ static std::unique_ptr<Sandbox> sandbox = std::make_unique<Sandbox>(40, 100);
static OglImage gl;
+ ImGui::InputFloat("Tile size", &tile_size);
+
+ {
+ constexpr auto kModify = "Modify sandbox parameters";
+ static int new_width, new_height;
+
+ ImGui::Text("size = (%d, %d)", sandbox->width, sandbox->height);
+ if (ImGui::Button("Modify")) {
+ ImGui::OpenPopup(kModify);
+ new_width = sandbox->width;
+ new_height = sandbox->height;
+ }
+ if (ImGui::BeginPopup(kModify)) {
+ ImGui::InputInt("Sandbox width", &new_width);
+ ImGui::InputInt("Sandbox height", &new_height);
+ if (ImGui::Button("Confirm")) {
+ sandbox = std::make_unique<Sandbox>(new_width, new_height);
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("Cancel")) {
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::EndPopup();
+ }
+ }
+
static bool running = false;
ImGui::Checkbox("Run", &running);
static bool show_dirty_rect = true;
@@ -59,32 +101,28 @@ void ShowEverything() {
sandbox->simulate_step();
}
- // TODO popup for changing these params?
- // TODO migrate existing content
- ImGui::InputInt("Sandbox width", &cfg.width);
- ImGui::InputInt("Sandbox height", &cfg.height);
- if (ImGui::Button("Recreate")) {
- sandbox = cfg.make_sandbox();
- }
- ImGui::SameLine();
if (ImGui::Button("Add sand")) {
AddSand(*sandbox);
}
- ImVec2 img_size(cfg.tile_size * sandbox->width, cfg.tile_size * sandbox->height);
- auto img_topleft = ImGui::GetCursorScreenPos();
+ ImGui::End();
+
+ ImGui::Begin("Sandbox");
+ // Update texture to the current state of the the sandbox.
+ // Do this every frame, because it's easier than trying to track when did the sandbox change, which may be caused by:
+ // - Initialization
+ // - Simulation step
+ // - User interaction (painting, save/load, etc.)
gl.upload(reinterpret_cast<const char*>(sandbox->bitmap), sandbox->width, sandbox->height);
- ImGui::Image(gl.as_imgui(), img_size, ImVec2(0, 1), ImVec2(1, 0));
- // bottom-left corner of the sandbox, in screen space
- auto origin = img_topleft;
- origin.y += img_size.y;
+
+ SandboxDisplay dis(tile_size, *sandbox);
+ dis.show_image(gl.as_imgui());
if (show_dirty_rect) {
auto dl = ImGui::GetWindowDrawList();
- auto [top_left, bottom_right] = cfg.tr_sandbox2screen(origin, sandbox->dirty_writeto);
+ auto [top_left, bottom_right] = dis.tr_sandbox2screen(sandbox->dirty_writeto);
dl->AddRect(top_left, bottom_right, IM_COL32(255, 0, 0, 255));
}
-
ImGui::End();
ImGui::ShowDemoWindow();