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) | ||||