DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

InfoExampleUI.cpp (9326B)


      1 /*
      2  * DISTRHO Plugin Framework (DPF)
      3  * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
      4  *
      5  * Permission to use, copy, modify, and/or distribute this software for any purpose with
      6  * or without fee is hereby granted, provided that the above copyright notice and this
      7  * permission notice appear in all copies.
      8  *
      9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
     10  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
     11  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
     13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include "DistrhoUI.hpp"
     18 
     19 #include "ResizeHandle.hpp"
     20 
     21 START_NAMESPACE_DISTRHO
     22 
     23 using DGL_NAMESPACE::ResizeHandle;
     24 
     25 // -----------------------------------------------------------------------------------------------------------
     26 
     27 class InfoExampleUI : public UI
     28 {
     29 public:
     30     InfoExampleUI()
     31         : UI(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT),
     32           fSampleRate(getSampleRate()),
     33           fResizable(isResizable()),
     34           fScale(1.0f),
     35           fScaleFactor(getScaleFactor()),
     36           fResizeHandle(this)
     37     {
     38         std::memset(fParameters, 0, sizeof(float)*kParameterCount);
     39         std::memset(fStrBuf, 0, sizeof(char)*(0xff+1));
     40 
     41        #ifdef DGL_NO_SHARED_RESOURCES
     42         createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
     43        #else
     44         loadSharedResources();
     45        #endif
     46 
     47         if (d_isNotEqual(fScaleFactor, 1.0))
     48         {
     49             const uint width = DISTRHO_UI_DEFAULT_WIDTH * fScaleFactor;
     50             const uint height = DISTRHO_UI_DEFAULT_HEIGHT * fScaleFactor;
     51             setGeometryConstraints(width, height, true);
     52             setSize(width, height);
     53         }
     54         else
     55         {
     56             setGeometryConstraints(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT, true);
     57         }
     58 
     59         // no need to show resize handle if window is user-resizable
     60         if (fResizable)
     61             fResizeHandle.hide();
     62     }
     63 
     64 protected:
     65    /* --------------------------------------------------------------------------------------------------------
     66     * DSP/Plugin Callbacks */
     67 
     68    /**
     69       A parameter has changed on the plugin side.
     70       This is called by the host to inform the UI about parameter changes.
     71     */
     72     void parameterChanged(uint32_t index, float value) override
     73     {
     74         // some hosts send parameter change events for output parameters even when nothing changed
     75         // we catch that here in order to prevent excessive repaints
     76         if (d_isEqual(fParameters[index], value))
     77             return;
     78 
     79         fParameters[index] = value;
     80         repaint();
     81     }
     82 
     83    /* --------------------------------------------------------------------------------------------------------
     84     * DSP/Plugin Callbacks (optional) */
     85 
     86    /**
     87       Optional callback to inform the UI about a sample rate change on the plugin side.
     88     */
     89     void sampleRateChanged(double newSampleRate) override
     90     {
     91         fSampleRate = newSampleRate;
     92         repaint();
     93     }
     94 
     95    /* --------------------------------------------------------------------------------------------------------
     96     * Widget Callbacks */
     97 
     98    /**
     99       The NanoVG drawing function.
    100     */
    101     void onNanoDisplay() override
    102     {
    103         const float lineHeight = 20 * fScale;
    104 
    105         fontSize(15.0f * fScale);
    106         textLineHeight(lineHeight);
    107 
    108         float x = 0.0f * fScale;
    109         float y = 15.0f * fScale;
    110 
    111         // buffer size
    112         drawLeft(x, y, "Buffer Size:");
    113         drawRight(x, y, getTextBufInt(fParameters[kParameterBufferSize]));
    114         y+=lineHeight;
    115 
    116         // sample rate
    117         drawLeft(x, y, "Sample Rate:");
    118         drawRight(x, y, getTextBufFloat(fSampleRate));
    119         y+=lineHeight;
    120 
    121         // separator
    122         y+=lineHeight;
    123 
    124         // time stuff
    125         drawLeft(x, y, "Playing:");
    126         drawRight(x, y, (fParameters[kParameterTimePlaying] > 0.5f) ? "Yes" : "No");
    127         y+=lineHeight;
    128 
    129         drawLeft(x, y, "Frame:");
    130         drawRight(x, y, getTextBufInt(fParameters[kParameterTimeFrame]));
    131         y+=lineHeight;
    132 
    133         drawLeft(x, y, "Time:");
    134         drawRight(x, y, getTextBufTime(fParameters[kParameterTimeFrame]));
    135         y+=lineHeight;
    136 
    137         // separator
    138         y+=lineHeight;
    139 
    140         // param changes
    141         drawLeft(x, y, "Param Changes:", 20);
    142         drawRight(x, y, (fParameters[kParameterCanRequestParameterValueChanges] > 0.5f) ? "Yes" : "No", 40);
    143         y+=lineHeight;
    144 
    145         // resizable
    146         drawLeft(x, y, "Host resizable:", 20);
    147         drawRight(x, y, fResizable ? "Yes" : "No", 40);
    148         y+=lineHeight;
    149 
    150         // host scale factor
    151         drawLeft(x, y, "Host scale factor:", 20);
    152         drawRight(x, y, getTextBufFloat(fScaleFactor), 40);
    153         y+=lineHeight;
    154 
    155         // BBT
    156         x = 200.0f * fScale;
    157         y = 15.0f * fScale;
    158 
    159         const bool validBBT(fParameters[kParameterTimeValidBBT] > 0.5f);
    160         drawLeft(x, y, "BBT Valid:");
    161         drawRight(x, y, validBBT ? "Yes" : "No");
    162         y+=lineHeight;
    163 
    164         if (! validBBT)
    165             return;
    166 
    167         drawLeft(x, y, "Bar:");
    168         drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBar]));
    169         y+=lineHeight;
    170 
    171         drawLeft(x, y, "Beat:");
    172         drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBeat]));
    173         y+=lineHeight;
    174 
    175         drawLeft(x, y, "Tick:");
    176         drawRight(x, y, getTextBufFloatExtra(fParameters[kParameterTimeTick]));
    177         y+=lineHeight;
    178 
    179         drawLeft(x, y, "Bar Start Tick:");
    180         drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBarStartTick]));
    181         y+=lineHeight;
    182 
    183         drawLeft(x, y, "Beats Per Bar:");
    184         drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerBar]));
    185         y+=lineHeight;
    186 
    187         drawLeft(x, y, "Beat Type:");
    188         drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatType]));
    189         y+=lineHeight;
    190 
    191         drawLeft(x, y, "Ticks Per Beat:");
    192         drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeTicksPerBeat]));
    193         y+=lineHeight;
    194 
    195         drawLeft(x, y, "BPM:");
    196         drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerMinute]));
    197         y+=lineHeight;
    198     }
    199 
    200     void onResize(const ResizeEvent& ev) override
    201     {
    202         fScale = static_cast<float>(ev.size.getHeight())/static_cast<float>(DISTRHO_UI_DEFAULT_HEIGHT);
    203 
    204         UI::onResize(ev);
    205     }
    206 
    207     void uiScaleFactorChanged(const double scaleFactor) override
    208     {
    209         fScaleFactor = scaleFactor;
    210     }
    211 
    212     // -------------------------------------------------------------------------------------------------------
    213 
    214 private:
    215     // Parameters
    216     float  fParameters[kParameterCount];
    217     double fSampleRate;
    218 
    219     // UI stuff
    220     bool fResizable;
    221     float fScale; // our internal scaling
    222     double fScaleFactor; // host reported scale factor
    223     ResizeHandle fResizeHandle;
    224 
    225     // temp buf for text
    226     char fStrBuf[0xff+1];
    227 
    228     // helpers for putting text into fStrBuf and returning it
    229     const char* getTextBufInt(const int value)
    230     {
    231         std::snprintf(fStrBuf, 0xff, "%i", value);
    232         return fStrBuf;
    233     }
    234 
    235     const char* getTextBufFloat(const float value)
    236     {
    237         std::snprintf(fStrBuf, 0xff, "%.1f", value);
    238         return fStrBuf;
    239     }
    240 
    241     const char* getTextBufFloatExtra(const float value)
    242     {
    243         std::snprintf(fStrBuf, 0xff, "%.2f", value + 0.001f);
    244         return fStrBuf;
    245     }
    246 
    247     const char* getTextBufTime(const uint64_t frame)
    248     {
    249         const uint32_t time = frame / uint64_t(fSampleRate);
    250         const uint32_t secs =  time % 60;
    251         const uint32_t mins = (time / 60) % 60;
    252         const uint32_t hrs  = (time / 3600) % 60;
    253         std::snprintf(fStrBuf, 0xff, "%02i:%02i:%02i", hrs, mins, secs);
    254         return fStrBuf;
    255     }
    256 
    257     // helpers for drawing text
    258     void drawLeft(float x, const float y, const char* const text, const int offset = 0)
    259     {
    260         const float width = (100.0f + offset) * fScale;
    261         x += offset * fScale;
    262         beginPath();
    263         fillColor(200, 200, 200);
    264         textAlign(ALIGN_RIGHT|ALIGN_TOP);
    265         textBox(x, y, width, text);
    266         closePath();
    267     }
    268 
    269     void drawRight(float x, const float y, const char* const text, const int offset = 0)
    270     {
    271         const float width = (100.0f + offset) * fScale;
    272         x += offset * fScale;
    273         beginPath();
    274         fillColor(255, 255, 255);
    275         textAlign(ALIGN_LEFT|ALIGN_TOP);
    276         textBox(x + (105 * fScale), y, width, text);
    277         closePath();
    278     }
    279 
    280    /**
    281       Set our UI class as non-copyable and add a leak detector just in case.
    282     */
    283     DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(InfoExampleUI)
    284 };
    285 
    286 /* ------------------------------------------------------------------------------------------------------------
    287  * UI entry point, called by DPF to create a new UI instance. */
    288 
    289 UI* createUI()
    290 {
    291     return new InfoExampleUI();
    292 }
    293 
    294 // -----------------------------------------------------------------------------------------------------------
    295 
    296 END_NAMESPACE_DISTRHO