Signed-off-by: falkTX <falktx@falktx.com>pull/443/head
| @@ -2,13 +2,12 @@ | |||||
| # ------------------------------ # | # ------------------------------ # | ||||
| dpf_add_plugin(d_cairoui | dpf_add_plugin(d_cairoui | ||||
| TARGETS jack dssi lv2 vst2 | |||||
| TARGETS clap dssi jack lv2_sep vst2 vst3 | |||||
| UI_TYPE cairo | UI_TYPE cairo | ||||
| FILES_DSP | FILES_DSP | ||||
| CairoExamplePlugin.cpp | CairoExamplePlugin.cpp | ||||
| FILES_UI | FILES_UI | ||||
| Artwork.cpp | Artwork.cpp | ||||
| DemoWidgetBanner.cpp | |||||
| CairoExampleUI.cpp) | CairoExampleUI.cpp) | ||||
| target_include_directories( | target_include_directories( | ||||
| @@ -23,33 +23,62 @@ START_NAMESPACE_DISTRHO | |||||
| class CairoExamplePlugin : public Plugin | class CairoExamplePlugin : public Plugin | ||||
| { | { | ||||
| float fParameters[kParameterCount]; | |||||
| public: | public: | ||||
| CairoExamplePlugin() | CairoExamplePlugin() | ||||
| : Plugin(0, 0, 0) | |||||
| : Plugin(kParameterCount, 0, 0) | |||||
| { | { | ||||
| std::memset(fParameters, 0, sizeof(fParameters)); | |||||
| } | } | ||||
| const char* getLabel() const | |||||
| /** | |||||
| Get the plugin label.@n | |||||
| This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. | |||||
| */ | |||||
| const char* getLabel() const override | |||||
| { | |||||
| return "cairo_ui"; | |||||
| } | |||||
| /** | |||||
| Get an extensive comment/description about the plugin. | |||||
| */ | |||||
| const char* getDescription() const override | |||||
| { | { | ||||
| return "Cairo DPF Example"; | return "Cairo DPF Example"; | ||||
| } | } | ||||
| const char* getMaker() const | |||||
| /** | |||||
| Get the plugin author/maker. | |||||
| */ | |||||
| const char* getMaker() const override | |||||
| { | { | ||||
| return "Jean Pierre Cimalando"; | |||||
| return "DISTRHO"; | |||||
| } | } | ||||
| const char* getLicense() const | |||||
| /** | |||||
| Get the plugin license (a single line of text or a URL).@n | |||||
| For commercial plugins this should return some short copyright information. | |||||
| */ | |||||
| const char* getLicense() const override | |||||
| { | { | ||||
| return "ISC"; | return "ISC"; | ||||
| } | } | ||||
| uint32_t getVersion() const | |||||
| /** | |||||
| Get the plugin version, in hexadecimal. | |||||
| */ | |||||
| uint32_t getVersion() const override | |||||
| { | { | ||||
| return d_version(1, 0, 0); | return d_version(1, 0, 0); | ||||
| } | } | ||||
| int64_t getUniqueId() const | |||||
| /** | |||||
| Get the plugin unique Id.@n | |||||
| This value is used by LADSPA, DSSI, VST2 and VST3 plugin formats. | |||||
| */ | |||||
| int64_t getUniqueId() const override | |||||
| { | { | ||||
| return d_cconst('d', 'C', 'a', 'i'); | return d_cconst('d', 'C', 'a', 'i'); | ||||
| } | } | ||||
| @@ -58,7 +87,7 @@ public: | |||||
| Initialize the audio port @a index.@n | Initialize the audio port @a index.@n | ||||
| This function will be called once, shortly after the plugin is created. | This function will be called once, shortly after the plugin is created. | ||||
| */ | */ | ||||
| void initAudioPort(bool input, uint32_t index, AudioPort& port) override | |||||
| void initAudioPort(const bool input, const uint32_t index, AudioPort& port) override | |||||
| { | { | ||||
| // treat meter audio ports as stereo | // treat meter audio ports as stereo | ||||
| port.groupId = kPortGroupMono; | port.groupId = kPortGroupMono; | ||||
| @@ -67,29 +96,91 @@ public: | |||||
| Plugin::initAudioPort(input, index, port); | Plugin::initAudioPort(input, index, port); | ||||
| } | } | ||||
| void initParameter(uint32_t index, Parameter& parameter) | |||||
| /** | |||||
| Initialize the parameter @a index.@n | |||||
| This function will be called once, shortly after the plugin is created. | |||||
| */ | |||||
| void initParameter(const uint32_t index, Parameter& parameter) override | |||||
| { | { | ||||
| // unused | |||||
| (void)index; | |||||
| (void)parameter; | |||||
| /** | |||||
| All parameters in this plugin have the same ranges. | |||||
| */ | |||||
| switch (index) | |||||
| { | |||||
| case kParameterKnob: | |||||
| parameter.hints = kParameterIsAutomatable; | |||||
| parameter.name = "Knob"; | |||||
| parameter.symbol = "knob"; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| parameter.ranges.def = 0.0f; | |||||
| break; | |||||
| case kParameterTriState: | |||||
| parameter.hints = kParameterIsAutomatable|kParameterIsInteger; | |||||
| parameter.name = "Color"; | |||||
| parameter.symbol = "color"; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 2.0f; | |||||
| parameter.ranges.def = 0.0f; | |||||
| parameter.enumValues.count = 3; | |||||
| parameter.enumValues.restrictedMode = true; | |||||
| { | |||||
| ParameterEnumerationValue* const values = new ParameterEnumerationValue[3]; | |||||
| parameter.enumValues.values = values; | |||||
| values[0].label = "Red"; | |||||
| values[0].value = 0; | |||||
| values[1].label = "Green"; | |||||
| values[1].value = 1; | |||||
| values[2].label = "Blue"; | |||||
| values[2].value = 2; | |||||
| } | |||||
| break; | |||||
| case kParameterButton: | |||||
| parameter.hints = kParameterIsAutomatable|kParameterIsBoolean; | |||||
| parameter.name = "Button"; | |||||
| parameter.symbol = "button"; | |||||
| parameter.ranges.min = 0.0f; | |||||
| parameter.ranges.max = 1.0f; | |||||
| parameter.ranges.def = 0.0f; | |||||
| parameter.enumValues.count = 2; | |||||
| parameter.enumValues.restrictedMode = true; | |||||
| { | |||||
| ParameterEnumerationValue* const values = new ParameterEnumerationValue[2]; | |||||
| parameter.enumValues.values = values; | |||||
| values[0].label = "Off"; | |||||
| values[0].value = 0; | |||||
| values[1].label = "On"; | |||||
| values[1].value = 1; | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| float getParameterValue(uint32_t index) const | |||||
| /** | |||||
| Get the current value of a parameter.@n | |||||
| The host may call this function from any context, including realtime processing. | |||||
| */ | |||||
| float getParameterValue(const uint32_t index) const override | |||||
| { | { | ||||
| return 0; | |||||
| // unused | |||||
| (void)index; | |||||
| return fParameters[index]; | |||||
| } | } | ||||
| void setParameterValue(uint32_t index, float value) | |||||
| /** | |||||
| Change a parameter value.@n | |||||
| The host may call this function from any context, including realtime processing.@n | |||||
| When a parameter is marked as automatable, you must ensure no non-realtime operations are performed. | |||||
| @note This function will only be called for parameter inputs. | |||||
| */ | |||||
| void setParameterValue(const uint32_t index, const float value) override | |||||
| { | { | ||||
| // unused | |||||
| (void)index; | |||||
| (void)value; | |||||
| fParameters[index] = value; | |||||
| } | } | ||||
| void run(const float** inputs, float** outputs, uint32_t frames) | |||||
| /** | |||||
| Run/process function for plugins without MIDI input. | |||||
| @note Some parameters might be null if there are no audio inputs or outputs. | |||||
| */ | |||||
| void run(const float** const inputs, float** const outputs, const uint32_t frames) override | |||||
| { | { | ||||
| /** | /** | ||||
| This plugin does nothing, it just demonstrates cairo UI usage. | This plugin does nothing, it just demonstrates cairo UI usage. | ||||
| @@ -23,42 +23,56 @@ | |||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| /** | |||||
| We need a few classes from DGL. | |||||
| */ | |||||
| // We need a few classes from DGL. | |||||
| using DGL_NAMESPACE::CairoGraphicsContext; | using DGL_NAMESPACE::CairoGraphicsContext; | ||||
| using DGL_NAMESPACE::CairoImage; | using DGL_NAMESPACE::CairoImage; | ||||
| using DGL_NAMESPACE::CairoImageButton; | |||||
| using DGL_NAMESPACE::CairoImageKnob; | using DGL_NAMESPACE::CairoImageKnob; | ||||
| using DGL_NAMESPACE::CairoImageSwitch; | |||||
| // And from ourselves | |||||
| using DGL_NAMESPACE::DemoWidgetBanner; | |||||
| class CairoExampleUI : public UI | |||||
| class CairoExampleUI : public UI, | |||||
| public CairoImageKnob::Callback, | |||||
| public CairoImageSwitch::Callback, | |||||
| public DemoWidgetClickable::Callback | |||||
| { | { | ||||
| ScopedPointer<CairoImageKnob> fKnob; | |||||
| ScopedPointer<CairoImageSwitch> fButton; | |||||
| ScopedPointer<DemoWidgetBanner> fWidgetBanner; | |||||
| ScopedPointer<DemoWidgetClickable> fWidgetClickable; | |||||
| public: | public: | ||||
| CairoExampleUI() | CairoExampleUI() | ||||
| : UI(200, 200) | |||||
| { | { | ||||
| fWidgetClickable = new DemoWidgetClickable(this); | |||||
| fWidgetClickable->setSize(50, 50); | |||||
| fWidgetClickable->setAbsolutePos(100, 100); | |||||
| CairoImage knobSkin; | |||||
| knobSkin.loadFromPNG(Artwork::knobData, Artwork::knobDataSize); | |||||
| fWidgetBanner = new DemoWidgetBanner(this); | fWidgetBanner = new DemoWidgetBanner(this); | ||||
| fWidgetBanner->setSize(180, 80); | |||||
| fWidgetBanner->setAbsolutePos(10, 10); | fWidgetBanner->setAbsolutePos(10, 10); | ||||
| fWidgetBanner->setSize(180, 80); | |||||
| CairoImage knobSkin; | |||||
| knobSkin.loadFromPNG(Artwork::knobData, Artwork::knobDataSize); | |||||
| fWidgetClickable = new DemoWidgetClickable(this); | |||||
| fWidgetClickable->setAbsolutePos(100, 100); | |||||
| fWidgetClickable->setSize(50, 50); | |||||
| fWidgetClickable->setCallback(this); | |||||
| fWidgetClickable->setId(kParameterTriState); | |||||
| fKnob = new CairoImageKnob(this, knobSkin); | fKnob = new CairoImageKnob(this, knobSkin); | ||||
| fKnob->setSize(80, 80); | |||||
| fKnob->setAbsolutePos(10, 100); | fKnob->setAbsolutePos(10, 100); | ||||
| fKnob->setSize(80, 80); | |||||
| fKnob->setCallback(this); | |||||
| fKnob->setId(kParameterKnob); | |||||
| CairoImage buttonOn, buttonOff; | CairoImage buttonOn, buttonOff; | ||||
| buttonOn.loadFromPNG(Artwork::buttonOnData, Artwork::buttonOnDataSize); | buttonOn.loadFromPNG(Artwork::buttonOnData, Artwork::buttonOnDataSize); | ||||
| buttonOff.loadFromPNG(Artwork::buttonOffData, Artwork::buttonOffDataSize); | buttonOff.loadFromPNG(Artwork::buttonOffData, Artwork::buttonOffDataSize); | ||||
| fButton = new CairoImageButton(this, buttonOff, buttonOn); | |||||
| fButton->setSize(60, 35); | |||||
| fButton = new CairoImageSwitch(this, buttonOff, buttonOn); | |||||
| fButton->setAbsolutePos(100, 160); | fButton->setAbsolutePos(100, 160); | ||||
| fButton->setSize(60, 35); | |||||
| fButton->setCallback(this); | |||||
| fButton->setId(kParameterButton); | |||||
| #if 0 | #if 0 | ||||
| // we can use this if/when our resources are scalable, for now they are PNGs | // we can use this if/when our resources are scalable, for now they are PNGs | ||||
| @@ -67,7 +81,7 @@ public: | |||||
| setSize(200 * scaleFactor, 200 * scaleFactor); | setSize(200 * scaleFactor, 200 * scaleFactor); | ||||
| #else | #else | ||||
| // without scalable resources, let DPF handle the scaling internally | // without scalable resources, let DPF handle the scaling internally | ||||
| setGeometryConstraints(200, 200, true, true); | |||||
| setGeometryConstraints(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT, true, true); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -101,18 +115,46 @@ protected: | |||||
| } | } | ||||
| #endif | #endif | ||||
| void parameterChanged(uint32_t index, float value) override | |||||
| void parameterChanged(const uint32_t index, const float value) override | |||||
| { | { | ||||
| // unused | |||||
| (void)index; | |||||
| (void)value; | |||||
| switch (index) | |||||
| { | |||||
| case kParameterKnob: | |||||
| fKnob->setValue(value); | |||||
| break; | |||||
| case kParameterTriState: | |||||
| fWidgetClickable->setColorId(static_cast<int>(value + 0.5f)); | |||||
| break; | |||||
| case kParameterButton: | |||||
| fButton->setDown(value > 0.5f); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| private: | |||||
| ScopedPointer<DemoWidgetClickable> fWidgetClickable; | |||||
| ScopedPointer<DemoWidgetBanner> fWidgetBanner; | |||||
| ScopedPointer<CairoImageKnob> fKnob; | |||||
| ScopedPointer<CairoImageButton> fButton; | |||||
| void demoWidgetClicked(DemoWidgetClickable*, const uint8_t colorId) override | |||||
| { | |||||
| setParameterValue(kParameterTriState, colorId); | |||||
| } | |||||
| void imageKnobDragStarted(CairoImageKnob*) override | |||||
| { | |||||
| editParameter(kParameterKnob, true); | |||||
| } | |||||
| void imageKnobDragFinished(CairoImageKnob*) override | |||||
| { | |||||
| editParameter(kParameterKnob, false); | |||||
| } | |||||
| void imageKnobValueChanged(CairoImageKnob*, const float value) override | |||||
| { | |||||
| setParameterValue(kParameterKnob, value); | |||||
| } | |||||
| void imageSwitchClicked(CairoImageSwitch*, bool down) override | |||||
| { | |||||
| setParameterValue(kParameterButton, down ? 1.f : 0.f); | |||||
| } | |||||
| }; | }; | ||||
| UI* createUI() | UI* createUI() | ||||
| @@ -1,99 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2019-2021 Jean Pierre Cimalando <jp-dev@inbox.ru> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #include "DemoWidgetBanner.hpp" | |||||
| START_NAMESPACE_DGL | |||||
| // ----------------------------------------------------------------------- | |||||
| static const char* banner = | |||||
| " " | |||||
| " * * * * * " | |||||
| " ** ** * * * * " | |||||
| " * * * * * * * " | |||||
| " * * * **** *** * **** * * ** **** * *** " | |||||
| " * * * * ** * * * * * * ** * " | |||||
| " * * ***** * * ****** * * * * * * * " | |||||
| " * * * * * * * * * * * * * * " | |||||
| " * * * ** * ** * * * * * * * * * * " | |||||
| " * * *** * *** * **** ** ** ***** ** * * " | |||||
| " " | |||||
| " " | |||||
| " " | |||||
| " ***** **** ***** " | |||||
| " * * * * * " | |||||
| " * * * * * " | |||||
| " * * * * * " | |||||
| " * * **** **** " | |||||
| " * * * * " | |||||
| " * * * * " | |||||
| " * * * * " | |||||
| " ***** * * " | |||||
| " "; | |||||
| enum | |||||
| { | |||||
| rows = 23, | |||||
| columns = 72, | |||||
| }; | |||||
| DemoWidgetBanner::DemoWidgetBanner(SubWidget* parent) | |||||
| : CairoSubWidget(parent) {} | |||||
| DemoWidgetBanner::DemoWidgetBanner(TopLevelWidget* parent) | |||||
| : CairoSubWidget(parent) {} | |||||
| void DemoWidgetBanner::onCairoDisplay(const CairoGraphicsContext& context) | |||||
| { | |||||
| cairo_t* cr = context.handle; | |||||
| Size<uint> sz = getSize(); | |||||
| int w = sz.getWidth(); | |||||
| int h = sz.getHeight(); | |||||
| double diameter = (double)w / columns; | |||||
| double radius = 0.5 * diameter; | |||||
| double xoff = 0; | |||||
| double yoff = 0.5 * (h - rows * diameter); | |||||
| for (int r = 0; r < rows; ++r) | |||||
| { | |||||
| for (int c = 0; c < columns; ++c) | |||||
| { | |||||
| double cx = xoff + radius + c * diameter; | |||||
| double cy = yoff + radius + r * diameter; | |||||
| char ch = banner[c + r * columns]; | |||||
| if (ch != ' ') | |||||
| cairo_set_source_rgb(cr, 0.5, 0.9, 0.2); | |||||
| else | |||||
| cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); | |||||
| cairo_save(cr); | |||||
| cairo_translate(cr, cx, cy); | |||||
| cairo_scale(cr, radius, radius); | |||||
| cairo_arc(cr, 0.0, 0.0, 1.0, 0.0, 2 * M_PI); | |||||
| cairo_restore(cr); | |||||
| cairo_fill(cr); | |||||
| } | |||||
| } | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | |||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2019-2021 Jean Pierre Cimalando <jp-dev@inbox.ru> | * Copyright (C) 2019-2021 Jean Pierre Cimalando <jp-dev@inbox.ru> | ||||
| * Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -23,17 +23,84 @@ START_NAMESPACE_DGL | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| static constexpr const char banner[] = | |||||
| " " | |||||
| " * * * * * " | |||||
| " ** ** * * * * " | |||||
| " * * * * * * * " | |||||
| " * * * **** *** * **** * * ** **** * *** " | |||||
| " * * * * ** * * * * * * ** * " | |||||
| " * * ***** * * ****** * * * * * * * " | |||||
| " * * * * * * * * * * * * * * " | |||||
| " * * * ** * ** * * * * * * * * * * " | |||||
| " * * *** * *** * **** ** ** ***** ** * * " | |||||
| " " | |||||
| " " | |||||
| " " | |||||
| " ***** **** ***** " | |||||
| " * * * * * " | |||||
| " * * * * * " | |||||
| " * * * * * " | |||||
| " * * **** **** " | |||||
| " * * * * " | |||||
| " * * * * " | |||||
| " * * * * " | |||||
| " ***** * * " | |||||
| " "; | |||||
| enum { | |||||
| rows = 23, | |||||
| columns = 72, | |||||
| }; | |||||
| class DemoWidgetBanner : public CairoSubWidget | class DemoWidgetBanner : public CairoSubWidget | ||||
| { | { | ||||
| public: | public: | ||||
| explicit DemoWidgetBanner(SubWidget* parent); | |||||
| explicit DemoWidgetBanner(TopLevelWidget* parent); | |||||
| explicit DemoWidgetBanner(SubWidget* const parent) | |||||
| : CairoSubWidget(parent) {} | |||||
| explicit DemoWidgetBanner(TopLevelWidget* const parent) | |||||
| : CairoSubWidget(parent) {} | |||||
| protected: | protected: | ||||
| void onCairoDisplay(const CairoGraphicsContext& context) override; | |||||
| void onCairoDisplay(const CairoGraphicsContext& context) override | |||||
| { | |||||
| cairo_t* const cr = context.handle; | |||||
| Size<uint> sz = getSize(); | |||||
| int w = sz.getWidth(); | |||||
| int h = sz.getHeight(); | |||||
| const double diameter = (double)w / columns; | |||||
| const double radius = 0.5 * diameter; | |||||
| const double xoff = 0; | |||||
| const double yoff = 0.5 * (h - rows * diameter); | |||||
| for (int r = 0; r < rows; ++r) | |||||
| { | |||||
| for (int c = 0; c < columns; ++c) | |||||
| { | |||||
| double cx = xoff + radius + c * diameter; | |||||
| double cy = yoff + radius + r * diameter; | |||||
| char ch = banner[c + r * columns]; | |||||
| if (ch != ' ') | |||||
| cairo_set_source_rgb(cr, 0.5, 0.9, 0.2); | |||||
| else | |||||
| cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); | |||||
| cairo_save(cr); | |||||
| cairo_translate(cr, cx, cy); | |||||
| cairo_scale(cr, radius, radius); | |||||
| cairo_arc(cr, 0.0, 0.0, 1.0, 0.0, 2 * M_PI); | |||||
| cairo_restore(cr); | |||||
| cairo_fill(cr); | |||||
| } | |||||
| } | |||||
| } | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| using DGL_NAMESPACE::DemoWidgetBanner; | |||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2019-2021 Jean Pierre Cimalando <jp-dev@inbox.ru> | * Copyright (C) 2019-2021 Jean Pierre Cimalando <jp-dev@inbox.ru> | ||||
| * Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -23,16 +23,51 @@ START_NAMESPACE_DGL | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| class DemoWidgetClickable : public CairoSubWidget | |||||
| class DemoWidgetClickable : public CairoSubWidget, | |||||
| public ButtonEventHandler, | |||||
| public ButtonEventHandler::Callback | |||||
| { | { | ||||
| public: | public: | ||||
| class Callback | |||||
| { | |||||
| public: | |||||
| virtual ~Callback() {} | |||||
| virtual void demoWidgetClicked(DemoWidgetClickable* widget, uint8_t colorId) = 0; | |||||
| }; | |||||
| explicit DemoWidgetClickable(SubWidget* const parent) | explicit DemoWidgetClickable(SubWidget* const parent) | ||||
| : CairoSubWidget(parent), | : CairoSubWidget(parent), | ||||
| colorId(0) {} | |||||
| ButtonEventHandler(this), | |||||
| fCallback(nullptr), | |||||
| fColorId(0) | |||||
| { | |||||
| ButtonEventHandler::setCallback(this); | |||||
| } | |||||
| explicit DemoWidgetClickable(TopLevelWidget* const parent) | explicit DemoWidgetClickable(TopLevelWidget* const parent) | ||||
| : CairoSubWidget(parent), | : CairoSubWidget(parent), | ||||
| colorId(0) {} | |||||
| ButtonEventHandler(this), | |||||
| fCallback(nullptr), | |||||
| fColorId(0) | |||||
| { | |||||
| ButtonEventHandler::setCallback(this); | |||||
| } | |||||
| void setCallback(Callback* const callback) noexcept | |||||
| { | |||||
| fCallback = callback; | |||||
| } | |||||
| uint8_t getColorId() const noexcept | |||||
| { | |||||
| return fColorId; | |||||
| } | |||||
| void setColorId(uint8_t colorId) noexcept | |||||
| { | |||||
| fColorId = colorId; | |||||
| repaint(); | |||||
| } | |||||
| protected: | protected: | ||||
| void onCairoDisplay(const CairoGraphicsContext& context) override | void onCairoDisplay(const CairoGraphicsContext& context) override | ||||
| @@ -43,7 +78,7 @@ protected: | |||||
| const int w = sz.getWidth(); | const int w = sz.getWidth(); | ||||
| const int h = sz.getHeight(); | const int h = sz.getHeight(); | ||||
| switch (colorId) | |||||
| switch (fColorId) | |||||
| { | { | ||||
| case 0: | case 0: | ||||
| cairo_set_source_rgb(cr, 0.75, 0.0, 0.0); | cairo_set_source_rgb(cr, 0.75, 0.0, 0.0); | ||||
| @@ -72,26 +107,21 @@ protected: | |||||
| bool onMouse(const MouseEvent& event) override | bool onMouse(const MouseEvent& event) override | ||||
| { | { | ||||
| if (event.press) | |||||
| { | |||||
| const int w = getWidth(); | |||||
| const int h = getHeight(); | |||||
| const int mx = event.pos.getX(); | |||||
| const int my = event.pos.getY(); | |||||
| // inside | |||||
| if (mx >= 0 && my >= 0 && mx < w && my < h) | |||||
| { | |||||
| colorId = (colorId + 1) % 3; | |||||
| repaint(); | |||||
| } | |||||
| } | |||||
| return ButtonEventHandler::mouseEvent(event); | |||||
| } | |||||
| void buttonClicked(SubWidget*, int) override | |||||
| { | |||||
| fColorId = (fColorId + 1) % 3; | |||||
| repaint(); | |||||
| return CairoSubWidget::onMouse(event); | |||||
| if (fCallback != nullptr) | |||||
| fCallback->demoWidgetClicked(this, fColorId); | |||||
| } | } | ||||
| private: | private: | ||||
| uint colorId; | |||||
| Callback* fCallback; | |||||
| uint8_t fColorId; | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -118,10 +118,36 @@ | |||||
| #define DISTRHO_UI_USE_NANOVG 0 | #define DISTRHO_UI_USE_NANOVG 0 | ||||
| /** | /** | ||||
| The %UI URI when exporting in LV2 format.@n | |||||
| By default this is set to @ref DISTRHO_PLUGIN_URI with "#UI" as suffix. | |||||
| Default UI width to use when creating initial and temporary windows.@n | |||||
| Setting this macro allows to skip a temporary UI from being created in certain VST2 and VST3 hosts. | |||||
| (which would normally be done for knowing the UI size before host creates a window for it) | |||||
| Value must match 1x scale factor. | |||||
| When this macro is defined, the companion DISTRHO_UI_DEFAULT_HEIGHT macro must be defined as well. | |||||
| */ | */ | ||||
| #define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI" | |||||
| #define DISTRHO_UI_DEFAULT_WIDTH 200 | |||||
| #define DISTRHO_UI_FILE_BROWSER 0 | |||||
| /** | |||||
| Default UI height to use when creating initial and temporary windows.@n | |||||
| Setting this macro allows to skip a temporary UI from being created in certain VST2 and VST3 hosts. | |||||
| (which would normally be done for knowing the UI size before host creates a window for it) | |||||
| Value must match 1x scale factor. | |||||
| When this macro is defined, the companion DISTRHO_UI_DEFAULT_WIDTH macro must be defined as well. | |||||
| */ | |||||
| #define DISTRHO_UI_DEFAULT_HEIGHT 200 | |||||
| // TODO document this | |||||
| #define DISTRHO_UI_USE_CAIRO 1 | #define DISTRHO_UI_USE_CAIRO 1 | ||||
| // TODO document this | |||||
| #define DISTRHO_UI_FILE_BROWSER 0 | |||||
| enum Parameters { | |||||
| kParameterKnob, | |||||
| kParameterTriState, | |||||
| kParameterButton, | |||||
| kParameterCount | |||||
| }; | |||||
| @@ -17,7 +17,6 @@ FILES_DSP = \ | |||||
| FILES_UI = \ | FILES_UI = \ | ||||
| Artwork.cpp \ | Artwork.cpp \ | ||||
| DemoWidgetBanner.cpp \ | |||||
| CairoExampleUI.cpp | CairoExampleUI.cpp | ||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| @@ -29,11 +28,7 @@ include ../../Makefile.plugins.mk | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # Enable all possible plugin types | # Enable all possible plugin types | ||||
| TARGETS += clap | |||||
| TARGETS += dssi | |||||
| TARGETS += jack | |||||
| TARGETS += lv2_sep | |||||
| TARGETS += vst2 | |||||
| TARGETS = clap dssi jack lv2_sep vst2 vst3 | |||||
| all: $(TARGETS) | all: $(TARGETS) | ||||