SendNoteExampleUI.cpp (5114B)
1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2021 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 "Color.hpp" 20 21 #include <cstring> 22 23 START_NAMESPACE_DISTRHO 24 25 /** 26 We need a few classes from DGL. 27 */ 28 using DGL_NAMESPACE::Color; 29 using DGL_NAMESPACE::GraphicsContext; 30 using DGL_NAMESPACE::Rectangle; 31 32 // ----------------------------------------------------------------------------------------------------------- 33 34 class SendNoteExampleUI : public UI 35 { 36 public: 37 SendNoteExampleUI() 38 : UI(64*12+8, 64+8), 39 fLastKey(-1) 40 { 41 std::memset(fKeyState, 0, sizeof(fKeyState)); 42 } 43 44 protected: 45 /* -------------------------------------------------------------------------------------------------------- 46 * DSP/Plugin Callbacks */ 47 48 /** 49 A parameter has changed on the plugin side. 50 This is called by the host to inform the UI about parameter changes. 51 */ 52 void parameterChanged(uint32_t index, float value) override 53 { 54 (void)index; 55 (void)value; 56 } 57 58 /* -------------------------------------------------------------------------------------------------------- 59 * Widget Callbacks */ 60 61 /** 62 The OpenGL drawing function. 63 This UI will draw a row of 12 keys, with on/off states according to pressed status. 64 */ 65 void onDisplay() override 66 { 67 const GraphicsContext& context(getGraphicsContext()); 68 69 for (int key = 0; key < 12; ++key) 70 { 71 bool pressed = fKeyState[key]; 72 Rectangle<int> bounds = getKeyBounds(key); 73 74 if (pressed) 75 Color(0.8f, 0.5f, 0.3f).setFor(context); 76 else 77 Color(0.3f, 0.5f, 0.8f).setFor(context); 78 79 bounds.draw(context); 80 } 81 } 82 83 /** 84 Mouse press event. 85 This UI will de/activate keys when you click them and reports it as MIDI note events to the plugin. 86 */ 87 bool onMouse(const MouseEvent& ev) override 88 { 89 // Test for last key release first 90 if (fLastKey != -1 && ! ev.press) 91 { 92 // Send a note event. Velocity=0 means off 93 sendNote(0, kNoteOctaveStart+fLastKey, 0); 94 // Unset key state 95 fKeyState[fLastKey] = false; 96 fLastKey = -1; 97 repaint(); 98 return true; 99 } 100 101 // Test for left-clicked first. 102 if (ev.button != 1) 103 return false; 104 105 // Find the key which is pressed, if any 106 int whichKey = -1; 107 for (int key = 0; key < 12 && whichKey == -1; ++key) 108 { 109 Rectangle<int> bounds = getKeyBounds(key); 110 111 if (bounds.contains(ev.pos)) 112 whichKey = key; 113 } 114 115 if (whichKey == -1) 116 return false; 117 if (fKeyState[whichKey] == ev.press) 118 return false; 119 120 // Send a note event. Velocity=0 means off 121 sendNote(0, kNoteOctaveStart+whichKey, ev.press ? kNoteVelocity : 0); 122 123 // Set pressed state of this key, and update display 124 fLastKey = whichKey; 125 fKeyState[whichKey] = ev.press; 126 repaint(); 127 128 return true; 129 } 130 131 /** 132 Set our UI class as non-copyable and add a leak detector just in case. 133 */ 134 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SendNoteExampleUI) 135 136 private: 137 /** 138 Get the bounds of a particular key of the virtual MIDI keyboard. 139 */ 140 Rectangle<int> getKeyBounds(unsigned index) const 141 { 142 Rectangle<int> bounds; 143 int padding = 8; 144 bounds.setX(64 * index + padding); 145 bounds.setY(padding); 146 bounds.setWidth(64 - padding); 147 bounds.setHeight(64 - padding); 148 return bounds; 149 } 150 151 /** 152 The pressed state of one octave of a virtual MIDI keyboard. 153 */ 154 bool fKeyState[12]; 155 int8_t fLastKey; 156 157 enum 158 { 159 kNoteVelocity = 100, // velocity of sent Note-On events 160 kNoteOctaveStart = 60, // starting note of the virtual MIDI keyboard 161 }; 162 }; 163 164 /* ------------------------------------------------------------------------------------------------------------ 165 * UI entry point, called by DPF to create a new UI instance. */ 166 167 UI* createUI() 168 { 169 return new SendNoteExampleUI(); 170 } 171 172 // ----------------------------------------------------------------------------------------------------------- 173 174 END_NAMESPACE_DISTRHO