From 11bbce74479994e8ee9420112f80a01eb2944f28 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 15 Sep 2016 19:08:08 +0200 Subject: Added new inline display for showing load progress. --- plugin/drumgizmo.ttl | 2 + plugin/drumgizmo_plugin.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++++ plugin/drumgizmo_plugin.h | 34 ++++++++++++++++ plugingui/pixelbuffer.cc | 8 +++- plugingui/pixelbuffer.h | 18 +++++---- 5 files changed, 149 insertions(+), 10 deletions(-) diff --git a/plugin/drumgizmo.ttl b/plugin/drumgizmo.ttl index 2e9b930..e5b163d 100644 --- a/plugin/drumgizmo.ttl +++ b/plugin/drumgizmo.ttl @@ -22,6 +22,7 @@ @prefix pprops: . @prefix lv2: . @prefix rdfs: . +@prefix idpy: . a ui:X11UI ; @@ -43,6 +44,7 @@ doap:license ; lv2:optionalFeature ; lv2:optionalFeature ; + lv2:optionalFeature idpy:queue_draw ; lv2:extensionData state:interface ; lv2:port [ a lv2:InputPort, lv2:ControlPort ; diff --git a/plugin/drumgizmo_plugin.cc b/plugin/drumgizmo_plugin.cc index fa51575..9414914 100644 --- a/plugin/drumgizmo_plugin.cc +++ b/plugin/drumgizmo_plugin.cc @@ -156,6 +156,103 @@ void DrumGizmoPlugin::process(size_t pos, this->output_samples = nullptr; } +bool DrumGizmoPlugin::hasInlineGUI() +{ + return true; +} + +class InlinePixelBufferAlpha + : public GUI::PixelBufferAlpha +{ +public: + InlinePixelBufferAlpha(Plugin::InlineDrawContext& context) + { + buf = context.data; + width = context.width; + height = context.height; + x = 0; + y = 0; + } +}; + +class InlineCanvas + : public GUI::Canvas +{ +public: + InlineCanvas(Plugin::InlineDrawContext& context) + : pixbuf(context) + { + } + + GUI::PixelBufferAlpha& GetPixelBuffer() + { + return pixbuf; + } + void beginPaint() {} + void endPaint() {} + +private: + InlinePixelBufferAlpha pixbuf; +}; + +void DrumGizmoPlugin::onInlineRedraw(std::size_t width, + std::size_t max_height, + InlineDrawContext& context) +{ + std::size_t height = std::min(11u, max_height); + if(!context.data || + (context.width != width) || + (context.height != height) || + settingsGetter.number_of_files.hasChanged() || + settingsGetter.number_of_files_loaded.hasChanged() || + settingsGetter.drumkit_load_status.hasChanged()) + { + context.width = width; + context.height = height; + assert(context.width * context.height <= sizeof(inlineDisplayBuffer)); +) + context.data = (unsigned char*)inlineDisplayBuffer; + box.setSize(context.width, context.height); + + InlineCanvas canvas(context); + GUI::Painter painter(canvas); + painter.clear(); + painter.drawImage(0, 1, box); + + double progress = + (double)settingsGetter.number_of_files_loaded.getValue() / + (double)settingsGetter.number_of_files.getValue(); + + int brd = 4; + int val = (width - (2 * brd)) * progress; + + switch(settingsGetter.drumkit_load_status.getValue()) + { + case LoadStatus::Error: + bar_red.setSize(val, height); + painter.drawImage(brd, 0, bar_red); + break; + case LoadStatus::Done: + bar_green.setSize(val, height); + painter.drawImage(brd, 0, bar_green); + break; + case LoadStatus::Loading: + case LoadStatus::Idle: + bar_blue.setSize(val, height); + painter.drawImage(brd, 0, bar_blue); + break; + } + + // Convert to correct pixel format + for(std::size_t i = 0; i < context.height * context.width; ++i) + { + std::uint32_t pixel = inlineDisplayBuffer[i]; + unsigned char* p = (unsigned char*)&pixel; + inlineDisplayBuffer[i] = pgzRGBA(p[0], p[1], p[2], p[3]); + } + } +} + bool DrumGizmoPlugin::hasGUI() { return true; diff --git a/plugin/drumgizmo_plugin.h b/plugin/drumgizmo_plugin.h index 2e3da26..de4f4af 100644 --- a/plugin/drumgizmo_plugin.h +++ b/plugin/drumgizmo_plugin.h @@ -50,6 +50,9 @@ #include #include +#include +#include + class DrumGizmoPlugin #ifdef LV2 : public PluginLV2 @@ -94,6 +97,14 @@ public: const std::vector& output_samples, size_t count) override; + // + // Inline GUI + // + bool hasInlineGUI() override; + void onInlineRedraw(std::size_t width, + std::size_t max_height, + InlineDrawContext& context) override; + // // GUI // @@ -174,7 +185,30 @@ private: Settings settings; ConfigStringIO config_string_io; + SettingsGetter settingsGetter{settings}; + + GUI::ImageCache imageCache; + GUI::TexturedBox box{imageCache, ":progress.png", + 0, 0, // atlas offset (x, y) + 6, 1, 6, // dx1, dx2, dx3 + 11, 0, 0}; // dy1, dy2, dy3 + + GUI::TexturedBox bar_red{imageCache, ":progress.png", + 13, 0, // atlas offset (x, y) + 2, 1, 2, // dx1, dx2, dx3 + 11, 0, 0}; // dy1, dy2, dy3 + + GUI::TexturedBox bar_green{imageCache, ":progress.png", + 18, 0, // atlas offset (x, y) + 2, 1, 2, // dx1, dx2, dx3 + 11, 0, 0}; // dy1, dy2, dy3 + + GUI::TexturedBox bar_blue{imageCache, ":progress.png", + 23, 0, // atlas offset (x, y) + 2, 1, 2, // dx1, dx2, dx3 + 11, 0, 0}; // dy1, dy2, dy3 std::shared_ptr plugin_gui; std::shared_ptr drumgizmo; + std::uint32_t inlineDisplayBuffer[1024*1024]; }; diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc index 906e4d6..5d032b4 100644 --- a/plugingui/pixelbuffer.cc +++ b/plugingui/pixelbuffer.cc @@ -69,7 +69,8 @@ void PixelBuffer::setPixel(size_t x, size_t y, } PixelBufferAlpha::PixelBufferAlpha(size_t width, size_t height) - : buf(nullptr) + : managed(true) + , buf(nullptr) , x(0) , y(0) { @@ -78,7 +79,10 @@ PixelBufferAlpha::PixelBufferAlpha(size_t width, size_t height) PixelBufferAlpha::~PixelBufferAlpha() { - free(buf); + if(managed) + { + free(buf); + } } void PixelBufferAlpha::realloc(size_t width, size_t height) diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h index 8e7618d..762aaa6 100644 --- a/plugingui/pixelbuffer.h +++ b/plugingui/pixelbuffer.h @@ -45,13 +45,14 @@ public: unsigned char blue, unsigned char alpha); - unsigned char* buf; - size_t width; - size_t height; + unsigned char* buf{nullptr}; + size_t width{0}; + size_t height{0}; }; class PixelBufferAlpha { public: + PixelBufferAlpha() = default; PixelBufferAlpha(size_t width, size_t height); ~PixelBufferAlpha(); @@ -77,11 +78,12 @@ public: unsigned char* blue, unsigned char* alpha); - unsigned char* buf; - size_t width; - size_t height; - size_t x; - size_t y; + bool managed{false}; + unsigned char* buf{nullptr}; + size_t width{0}; + size_t height{0}; + size_t x{0}; + size_t y{0}; }; } // GUI:: -- cgit v1.2.3