- Add an EditValue in the knob
- Shade the knobs when editing
- Right-click on the knob allows to change from low resolution to high resolution CC
This commit is contained in:
Paul Fd 2021-07-07 01:27:33 +02:00
parent af902ee8b0
commit f34de3e3c9
4 changed files with 259 additions and 46 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)
@ -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<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 +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<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;
}
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());

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"
@ -230,9 +231,6 @@ public:
void setFontColor(CColor fontColor);
CColor getFontColor() const { return fontColor_; }
using ValueToStringFunction = std::function<bool(float value, std::string& result)>;
void setValueToStringFunction(ValueToStringFunction func);
CLASS_METHODS(SStyledKnob, CKnobBase)
protected:
void draw(CDrawContext* dc) override;
@ -244,16 +242,37 @@ private:
SharedPointer<CFontDesc> 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<CTextLabel> label_;
SharedPointer<CTextEdit> valueEdit_;
SharedPointer<SStyledKnob> knob_;
SharedPointer<CTextLabel> ccLabel_;
SharedPointer<CFilledRect> shadingRectangle_;
SharedPointer<CMenuItem> 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> 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);

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