diff --git a/plugins/editor/src/editor/Editor.cpp b/plugins/editor/src/editor/Editor.cpp index 14987bf1..173d7166 100644 --- a/plugins/editor/src/editor/Editor.cpp +++ b/plugins/editor/src/editor/Editor.cpp @@ -164,6 +164,7 @@ struct Editor::Impl : EditorController::Receiver, IControlListener { void updateTuningFrequencyLabel(float tuningFrequency); void updateStretchedTuningLabel(float stretchedTuning); + void updateKeyUsed(unsigned key, bool used); void updateCCUsed(unsigned cc, bool used); void updateCCValue(unsigned cc, float value); void updateCCDefaultValue(unsigned cc, float value); @@ -394,7 +395,12 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi unsigned indices[8]; if (Messages::matchOSC("/key/slots", path, indices) && !strcmp(sig, "b")) { - // TODO(jpc) key ranges + size_t numBits = 8 * args[0].b->size; + ConstBitSpan bits { args[0].b->data, numBits }; + for (unsigned key = 0; key < 128; ++key) { + bool used = key < numBits && bits.test(key); + updateKeyUsed(key, used); + } } else if (Messages::matchOSC("/cc/slots", path, indices) && !strcmp(sig, "b")) { size_t numBits = 8 * args[0].b->size; @@ -1274,6 +1280,12 @@ void Editor::Impl::updateStretchedTuningLabel(float stretchedTuning) label->setText(text); } +void Editor::Impl::updateKeyUsed(unsigned key, bool used) +{ + if (SPiano* piano = piano_) + piano->setKeyUsed(key, used); +} + void Editor::Impl::updateCCUsed(unsigned cc, bool used) { if (SControlsPanel* panel = controlsPanel_) diff --git a/plugins/editor/src/editor/GUIPiano.cpp b/plugins/editor/src/editor/GUIPiano.cpp index 2c17ddc4..b2c00459 100644 --- a/plugins/editor/src/editor/GUIPiano.cpp +++ b/plugins/editor/src/editor/GUIPiano.cpp @@ -5,6 +5,7 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #include "GUIPiano.h" +#include "ColorHelpers.h" #include "utility/vstgui_before.h" #include "vstgui/lib/cdrawcontext.h" #include "vstgui/lib/cgraphicspath.h" @@ -37,6 +38,18 @@ void SPiano::setNumOctaves(unsigned octs) invalid(); } +void SPiano::setKeyUsed(unsigned key, bool used) +{ + if (key >= 128) + return; + + if (keyUsed_.test(key) == used) + return; + + keyUsed_.set(key, used); + invalid(); +} + void SPiano::draw(CDrawContext* dc) { const Dimensions dim = getDimensions(false); @@ -56,9 +69,17 @@ void SPiano::draw(CDrawContext* dc) for (unsigned key = 0; key < keyCount; ++key) { if (!black[key % 12]) { CRect rect = keyRect(key); - CColor keycolor = whiteFill_; + + SColorHCY hcy(keyUsedHue_, 1.0, whiteKeyLuma_); + if (!keyUsed_[key]) { + hcy.y = 1.0; + if (keyval_[key]) + hcy.c = 0.0; + } if (keyval_[key]) - keycolor = pressedFill_; + hcy.y = std::max(0.0f, hcy.y - keyLumaPressDelta_); + + CColor keycolor = hcy.toColor(); dc->setFillColor(keycolor); dc->drawRect(rect, kDrawFilled); } @@ -76,9 +97,14 @@ void SPiano::draw(CDrawContext* dc) for (unsigned key = 0; key < keyCount; ++key) { if (black[key % 12]) { CRect rect = keyRect(key); - CColor keycolor = blackFill_; + + SColorHCY hcy(keyUsedHue_, 1.0, blackKeyLuma_); + if (!keyUsed_[key]) + hcy.c = 0.0; if (keyval_[key]) - keycolor = pressedFill_; + hcy.y = std::max(0.0f, hcy.y - keyLumaPressDelta_); + + CColor keycolor = hcy.toColor(); dc->setFillColor(keycolor); dc->drawRect(rect, kDrawFilled); dc->setFrameColor(outline_); diff --git a/plugins/editor/src/editor/GUIPiano.h b/plugins/editor/src/editor/GUIPiano.h index 6927b06f..13e3ac4e 100644 --- a/plugins/editor/src/editor/GUIPiano.h +++ b/plugins/editor/src/editor/GUIPiano.h @@ -11,6 +11,7 @@ #include "utility/vstgui_after.h" #include #include +#include using namespace VSTGUI; @@ -24,6 +25,8 @@ public: unsigned getNumOctaves() const { return octs_; } void setNumOctaves(unsigned octs); + void setKeyUsed(unsigned key, bool used); + std::function onKeyPressed; std::function onKeyReleased; @@ -52,6 +55,7 @@ private: private: unsigned octs_ {}; std::vector keyval_; + std::bitset<128> keyUsed_; unsigned mousePressedKey_ = ~0u; CCoord innerPaddingX_ = 4.0; @@ -60,9 +64,12 @@ private: CColor backgroundFill_ { 0xca, 0xca, 0xca, 0xff }; float backgroundRadius_ = 5.0; - CColor whiteFill_ { 0xee, 0xee, 0xec, 0xff }; - CColor blackFill_ { 0x2e, 0x34, 0x36, 0xff }; - CColor pressedFill_ { 0xa0, 0xa0, 0xa0, 0xff }; + + float keyUsedHue_ = 0.55; + float whiteKeyLuma_ = 0.5; + float blackKeyLuma_ = 0.25; + float keyLumaPressDelta_ = 0.20; + CColor outline_ { 0x00, 0x00, 0x00, 0xff }; CColor shadeOutline_ { 0x80, 0x80, 0x80, 0xff }; CColor labelStroke_ { 0x63, 0x63, 0x63, 0xff };