Merge pull request #945 from paulfd/cc-input

CC input
This commit is contained in:
Paul Ferrand 2021-09-21 21:37:22 +02:00 committed by GitHub
commit 2ca137f22e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 285 additions and 31 deletions

View file

@ -162,11 +162,11 @@ struct Editor::Impl : EditorController::Receiver,
SharedPointer<CBitmap> backgroundBitmap_;
SharedPointer<CBitmap> 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);
}

View file

@ -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)
@ -582,7 +583,7 @@ void SStyledKnob::draw(CDrawContext* dc)
dc->drawLine(p1, p2);
}
if (valueToStringFunction_ && fontColor_.alpha > 0) {
if (valueToStringFunction_ && fontColor_.alpha > 0 && !hideValue_) {
std::string text;
if (valueToStringFunction_(getValue(), text)) {
dc->setFont(font_);
@ -592,12 +593,29 @@ void SStyledKnob::draw(CDrawContext* dc)
}
}
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);
}
}
///
SKnobCCBox::SKnobCCBox(const CRect& size, IControlListener* listener, int32_t tag)
: CViewContainer(size),
label_(makeOwned<CTextLabel>(CRect())),
valueEdit_(makeOwned<CTextEdit>(CRect(), listener, tag)),
knob_(makeOwned<SStyledKnob>(CRect(), listener, tag)),
ccLabel_(makeOwned<CTextLabel>(CRect()))
ccLabel_(makeOwned<CTextLabel>(CRect())),
shadingRectangle_(makeOwned<CFilledRect>(CRect())),
menuEntry_(makeOwned<CMenuItem>("Use HDCC", tag)),
menuListener_(owned(new MenuListener(*this)))
{
setBackgroundColor(CColor(0x00, 0x00, 0x00, 0x00));
@ -614,17 +632,129 @@ 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(false);
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) {
auto valueToString = [](float value, std::string& text, VSTGUI::CParamDisplay*) -> bool {
std::string s = std::to_string(value + 0.005f);
text = s.substr(0, 4);
return true;
};
knob_->setValueToStringFunction([valueToString](float value, std::string& text) {
return valueToString(value, text, nullptr);
});
valueEdit_->setValueToStringFunction2(valueToString);
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 {
auto valueToString = [](float value, std::string& text, VSTGUI::CParamDisplay*) -> bool {
text = std::to_string(std::lround(value * 127));
return true;
};
knob_->setValueToStringFunction([valueToString](float value, std::string& text) {
return valueToString(value, text, nullptr);
});
valueEdit_->setValueToStringFunction2(valueToString);
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<COptionMenu> 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;
} else if (buttons.isDoubleClick() && !valueEdit_->isVisible()) {
valueEdit_->setVisible(true);
shadingRectangle_->setVisible(true);
knob_->setHideValue(true);
valueEdit_->takeFocus();
invalid();
return kMouseEventHandled;
}
return CViewContainer::onMouseDown(where, buttons);
}
void SKnobCCBox::viewLostFocus (CView* view)
{
if (view == valueEdit_.get()) {
shadingRectangle_->setVisible(false);
valueEdit_->setVisible(false);
knob_->setHideValue(false);
invalid();
}
}
void SKnobCCBox::setHue(float hue)
{
hue_ = hue;
@ -637,12 +767,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,19 +801,30 @@ 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());
knobSize_.extend(-0.5 * side, 0.0);
shadingRectangleSize_ = knobSize_;
shadingRectangleSize_.bottom -= ypad;
//
label_->setViewSize(nameLabelSize_);
knob_->setViewSize(knobSize_);
ccLabel_->setViewSize(ccLabelSize_);
valueEdit_->setViewSize(valueEditSize_);
shadingRectangle_->setViewSize(shadingRectangleSize_);
invalid();
}
@ -746,11 +908,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 +917,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 +927,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 +944,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 +973,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 +1123,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());

View file

@ -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"
@ -233,6 +234,9 @@ public:
using ValueToStringFunction = std::function<bool(float value, std::string& result)>;
void setValueToStringFunction(ValueToStringFunction func);
void setHideValue(bool hide) { hideValue_ = hide; invalid(); }
bool getHideValue() const { return hideValue_; }
CLASS_METHODS(SStyledKnob, CKnobBase)
protected:
void draw(CDrawContext* dc) override;
@ -241,6 +245,7 @@ private:
CColor activeTrackColor_;
CColor inactiveTrackColor_;
CColor lineIndicatorColor_;
bool hideValue_ { false };
SharedPointer<CFontDesc> font_ = kNormalFont;
CColor fontColor_ { 0x00, 0x00, 0x00 };
@ -248,12 +253,35 @@ private:
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 +292,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 +328,44 @@ 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(); }
// Edit box listener
void viewLostFocus (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<CTextLabel> label_;
SharedPointer<CTextEdit> valueEdit_;
SharedPointer<SStyledKnob> knob_;
SharedPointer<CTextLabel> ccLabel_;
SharedPointer<CFilledRect> shadingRectangle_;
SharedPointer<CMenuItem> menuEntry_;
CRect nameLabelSize_;
CRect knobSize_;
CRect shadingRectangleSize_;
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> menuListener_;
bool hdMode_ { false };
};
///
@ -320,6 +383,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);

View file

@ -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;
}

View file

@ -101,7 +101,7 @@ struct sfizz_ui_t : EditorController, VSTGUIEditorInterface {
/// VSTGUIEditorInterface
CFrame* getFrame() const override { return uiFrame.get(); }
int32_t getKnobMode () const override { return kLinearMode; }
LV2_Atom_Forge atom_forge;
LV2_URID atom_event_transfer_uri;
LV2_URID atom_object_uri;

View file

@ -145,6 +145,9 @@ tresult PLUGIN_API SfizzVstControllerNoUi::initialize(FUnknown* context)
addProgramList(list);
list->addRef();
// Use linear knobs
setKnobMode(kLinearMode);
return kResultTrue;
}