Button awareness

This commit is contained in:
yaw-man 2022-08-16 19:45:40 -03:00
parent b2eeb12fc3
commit 5846220601
4 changed files with 125 additions and 46 deletions

View File

@ -23,7 +23,8 @@ enum Parameters {
ktpay, ktpay,
ktpaz, ktpaz,
ktpap, ktpap,
ktpab, kParameterButtonA,
kParameterButtonB,
kParameterTime, kParameterTime,
kParameterCount kParameterCount
}; };

View File

@ -49,16 +49,19 @@ protected:
parameter.name = "p"; parameter.name = "p";
parameter.symbol = "p"; parameter.symbol = "p";
break; break;
case ktpab: case kParameterButtonA:
parameter.name = "Buttons"; parameter.name = "Button A";
parameter.symbol = "b"; parameter.symbol = "A";
parameter.hints = kParameterIsAutomable | kParameterIsInteger; parameter.hints |= kParameterIsBoolean;
break;
case kParameterButtonB:
parameter.name = "Button B";
parameter.symbol = "B";
parameter.hints |= kParameterIsBoolean;
break; break;
case kParameterTime: case kParameterTime:
parameter.name = "t"; parameter.name = "t";
parameter.symbol = "t"; parameter.symbol = "t";
parameter.ranges.min = 0.0f;
parameter.ranges.max = 30.0f;
parameter.hints = kParameterIsOutput; parameter.hints = kParameterIsOutput;
break; break;
} }
@ -88,7 +91,9 @@ protected:
case ktpap: case ktpap:
volume = val; volume = val;
break; break;
case ktpab: case kParameterButtonA:
break;
case kParameterButtonB:
break; break;
} }
} }

View File

