diff --git a/plugins/editor/src/editor/Editor.cpp b/plugins/editor/src/editor/Editor.cpp index 67694856..bc7b4d71 100644 --- a/plugins/editor/src/editor/Editor.cpp +++ b/plugins/editor/src/editor/Editor.cpp @@ -162,11 +162,11 @@ struct Editor::Impl : EditorController::Receiver, SharedPointer backgroundBitmap_; SharedPointer defaultBackgroundBitmap_; - CControl* getSecondaryCCControl(unsigned cc) + SKnobCCBox* getSecondaryCCKnob(unsigned cc) { switch (cc) { - case 7: return volumeCCKnob_ ? volumeCCKnob_->getControl() : nullptr; - case 10: return panCCKnob_ ? panCCKnob_->getControl() : nullptr; + case 7: return volumeCCKnob_ ? volumeCCKnob_ : nullptr; + case 10: return panCCKnob_ ? panCCKnob_ : nullptr; default: return nullptr; } } @@ -906,6 +906,10 @@ void Editor::Impl::createFrameContents() box->setCCLabelFont(font); OnThemeChanged.push_back([box, palette]() { box->setNameLabelFontColor(palette->knobText); + box->setValueEditFontColor(palette->knobText); + auto shadingColor = palette->knobText; + shadingColor.alpha = 70; + box->setShadingRectangleColor(shadingColor); box->setCCLabelFontColor(palette->knobLabelText); box->setCCLabelBackColor(palette->knobLabelBackground); box->setKnobFontColor(palette->knobText); @@ -913,10 +917,6 @@ void Editor::Impl::createFrameContents() box->setKnobActiveTrackColor(palette->knobActiveTrack); box->setKnobInactiveTrackColor(palette->knobInactiveTrack); }); - box->setValueToStringFunction([](float value, std::string& text) -> bool { - text = std::to_string(std::lround(value * 127)); - return true; - }); return box; }; auto createBackground = [&background](const CRect& bounds, int, const char*, CHoriTxtAlign, int) { @@ -932,6 +932,10 @@ void Editor::Impl::createFrameContents() panel->setCCLabelFont(font); OnThemeChanged.push_back([panel, palette]() { panel->setNameLabelFontColor(palette->knobText); + panel->setValueEditFontColor(palette->knobText); + auto shadingColor = palette->knobText; + shadingColor.alpha = 70; + panel->setShadingRectangleColor(shadingColor); panel->setCCLabelFontColor(palette->knobLabelText); panel->setCCLabelBackColor(palette->knobLabelBackground); panel->setKnobFontColor(palette->knobText); @@ -1665,7 +1669,7 @@ void Editor::Impl::updateCCValue(unsigned cc, float value) if (SControlsPanel* panel = controlsPanel_) panel->setControlValue(cc, value); - if (CControl* other = getSecondaryCCControl(cc)) { + if (SKnobCCBox* other = getSecondaryCCKnob(cc)) { other->setValue(value); other->invalid(); } @@ -1676,7 +1680,7 @@ void Editor::Impl::updateCCDefaultValue(unsigned cc, float value) if (SControlsPanel* panel = controlsPanel_) panel->setControlDefaultValue(cc, value); - if (CControl* other = getSecondaryCCControl(cc)) + if (SKnobCCBox* other = getSecondaryCCKnob(cc)) other->setDefaultValue(value); } diff --git a/plugins/editor/src/editor/GUIComponents.cpp b/plugins/editor/src/editor/GUIComponents.cpp index 769503fc..968b13c4 100644 --- a/plugins/editor/src/editor/GUIComponents.cpp +++ b/plugins/editor/src/editor/GUIComponents.cpp @@ -15,6 +15,7 @@ #include "vstgui/lib/cvstguitimer.h" #include "vstgui/lib/cframe.h" #include "utility/vstgui_after.h" +#include "absl/strings/numbers.h" /// SBoxContainer::SBoxContainer(const CRect& size) @@ -517,12 +518,6 @@ void SStyledKnob::setFontColor(CColor fontColor) invalid(); } -void SStyledKnob::setValueToStringFunction(ValueToStringFunction func) -{ - valueToStringFunction_ = std::move(func); - invalid(); -} - void SStyledKnob::draw(CDrawContext* dc) { const CCoord lineWidth = 4.0; @@ -581,14 +576,18 @@ void SStyledKnob::draw(CDrawContext* dc) dc->setLineStyle(kLineSolid); dc->drawLine(p1, p2); } +} - if (valueToStringFunction_ && fontColor_.alpha > 0) { - std::string text; - if (valueToStringFunction_(getValue(), text)) { - dc->setFont(font_); - dc->setFontColor(fontColor_); - dc->drawString(text.c_str(), bounds); - } +void CFilledRect::draw(CDrawContext* dc) +{ + CRect bounds = getViewSize(); + dc->setFillColor(color_); + bool isRounded = radius_ > 0.0; + if (isRounded) { + auto roundRect = owned(dc->createRoundRectGraphicsPath(bounds, radius_)); + dc->drawGraphicsPath(roundRect, CDrawContext::kPathFilled); + } else { + dc->drawRect(bounds, kDrawFilled); } } @@ -596,8 +595,12 @@ void SStyledKnob::draw(CDrawContext* dc) SKnobCCBox::SKnobCCBox(const CRect& size, IControlListener* listener, int32_t tag) : CViewContainer(size), label_(makeOwned(CRect())), + valueEdit_(makeOwned(CRect(), listener, tag)), knob_(makeOwned(CRect(), listener, tag)), - ccLabel_(makeOwned(CRect())) + ccLabel_(makeOwned(CRect())), + shadingRectangle_(makeOwned(CRect())), + menuEntry_(makeOwned("Use HDCC", tag)), + menuListener_(owned(new MenuListener(*this))) { setBackgroundColor(CColor(0x00, 0x00, 0x00, 0x00)); @@ -614,17 +617,118 @@ SKnobCCBox::SKnobCCBox(const CRect& size, IControlListener* listener, int32_t ta ccLabel_->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); ccLabel_->setFontColor(CColor(0xff, 0xff, 0xff)); + valueEdit_->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + valueEdit_->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + valueEdit_->setFontColor(CColor(0x00, 0x00, 0x00, 0xff)); + valueEdit_->registerViewListener(this); + setHDMode(false); + valueEdit_->setVisible(true); + + shadingRectangle_->setVisible(false); + addView(label_); label_->remember(); addView(knob_); knob_->remember(); + addView(shadingRectangle_); + shadingRectangle_->remember(); + addView(valueEdit_); + valueEdit_->remember(); addView(ccLabel_); ccLabel_->remember(); - updateViewColors(); updateViewSizes(); } +SKnobCCBox::~SKnobCCBox() +{ + valueEdit_->unregisterViewListener(this); +} + +void SKnobCCBox::setHDMode(bool mode) +{ + if (mode) { + valueEdit_->setValueToStringFunction2([](float value, std::string& text, VSTGUI::CParamDisplay*) -> bool { + std::string s = std::to_string(value + 0.005f); + text = s.substr(0, 4); + return true; + }); + valueEdit_->setStringToValueFunction([](UTF8StringPtr txt, float& result, CTextEdit*) -> bool { + float value; + if (absl::SimpleAtof(txt, &value)) { + result = value; + return true; + } + + return false; + }); + menuEntry_->setTitle("Use low-res. CC"); + } else { + valueEdit_->setValueToStringFunction2([](float value, std::string& text, VSTGUI::CParamDisplay*) -> bool { + text = std::to_string(std::lround(value * 127)); + return true; + }); + valueEdit_->setStringToValueFunction([](UTF8StringPtr txt, float& result, CTextEdit*) -> bool { + float value; + if (absl::SimpleAtof(txt, &value)) { + result = value / 127.0f; + return true; + } + + return false; + }); + menuEntry_->setTitle("Use high-res. CC"); + } + + hdMode_ = mode; + valueEdit_->setValue(valueEdit_->getValue()); + invalid(); +} + +CMouseEventResult SKnobCCBox::onMouseDown(CPoint& where, const CButtonState& buttons) +{ + if (buttons.isRightButton()) { + CFrame* frame = getFrame(); + CPoint frameWhere = where; + frameWhere.offset(-getViewSize().left, -getViewSize().top); + this->localToFrame(frameWhere); + + auto self = shared(this); + frame->doAfterEventProcessing([self, frameWhere]() { + if (CFrame* frame = self->getFrame()) { + SharedPointer menu = + owned(new COptionMenu(CRect(), self->menuListener_, -1, nullptr, nullptr, COptionMenu::kPopupStyle)); + menu->addEntry(self->menuEntry_); + self->menuEntry_->remember(); // above call does not increment refcount + + menu->setFont(self->getValueEditFont()); + menu->setFontColor(self->getValueEditFontColor()); + menu->setBackColor(self->getValueEditBackColor()); + menu->popup(frame, frameWhere); + } + }); + return kMouseEventHandled; + } + + return CViewContainer::onMouseDown(where, buttons); +} + +void SKnobCCBox::viewLostFocus (CView* view) +{ + if (view == valueEdit_.get()) { + shadingRectangle_->setVisible(false); + invalid(); + } +} + +void SKnobCCBox::viewTookFocus (CView* view) +{ + if (view == valueEdit_.get()) { + shadingRectangle_->setVisible(true); + invalid(); + } +} + void SKnobCCBox::setHue(float hue) { hue_ = hue; @@ -637,12 +741,33 @@ void SKnobCCBox::setNameLabelFont(CFontRef font) updateViewSizes(); } +void SKnobCCBox::setValueEditFont(CFontRef font) +{ + label_->setFont(font); + updateViewSizes(); +} + void SKnobCCBox::setCCLabelFont(CFontRef font) { ccLabel_->setFont(font); updateViewSizes(); } +void SKnobCCBox::setValue(float value) +{ + float oldValue = knob_->getValue(); + knob_->setValue(value); + valueEdit_->setValue(value); + if (value != oldValue) + invalid(); +} + +void SKnobCCBox::setDefaultValue(float value) +{ + knob_->setDefaultValue(value); + valueEdit_->setDefaultValue(value); +} + void SKnobCCBox::updateViewSizes() { const CRect size = getViewSize(); @@ -650,10 +775,17 @@ void SKnobCCBox::updateViewSizes() const CFontRef nameFont = label_->getFont(); const CFontRef ccFont = ccLabel_->getFont(); + const CFontRef valueFont = valueEdit_->getFont(); nameLabelSize_ = CRect(0.0, 0.0, size.getWidth(), nameFont->getSize() + 2 * ypad); ccLabelSize_ = CRect(0.0, size.getHeight() - ccFont->getSize() - 2 * ypad, size.getWidth(), size.getHeight()); knobSize_ = CRect(0.0, nameLabelSize_.bottom, size.getWidth(), ccLabelSize_.top); + valueEditSize_ = CRect( + size.getWidth() / 2 - valueFont->getSize(), + size.getHeight() / 2 - valueFont->getSize() / 2, + size.getWidth() / 2 + valueFont->getSize(), + size.getHeight() / 2 + valueFont->getSize() / 2 + ); // remove knob side areas CCoord side = std::max(0.0, knobSize_.getWidth() - knobSize_.getHeight()); @@ -663,6 +795,8 @@ void SKnobCCBox::updateViewSizes() label_->setViewSize(nameLabelSize_); knob_->setViewSize(knobSize_); ccLabel_->setViewSize(ccLabelSize_); + valueEdit_->setViewSize(valueEditSize_); + shadingRectangle_->setViewSize(knobSize_); invalid(); } @@ -746,11 +880,6 @@ SControlsPanel::ControlSlot* SControlsPanel::getOrCreateSlot(uint32_t index) slot->box = box; slot->box->setCCLabelText(("CC " + std::to_string(index)).c_str()); - slot->box->setValueToStringFunction([](float value, std::string& text) -> bool { - text = std::to_string(std::lround(value * 127)); - return true; - }); - syncSlotStyle(index); return slot; @@ -760,10 +889,9 @@ void SControlsPanel::setControlValue(uint32_t index, float value) { ControlSlot* slot = getOrCreateSlot(index); SKnobCCBox* box = slot->box; - auto* control = box->getControl(); - float oldValue = control->getValue(); - control->setValue(value); - if (control->getValue() != oldValue) + float oldValue = box->getValue(); + box->setValue(value); + if (box->getValue() != oldValue) box->invalid(); } @@ -771,7 +899,7 @@ void SControlsPanel::setControlDefaultValue(uint32_t index, float value) { ControlSlot* slot = getOrCreateSlot(index); SKnobCCBox* box = slot->box; - box->getControl()->setDefaultValue(value); + box->setDefaultValue(value); } void SControlsPanel::setControlLabelText(uint32_t index, UTF8StringPtr text) @@ -788,12 +916,14 @@ void SControlsPanel::setControlLabelText(uint32_t index, UTF8StringPtr text) void SControlsPanel::setNameLabelFont(CFontRef font) { slots_[0]->box->setNameLabelFont(font); + slots_[0]->box->setValueEditFont(font); syncAllSlotStyles(); } void SControlsPanel::setNameLabelFontColor(CColor color) { slots_[0]->box->setNameLabelFontColor(color); + slots_[0]->box->setValueEditFontColor(color); syncAllSlotStyles(); } @@ -815,6 +945,24 @@ void SControlsPanel::setCCLabelFontColor(CColor color) syncAllSlotStyles(); } +void SControlsPanel::setValueEditBackColor(CColor color) +{ + slots_[0]->box->setValueEditBackColor(color); + syncAllSlotStyles(); +} + +void SControlsPanel::setShadingRectangleColor(CColor color) +{ + slots_[0]->box->setShadingRectangleColor(color); + syncAllSlotStyles(); +} + +void SControlsPanel::setValueEditFontColor(CColor color) +{ + slots_[0]->box->setValueEditFontColor(color); + syncAllSlotStyles(); +} + void SControlsPanel::setKnobActiveTrackColor(CColor color) { slots_[0]->box->setKnobActiveTrackColor(color); @@ -947,6 +1095,11 @@ void SControlsPanel::syncSlotStyle(uint32_t index) cur->setNameLabelFont(ref->getNameLabelFont()); cur->setNameLabelFontColor(ref->getNameLabelFontColor()); + cur->setValueEditFont(ref->getValueEditFont()); + cur->setValueEditFontColor(ref->getValueEditFontColor()); + + cur->setShadingRectangleColor(ref->getShadingRectangleColor()); + cur->setCCLabelFont(ref->getCCLabelFont()); cur->setCCLabelFontColor(ref->getCCLabelFontColor()); cur->setCCLabelBackColor(ref->getCCLabelBackColor()); diff --git a/plugins/editor/src/editor/GUIComponents.h b/plugins/editor/src/editor/GUIComponents.h index 8161154f..9ff96eeb 100644 --- a/plugins/editor/src/editor/GUIComponents.h +++ b/plugins/editor/src/editor/GUIComponents.h @@ -14,6 +14,7 @@ #include "vstgui/lib/controls/cslider.h" #include "vstgui/lib/controls/cknob.h" #include "vstgui/lib/controls/ctextlabel.h" +#include "vstgui/lib/controls/ctextedit.h" #include "vstgui/lib/controls/cbuttons.h" #include "vstgui/lib/controls/coptionmenu.h" #include "vstgui/lib/controls/cscrollbar.h" @@ -230,9 +231,6 @@ public: void setFontColor(CColor fontColor); CColor getFontColor() const { return fontColor_; } - using ValueToStringFunction = std::function; - void setValueToStringFunction(ValueToStringFunction func); - CLASS_METHODS(SStyledKnob, CKnobBase) protected: void draw(CDrawContext* dc) override; @@ -244,16 +242,37 @@ private: SharedPointer font_ = kNormalFont; CColor fontColor_ { 0x00, 0x00, 0x00 }; +}; - ValueToStringFunction valueToStringFunction_; +class CFilledRect : public CView +{ +public: + explicit CFilledRect(const CRect& size) + : CView(size) {} + + void setRadius(CCoord radius) { radius_ = radius; invalid(); } + CCoord getRadius() const { return radius_; } + + void setColor(CColor color){ color_ = color; invalid(); } + CColor getColor() { return color_; } +protected: + void draw(CDrawContext* dc) override; +private: + CCoord radius_ { 5.0 }; + CColor color_ { 0, 0, 0, 70 }; }; /// -class SKnobCCBox : public CViewContainer { +class SKnobCCBox : public CViewContainer, ViewListenerAdapter { public: SKnobCCBox(const CRect& size, IControlListener* listener, int32_t tag); + ~SKnobCCBox(); void setHue(float hue); - SStyledKnob* getControl() const { return knob_; } + + float getValue() const { return knob_->getValue(); } + float getDefaultValue() const { return knob_->getDefaultValue(); } + void setValue(float value); + void setDefaultValue(float value); void setNameLabelText(const UTF8String& name) { label_->setText(name); label_->invalid(); } void setCCLabelText(const UTF8String& name) { ccLabel_->setText(name); ccLabel_->invalid(); } @@ -264,6 +283,18 @@ public: void setNameLabelFontColor(CColor color) { label_->setFontColor(color); label_->invalid(); } CColor getNameLabelFontColor() const { return label_->getFontColor(); } + void setValueEditFont(CFontRef font); + CFontRef getValueEditFont() const { return label_->getFont(); } + + void setValueEditFontColor(CColor color) { valueEdit_->setFontColor(color); valueEdit_->invalid(); } + CColor getValueEditFontColor() const { return valueEdit_->getFontColor(); } + + void setValueEditBackColor(CColor color) { valueEdit_->setBackColor(color); valueEdit_->invalid(); } + CColor getValueEditBackColor() const { return valueEdit_->getBackColor(); } + + void setShadingRectangleColor(CColor color) { shadingRectangle_->setColor(color); shadingRectangle_->invalid(); } + CColor getShadingRectangleColor() const { return shadingRectangle_->getColor(); } + void setCCLabelFont(CFontRef font); CFontRef getCCLabelFont() const { return ccLabel_->getFont(); } @@ -288,21 +319,43 @@ public: void setKnobFontColor(CColor color) { knob_->setFontColor(color); knob_->invalid(); } CColor getKnobFontColor() const { return knob_->getFontColor(); } - using ValueToStringFunction = SStyledKnob::ValueToStringFunction; - void setValueToStringFunction(ValueToStringFunction f) { knob_->setValueToStringFunction(std::move(f)); knob_->invalid(); } + void viewLostFocus (CView* view) override; + void viewTookFocus (CView* view) override; + + bool isHD() const noexcept { return hdMode_; } + void setHDMode(bool mode); + +protected: + CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons) override; private: void updateViewSizes(); void updateViewColors(); - -private: SharedPointer label_; + SharedPointer valueEdit_; SharedPointer knob_; SharedPointer ccLabel_; + SharedPointer shadingRectangle_; + SharedPointer menuEntry_; CRect nameLabelSize_; CRect knobSize_; CRect ccLabelSize_; + CRect valueEditSize_; + CRect rectangleSize_; float hue_ = 0.35; + + class MenuListener : public IControlListener, public NonAtomicReferenceCounted { + public: + explicit MenuListener(SKnobCCBox& box) : box_(box) {} + void valueChanged(CControl*) override + { + box_.setHDMode(!box_.isHD()); + } + private: + SKnobCCBox& box_; + }; + SharedPointer menuListener_; + bool hdMode_ { false }; }; /// @@ -320,6 +373,9 @@ public: void setCCLabelFont(CFontRef font); void setCCLabelBackColor(CColor color); void setCCLabelFontColor(CColor color); + void setValueEditBackColor(CColor color); + void setValueEditFontColor(CColor color); + void setShadingRectangleColor(CColor color); void setKnobActiveTrackColor(CColor color); void setKnobInactiveTrackColor(CColor color); void setKnobLineIndicatorColor(CColor color); diff --git a/plugins/editor/src/editor/GUIPiano.cpp b/plugins/editor/src/editor/GUIPiano.cpp index 9ecc86b7..13204475 100644 --- a/plugins/editor/src/editor/GUIPiano.cpp +++ b/plugins/editor/src/editor/GUIPiano.cpp @@ -188,7 +188,7 @@ void SPiano::draw(CDrawContext* dc) case KeyRole::Switch: hcy.h = impl.keySwitchHue_; break; - default: whiteKeyDefault: + default: hcy.y = 1.0; if (impl.keyval_[key]) hcy.c = 0.0; @@ -226,7 +226,7 @@ void SPiano::draw(CDrawContext* dc) case KeyRole::Switch: hcy.h = impl.keySwitchHue_; break; - default: blackKeyDefault: + default: hcy.c = 0.0; break; }