image_controls opcode to add a background image on Controls tab

This commit is contained in:
redtide 2023-04-12 16:19:17 +02:00
parent 4273cf47f9
commit aea0632dd1
13 changed files with 62 additions and 12 deletions

View file

@ -102,6 +102,7 @@ std::string getDescriptionBlob(sfizz_synth_t* handle)
synth.sendMessage(*client, 0, "/num_samples", "", nullptr); synth.sendMessage(*client, 0, "/num_samples", "", nullptr);
synth.sendMessage(*client, 0, "/root_path", "", nullptr); synth.sendMessage(*client, 0, "/root_path", "", nullptr);
synth.sendMessage(*client, 0, "/image", "", nullptr); synth.sendMessage(*client, 0, "/image", "", nullptr);
synth.sendMessage(*client, 0, "/image_controls", "", nullptr);
synth.sendMessage(*client, 0, "/key/slots", "", nullptr); synth.sendMessage(*client, 0, "/key/slots", "", nullptr);
synth.sendMessage(*client, 0, "/sw/last/slots", "", nullptr); synth.sendMessage(*client, 0, "/sw/last/slots", "", nullptr);
synth.sendMessage(*client, 0, "/cc/slots", "", nullptr); synth.sendMessage(*client, 0, "/cc/slots", "", nullptr);
@ -149,6 +150,8 @@ InstrumentDescription parseDescriptionBlob(absl::string_view blob)
desc.rootPath = args[0].s; desc.rootPath = args[0].s;
else if (Messages::matchOSC("/image", path, indices) && !strcmp(sig, "s")) else if (Messages::matchOSC("/image", path, indices) && !strcmp(sig, "s"))
desc.image = args[0].s; desc.image = args[0].s;
else if (Messages::matchOSC("/image_controls", path, indices) && !strcmp(sig, "s"))
desc.image_controls = args[0].s;
else if (Messages::matchOSC("/key/slots", path, indices) && !strcmp(sig, "b")) else if (Messages::matchOSC("/key/slots", path, indices) && !strcmp(sig, "b"))
copyArgToBitSpan(args[0], desc.keyUsed.span()); copyArgToBitSpan(args[0], desc.keyUsed.span());
else if (Messages::matchOSC("/sw/last/slots", path, indices) && !strcmp(sig, "b")) else if (Messages::matchOSC("/sw/last/slots", path, indices) && !strcmp(sig, "b"))
@ -187,6 +190,7 @@ std::ostream& operator<<(std::ostream& os, const InstrumentDescription& desc)
os << " root_path: " << desc.rootPath << "\n"; os << " root_path: " << desc.rootPath << "\n";
os << " image: " << desc.image << "\n"; os << " image: " << desc.image << "\n";
os << " image_controls: " << desc.image_controls << "\n";
os << " keys:\n"; os << " keys:\n";
for (unsigned i = 0; i < 128; ++i) { for (unsigned i = 0; i < 128; ++i) {

View file

@ -24,6 +24,7 @@ struct InstrumentDescription {
uint32_t numSamples {}; uint32_t numSamples {};
std::string rootPath; std::string rootPath;
std::string image; std::string image;
std::string image_controls;
BitArray<128> keyUsed {}; BitArray<128> keyUsed {};
BitArray<128> keyswitchUsed {}; BitArray<128> keyswitchUsed {};
BitArray<128> sustainOrSostenuto {}; BitArray<128> sustainOrSostenuto {};

View file

@ -22,7 +22,7 @@ SAboutDialog::SAboutDialog(const CRect& bounds)
: CViewContainer(bounds) : CViewContainer(bounds)
{ {
SharedPointer<CBitmap> logo = owned(new CBitmap("logo_orange.png")); SharedPointer<CBitmap> logo = owned(new CBitmap("logo_orange.png"));
setBackgroundColor(kColorControlsScroller); setBackgroundColor(kColorControlsScrollerTransparency);
CView* aboutView = nullptr; CView* aboutView = nullptr;
{ {

View file

@ -54,6 +54,7 @@ enum class EditId : int {
UIZoom, UIZoom,
// //
BackgroundImage, BackgroundImage,
ControlsImage,
// //
PluginFormat, PluginFormat,
PluginHost, PluginHost,

View file

@ -180,6 +180,7 @@ struct Editor::Impl : EditorController::Receiver,
SharedPointer<CBitmap> backgroundBitmap_; SharedPointer<CBitmap> backgroundBitmap_;
SharedPointer<CBitmap> defaultBackgroundBitmap_; SharedPointer<CBitmap> defaultBackgroundBitmap_;
SharedPointer<CBitmap> controlsBitmap_;
CTextLabel* sfizzVersionLabel_ = nullptr; CTextLabel* sfizzVersionLabel_ = nullptr;
@ -258,6 +259,7 @@ struct Editor::Impl : EditorController::Receiver,
void updateSWLastCurrent(int sw); void updateSWLastCurrent(int sw);
void updateSWLastLabel(unsigned sw, const char* label); void updateSWLastLabel(unsigned sw, const char* label);
void updateBackgroundImage(const char* filepath); void updateBackgroundImage(const char* filepath);
void updateControlsImage(const char* filepath);
void updateMemoryUsed(uint64_t mem); void updateMemoryUsed(uint64_t mem);
// edition of CC by UI // edition of CC by UI
@ -576,6 +578,12 @@ void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v)
updateBackgroundImage(value.c_str()); updateBackgroundImage(value.c_str());
} }
break; break;
case EditId::ControlsImage:
{
const std::string& value = v.to_string();
updateControlsImage(value.c_str());
}
break;
case EditId::PluginOutputs: case EditId::PluginOutputs:
{ {
const int value = static_cast<int>(v.to_float()); const int value = static_cast<int>(v.to_float());
@ -728,6 +736,7 @@ void Editor::Impl::createFrameContents()
defaultBackgroundBitmap_ = background; defaultBackgroundBitmap_ = background;
backgroundBitmap_ = background; backgroundBitmap_ = background;
controlsBitmap_ = nullptr;
{ {
theme = new Theme; theme = new Theme;
@ -764,7 +773,7 @@ void Editor::Impl::createFrameContents()
}; };
auto createSquaredTransparentGroup = [](const CRect& bounds, int, const char*, CHoriTxtAlign, int) { auto createSquaredTransparentGroup = [](const CRect& bounds, int, const char*, CHoriTxtAlign, int) {
auto* box = new CViewContainer(bounds); auto* box = new CViewContainer(bounds);
box->setBackgroundColor(kColorSemiTransparent); box->setBackgroundColor(kColorInfoTransparency);
return box; return box;
}; };
#if 0 #if 0
@ -1082,10 +1091,10 @@ void Editor::Impl::createFrameContents()
panel->setKnobFont(font); panel->setKnobFont(font);
panel->setKnobFontColor(kWhiteCColor); panel->setKnobFontColor(kWhiteCColor);
panel->setKnobLineIndicatorColor(kWhiteCColor); panel->setKnobLineIndicatorColor(kWhiteCColor);
panel->setKnobRotatorColor(kColorSemiTransparent); panel->setKnobRotatorColor(kColorControlsTransparency);
panel->setNameLabelFont(font); panel->setNameLabelFont(font);
panel->setNameLabelFontColor(kWhiteCColor); panel->setNameLabelFontColor(kWhiteCColor);
panel->setNameLabelBackColor(kColorSemiTransparent); panel->setNameLabelBackColor(kColorControlsTransparency);
OnThemeChanged.push_back([panel, palette]() { OnThemeChanged.push_back([panel, palette]() {
panel->setValueEditFontColor(palette->knobText); panel->setValueEditFontColor(palette->knobText);
auto shadingColor = palette->knobText; auto shadingColor = palette->knobText;
@ -1955,6 +1964,17 @@ void Editor::Impl::updateBackgroundImage(const char* filepath)
applyBackgroundForCurrentPanel(); applyBackgroundForCurrentPanel();
} }
void Editor::Impl::updateControlsImage(const char* filepath)
{
controlsBitmap_ = loadAnyFormatImage(filepath);
if (!controlsBitmap_) {
return;
}
applyBackgroundForCurrentPanel();
}
void Editor::Impl::setupCurrentPanel() void Editor::Impl::setupCurrentPanel()
{ {
for (unsigned i = 0; i < kNumPanels; ++i) { for (unsigned i = 0; i < kNumPanels; ++i) {
@ -1968,10 +1988,19 @@ void Editor::Impl::setupCurrentPanel()
void Editor::Impl::applyBackgroundForCurrentPanel() void Editor::Impl::applyBackgroundForCurrentPanel()
{ {
CBitmap* bitmap; CBitmap* bitmap;
if (activePanel_ == kPanelGeneral || activePanel_ == kPanelInfo) imageContainer_->setBackgroundColor(theme_->frameBackground);
if (activePanel_ == kPanelGeneral || activePanel_ == kPanelInfo) {
bitmap = backgroundBitmap_; bitmap = backgroundBitmap_;
else } else if (activePanel_ == kPanelControls) {
bitmap = defaultBackgroundBitmap_; bitmap = controlsBitmap_;
if (!controlsBitmap_) {
imageContainer_->setBackground(nullptr);
return;
}
} else {
return;
}
downscaleToWidthAndHeight(bitmap, imageContainer_->getViewSize().getSize()); downscaleToWidthAndHeight(bitmap, imageContainer_->getViewSize().getSize());

View file

@ -1094,7 +1094,7 @@ void SControlsPanel::recalculateSubViews()
// update scrollbar style // update scrollbar style
vsb->setFrameColor(kColorTransparent); vsb->setFrameColor(kColorTransparent);
vsb->setBackgroundColor(kColorTransparent); vsb->setBackgroundColor(kColorTransparent);
vsb->setScrollerColor(kColorControlsScroller); vsb->setScrollerColor(kColorControlsScrollerTransparency);
} }
} }

View file

@ -12,13 +12,14 @@
namespace gui { namespace gui {
const CColor kColorSemiTransparent { CColor(0x00, 0x00, 0x00, 0x99) };
const CColor kColorTransparent { CColor(0x00, 0x00, 0x00, 0x00) }; const CColor kColorTransparent { CColor(0x00, 0x00, 0x00, 0x00) };
const CColor kColorTransparentDark { CColor(0x00, 0x00, 0x00, 0xc0) }; const CColor kColorTransparentDark { CColor(0x00, 0x00, 0x00, 0xc0) };
const CColor kColorOrange { CColor(0xfd, 0x98, 0x00, 0xff) }; const CColor kColorOrange { CColor(0xfd, 0x98, 0x00, 0xff) };
const CColor kColorControlsScroller { CColor(0x00, 0x00, 0x00, 0x80) }; const CColor kColorControlsScrollerTransparency { CColor(0x00, 0x00, 0x00, 0x80) };
const CColor kColorControlsTransparency { CColor(0x00, 0x00, 0x00, 0x80) };
const CColor kColorInfoTransparency { CColor(0x00, 0x00, 0x00, 0x99) };
const CColor kColorMeterDanger { CColor(0xaa, 0x00, 0x00) }; const CColor kColorMeterDanger { CColor(0xaa, 0x00, 0x00) };
const CColor kColorMeterNormal { CColor(0x00, 0xaa, 0x11) }; const CColor kColorMeterNormal { CColor(0x00, 0xaa, 0x11) };
const CColor kColorTooltipBackground { CColor(0xff, 0xff, 0xd2, 0xff) }; const CColor kColorTooltipBackground { CColor(0xff, 0xff, 0xd2, 0xff) };

View file

@ -14,13 +14,14 @@ using VSTGUI::CColor;
namespace gui { namespace gui {
extern const CColor kColorSemiTransparent;
extern const CColor kColorTransparent; extern const CColor kColorTransparent;
extern const CColor kColorTransparentDark; extern const CColor kColorTransparentDark;
extern const CColor kColorOrange; extern const CColor kColorOrange;
extern const CColor kColorControlsScroller; extern const CColor kColorControlsScrollerTransparency;
extern const CColor kColorControlsTransparency;
extern const CColor kColorInfoTransparency;
extern const CColor kColorMeterDanger; extern const CColor kColorMeterDanger;
extern const CColor kColorMeterNormal; extern const CColor kColorMeterNormal;
extern const CColor kColorTooltipBackground; extern const CColor kColorTooltipBackground;

View file

@ -560,7 +560,9 @@ sfizz_ui_update_description(sfizz_ui_t *self, const InstrumentDescription& desc)
const fs::path rootPath = fs::u8path(desc.rootPath); const fs::path rootPath = fs::u8path(desc.rootPath);
const fs::path imagePath = rootPath / fs::u8path(desc.image); const fs::path imagePath = rootPath / fs::u8path(desc.image);
const fs::path imageCtrlPath = rootPath / fs::u8path(desc.image_controls);
self->uiReceiveValue(EditId::BackgroundImage, imagePath.u8string()); self->uiReceiveValue(EditId::BackgroundImage, imagePath.u8string());
self->uiReceiveValue(EditId::ControlsImage, imageCtrlPath.u8string());
for (unsigned key = 0; key < 128; ++key) { for (unsigned key = 0; key < 128; ++key) {
bool keyUsed = desc.keyUsed.test(key); bool keyUsed = desc.keyUsed.test(key);

View file

@ -238,6 +238,9 @@ bool SfizzVstEditor::processUpdate(FUnknown* changedUnknown, int32 message)
const fs::path imagePath = rootPath / fs::u8path(desc.image); const fs::path imagePath = rootPath / fs::u8path(desc.image);
uiReceiveValue(EditId::BackgroundImage, imagePath.u8string()); uiReceiveValue(EditId::BackgroundImage, imagePath.u8string());
const fs::path ctrlImagePath = rootPath / fs::u8path(desc.image_controls);
uiReceiveValue(EditId::ControlsImage, ctrlImagePath.u8string());
for (unsigned key = 0; key < 128; ++key) { for (unsigned key = 0; key < 128; ++key) {
bool keyUsed = desc.keyUsed.test(key); bool keyUsed = desc.keyUsed.test(key);
bool keyswitchUsed = desc.keyswitchUsed.test(key); bool keyswitchUsed = desc.keyswitchUsed.test(key);

View file

@ -429,6 +429,9 @@ void Synth::Impl::handleControlOpcodes(const std::vector<Opcode>& members)
case hash("image"): case hash("image"):
image_ = absl::StrCat(defaultPath_, absl::StrReplaceAll(trim(member.value), { { "\\", "/" } })); image_ = absl::StrCat(defaultPath_, absl::StrReplaceAll(trim(member.value), { { "\\", "/" } }));
break; break;
case hash("image_controls"):
image_controls_ = absl::StrCat(defaultPath_, absl::StrReplaceAll(trim(member.value), { { "\\", "/" } }));
break;
case hash("note_offset"): case hash("note_offset"):
noteOffset_ = member.read(Default::noteOffset); noteOffset_ = member.read(Default::noteOffset);
break; break;

View file

@ -125,6 +125,10 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co
client.receive<'s'>(delay, path, impl.image_.c_str()); client.receive<'s'>(delay, path, impl.image_.c_str());
} break; } break;
MATCH("/image_controls", "") {
client.receive<'s'>(delay, path, impl.image_controls_.c_str());
} break;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
MATCH("/sw/last/slots", "") { MATCH("/sw/last/slots", "") {

View file

@ -334,6 +334,7 @@ struct Synth::Impl final: public Parser::Listener {
// Control opcodes // Control opcodes
std::string defaultPath_ { "" }; std::string defaultPath_ { "" };
std::string image_ { "" }; std::string image_ { "" };
std::string image_controls_ { "" };
int noteOffset_ { Default::noteOffset }; int noteOffset_ { Default::noteOffset };
int octaveOffset_ { Default::octaveOffset }; int octaveOffset_ { Default::octaveOffset };