@ -6,6 +6,7 @@
#include <Windows.h> #include <Windows.h>
#include "MSGPACK.H" #include "MSGPACK.H"
#include "wintab.h" #include "wintab.h"
typedef unsigned long ButtonMask;
#endif #endif
@ -14,7 +15,7 @@ struct Packet {
float y; float y;
float z; float z;
float p; float p;
unsigned long buttons; ButtonMask buttons;
bool operator==(const Packet& p) bool operator==(const Packet& p)
{ return { return
this->x == p.x && this->x == p.x &&
@ -33,11 +34,9 @@ public:
bool GetPacket( Packet &pkt ); bool GetPacket( Packet &pkt );
bool initialized; bool initialized;
std::string errormsg = ""; std::string errormsg = "";
private:
Packet ext = { 0 }; Packet ext = { 0 };
private:
#ifdef YAW_USE_WINTAB #ifdef YAW_USE_WINTAB
void NewContext(HWND hwnd); void NewContext(HWND hwnd);
HCTX hctx = NULL; HCTX hctx = NULL;

View File

@ -1,20 +1,87 @@
#include "DistrhoUI.hpp" #include "DistrhoUI.hpp"
#include "tablet.h" #include "tablet.h"
#include <format> #include <format>
#include <optional>
START_NAMESPACE_DISTRHO START_NAMESPACE_DISTRHO
//UI element for mapping the currently pressed pen button combination to a parameter.
class ButtonMappingWidget : public NanoSubWidget
{
public:
ButtonMappingWidget(
Widget* parent,
float initialSize,
float initialX,
float initialY,
Parameters associatedParameter) :
x(initialX),
y(initialY),
size(initialSize),
param(associatedParameter),
isClicked(false),
isPenPressed(false),
mask(0),
NanoSubWidget(parent)
{
setNeedsFullViewportDrawing(true);
setSize(Size<uint>(static_cast<uint>(size), static_cast<uint>(size)));
setAbsolutePos((int)x, (int)y);
}
void onNanoDisplay() override
{
beginPath();
strokeColor(200, 200, 200);
//if (isClicked)
fillColor(0.5f, 0.5f, 0.5f, 0.5f);
//roundedRect(x, y, size, size, 0.f);
circle(0.5 * getWidth(), 0.5 * getHeight(), 10.f);
closePath();
}
bool onMouse(const MouseEvent& ev) override
{
isClicked = ev.press && contains(ev.pos);
repaint();
return false;
}
void setMask(const ButtonMask m)
{
mask = m;
}
bool matchesMask(const ButtonMask m)
{
isPenPressed = (m && mask == m);
return isPenPressed;
}
bool isClicked;
bool isPenPressed;
private:
float x = 0;
float y = 0;
float size = 0;
const Parameters param;
ButtonMask mask;
};
class TabUI : public UI class TabUI : public UI
{ {
static const uint kInitialWidth = 405; static const uint kInitialWidth = 800;
static const uint kInitialHeight = 256; static const uint kInitialHeight = 600;
public: public:
TabUI() TabUI()
: UI(kInitialWidth, kInitialHeight), : UI(kInitialWidth, kInitialHeight),
fSampleRate(getSampleRate()), tab(getWindow().getNativeWindowHandle()),
fResizable(isResizable()), AButtonWidget(this, 5.f, 0.f, 0.f, kParameterButtonA),
tab(getWindow().getNativeWindowHandle()) BButtonWidget(this, 50.f, 0.f, 0.f, kParameterButtonB)
{ {
#ifdef DGL_NO_SHARED_RESOURCES #ifdef DGL_NO_SHARED_RESOURCES
@ -23,7 +90,8 @@ public:
loadSharedResources(); loadSharedResources();
#endif #endif
setGeometryConstraints(kInitialWidth, kInitialHeight, true); if (!tab.initialized) return;
//setGeometryConstraints(400, static_cast<uint>(300 * tabletAspectRatio), true, false);
} }
protected: protected:
@ -36,10 +104,24 @@ protected:
if (pkt.y != lastPkt.y) setParameterValue(ktpay, pkt.y); if (pkt.y != lastPkt.y) setParameterValue(ktpay, pkt.y);
if (pkt.z != lastPkt.z) setParameterValue(ktpaz, pkt.z); if (pkt.z != lastPkt.z) setParameterValue(ktpaz, pkt.z);
if (pkt.p != lastPkt.p) setParameterValue(ktpap, pkt.p); if (pkt.p != lastPkt.p) setParameterValue(ktpap, pkt.p);
if (pkt.buttons != lastPkt.buttons) setParameterValue(ktpab, pkt.buttons); if (pkt.buttons != lastPkt.buttons) setButtonsValue(pkt.buttons);
lastPkt = pkt; 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);
if (AButtonWidget.isClicked) AButtonWidget.setMask(buttonMask);
if (BButtonWidget.isClicked) BButtonWidget.setMask(buttonMask);
}
void parameterChanged(uint32_t index, float value) override void parameterChanged(uint32_t index, float value) override
{ {
@ -50,7 +132,6 @@ protected:
case(ktpay): pkt.y = value; case(ktpay): pkt.y = value;
case(ktpaz): pkt.z = value; case(ktpaz): pkt.z = value;
case(ktpap): pkt.p = value; case(ktpap): pkt.p = value;
case(ktpab): pkt.buttons = static_cast<unsigned long>(value);
} }
return; return;
} }
@ -59,13 +140,6 @@ protected:
repaint(); repaint();
} }
void sampleRateChanged(double newSampleRate) override
{
fSampleRate = newSampleRate;
repaint();
}
void uiIdle() override void uiIdle() override
{ {
getTabletData(); getTabletData();
@ -79,6 +153,20 @@ protected:
return false; //Allow event to propagate. 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 void onNanoDisplay() override
{ {
@ -91,7 +179,7 @@ protected:
std::make_format_args(tab.errormsg)); std::make_format_args(tab.errormsg));
beginPath(); beginPath();
fillColor(200, 200, 200); fillColor(200, 200, 200);
// textBox(0.f, 15.f, 250.f, err.c_str(), nullptr); textBox(0.f, 15.f, 250.f, err.c_str(), nullptr);
closePath(); closePath();
return; return;
} }
@ -144,34 +232,20 @@ protected:
closePath(); closePath();
} }
void onResize(const ResizeEvent& ev) override
{
fScale = static_cast<float>(ev.size.getHeight()) / static_cast<float>(kInitialHeight);
UI::onResize(ev);
}
void uiScaleFactorChanged(const double scaleFactor) override
{
fScaleFactor = scaleFactor;
}
// ------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------
private: private:
// Parameters
double fSampleRate;
// UI stuff
bool fResizable;
float fScale; // our internal scaling
double fScaleFactor; // host reported scale factor
// Tablet context handler // Tablet context handler
Tablet tab; Tablet tab;
Packet pkt = { 0 }; Packet pkt = { 0 };
Packet lastPkt = { 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. Set our UI class as non-copyable and add a leak detector just in case.