ImGuiLayer.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright 2017 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef ImGuiLayer_DEFINED
  8. #define ImGuiLayer_DEFINED
  9. #include "include/core/SkPaint.h"
  10. #include "include/private/SkTArray.h"
  11. #include "tools/sk_app/Window.h"
  12. #include "imgui.h"
  13. namespace ImGui {
  14. // Helper object for drawing in a widget region, with draggable points
  15. struct DragCanvas {
  16. DragCanvas(const void* id, SkPoint tl = { 0.0f, 0.0f }, SkPoint br = { 1.0f, 1.0f },
  17. float aspect = -1.0f)
  18. : fID(0), fDragging(false) {
  19. ImGui::PushID(id);
  20. fDrawList = ImGui::GetWindowDrawList();
  21. // Logical size
  22. SkScalar w = SkTAbs(br.fX - tl.fX),
  23. h = SkTAbs(br.fY - tl.fY);
  24. // Determine aspect ratio automatically by default
  25. if (aspect < 0) {
  26. aspect = h / w;
  27. }
  28. float availWidth = SkTMax(ImGui::GetContentRegionAvailWidth(), 1.0f);
  29. fPos = ImGui::GetCursorScreenPos();
  30. fSize = ImVec2(availWidth, availWidth * aspect);
  31. SkPoint local[4] = {
  32. { tl.fX, tl.fY },
  33. { br.fX, tl.fY },
  34. { tl.fX, br.fY },
  35. { br.fX, br.fY },
  36. };
  37. SkPoint screen[4] = {
  38. { fPos.x , fPos.y },
  39. { fPos.x + fSize.x, fPos.y },
  40. { fPos.x , fPos.y + fSize.y },
  41. { fPos.x + fSize.x, fPos.y + fSize.y },
  42. };
  43. fLocalToScreen.setPolyToPoly(local, screen, 4);
  44. fScreenToLocal.setPolyToPoly(screen, local, 4);
  45. }
  46. ~DragCanvas() {
  47. ImGui::SetCursorScreenPos(ImVec2(fPos.x, fPos.y + fSize.y));
  48. ImGui::Spacing();
  49. ImGui::PopID();
  50. }
  51. void fillColor(ImU32 color) {
  52. fDrawList->AddRectFilled(fPos, ImVec2(fPos.x + fSize.x, fPos.y + fSize.y), color);
  53. }
  54. void dragPoint(SkPoint* p, bool tooltip = false, ImU32 color = 0xFFFFFFFF) {
  55. // Transform points from logical coordinates to screen coordinates
  56. SkPoint center = fLocalToScreen.mapXY(p->fX, p->fY);
  57. // Invisible 10x10 button
  58. ImGui::PushID(fID++);
  59. ImGui::SetCursorScreenPos(ImVec2(center.fX - 5, center.fY - 5));
  60. ImGui::InvisibleButton("", ImVec2(10, 10));
  61. if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) {
  62. // Update screen position to track mouse, clamped to our area
  63. ImGuiIO& io = ImGui::GetIO();
  64. center.set(SkTPin(io.MousePos.x, fPos.x, fPos.x + fSize.x),
  65. SkTPin(io.MousePos.y, fPos.y, fPos.y + fSize.y));
  66. // Update local coordinates for the caller
  67. *p = fScreenToLocal.mapXY(center.fX, center.fY);
  68. fDragging = true;
  69. }
  70. if (tooltip && ImGui::IsItemHovered()) {
  71. ImGui::SetTooltip("x: %.3f\ny: %.3f", p->fX, p->fY);
  72. }
  73. ImGui::PopID();
  74. fScreenPoints.push_back(ImVec2(center.fX, center.fY));
  75. fDrawList->AddCircle(fScreenPoints.back(), 5.0f, color);
  76. }
  77. ImDrawList* fDrawList;
  78. // Location and dimensions (in screen coordinates)
  79. ImVec2 fPos;
  80. ImVec2 fSize;
  81. // Screen coordinates of points (for additional user drawing)
  82. SkSTArray<4, ImVec2, true> fScreenPoints;
  83. // To simplify dragPoint
  84. SkMatrix fLocalToScreen;
  85. SkMatrix fScreenToLocal;
  86. int fID;
  87. bool fDragging;
  88. };
  89. }
  90. class ImGuiLayer : public sk_app::Window::Layer {
  91. public:
  92. ImGuiLayer();
  93. ~ImGuiLayer() override;
  94. typedef std::function<void(SkCanvas*)> SkiaWidgetFunc;
  95. void skiaWidget(const ImVec2& size, SkiaWidgetFunc func);
  96. void onAttach(sk_app::Window* window) override;
  97. void onPrePaint() override;
  98. void onPaint(SkSurface*) override;
  99. bool onMouse(int x, int y, InputState state, ModifierKey modifiers) override;
  100. bool onMouseWheel(float delta, ModifierKey modifiers) override;
  101. bool onKey(sk_app::Window::Key key, InputState state, ModifierKey modifiers) override;
  102. bool onChar(SkUnichar c, ModifierKey modifiers) override;
  103. private:
  104. sk_app::Window* fWindow;
  105. SkPaint fFontPaint;
  106. SkTArray<SkiaWidgetFunc> fSkiaWidgetFuncs;
  107. };
  108. #endif