From 4be3053ecb1dd54614e49d0ac7077c70d90c9bef Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 24 Feb 2022 17:09:21 -0800 Subject: [PATCH] Add immediate mode manipulator widget macros for the playground (#28) --- impeller/playground/BUILD.gn | 2 + impeller/playground/widgets.cc | 11 +++++ impeller/playground/widgets.h | 75 ++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 impeller/playground/widgets.cc create mode 100644 impeller/playground/widgets.h diff --git a/impeller/playground/BUILD.gn b/impeller/playground/BUILD.gn index b01803ed86281..5f9618e98db35 100644 --- a/impeller/playground/BUILD.gn +++ b/impeller/playground/BUILD.gn @@ -11,6 +11,8 @@ impeller_component("playground") { sources = [ "playground.h", "playground.mm", + "widgets.cc", + "widgets.h", ] public_deps = [ diff --git a/impeller/playground/widgets.cc b/impeller/playground/widgets.cc new file mode 100644 index 0000000000000..ed3f76c380098 --- /dev/null +++ b/impeller/playground/widgets.cc @@ -0,0 +1,11 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "widgets.h" + +namespace impeller { + +// + +} // namespace impeller diff --git a/impeller/playground/widgets.h b/impeller/playground/widgets.h new file mode 100644 index 0000000000000..819d47ff2c64c --- /dev/null +++ b/impeller/playground/widgets.h @@ -0,0 +1,75 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include + +#include "impeller/base/strings.h" +#include "impeller/geometry/color.h" +#include "impeller/geometry/point.h" +#include "third_party/imgui/imgui.h" + +#define IMPELLER_PLAYGROUND_POINT(default_position, radius, color) \ + ({ \ + static impeller::Point position = default_position; \ + static impeller::Point reset_position = default_position; \ + float radius_ = radius; \ + impeller::Color color_ = color; \ + \ + static bool dragging = false; \ + impeller::Point mouse_pos(ImGui::GetMousePos().x, ImGui::GetMousePos().y); \ + static impeller::Point prev_mouse_pos = mouse_pos; \ + \ + if (ImGui::IsKeyPressed('R')) { \ + position = reset_position; \ + dragging = false; \ + } \ + \ + bool hovering = position.GetDistance(mouse_pos) < radius_ && \ + position.GetDistance(prev_mouse_pos) < radius_; \ + if (!ImGui::IsMouseDown(0)) { \ + dragging = false; \ + } else if (hovering && ImGui::IsMouseClicked(0)) { \ + dragging = true; \ + } \ + if (dragging) { \ + position += mouse_pos - prev_mouse_pos; \ + } \ + ImGui::GetBackgroundDrawList()->AddCircleFilled( \ + {position.x, position.y}, radius_, \ + ImColor(color_.red, color_.green, color_.blue, \ + (hovering || dragging) ? 0.6f : 0.3f)); \ + if (hovering || dragging) { \ + ImGui::GetBackgroundDrawList()->AddText( \ + {position.x - radius_, position.y + radius_ + 10}, \ + ImColor(color_.red, color.green, color.blue, 1.0f), \ + impeller::SPrintF("x:%0.3f y:%0.3f", position.x, position.y) \ + .c_str()); \ + } \ + prev_mouse_pos = mouse_pos; \ + position; \ + }) + +#define IMPELLER_PLAYGROUND_LINE(default_position_a, default_position_b, \ + radius, color_a, color_b) \ + ({ \ + impeller::Point position_a = default_position_a; \ + impeller::Point position_b = default_position_b; \ + float r_ = radius; \ + impeller::Color color_a_ = color_a; \ + impeller::Color color_b_ = color_b; \ + \ + position_a = IMPELLER_PLAYGROUND_POINT(position_a, r_, color_a_); \ + position_b = IMPELLER_PLAYGROUND_POINT(position_b, r_, color_b_); \ + \ + auto dir = (position_b - position_a).Normalize() * r_; \ + auto line_a = position_a + dir; \ + auto line_b = position_b - dir; \ + ImGui::GetBackgroundDrawList()->AddLine( \ + {line_a.x, line_a.y}, {line_b.x, line_b.y}, \ + ImColor(color_b.red, color_b.green, color_b.blue, 0.3f)); \ + \ + std::make_tuple(position_a, position_b); \ + })