aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-12-08 16:46:09 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-12-11 17:37:58 +0000
commitd67e5189802e89e74217244b36cc7263883d5dba (patch)
tree89870d274c56c96dda04329f73538011c762a3d6
parent2326177e3499d96e1e5df68504cc98764d80209a (diff)
Move ImGui support code to ImGuiLayer
Viewer still has plenty of code that uses ImGui to create application specific UI, but the structural code that forwards input to ImGui, and converts per-frame ImGui rendering data to Skia draw commands is now in a single component that can be reused in any sk_app-based application. Bug: skia: Change-Id: Ic14ece659d4af8ee13b69c638bdaf7df6c24f5c0 Reviewed-on: https://skia-review.googlesource.com/82627 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com>
-rw-r--r--BUILD.gn1
-rw-r--r--tools/sk_app/Window.cpp3
-rw-r--r--tools/sk_app/Window.h3
-rw-r--r--tools/viewer/ImGuiLayer.cpp188
-rw-r--r--tools/viewer/ImGuiLayer.h37
-rw-r--r--tools/viewer/Viewer.cpp205
-rw-r--r--tools/viewer/Viewer.h6
7 files changed, 260 insertions, 183 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 5bc5376242..d838ccdc06 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1802,6 +1802,7 @@ if (skia_enable_tools) {
}
sources = [
"tools/viewer/GMSlide.cpp",
+ "tools/viewer/ImGuiLayer.cpp",
"tools/viewer/ImageSlide.cpp",
"tools/viewer/SKPSlide.cpp",
"tools/viewer/SampleSlide.cpp",
diff --git a/tools/sk_app/Window.cpp b/tools/sk_app/Window.cpp
index 436b6b9aa9..6713c4c2c9 100644
--- a/tools/sk_app/Window.cpp
+++ b/tools/sk_app/Window.cpp
@@ -88,6 +88,9 @@ void Window::onPaint() {
SkCanvas* canvas = backbuffer->getCanvas();
for (int i = 0; i < fLayers.count(); ++i) {
+ fLayers[i]->onPrePaint();
+ }
+ for (int i = 0; i < fLayers.count(); ++i) {
fLayers[i]->onPaint(canvas);
}
diff --git a/tools/sk_app/Window.h b/tools/sk_app/Window.h
index 77478b598e..b541e241a2 100644
--- a/tools/sk_app/Window.h
+++ b/tools/sk_app/Window.h
@@ -136,16 +136,19 @@ public:
// return value of 'true' means 'I have handled this event'
virtual void onBackendCreated() {}
+ virtual void onAttach(Window* window) {}
virtual bool onChar(SkUnichar c, uint32_t modifiers) { return false; }
virtual bool onKey(Key key, InputState state, uint32_t modifiers) { return false; }
virtual bool onMouse(int x, int y, InputState state, uint32_t modifiers) { return false; }
virtual bool onMouseWheel(float delta, uint32_t modifiers) { return false; }
virtual bool onTouch(intptr_t owner, InputState state, float x, float y) { return false; }
virtual void onUIStateChanged(const SkString& stateName, const SkString& stateValue) {}
+ virtual void onPrePaint() {}
virtual void onPaint(SkCanvas*) {}
};
void pushLayer(Layer* layer) {
+ layer->onAttach(this);
fLayers.push(layer);
}
diff --git a/tools/viewer/ImGuiLayer.cpp b/tools/viewer/ImGuiLayer.cpp
new file mode 100644
index 0000000000..e55ac9c9c6
--- /dev/null
+++ b/tools/viewer/ImGuiLayer.cpp
@@ -0,0 +1,188 @@
+/*
+* Copyright 2017 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "ImGuiLayer.h"
+
+#include "SkCanvas.h"
+#include "SkImage.h"
+#include "SkPixmap.h"
+#include "SkSwizzle.h"
+#include "SkVertices.h"
+
+#include "imgui.h"
+
+#include <stdlib.h>
+#include <map>
+
+using namespace sk_app;
+
+ImGuiLayer::ImGuiLayer() {
+ // ImGui initialization:
+ ImGuiIO& io = ImGui::GetIO();
+
+ // Keymap...
+ io.KeyMap[ImGuiKey_Tab] = (int)Window::Key::kTab;
+ io.KeyMap[ImGuiKey_LeftArrow] = (int)Window::Key::kLeft;
+ io.KeyMap[ImGuiKey_RightArrow] = (int)Window::Key::kRight;
+ io.KeyMap[ImGuiKey_UpArrow] = (int)Window::Key::kUp;
+ io.KeyMap[ImGuiKey_DownArrow] = (int)Window::Key::kDown;
+ io.KeyMap[ImGuiKey_PageUp] = (int)Window::Key::kPageUp;
+ io.KeyMap[ImGuiKey_PageDown] = (int)Window::Key::kPageDown;
+ io.KeyMap[ImGuiKey_Home] = (int)Window::Key::kHome;
+ io.KeyMap[ImGuiKey_End] = (int)Window::Key::kEnd;
+ io.KeyMap[ImGuiKey_Delete] = (int)Window::Key::kDelete;
+ io.KeyMap[ImGuiKey_Backspace] = (int)Window::Key::kBack;
+ io.KeyMap[ImGuiKey_Enter] = (int)Window::Key::kOK;
+ io.KeyMap[ImGuiKey_Escape] = (int)Window::Key::kEscape;
+ io.KeyMap[ImGuiKey_A] = (int)Window::Key::kA;
+ io.KeyMap[ImGuiKey_C] = (int)Window::Key::kC;
+ io.KeyMap[ImGuiKey_V] = (int)Window::Key::kV;
+ io.KeyMap[ImGuiKey_X] = (int)Window::Key::kX;
+ io.KeyMap[ImGuiKey_Y] = (int)Window::Key::kY;
+ io.KeyMap[ImGuiKey_Z] = (int)Window::Key::kZ;
+
+ int w, h;
+ unsigned char* pixels;
+ io.Fonts->GetTexDataAsAlpha8(&pixels, &w, &h);
+ SkImageInfo info = SkImageInfo::MakeA8(w, h);
+ SkPixmap pmap(info, pixels, info.minRowBytes());
+ SkMatrix localMatrix = SkMatrix::MakeScale(1.0f / w, 1.0f / h);
+ auto fontImage = SkImage::MakeFromRaster(pmap, nullptr, nullptr);
+ auto fontShader = fontImage->makeShader(&localMatrix);
+ fFontPaint.setShader(fontShader);
+ fFontPaint.setColor(SK_ColorWHITE);
+ fFontPaint.setFilterQuality(kLow_SkFilterQuality);
+ io.Fonts->TexID = &fFontPaint;
+}
+
+void ImGuiLayer::onAttach(Window* window) {
+ fWindow = window;
+}
+
+bool ImGuiLayer::onMouse(int x, int y, Window::InputState state, uint32_t modifiers) {
+ ImGuiIO& io = ImGui::GetIO();
+ io.MousePos.x = static_cast<float>(x);
+ io.MousePos.y = static_cast<float>(y);
+ if (Window::kDown_InputState == state) {
+ io.MouseDown[0] = true;
+ } else if (Window::kUp_InputState == state) {
+ io.MouseDown[0] = false;
+ }
+ return io.WantCaptureMouse;
+}
+
+bool ImGuiLayer::onMouseWheel(float delta, uint32_t modifiers) {
+ ImGuiIO& io = ImGui::GetIO();
+ io.MouseWheel += delta;
+ return true;
+}
+
+void ImGuiLayer::skiaWidget(const ImVec2& size, SkiaWidgetFunc func) {
+ intptr_t funcIndex = fSkiaWidgetFuncs.count();
+ fSkiaWidgetFuncs.push_back(func);
+ ImGui::Image((ImTextureID)funcIndex, size);
+}
+
+void ImGuiLayer::onPrePaint() {
+ // Update ImGui input
+ ImGuiIO& io = ImGui::GetIO();
+ io.DeltaTime = 1.0f / 60.0f;
+ io.DisplaySize.x = static_cast<float>(fWindow->width());
+ io.DisplaySize.y = static_cast<float>(fWindow->height());
+
+ io.KeyAlt = io.KeysDown[static_cast<int>(Window::Key::kOption)];
+ io.KeyCtrl = io.KeysDown[static_cast<int>(Window::Key::kCtrl)];
+ io.KeyShift = io.KeysDown[static_cast<int>(Window::Key::kShift)];
+
+ ImGui::NewFrame();
+}
+
+void ImGuiLayer::onPaint(SkCanvas* canvas) {
+ // This causes ImGui to rebuild vertex/index data based on all immediate-mode commands
+ // (widgets, etc...) that have been issued
+ ImGui::Render();
+
+ // Then we fetch the most recent data, and convert it so we can render with Skia
+ const ImDrawData* drawData = ImGui::GetDrawData();
+ SkTDArray<SkPoint> pos;
+ SkTDArray<SkPoint> uv;
+ SkTDArray<SkColor> color;
+
+ for (int i = 0; i < drawData->CmdListsCount; ++i) {
+ const ImDrawList* drawList = drawData->CmdLists[i];
+
+ // De-interleave all vertex data (sigh), convert to Skia types
+ pos.rewind(); uv.rewind(); color.rewind();
+ for (int i = 0; i < drawList->VtxBuffer.size(); ++i) {
+ const ImDrawVert& vert = drawList->VtxBuffer[i];
+ pos.push(SkPoint::Make(vert.pos.x, vert.pos.y));
+ uv.push(SkPoint::Make(vert.uv.x, vert.uv.y));
+ color.push(vert.col);
+ }
+ // ImGui colors are RGBA
+ SkSwapRB(color.begin(), color.begin(), color.count());
+
+ int indexOffset = 0;
+
+ // Draw everything with canvas.drawVertices...
+ for (int j = 0; j < drawList->CmdBuffer.size(); ++j) {
+ const ImDrawCmd* drawCmd = &drawList->CmdBuffer[j];
+
+ SkAutoCanvasRestore acr(canvas, true);
+
+ // TODO: Find min/max index for each draw, so we know how many vertices (sigh)
+ if (drawCmd->UserCallback) {
+ drawCmd->UserCallback(drawList, drawCmd);
+ } else {
+ intptr_t idIndex = (intptr_t)drawCmd->TextureId;
+ if (idIndex < fSkiaWidgetFuncs.count()) {
+ // Small image IDs are actually indices into a list of callbacks. We directly
+ // examing the vertex data to deduce the image rectangle, then reconfigure the
+ // canvas to be clipped and translated so that the callback code gets to use
+ // Skia to render a widget in the middle of an ImGui panel.
+ ImDrawIdx rectIndex = drawList->IdxBuffer[indexOffset];
+ SkPoint tl = pos[rectIndex], br = pos[rectIndex + 2];
+ canvas->clipRect(SkRect::MakeLTRB(tl.fX, tl.fY, br.fX, br.fY));
+ canvas->translate(tl.fX, tl.fY);
+ fSkiaWidgetFuncs[idIndex](canvas);
+ } else {
+ SkPaint* paint = static_cast<SkPaint*>(drawCmd->TextureId);
+ SkASSERT(paint);
+
+ canvas->clipRect(SkRect::MakeLTRB(drawCmd->ClipRect.x, drawCmd->ClipRect.y,
+ drawCmd->ClipRect.z, drawCmd->ClipRect.w));
+ auto vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
+ drawList->VtxBuffer.size(),
+ pos.begin(), uv.begin(), color.begin(),
+ drawCmd->ElemCount,
+ drawList->IdxBuffer.begin() + indexOffset);
+ canvas->drawVertices(vertices, SkBlendMode::kModulate, *paint);
+ indexOffset += drawCmd->ElemCount;
+ }
+ }
+ }
+ }
+
+ fSkiaWidgetFuncs.reset();
+}
+
+bool ImGuiLayer::onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers) {
+ ImGuiIO& io = ImGui::GetIO();
+ io.KeysDown[static_cast<int>(key)] = (Window::kDown_InputState == state);
+ return io.WantCaptureKeyboard;
+}
+
+bool ImGuiLayer::onChar(SkUnichar c, uint32_t modifiers) {
+ ImGuiIO& io = ImGui::GetIO();
+ if (io.WantTextInput) {
+ if (c > 0 && c < 0x10000) {
+ io.AddInputCharacter(c);
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/tools/viewer/ImGuiLayer.h b/tools/viewer/ImGuiLayer.h
new file mode 100644
index 0000000000..1cefcd4097
--- /dev/null
+++ b/tools/viewer/ImGuiLayer.h
@@ -0,0 +1,37 @@
+/*
+* Copyright 2017 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef ImGuiLayer_DEFINED
+#define ImGuiLayer_DEFINED
+
+#include "SkPaint.h"
+#include "SkTArray.h"
+#include "sk_app/Window.h"
+#include "imgui.h"
+
+class ImGuiLayer : public sk_app::Window::Layer {
+public:
+ ImGuiLayer();
+
+ typedef std::function<void(SkCanvas*)> SkiaWidgetFunc;
+ void skiaWidget(const ImVec2& size, SkiaWidgetFunc func);
+
+ void onAttach(sk_app::Window* window) override;
+ void onPrePaint() override;
+ void onPaint(SkCanvas* canvas) override;
+ bool onMouse(int x, int y, sk_app::Window::InputState state, uint32_t modifiers) override;
+ bool onMouseWheel(float delta, uint32_t modifiers) override;
+ bool onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers) override;
+ bool onChar(SkUnichar c, uint32_t modifiers) override;
+
+private:
+ sk_app::Window* fWindow;
+ SkPaint fFontPaint;
+ SkTArray<SkiaWidgetFunc> fSkiaWidgetFuncs;
+};
+
+#endif
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index a1b7baac6b..c184eecade 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -251,6 +251,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
// register callbacks
fCommands.attach(fWindow);
fWindow->pushLayer(this);
+ fWindow->pushLayer(&fImGuiLayer);
// add key-bindings
fCommands.addCommand(' ', "GUI", "Toggle Debug GUI", [this]() {
@@ -412,45 +413,6 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
fAnimTimer.run();
- // ImGui initialization:
- ImGuiIO& io = ImGui::GetIO();
- io.DisplaySize.x = static_cast<float>(fWindow->width());
- io.DisplaySize.y = static_cast<float>(fWindow->height());
-
- // Keymap...
- io.KeyMap[ImGuiKey_Tab] = (int)Window::Key::kTab;
- io.KeyMap[ImGuiKey_LeftArrow] = (int)Window::Key::kLeft;
- io.KeyMap[ImGuiKey_RightArrow] = (int)Window::Key::kRight;
- io.KeyMap[ImGuiKey_UpArrow] = (int)Window::Key::kUp;
- io.KeyMap[ImGuiKey_DownArrow] = (int)Window::Key::kDown;
- io.KeyMap[ImGuiKey_PageUp] = (int)Window::Key::kPageUp;
- io.KeyMap[ImGuiKey_PageDown] = (int)Window::Key::kPageDown;
- io.KeyMap[ImGuiKey_Home] = (int)Window::Key::kHome;
- io.KeyMap[ImGuiKey_End] = (int)Window::Key::kEnd;
- io.KeyMap[ImGuiKey_Delete] = (int)Window::Key::kDelete;
- io.KeyMap[ImGuiKey_Backspace] = (int)Window::Key::kBack;
- io.KeyMap[ImGuiKey_Enter] = (int)Window::Key::kOK;
- io.KeyMap[ImGuiKey_Escape] = (int)Window::Key::kEscape;
- io.KeyMap[ImGuiKey_A] = (int)Window::Key::kA;
- io.KeyMap[ImGuiKey_C] = (int)Window::Key::kC;
- io.KeyMap[ImGuiKey_V] = (int)Window::Key::kV;
- io.KeyMap[ImGuiKey_X] = (int)Window::Key::kX;
- io.KeyMap[ImGuiKey_Y] = (int)Window::Key::kY;
- io.KeyMap[ImGuiKey_Z] = (int)Window::Key::kZ;
-
- int w, h;
- unsigned char* pixels;
- io.Fonts->GetTexDataAsAlpha8(&pixels, &w, &h);
- SkImageInfo info = SkImageInfo::MakeA8(w, h);
- SkPixmap pmap(info, pixels, info.minRowBytes());
- SkMatrix localMatrix = SkMatrix::MakeScale(1.0f / w, 1.0f / h);
- auto fontImage = SkImage::MakeFromRaster(pmap, nullptr, nullptr);
- auto fontShader = fontImage->makeShader(&localMatrix);
- fImGuiFontPaint.setShader(fontShader);
- fImGuiFontPaint.setColor(SK_ColorWHITE);
- fImGuiFontPaint.setFilterQuality(kLow_SkFilterQuality);
- io.Fonts->TexID = &fImGuiFontPaint;
-
auto gamutImage = GetResourceAsImage("images/gamut.png");
if (gamutImage) {
fImGuiGamutPaint.setShader(gamutImage->makeShader());
@@ -729,6 +691,8 @@ void Viewer::setBackend(sk_app::Window::BackendType backendType) {
// re-register callbacks
fCommands.attach(fWindow);
fWindow->pushLayer(this);
+ fWindow->pushLayer(&fImGuiLayer);
+
// Don't allow the window to re-attach. If we're in MSAA mode, the params we grabbed above
// will still include our correct sample count. But the re-created fWindow will lose that
// information. On Windows, we need to re-create the window when changing sample count,
@@ -876,18 +840,6 @@ void Viewer::onBackendCreated() {
}
void Viewer::onPaint(SkCanvas* canvas) {
- // Update ImGui input
- ImGuiIO& io = ImGui::GetIO();
- io.DeltaTime = 1.0f / 60.0f;
- io.DisplaySize.x = static_cast<float>(fWindow->width());
- io.DisplaySize.y = static_cast<float>(fWindow->height());
-
- io.KeyAlt = io.KeysDown[static_cast<int>(Window::Key::kOption)];
- io.KeyCtrl = io.KeysDown[static_cast<int>(Window::Key::kCtrl)];
- io.KeyShift = io.KeysDown[static_cast<int>(Window::Key::kShift)];
-
- ImGui::NewFrame();
-
this->drawSlide(canvas);
// Advance our timing bookkeeping
@@ -904,7 +856,7 @@ void Viewer::onPaint(SkCanvas* canvas) {
}
fCommands.drawHelp(canvas);
- this->drawImGui(canvas);
+ this->drawImGui();
// Update the FPS
this->updateUIState();
@@ -935,45 +887,27 @@ bool Viewer::onTouch(intptr_t owner, Window::InputState state, float x, float y)
}
bool Viewer::onMouse(int x, int y, Window::InputState state, uint32_t modifiers) {
- ImGuiIO& io = ImGui::GetIO();
- io.MousePos.x = static_cast<float>(x);
- io.MousePos.y = static_cast<float>(y);
- if (Window::kDown_InputState == state) {
- io.MouseDown[0] = true;
- } else if (Window::kUp_InputState == state) {
- io.MouseDown[0] = false;
- }
- if (io.WantCaptureMouse) {
- return true;
- } else {
- if (!fSlides[fCurrentSlide]->onMouse(x, y, state, modifiers)) {
- if (GestureDevice::kTouch == fGestureDevice) {
- return false;
+ if (!fSlides[fCurrentSlide]->onMouse(x, y, state, modifiers)) {
+ if (GestureDevice::kTouch == fGestureDevice) {
+ return false;
+ }
+ switch (state) {
+ case Window::kUp_InputState: {
+ fGesture.touchEnd(nullptr);
+ break;
}
- switch (state) {
- case Window::kUp_InputState: {
- fGesture.touchEnd(nullptr);
- break;
- }
- case Window::kDown_InputState: {
- fGesture.touchBegin(nullptr, x, y);
- break;
- }
- case Window::kMove_InputState: {
- fGesture.touchMoved(nullptr, x, y);
- break;
- }
+ case Window::kDown_InputState: {
+ fGesture.touchBegin(nullptr, x, y);
+ break;
+ }
+ case Window::kMove_InputState: {
+ fGesture.touchMoved(nullptr, x, y);
+ break;
}
- fGestureDevice = fGesture.isBeingTouched() ? GestureDevice::kMouse : GestureDevice::kNone;
}
- fWindow->inval();
- return true;
+ fGestureDevice = fGesture.isBeingTouched() ? GestureDevice::kMouse : GestureDevice::kNone;
}
-}
-
-bool Viewer::onMouseWheel(float delta, uint32_t modifiers) {
- ImGuiIO& io = ImGui::GetIO();
- io.MouseWheel += delta;
+ fWindow->inval();
return true;
}
@@ -1133,16 +1067,7 @@ static void ImGui_Primaries(SkColorSpacePrimaries* primaries, SkPaint* gamutPain
ImGui::SetCursorPos(endPos);
}
-typedef std::function<void(SkCanvas*)> CustomGuiPainter;
-static SkTArray<CustomGuiPainter> gCustomGuiPainters;
-
-static void ImGui_Skia_Callback(const ImVec2& size, CustomGuiPainter painter) {
- intptr_t painterIndex = gCustomGuiPainters.count();
- gCustomGuiPainters.push_back(painter);
- ImGui::Image((ImTextureID)painterIndex, size);
-}
-
-void Viewer::drawImGui(SkCanvas* canvas) {
+void Viewer::drawImGui() {
// Support drawing the ImGui demo window. Superfluous, but gives a good idea of what's possible
if (fShowImGuiTestWindow) {
ImGui::ShowTestWindow(&fShowImGuiTestWindow);
@@ -1351,7 +1276,7 @@ void Viewer::drawImGui(SkCanvas* canvas) {
SkGetPackedB32(pixel), SkGetPackedA32(pixel));
}
- ImGui_Skia_Callback(avail, [=](SkCanvas* c) {
+ fImGuiLayer.skiaWidget(avail, [=](SkCanvas* c) {
// Translate so the region of the image that's under the mouse cursor is centered
// in the zoom canvas:
c->scale(zoomFactor, zoomFactor);
@@ -1367,73 +1292,6 @@ void Viewer::drawImGui(SkCanvas* canvas) {
ImGui::End();
}
-
- // This causes ImGui to rebuild vertex/index data based on all immediate-mode commands
- // (widgets, etc...) that have been issued
- ImGui::Render();
-
- // Then we fetch the most recent data, and convert it so we can render with Skia
- const ImDrawData* drawData = ImGui::GetDrawData();
- SkTDArray<SkPoint> pos;
- SkTDArray<SkPoint> uv;
- SkTDArray<SkColor> color;
-
- for (int i = 0; i < drawData->CmdListsCount; ++i) {
- const ImDrawList* drawList = drawData->CmdLists[i];
-
- // De-interleave all vertex data (sigh), convert to Skia types
- pos.rewind(); uv.rewind(); color.rewind();
- for (int i = 0; i < drawList->VtxBuffer.size(); ++i) {
- const ImDrawVert& vert = drawList->VtxBuffer[i];
- pos.push(SkPoint::Make(vert.pos.x, vert.pos.y));
- uv.push(SkPoint::Make(vert.uv.x, vert.uv.y));
- color.push(vert.col);
- }
- // ImGui colors are RGBA
- SkSwapRB(color.begin(), color.begin(), color.count());
-
- int indexOffset = 0;
-
- // Draw everything with canvas.drawVertices...
- for (int j = 0; j < drawList->CmdBuffer.size(); ++j) {
- const ImDrawCmd* drawCmd = &drawList->CmdBuffer[j];
-
- SkAutoCanvasRestore acr(canvas, true);
-
- // TODO: Find min/max index for each draw, so we know how many vertices (sigh)
- if (drawCmd->UserCallback) {
- drawCmd->UserCallback(drawList, drawCmd);
- } else {
- intptr_t idIndex = (intptr_t)drawCmd->TextureId;
- if (idIndex < gCustomGuiPainters.count()) {
- // Small image IDs are actually indices into a list of callbacks. We directly
- // examing the vertex data to deduce the image rectangle, then reconfigure the
- // canvas to be clipped and translated so that the callback code gets to use
- // Skia to render a widget in the middle of an ImGui panel.
- ImDrawIdx rectIndex = drawList->IdxBuffer[indexOffset];
- SkPoint tl = pos[rectIndex], br = pos[rectIndex + 2];
- canvas->clipRect(SkRect::MakeLTRB(tl.fX, tl.fY, br.fX, br.fY));
- canvas->translate(tl.fX, tl.fY);
- gCustomGuiPainters[idIndex](canvas);
- } else {
- SkPaint* paint = static_cast<SkPaint*>(drawCmd->TextureId);
- SkASSERT(paint);
-
- canvas->clipRect(SkRect::MakeLTRB(drawCmd->ClipRect.x, drawCmd->ClipRect.y,
- drawCmd->ClipRect.z, drawCmd->ClipRect.w));
- auto vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
- drawList->VtxBuffer.size(),
- pos.begin(), uv.begin(), color.begin(),
- drawCmd->ElemCount,
- drawList->IdxBuffer.begin() + indexOffset);
- canvas->drawVertices(vertices, SkBlendMode::kModulate, *paint);
- indexOffset += drawCmd->ElemCount;
- }
- }
- }
- }
-
- gCustomGuiPainters.reset();
}
void Viewer::onIdle() {
@@ -1626,24 +1484,11 @@ void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateVa
}
bool Viewer::onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers) {
- ImGuiIO& io = ImGui::GetIO();
- io.KeysDown[static_cast<int>(key)] = (Window::kDown_InputState == state);
-
- if (io.WantCaptureKeyboard) {
- return true;
- } else {
- return fCommands.onKey(key, state, modifiers);
- }
+ return fCommands.onKey(key, state, modifiers);
}
bool Viewer::onChar(SkUnichar c, uint32_t modifiers) {
- ImGuiIO& io = ImGui::GetIO();
- if (io.WantTextInput) {
- if (c > 0 && c < 0x10000) {
- io.AddInputCharacter(c);
- }
- return true;
- } else if (fSlides[fCurrentSlide]->onChar(c)) {
+ if (fSlides[fCurrentSlide]->onChar(c)) {
fWindow->inval();
return true;
} else {
diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h
index 1f5d1c5dc4..2ab3de5281 100644
--- a/tools/viewer/Viewer.h
+++ b/tools/viewer/Viewer.h
@@ -12,6 +12,7 @@
#include "sk_app/CommandSet.h"
#include "sk_app/Window.h"
#include "gm.h"
+#include "ImGuiLayer.h"
#include "SkAnimTimer.h"
#include "SkExecutor.h"
#include "SkJSONCPP.h"
@@ -31,7 +32,6 @@ public:
void onPaint(SkCanvas* canvas) override;
bool onTouch(intptr_t owner, sk_app::Window::InputState state, float x, float y) override;
bool onMouse(int x, int y, sk_app::Window::InputState state, uint32_t modifiers) override;
- bool onMouseWheel(float delta, uint32_t modifiers) override;
void onUIStateChanged(const SkString& stateName, const SkString& stateValue) override;
bool onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers) override;
bool onChar(SkUnichar c, uint32_t modifiers) override;
@@ -57,7 +57,7 @@ private:
void drawSlide(SkCanvas* canvs);
void drawStats(SkCanvas* canvas);
- void drawImGui(SkCanvas* canvas);
+ void drawImGui();
void changeZoomLevel(float delta);
SkMatrix computeMatrix();
@@ -85,7 +85,7 @@ private:
bool fSaveToSKP;
- SkPaint fImGuiFontPaint;
+ ImGuiLayer fImGuiLayer;
SkPaint fImGuiGamutPaint;
bool fShowImGuiDebugWindow;
bool fShowSlidePicker;