From a6961d66266d63ca893069356a046c57cd0dab4d Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 3 Jan 2019 22:51:05 -0500 Subject: [PATCH] Tear down old Module Browser, make app widgets and Core plugins compatible with NULL Module --- include/math.hpp | 9 +- include/widgets/ObstructWidget.hpp | 35 ++ include/widgets/ZoomWidget.hpp | 9 +- src/Core/AudioInterface.cpp | 3 +- src/Core/MIDICCToCVInterface.cpp | 13 +- src/Core/MIDIToCVInterface.cpp | 3 +- src/Core/MIDITriggerToCVInterface.cpp | 9 +- src/Core/QuadMIDIToCVInterface.cpp | 3 +- src/app/AudioWidget.cpp | 31 +- src/app/MidiWidget.cpp | 22 +- src/app/ModuleBrowser.cpp | 534 ++------------------------ src/app/ModuleLightWidget.cpp | 4 +- src/app/ParamQuantity.cpp | 20 + src/app/PortWidget.cpp | 3 + 14 files changed, 166 insertions(+), 532 deletions(-) create mode 100644 include/widgets/ObstructWidget.hpp diff --git a/include/math.hpp b/include/math.hpp index a75635ce..683af7eb 100644 --- a/include/math.hpp +++ b/include/math.hpp @@ -296,18 +296,15 @@ struct Rect { Rect zeroPos() const { return Rect(Vec(), size); } + /** Expands each corner + Use a negative delta to shrink. + */ Rect grow(Vec delta) const { Rect r; r.pos = pos.minus(delta); r.size = size.plus(delta.mult(2.f)); return r; } - Rect shrink(Vec delta) const { - Rect r; - r.pos = pos.plus(delta); - r.size = size.minus(delta.mult(2.f)); - return r; - } }; diff --git a/include/widgets/ObstructWidget.hpp b/include/widgets/ObstructWidget.hpp new file mode 100644 index 00000000..eda33df9 --- /dev/null +++ b/include/widgets/ObstructWidget.hpp @@ -0,0 +1,35 @@ +#pragma once +#include "widgets/Widget.hpp" + + +namespace rack { + + +/** Widget that consumes recursing events without giving a chance for children to consume. +*/ +struct ObstructWidget : virtual Widget { + void onHover(const event::Hover &e) override { + e.consume(this); + } + void onButton(const event::Button &e) override { + e.consume(this); + } + void onHoverKey(const event::HoverKey &e) override { + e.consume(this); + } + void onHoverText(const event::HoverText &e) override { + e.consume(this); + } + void onHoverScroll(const event::HoverScroll &e) override { + e.consume(this); + } + void onDragHover(const event::DragHover &e) override { + e.consume(this); + } + void onPathDrop(const event::PathDrop &e) override { + e.consume(this); + } +}; + + +} // namespace rack diff --git a/include/widgets/ZoomWidget.hpp b/include/widgets/ZoomWidget.hpp index 1b6184bc..4ad0347f 100644 --- a/include/widgets/ZoomWidget.hpp +++ b/include/widgets/ZoomWidget.hpp @@ -22,11 +22,12 @@ struct ZoomWidget : virtual Widget { } void setZoom(float zoom) { - if (zoom != this->zoom) { - event::Zoom eZoom; - Widget::onZoom(eZoom); - } this->zoom = zoom; + + event::Context eZoomContext; + event::Zoom eZoom; + eZoom.context = &eZoomContext; + Widget::onZoom(eZoom); } void draw(NVGcontext *vg) override { diff --git a/src/Core/AudioInterface.cpp b/src/Core/AudioInterface.cpp index fba200d0..b3a25d19 100644 --- a/src/Core/AudioInterface.cpp +++ b/src/Core/AudioInterface.cpp @@ -276,7 +276,8 @@ struct AudioInterfaceWidget : ModuleWidget { AudioWidget *audioWidget = createWidget(mm2px(Vec(3.2122073, 14.837339))); audioWidget->box.size = mm2px(Vec(44, 28)); - audioWidget->audioIO = &module->audioIO; + if (module) + audioWidget->audioIO = &module->audioIO; addChild(audioWidget); } }; diff --git a/src/Core/MIDICCToCVInterface.cpp b/src/Core/MIDICCToCVInterface.cpp index 60802785..9fbe1afc 100644 --- a/src/Core/MIDICCToCVInterface.cpp +++ b/src/Core/MIDICCToCVInterface.cpp @@ -119,6 +119,10 @@ struct MidiCcChoice : GridChoice { } void step() override { + if (!module) { + text = ""; + return; + } if (module->learningId == id) { if (0 <= focusCc) text = string::f("%d", focusCc); @@ -136,11 +140,15 @@ struct MidiCcChoice : GridChoice { void onSelect(const event::Select &e) override { e.consume(this); + if (!module) + return; module->learningId = id; focusCc = -1; } void onDeselect(const event::Deselect &e) override { + if (!module) + return; if (0 <= focusCc && focusCc < 128) { module->learnedCcs[id] = focusCc; } @@ -159,7 +167,7 @@ struct MidiCcChoice : GridChoice { void onSelectKey(const event::SelectKey &e) override { if (context()->event->selectedWidget == this) { - if (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) { + if (e.action == GLFW_PRESS && (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER)) { event::Deselect eDeselect; onDeselect(eDeselect); context()->event->selectedWidget = NULL; @@ -209,7 +217,8 @@ struct MIDICCToCVInterfaceWidget : ModuleWidget { MidiCcWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); midiWidget->module = module; midiWidget->box.size = mm2px(Vec(44, 54.667)); - midiWidget->midiIO = &module->midiInput; + if (module) + midiWidget->midiIO = &module->midiInput; midiWidget->createGridChoices(); addChild(midiWidget); } diff --git a/src/Core/MIDIToCVInterface.cpp b/src/Core/MIDIToCVInterface.cpp index 2d712b2a..330858e7 100644 --- a/src/Core/MIDIToCVInterface.cpp +++ b/src/Core/MIDIToCVInterface.cpp @@ -283,7 +283,8 @@ struct MIDIToCVInterfaceWidget : ModuleWidget { MidiWidget *midiWidget = createWidget(mm2px(Vec(3.41891, 14.8373))); midiWidget->box.size = mm2px(Vec(33.840, 28)); - midiWidget->midiIO = &module->midiInput; + if (module) + midiWidget->midiIO = &module->midiInput; addChild(midiWidget); } diff --git a/src/Core/MIDITriggerToCVInterface.cpp b/src/Core/MIDITriggerToCVInterface.cpp index ee0bbc3c..88942777 100644 --- a/src/Core/MIDITriggerToCVInterface.cpp +++ b/src/Core/MIDITriggerToCVInterface.cpp @@ -159,6 +159,8 @@ struct MidiTrigChoice : GridChoice { } void step() override { + if (!module) + return; if (module->learningId == id) { text = "LRN"; color.a = 0.5; @@ -180,10 +182,14 @@ struct MidiTrigChoice : GridChoice { void onSelect(const event::Select &e) override { e.consume(this); + if (!module) + return; module->learningId = id; } void onDeselect(const event::Deselect &e) override { + if (!module) + return; module->learningId = -1; } }; @@ -228,7 +234,8 @@ struct MIDITriggerToCVInterfaceWidget : ModuleWidget { MidiTrigWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); midiWidget->module = module; midiWidget->box.size = mm2px(Vec(44, 54.667)); - midiWidget->midiIO = &module->midiInput; + if (module) + midiWidget->midiIO = &module->midiInput; midiWidget->createGridChoices(); addChild(midiWidget); } diff --git a/src/Core/QuadMIDIToCVInterface.cpp b/src/Core/QuadMIDIToCVInterface.cpp index 6aeaca21..e3999ea4 100644 --- a/src/Core/QuadMIDIToCVInterface.cpp +++ b/src/Core/QuadMIDIToCVInterface.cpp @@ -329,7 +329,8 @@ struct QuadMIDIToCVInterfaceWidget : ModuleWidget { MidiWidget *midiWidget = createWidget(mm2px(Vec(3.4009969, 14.837336))); midiWidget->box.size = mm2px(Vec(44, 28)); - midiWidget->midiIO = &module->midiInput; + if (module) + midiWidget->midiIO = &module->midiInput; addChild(midiWidget); } diff --git a/src/app/AudioWidget.cpp b/src/app/AudioWidget.cpp index 712093ef..b39a13f1 100644 --- a/src/app/AudioWidget.cpp +++ b/src/app/AudioWidget.cpp @@ -17,6 +17,9 @@ struct AudioDriverItem : MenuItem { struct AudioDriverChoice : LedDisplayChoice { AudioWidget *audioWidget; void onAction(const event::Action &e) override { + if (!audioWidget->audioIO) + return; + Menu *menu = createMenu(); menu->addChild(createMenuLabel("Audio driver")); for (int driver : audioWidget->audioIO->getDrivers()) { @@ -29,7 +32,10 @@ struct AudioDriverChoice : LedDisplayChoice { } } void step() override { - text = audioWidget->audioIO->getDriverName(audioWidget->audioIO->driver); + if (audioWidget->audioIO) + text = audioWidget->audioIO->getDriverName(audioWidget->audioIO->driver); + else + text = ""; } }; @@ -49,6 +55,9 @@ struct AudioDeviceChoice : LedDisplayChoice { int maxTotalChannels = 128; void onAction(const event::Action &e) override { + if (!audioWidget->audioIO) + return; + Menu *menu = createMenu(); menu->addChild(createMenuLabel("Audio device")); int deviceCount = audioWidget->audioIO->getDeviceCount(); @@ -74,6 +83,10 @@ struct AudioDeviceChoice : LedDisplayChoice { } } void step() override { + if (!audioWidget->audioIO) { + text = ""; + return; + } text = audioWidget->audioIO->getDeviceDetail(audioWidget->audioIO->device, audioWidget->audioIO->offset); if (text.empty()) { text = "(No device)"; @@ -97,6 +110,9 @@ struct AudioSampleRateItem : MenuItem { struct AudioSampleRateChoice : LedDisplayChoice { AudioWidget *audioWidget; void onAction(const event::Action &e) override { + if (!audioWidget->audioIO) + return; + Menu *menu = createMenu(); menu->addChild(createMenuLabel("Sample rate")); std::vector sampleRates = audioWidget->audioIO->getSampleRates(); @@ -113,7 +129,10 @@ struct AudioSampleRateChoice : LedDisplayChoice { } } void step() override { - text = string::f("%g kHz", audioWidget->audioIO->sampleRate / 1000.f); + if (audioWidget->audioIO) + text = string::f("%g kHz", audioWidget->audioIO->sampleRate / 1000.f); + else + text = ""; } }; @@ -129,6 +148,9 @@ struct AudioBlockSizeItem : MenuItem { struct AudioBlockSizeChoice : LedDisplayChoice { AudioWidget *audioWidget; void onAction(const event::Action &e) override { + if (!audioWidget->audioIO) + return; + Menu *menu = createMenu(); menu->addChild(createMenuLabel("Block size")); std::vector blockSizes = audioWidget->audioIO->getBlockSizes(); @@ -146,7 +168,10 @@ struct AudioBlockSizeChoice : LedDisplayChoice { } } void step() override { - text = string::f("%d", audioWidget->audioIO->blockSize); + if (audioWidget->audioIO) + text = string::f("%d", audioWidget->audioIO->blockSize); + else + text = ""; } }; diff --git a/src/app/MidiWidget.cpp b/src/app/MidiWidget.cpp index 41e8d44b..564bea75 100644 --- a/src/app/MidiWidget.cpp +++ b/src/app/MidiWidget.cpp @@ -17,6 +17,9 @@ struct MidiDriverItem : MenuItem { struct MidiDriverChoice : LedDisplayChoice { MidiWidget *midiWidget; void onAction(const event::Action &e) override { + if (!midiWidget->midiIO) + return; + Menu *menu = createMenu(); menu->addChild(createMenuLabel("MIDI driver")); for (int driverId : midiWidget->midiIO->getDriverIds()) { @@ -29,6 +32,10 @@ struct MidiDriverChoice : LedDisplayChoice { } } void step() override { + if (!midiWidget->midiIO) { + text = ""; + return; + } text = midiWidget->midiIO->getDriverName(midiWidget->midiIO->driverId); if (text.empty()) { text = "(No driver)"; @@ -51,6 +58,9 @@ struct MidiDeviceItem : MenuItem { struct MidiDeviceChoice : LedDisplayChoice { MidiWidget *midiWidget; void onAction(const event::Action &e) override { + if (!midiWidget->midiIO) + return; + Menu *menu = createMenu(); menu->addChild(createMenuLabel("MIDI device")); { @@ -71,6 +81,10 @@ struct MidiDeviceChoice : LedDisplayChoice { } } void step() override { + if (!midiWidget->midiIO) { + text = ""; + return; + } text = midiWidget->midiIO->getDeviceName(midiWidget->midiIO->deviceId); if (text.empty()) { text = "(No device)"; @@ -93,6 +107,9 @@ struct MidiChannelItem : MenuItem { struct MidiChannelChoice : LedDisplayChoice { MidiWidget *midiWidget; void onAction(const event::Action &e) override { + if (!midiWidget->midiIO) + return; + Menu *menu = createMenu(); menu->addChild(createMenuLabel("MIDI channel")); for (int channel = -1; channel < 16; channel++) { @@ -105,7 +122,10 @@ struct MidiChannelChoice : LedDisplayChoice { } } void step() override { - text = midiWidget->midiIO->getChannelName(midiWidget->midiIO->channel); + if (midiWidget->midiIO) + text = midiWidget->midiIO->getChannelName(midiWidget->midiIO->channel); + else + text = ""; } }; diff --git a/src/app/ModuleBrowser.cpp b/src/app/ModuleBrowser.cpp index c42a14c0..c8989875 100644 --- a/src/app/ModuleBrowser.cpp +++ b/src/app/ModuleBrowser.cpp @@ -10,13 +10,12 @@ #include "app/Scene.hpp" #include "ui/List.hpp" #include "ui/TextField.hpp" +#include "widgets/ObstructWidget.hpp" +#include "widgets/ZoomWidget.hpp" #include "plugin.hpp" #include "context.hpp" -static const float itemMargin = 2.0; - - namespace rack { @@ -26,533 +25,46 @@ static std::string sTagFilter; -bool isMatch(std::string s, std::string search) { - s = string::lowercase(s); - search = string::lowercase(search); - return (s.find(search) != std::string::npos); -} - -static bool isModelMatch(Model *model, std::string search) { - if (search.empty()) - return true; - std::string s; - s += model->plugin->slug; - s += " "; - s += model->plugin->author; - s += " "; - s += model->name; - s += " "; - s += model->slug; - for (std::string tag : model->tags) { - std::string allowedTag = plugin::getAllowedTag(tag); - if (!allowedTag.empty()) { - s += " "; - s += allowedTag; - } - } - return isMatch(s, search); -} - - -struct FavoriteQuantity : Quantity { - std::string getString() override { - return "★"; - } -}; - - -struct FavoriteRadioButton : RadioButton { - Model *model = NULL; - - FavoriteRadioButton() { - quantity = new FavoriteQuantity; - } - - void onAction(const event::Action &e) override; -}; - - -struct SeparatorItem : OpaqueWidget { - SeparatorItem() { - box.size.y = 2*BND_WIDGET_HEIGHT + 2*itemMargin; - } - - void setText(std::string text) { - clearChildren(); - Label *label = createWidget