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, "/root_path", "", 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, "/sw/last/slots", "", nullptr);
synth.sendMessage(*client, 0, "/cc/slots", "", nullptr);
@ -149,6 +150,8 @@ InstrumentDescription parseDescriptionBlob(absl::string_view blob)
desc.rootPath = args[0].s;
else if (Messages::matchOSC("/image", path, indices) && !strcmp(sig, "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"))
copyArgToBitSpan(args[0], desc.keyUsed.span());
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 << " image: " << desc.image << "\n";
os << " image_controls: " << desc.image_controls << "\n";
os << " keys:\n";
for (unsigned i = 0; i < 128; ++i) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -12,13 +12,14 @@
namespace gui {
const CColor kColorSemiTransparent { CColor(0x00, 0x00, 0x00, 0x99) };
const CColor kColorTransparent { CColor(0x00, 0x00, 0x00, 0x00) };
const CColor kColorTransparentDark { CColor(0x00, 0x00, 0x00, 0xc0) };
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 kColorMeterNormal { CColor(0x00, 0xaa, 0x11) };
const CColor kColorTooltipBackground { CColor(0xff, 0xff, 0xd2, 0xff) };

View file

@ -14,13 +14,14 @@ using VSTGUI::CColor;
namespace gui {
extern const CColor kColorSemiTransparent;
extern const CColor kColorTransparent;
extern const CColor kColorTransparentDark;
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 kColorMeterNormal;
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 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::ControlsImage, imageCtrlPath.u8string());
for (unsigned key = 0; key < 128; ++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);
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) {
bool keyUsed = desc.keyUsed.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"):
image_ = absl::StrCat(defaultPath_, absl::StrReplaceAll(trim(member.value), { { "\\", "/" } }));
break;
case hash("image_controls"):
image_controls_ = absl::StrCat(defaultPath_, absl::StrReplaceAll(trim(member.value), { { "\\", "/" } }));
break;
case hash("note_offset"):
noteOffset_ = member.read(Default::noteOffset);
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());
} break;
MATCH("/image_controls", "") {
client.receive<'s'>(delay, path, impl.image_controls_.c_str());
} break;
//----------------------------------------------------------------------
MATCH("/sw/last/slots", "") {

View file

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