Build release version, separate UI into header file
This commit is contained in:
parent
d4644df706
commit
4c8cd87421
|
@ -1,5 +1,4 @@
|
|||
#include "DistrhoUI.hpp"
|
||||
#include "tablet.h"
|
||||
#include "ui.h"
|
||||
#ifdef DEBUG
|
||||
#include <format>
|
||||
#include <optional>
|
||||
|
@ -7,259 +6,231 @@
|
|||
|
||||
START_NAMESPACE_DISTRHO
|
||||
|
||||
//UI element for mapping the currently pressed pen button combination to a parameter.
|
||||
class ButtonMappingWidget : public NanoSubWidget,
|
||||
public ButtonEventHandler
|
||||
ButtonMappingWidget::ButtonMappingWidget(
|
||||
Widget *parent,
|
||||
float initialSize,
|
||||
float initialX,
|
||||
float initialY,
|
||||
Parameters associatedParameter,
|
||||
ButtonEventHandler::Callback *const callback) : x(initialX),
|
||||
y(initialY),
|
||||
size(initialSize),
|
||||
param(associatedParameter),
|
||||
isClicked(false),
|
||||
isPenPressed(false),
|
||||
mask(0),
|
||||
NanoSubWidget(parent),
|
||||
ButtonEventHandler(this)
|
||||
{
|
||||
public:
|
||||
ButtonMappingWidget(
|
||||
Widget* parent,
|
||||
float initialSize,
|
||||
float initialX,
|
||||
float initialY,
|
||||
Parameters associatedParameter,
|
||||
ButtonEventHandler::Callback* const callback) :
|
||||
x(initialX),
|
||||
y(initialY),
|
||||
size(initialSize),
|
||||
param(associatedParameter),
|
||||
isClicked(false),
|
||||
isPenPressed(false),
|
||||
mask(0),
|
||||
NanoSubWidget(parent),
|
||||
ButtonEventHandler(this)
|
||||
{
|
||||
setSize(Size<uint>(static_cast<uint>(size), static_cast<uint>(size)));
|
||||
setAbsolutePos((int)x, (int)y);
|
||||
ButtonEventHandler::setCallback(callback);
|
||||
}
|
||||
setSize(Size<uint>(static_cast<uint>(size), static_cast<uint>(size)));
|
||||
setAbsolutePos((int)x, (int)y);
|
||||
ButtonEventHandler::setCallback(callback);
|
||||
}
|
||||
|
||||
void onNanoDisplay() override
|
||||
{
|
||||
beginPath();
|
||||
strokeColor(200, 200, 200);
|
||||
fillColor(0.5f, 0.5f, 0.5f, 0.5f * (isClicked + isPenPressed));
|
||||
roundedRect(0.f, 0.f, size, size, 0.5f * size);
|
||||
stroke();
|
||||
fill();
|
||||
closePath();
|
||||
}
|
||||
|
||||
bool onMouse(const MouseEvent& ev) override
|
||||
{
|
||||
isClicked = ev.press;
|
||||
return ButtonEventHandler::mouseEvent(ev);
|
||||
}
|
||||
|
||||
void setMask(const ButtonMask m) { mask = m; }
|
||||
bool matchesMask(const ButtonMask m) { return isPenPressed = (m && mask == m); }
|
||||
|
||||
bool isClicked;
|
||||
bool isPenPressed;
|
||||
|
||||
private:
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
float size = 0;
|
||||
const Parameters param;
|
||||
ButtonMask mask;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class TabUI : public UI,
|
||||
public ButtonEventHandler::Callback
|
||||
void ButtonMappingWidget::onNanoDisplay()
|
||||
{
|
||||
static const uint kInitialWidth = 800;
|
||||
static const uint kInitialHeight = 600;
|
||||
beginPath();
|
||||
strokeColor(200, 200, 200);
|
||||
fillColor(0.5f, 0.5f, 0.5f, 0.5f * (isClicked + isPenPressed));
|
||||
roundedRect(0.f, 0.f, size, size, 0.5f * size);
|
||||
stroke();
|
||||
fill();
|
||||
closePath();
|
||||
}
|
||||
|
||||
public:
|
||||
TabUI()
|
||||
: UI(kInitialWidth, kInitialHeight),
|
||||
tab(getWindow().getNativeWindowHandle()),
|
||||
AButtonWidget(this, 75.f, 700.f, 500.f, kParameterButtonA, this),
|
||||
BButtonWidget(this, 75.f, 700.f, 400.f, kParameterButtonB, this)
|
||||
{
|
||||
bool ButtonMappingWidget::onMouse(const MouseEvent &ev)
|
||||
{
|
||||
isClicked = ev.press;
|
||||
return ButtonEventHandler::mouseEvent(ev);
|
||||
}
|
||||
|
||||
static constexpr uint kInitialWidth = 800;
|
||||
static constexpr uint kInitialHeight = 600;
|
||||
|
||||
TabUI::TabUI()
|
||||
: UI(kInitialWidth, kInitialHeight),
|
||||
tab(getWindow().getNativeWindowHandle()),
|
||||
AButtonWidget(this, 75.f, 700.f, 500.f, kParameterButtonA, this),
|
||||
BButtonWidget(this, 75.f, 700.f, 400.f, kParameterButtonB, this)
|
||||
{
|
||||
|
||||
#ifdef DGL_NO_SHARED_RESOURCES
|
||||
createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
|
||||
createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
|
||||
#else
|
||||
loadSharedResources();
|
||||
loadSharedResources();
|
||||
#endif
|
||||
|
||||
if (!tab.initialized) return;
|
||||
//setGeometryConstraints(400, static_cast<uint>(300 * tabletAspectRatio), true, false);
|
||||
}
|
||||
if (!tab.initialized)
|
||||
return;
|
||||
// setGeometryConstraints(400, static_cast<uint>(300 * tabletAspectRatio), true, false);
|
||||
}
|
||||
|
||||
protected:
|
||||
void TabUI::getTabletData()
|
||||
{
|
||||
if (!tab.initialized || !tab.GetPacket(pkt))
|
||||
return;
|
||||
if (pkt == lastPkt)
|
||||
return;
|
||||
if (pkt.x != lastPkt.x)
|
||||
setParameterValue(ktpax, pkt.x);
|
||||
if (pkt.y != lastPkt.y)
|
||||
setParameterValue(ktpay, pkt.y);
|
||||
if (pkt.z != lastPkt.z)
|
||||
setParameterValue(ktpaz, pkt.z);
|
||||
if (pkt.p != lastPkt.p)
|
||||
setParameterValue(ktpap, pkt.p);
|
||||
if (pkt.buttons != lastPkt.buttons)
|
||||
setButtonsValue(pkt.buttons);
|
||||
lastPkt = pkt;
|
||||
}
|
||||
|
||||
void getTabletData()
|
||||
void TabUI::setButtonsValue(unsigned long buttonMask)
|
||||
{
|
||||
if (AButtonWidget.matchesMask(buttonMask))
|
||||
setParameterValue(kParameterButtonA, 1.f);
|
||||
else
|
||||
setParameterValue(kParameterButtonA, 0.f);
|
||||
|
||||
if (BButtonWidget.matchesMask(buttonMask))
|
||||
setParameterValue(kParameterButtonB, 1.f);
|
||||
else
|
||||
setParameterValue(kParameterButtonB, 0.f);
|
||||
}
|
||||
|
||||
void TabUI::buttonClicked(SubWidget *const widget, int)
|
||||
{
|
||||
if (widget == &AButtonWidget)
|
||||
AButtonWidget.setMask(pkt.buttons);
|
||||
if (widget == &BButtonWidget)
|
||||
BButtonWidget.setMask(pkt.buttons);
|
||||
}
|
||||
|
||||
void TabUI::parameterChanged(uint32_t index, float value)
|
||||
{
|
||||
|
||||
if (index != kParameterTime && index < kParameterCount)
|
||||
{
|
||||
if (!tab.initialized || !tab.GetPacket(pkt)) return;
|
||||
if (pkt == lastPkt) return;
|
||||
if (pkt.x != lastPkt.x) setParameterValue(ktpax, pkt.x);
|
||||
if (pkt.y != lastPkt.y) setParameterValue(ktpay, pkt.y);
|
||||
if (pkt.z != lastPkt.z) setParameterValue(ktpaz, pkt.z);
|
||||
if (pkt.p != lastPkt.p) setParameterValue(ktpap, pkt.p);
|
||||
if (pkt.buttons != lastPkt.buttons) setButtonsValue(pkt.buttons);
|
||||
lastPkt = pkt;
|
||||
}
|
||||
|
||||
void setButtonsValue(unsigned long buttonMask)
|
||||
{
|
||||
if (AButtonWidget.matchesMask(buttonMask))
|
||||
setParameterValue(kParameterButtonA, 1.f);
|
||||
else setParameterValue(kParameterButtonA, 0.f);
|
||||
|
||||
if (BButtonWidget.matchesMask(buttonMask))
|
||||
setParameterValue(kParameterButtonB, 1.f);
|
||||
else setParameterValue(kParameterButtonB, 0.f);
|
||||
|
||||
}
|
||||
|
||||
void buttonClicked(SubWidget* const widget, int ) override
|
||||
{
|
||||
if (widget == &AButtonWidget) AButtonWidget.setMask(pkt.buttons);
|
||||
if (widget == &BButtonWidget) BButtonWidget.setMask(pkt.buttons);
|
||||
}
|
||||
|
||||
void parameterChanged(uint32_t index, float value) override
|
||||
{
|
||||
|
||||
if (index != kParameterTime && index < kParameterCount) {
|
||||
switch (index)
|
||||
{
|
||||
case(ktpax): pkt.x = value;
|
||||
case(ktpay): pkt.y = value;
|
||||
case(ktpaz): pkt.z = value;
|
||||
case(ktpap): pkt.p = value;
|
||||
}
|
||||
return;
|
||||
switch (index)
|
||||
{
|
||||
case (ktpax):
|
||||
pkt.x = value;
|
||||
case (ktpay):
|
||||
pkt.y = value;
|
||||
case (ktpaz):
|
||||
pkt.z = value;
|
||||
case (ktpap):
|
||||
pkt.p = value;
|
||||
}
|
||||
|
||||
getTabletData();
|
||||
repaint();
|
||||
return;
|
||||
}
|
||||
|
||||
void uiIdle() override
|
||||
getTabletData();
|
||||
repaint();
|
||||
}
|
||||
|
||||
void TabUI::uiIdle()
|
||||
{
|
||||
getTabletData();
|
||||
repaint();
|
||||
}
|
||||
|
||||
bool TabUI::onMouse(const MouseEvent &ev)
|
||||
{
|
||||
getTabletData();
|
||||
repaint();
|
||||
return false; // Allow event to propagate.
|
||||
}
|
||||
|
||||
bool TabUI::onScroll(const ScrollEvent &ev)
|
||||
{
|
||||
double add;
|
||||
const uint x = getWidth();
|
||||
const uint y = getHeight();
|
||||
|
||||
add = (ev.delta.getY() > 0) ? 1 : -1;
|
||||
|
||||
float tabletAspectRatio;
|
||||
if (tab.initialized)
|
||||
tabletAspectRatio = tab.ext.y / tab.ext.x;
|
||||
else
|
||||
tabletAspectRatio = 1.f;
|
||||
setSize(static_cast<uint>(x + add + 0.5), static_cast<uint>(tabletAspectRatio * (x + add + 0.5)));
|
||||
return true;
|
||||
}
|
||||
|
||||
void TabUI::onNanoDisplay()
|
||||
{
|
||||
fontSize(15.0f);
|
||||
textLineHeight(1.f);
|
||||
|
||||
// Report tablet errors.
|
||||
#ifdef DEBUG
|
||||
if (!tab.initialized)
|
||||
{
|
||||
getTabletData();
|
||||
repaint();
|
||||
}
|
||||
|
||||
bool onMouse(const MouseEvent& ev) override
|
||||
{
|
||||
getTabletData();
|
||||
repaint();
|
||||
return false; //Allow event to propagate.
|
||||
}
|
||||
|
||||
bool onScroll(const ScrollEvent& ev) override
|
||||
{
|
||||
double add;
|
||||
const uint x = getWidth();
|
||||
const uint y = getHeight();
|
||||
|
||||
add = (ev.delta.getY() > 0) ? 1 : -1;
|
||||
|
||||
float tabletAspectRatio;
|
||||
if (tab.initialized) tabletAspectRatio = tab.ext.y / tab.ext.x; else tabletAspectRatio = 1.f;
|
||||
setSize(static_cast<uint>(x + add + 0.5), static_cast<uint>(tabletAspectRatio * (x + add + 0.5)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void onNanoDisplay() override
|
||||
{
|
||||
fontSize(15.0f);
|
||||
textLineHeight(1.f);
|
||||
|
||||
//Report tablet errors.
|
||||
if (!tab.initialized) {
|
||||
const std::string err = std::vformat("Tablet not supported:\n{}",
|
||||
std::make_format_args(tab.errormsg));
|
||||
beginPath();
|
||||
fillColor(200, 200, 200);
|
||||
textBox(0.f, 15.f, 250.f, err.c_str(), nullptr);
|
||||
closePath();
|
||||
return;
|
||||
}
|
||||
|
||||
//Numerical feedback.
|
||||
const std::string err = std::vformat("Tablet not supported:\n{}",
|
||||
std::make_format_args(tab.errormsg));
|
||||
beginPath();
|
||||
fillColor(200, 200, 200);
|
||||
textBox(0.f, 15.f, 250.f,
|
||||
textBox(0.f, 15.f, 250.f, err.c_str(), nullptr);
|
||||
closePath();
|
||||
return;
|
||||
}
|
||||
|
||||
// Numerical feedback.
|
||||
beginPath();
|
||||
fillColor(200, 200, 200);
|
||||
textBox(0.f, 15.f, 250.f,
|
||||
std::format("x: {:.3f}\ny: {:.3f}\nz: {:.3f}\np: {:.3f}\nb: {}",
|
||||
pkt.x, pkt.y, pkt.z, pkt.p, pkt.buttons).c_str(), nullptr);
|
||||
closePath();
|
||||
pkt.x, pkt.y, pkt.z, pkt.p, pkt.buttons)
|
||||
.c_str(),
|
||||
nullptr);
|
||||
closePath();
|
||||
#endif
|
||||
|
||||
//Pen position and pressure.
|
||||
drawCircle(pkt.x, pkt.y, pkt.z, pkt.p);
|
||||
}
|
||||
// Pen position and pressure.
|
||||
drawCircle(pkt.x, pkt.y, pkt.z, pkt.p);
|
||||
}
|
||||
|
||||
void drawCircle(float x, float y, float z, float p) {
|
||||
void TabUI::drawCircle(float x, float y, float z, float p)
|
||||
{
|
||||
|
||||
static constexpr float circleRadius = 25.f;
|
||||
x *= getWidth();
|
||||
y = (1.f - y) * getHeight();
|
||||
z = 1.f - z;
|
||||
static constexpr float circleRadius = 25.f;
|
||||
x *= getWidth();
|
||||
y = (1.f - y) * getHeight();
|
||||
z = 1.f - z;
|
||||
|
||||
beginPath();
|
||||
strokeColor(1.f, 1.f, 1.f, 0.5f);
|
||||
moveTo(x - z * circleRadius, y);
|
||||
lineTo(x + z * circleRadius, y);
|
||||
stroke();
|
||||
closePath();
|
||||
beginPath();
|
||||
strokeColor(1.f, 1.f, 1.f, 0.5f);
|
||||
moveTo(x - z * circleRadius, y);
|
||||
lineTo(x + z * circleRadius, y);
|
||||
stroke();
|
||||
closePath();
|
||||
|
||||
beginPath();
|
||||
strokeColor(1.f, 1.f, 1.f, 0.5f);
|
||||
moveTo(x, y - z * circleRadius);
|
||||
lineTo(x, y + z * circleRadius);
|
||||
stroke();
|
||||
closePath();
|
||||
beginPath();
|
||||
strokeColor(1.f, 1.f, 1.f, 0.5f);
|
||||
moveTo(x, y - z * circleRadius);
|
||||
lineTo(x, y + z * circleRadius);
|
||||
stroke();
|
||||
closePath();
|
||||
|
||||
beginPath();
|
||||
fillColor(1.f, 1.f, 1.f, p);
|
||||
strokeColor(255, 255, 255, 255);
|
||||
circle(x, y, circleRadius);
|
||||
fill();
|
||||
stroke();
|
||||
closePath();
|
||||
beginPath();
|
||||
fillColor(1.f, 1.f, 1.f, p);
|
||||
strokeColor(255, 255, 255, 255);
|
||||
circle(x, y, circleRadius);
|
||||
fill();
|
||||
stroke();
|
||||
closePath();
|
||||
|
||||
beginPath();
|
||||
strokeColor(1.f, 1.f, 1.f, z);
|
||||
circle(x, y, z * circleRadius);
|
||||
stroke();
|
||||
closePath();
|
||||
}
|
||||
beginPath();
|
||||
strokeColor(1.f, 1.f, 1.f, z);
|
||||
circle(x, y, z * circleRadius);
|
||||
stroke();
|
||||
closePath();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
|
||||
// Tablet context handler
|
||||
Tablet tab;
|
||||
Packet pkt = { 0 };
|
||||
Packet lastPkt = { 0 };
|
||||
|
||||
// Button mapping widgets
|
||||
ButtonMappingWidget AButtonWidget;
|
||||
ButtonMappingWidget BButtonWidget;
|
||||
|
||||
|
||||
/**
|
||||
Set our UI class as non-copyable and add a leak detector just in case.
|
||||
*/
|
||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TabUI)
|
||||
};
|
||||
|
||||
|
||||
|
||||
UI* createUI()
|
||||
UI *createUI()
|
||||
{
|
||||
return new TabUI();
|
||||
}
|
||||
|
||||
|
||||
END_NAMESPACE_DISTRHO
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#include "DistrhoUI.hpp"
|
||||
#include "tablet.h"
|
||||
#ifdef DEBUG
|
||||
#include <format>
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
START_NAMESPACE_DISTRHO
|
||||
|
||||
class ButtonMappingWidget : public NanoSubWidget,
|
||||
public ButtonEventHandler
|
||||
{
|
||||
public:
|
||||
explicit ButtonMappingWidget(
|
||||
Widget *parent,
|
||||
float initialSize,
|
||||
float initialX,
|
||||
float initialY,
|
||||
Parameters associatedParameter,
|
||||
ButtonEventHandler::Callback *const callback);
|
||||
void onNanoDisplay() override;
|
||||
bool onMouse(const MouseEvent &ev) override;
|
||||
void setMask(const ButtonMask m) { mask = m; };
|
||||
bool matchesMask(const ButtonMask m) { return isPenPressed = (m && mask == m); };
|
||||
|
||||
bool isClicked;
|
||||
bool isPenPressed;
|
||||
|
||||
private:
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
float size = 0;
|
||||
const Parameters param;
|
||||
ButtonMask mask;
|
||||
};
|
||||
|
||||
class TabUI : public UI,
|
||||
public ButtonEventHandler::Callback
|
||||
{
|
||||
public:
|
||||
explicit TabUI();
|
||||
|
||||
void buttonClicked(SubWidget *const widget, int) override;
|
||||
void parameterChanged(uint32_t index, float value) override;
|
||||
|
||||
void uiIdle() override;
|
||||
bool onMouse(const MouseEvent &ev) override;
|
||||
bool onScroll(const ScrollEvent &ev) override;
|
||||
void onNanoDisplay() override;
|
||||
|
||||
private:
|
||||
void getTabletData();
|
||||
void setButtonsValue(unsigned long buttonMask);
|
||||
void drawCircle(float x, float y, float z, float p);
|
||||
|
||||
// Tablet context handler
|
||||
Tablet tab;
|
||||
Packet pkt = {0};
|
||||
Packet lastPkt = {0};
|
||||
|
||||
// Button mapping widgets
|
||||
ButtonMappingWidget AButtonWidget;
|
||||
ButtonMappingWidget BButtonWidget;
|
||||
|
||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TabUI)
|
||||
};
|
||||
|
||||
END_NAMESPACE_DISTRHO
|
Loading…
Reference in New Issue