diff --git a/src/yaw-tab/DistrhoPluginInfo.h b/src/yaw-tab/DistrhoPluginInfo.h index 29286c6..ffdcd0e 100644 --- a/src/yaw-tab/DistrhoPluginInfo.h +++ b/src/yaw-tab/DistrhoPluginInfo.h @@ -23,7 +23,8 @@ enum Parameters { ktpay, ktpaz, ktpap, - ktpab, + kParameterButtonA, + kParameterButtonB, kParameterTime, kParameterCount }; diff --git a/src/yaw-tab/dsp.cpp b/src/yaw-tab/dsp.cpp index 69642b5..0091087 100644 --- a/src/yaw-tab/dsp.cpp +++ b/src/yaw-tab/dsp.cpp @@ -49,16 +49,19 @@ protected: parameter.name = "p"; parameter.symbol = "p"; break; - case ktpab: - parameter.name = "Buttons"; - parameter.symbol = "b"; - parameter.hints = kParameterIsAutomable | kParameterIsInteger; + case kParameterButtonA: + parameter.name = "Button A"; + parameter.symbol = "A"; + parameter.hints |= kParameterIsBoolean; + break; + case kParameterButtonB: + parameter.name = "Button B"; + parameter.symbol = "B"; + parameter.hints |= kParameterIsBoolean; break; case kParameterTime: parameter.name = "t"; parameter.symbol = "t"; - parameter.ranges.min = 0.0f; - parameter.ranges.max = 30.0f; parameter.hints = kParameterIsOutput; break; } @@ -88,7 +91,9 @@ protected: case ktpap: volume = val; break; - case ktpab: + case kParameterButtonA: + break; + case kParameterButtonB: break; } } diff --git a/src/yaw-tab/tablet.h b/src/yaw-tab/tablet.h index be3167d..3258e1e 100644 --- a/src/yaw-tab/tablet.h +++ b/src/yaw-tab/tablet.h @@ -6,6 +6,7 @@ #include #include "MSGPACK.H" #include "wintab.h" +typedef unsigned long ButtonMask; #endif @@ -14,7 +15,7 @@ struct Packet { float y; float z; float p; - unsigned long buttons; + ButtonMask buttons; bool operator==(const Packet& p) { return this->x == p.x && @@ -33,11 +34,9 @@ public: bool GetPacket( Packet &pkt ); bool initialized; std::string errormsg = ""; - -private: - Packet ext = { 0 }; +private: #ifdef YAW_USE_WINTAB void NewContext(HWND hwnd); HCTX hctx = NULL; diff --git a/src/yaw-tab/ui.cpp b/src/yaw-tab/ui.cpp index eeac73d..286896a 100644 --- a/src/yaw-tab/ui.cpp +++ b/src/yaw-tab/ui.cpp @@ -1,20 +1,87 @@ #include "DistrhoUI.hpp" #include "tablet.h" #include +#include 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(static_cast(size), static_cast(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 { - static const uint kInitialWidth = 405; - static const uint kInitialHeight = 256; + static const uint kInitialWidth = 800; + static const uint kInitialHeight = 600; public: TabUI() : UI(kInitialWidth, kInitialHeight), - fSampleRate(getSampleRate()), - fResizable(isResizable()), - tab(getWindow().getNativeWindowHandle()) + tab(getWindow().getNativeWindowHandle()), + AButtonWidget(this, 5.f, 0.f, 0.f, kParameterButtonA), + BButtonWidget(this, 50.f, 0.f, 0.f, kParameterButtonB) { #ifdef DGL_NO_SHARED_RESOURCES @@ -23,7 +90,8 @@ public: loadSharedResources(); #endif - setGeometryConstraints(kInitialWidth, kInitialHeight, true); + if (!tab.initialized) return; + //setGeometryConstraints(400, static_cast(300 * tabletAspectRatio), true, false); } protected: @@ -36,10 +104,24 @@ protected: 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) setParameterValue(ktpab, pkt.buttons); + 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); + + if (AButtonWidget.isClicked) AButtonWidget.setMask(buttonMask); + if (BButtonWidget.isClicked) BButtonWidget.setMask(buttonMask); + } + void parameterChanged(uint32_t index, float value) override { @@ -50,7 +132,6 @@ protected: case(ktpay): pkt.y = value; case(ktpaz): pkt.z = value; case(ktpap): pkt.p = value; - case(ktpab): pkt.buttons = static_cast(value); } return; } @@ -59,13 +140,6 @@ protected: repaint(); } - - void sampleRateChanged(double newSampleRate) override - { - fSampleRate = newSampleRate; - repaint(); - } - void uiIdle() override { getTabletData(); @@ -79,6 +153,20 @@ protected: 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(x + add + 0.5), static_cast(tabletAspectRatio * (x + add + 0.5))); + return true; + } + void onNanoDisplay() override { @@ -91,7 +179,7 @@ protected: std::make_format_args(tab.errormsg)); beginPath(); 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(); return; } @@ -144,34 +232,20 @@ protected: closePath(); } - void onResize(const ResizeEvent& ev) override - { - fScale = static_cast(ev.size.getHeight()) / static_cast(kInitialHeight); - - UI::onResize(ev); - } - - void uiScaleFactorChanged(const double scaleFactor) override - { - fScaleFactor = scaleFactor; - } // ------------------------------------------------------------------------------------------------------- private: - // Parameters - double fSampleRate; - - // UI stuff - bool fResizable; - float fScale; // our internal scaling - double fScaleFactor; // host reported scale factor // 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.