2020-03-05 11:16:47 +01:00
|
|
|
// SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
|
|
|
|
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
|
|
|
|
// license. You should have receive a LICENSE.md file along with the code.
|
|
|
|
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
|
|
|
|
|
|
|
|
|
#include "SfizzVstEditor.h"
|
|
|
|
|
#include "SfizzVstState.h"
|
2020-03-05 18:21:46 +01:00
|
|
|
#include "GUIComponents.h"
|
2020-03-05 11:16:47 +01:00
|
|
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
|
|
|
|
#include "x11runloop.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
using namespace VSTGUI;
|
|
|
|
|
|
|
|
|
|
SfizzVstEditor::SfizzVstEditor(void *controller)
|
2020-03-05 15:53:01 +01:00
|
|
|
: VSTGUIEditor(controller),
|
|
|
|
|
_logo("logo.png")
|
2020-03-05 11:16:47 +01:00
|
|
|
{
|
2020-03-05 18:21:46 +01:00
|
|
|
getController()->addSfizzStateListener(this);
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SfizzVstEditor::~SfizzVstEditor()
|
|
|
|
|
{
|
2020-03-05 18:21:46 +01:00
|
|
|
getController()->removeSfizzStateListener(this);
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& platformType)
|
|
|
|
|
{
|
2020-03-05 15:53:01 +01:00
|
|
|
CRect wsize(0, 0, _logo.getWidth(), _logo.getHeight());
|
2020-03-05 11:16:47 +01:00
|
|
|
CFrame *frame = new CFrame(wsize, this);
|
|
|
|
|
this->frame = frame;
|
|
|
|
|
|
|
|
|
|
IPlatformFrameConfig* config = nullptr;
|
|
|
|
|
|
|
|
|
|
#if !defined(__APPLE__) && !defined(_WIN32)
|
|
|
|
|
X11::FrameConfig x11config;
|
|
|
|
|
x11config.runLoop = VSTGUI::owned(new RunLoop(plugFrame));
|
|
|
|
|
config = &x11config;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
createFrameContents();
|
|
|
|
|
updateStateDisplay();
|
|
|
|
|
|
|
|
|
|
frame->open(parent, platformType, config);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PLUGIN_API SfizzVstEditor::close()
|
|
|
|
|
{
|
|
|
|
|
CFrame *frame = this->frame;
|
|
|
|
|
if (frame) {
|
|
|
|
|
frame->forget();
|
|
|
|
|
this->frame = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
void SfizzVstEditor::valueChanged(CControl* ctl)
|
|
|
|
|
{
|
|
|
|
|
int32_t tag = ctl->getTag();
|
|
|
|
|
float value = ctl->getValue();
|
2020-03-05 18:21:46 +01:00
|
|
|
float valueNorm = ctl->getValueNormalized();
|
|
|
|
|
SfizzVstController* controller = getController();
|
2020-03-05 11:16:47 +01:00
|
|
|
|
|
|
|
|
switch (tag) {
|
|
|
|
|
case kTagLoadSfzFile:
|
|
|
|
|
if (value != 1)
|
|
|
|
|
break;
|
|
|
|
|
|
2020-03-05 15:53:01 +01:00
|
|
|
Call::later([this]() { chooseSfzFile(); });
|
2020-03-05 11:16:47 +01:00
|
|
|
break;
|
2020-03-05 16:41:59 +01:00
|
|
|
|
2020-03-05 18:21:46 +01:00
|
|
|
case kTagSetVolume:
|
|
|
|
|
controller->setParamNormalized(kPidVolume, valueNorm);
|
|
|
|
|
controller->performEdit(kPidVolume, valueNorm);
|
|
|
|
|
break;
|
|
|
|
|
|
2020-03-06 11:46:49 +01:00
|
|
|
case kTagSetNumVoices:
|
|
|
|
|
controller->setParamNormalized(kPidNumVoices, valueNorm);
|
|
|
|
|
controller->performEdit(kPidNumVoices, valueNorm);
|
|
|
|
|
break;
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
default:
|
|
|
|
|
if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel)
|
|
|
|
|
setActivePanel(tag - kTagFirstChangePanel);
|
|
|
|
|
break;
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-05 18:21:46 +01:00
|
|
|
void SfizzVstEditor::enterOrLeaveEdit(CControl* ctl, bool enter)
|
|
|
|
|
{
|
|
|
|
|
int32_t tag = ctl->getTag();
|
|
|
|
|
Vst::ParamID id;
|
|
|
|
|
|
|
|
|
|
switch (tag) {
|
|
|
|
|
case kTagSetVolume: id = kPidVolume; break;
|
2020-03-06 11:46:49 +01:00
|
|
|
case kTagSetNumVoices: id = kPidNumVoices; break;
|
2020-03-05 18:21:46 +01:00
|
|
|
default: return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SfizzVstController* controller = getController();
|
|
|
|
|
if (enter)
|
|
|
|
|
controller->beginEdit(id);
|
|
|
|
|
else
|
|
|
|
|
controller->endEdit(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SfizzVstEditor::controlBeginEdit(CControl* ctl)
|
|
|
|
|
{
|
|
|
|
|
enterOrLeaveEdit(ctl, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SfizzVstEditor::controlEndEdit(CControl* ctl)
|
|
|
|
|
{
|
|
|
|
|
enterOrLeaveEdit(ctl, false);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-05 11:16:47 +01:00
|
|
|
void SfizzVstEditor::onStateChanged()
|
|
|
|
|
{
|
|
|
|
|
updateStateDisplay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
void SfizzVstEditor::chooseSfzFile()
|
|
|
|
|
{
|
|
|
|
|
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame));
|
|
|
|
|
|
|
|
|
|
fs->setTitle("Load SFZ file");
|
|
|
|
|
fs->setDefaultExtension(CFileExtension("SFZ", "sfz"));
|
|
|
|
|
|
|
|
|
|
if (fs->runModal()) {
|
|
|
|
|
UTF8StringPtr file = fs->getSelectedFile(0);
|
|
|
|
|
if (file)
|
|
|
|
|
loadSfzFile(file);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SfizzVstEditor::loadSfzFile(const std::string& filePath)
|
|
|
|
|
{
|
2020-03-05 18:21:46 +01:00
|
|
|
SfizzVstController* ctl = getController();
|
2020-03-05 15:53:01 +01:00
|
|
|
|
2020-03-05 11:16:47 +01:00
|
|
|
Vst::IMessage *msg = ctl->allocateMessage();
|
2020-03-05 15:53:01 +01:00
|
|
|
if (!msg) {
|
|
|
|
|
fprintf(stderr, "[Sfizz] UI could not allocate message\n");
|
|
|
|
|
return;
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
2020-03-05 15:53:01 +01:00
|
|
|
|
|
|
|
|
msg->setMessageID("LoadSfz");
|
|
|
|
|
Vst::IAttributeList* attr = msg->getAttributes();
|
|
|
|
|
attr->setString("File", Steinberg::String(filePath.c_str()).text());
|
|
|
|
|
ctl->sendMessage(msg);
|
|
|
|
|
msg->release();
|
|
|
|
|
|
|
|
|
|
if (_fileLabel)
|
|
|
|
|
_fileLabel->setText(("File: " + filePath).c_str());
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
void SfizzVstEditor::createFrameContents()
|
|
|
|
|
{
|
2020-03-05 18:21:46 +01:00
|
|
|
SfizzVstController* controller = getController();
|
|
|
|
|
const SfizzUiState& uiState = controller->getSfizzUiState();
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
CFrame* frame = this->frame;
|
|
|
|
|
CRect bounds = frame->getViewSize();
|
|
|
|
|
|
|
|
|
|
frame->setBackgroundColor(CColor(0xff, 0xff, 0xff));
|
2020-03-05 11:16:47 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
CRect bottomRow = bounds;
|
|
|
|
|
bottomRow.top = bottomRow.bottom - 30;
|
|
|
|
|
|
|
|
|
|
CRect topRow = bounds;
|
|
|
|
|
topRow.bottom = topRow.top + 30;
|
|
|
|
|
|
|
|
|
|
CViewContainer* panel;
|
2020-03-05 18:21:46 +01:00
|
|
|
_activePanel = std::max(0, std::min(kNumPanels - 1, static_cast<int>(uiState.activePanel)));
|
2020-03-05 16:41:59 +01:00
|
|
|
|
|
|
|
|
CRect topLeftLabelBox = topRow;
|
|
|
|
|
topLeftLabelBox.right -= 20 * kNumPanels;
|
|
|
|
|
|
|
|
|
|
// general panel
|
2020-03-05 11:16:47 +01:00
|
|
|
{
|
2020-03-05 16:41:59 +01:00
|
|
|
panel = new CViewContainer(bounds);
|
|
|
|
|
frame->addView(panel);
|
|
|
|
|
panel->setTransparency(true);
|
|
|
|
|
|
|
|
|
|
CKickButton* sfizzButton = new CKickButton(bounds, this, kTagLoadSfzFile, &_logo);
|
|
|
|
|
panel->addView(sfizzButton);
|
|
|
|
|
|
|
|
|
|
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "No file loaded");
|
|
|
|
|
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
panel->addView(topLeftLabel);
|
|
|
|
|
_fileLabel = topLeftLabel;
|
|
|
|
|
|
|
|
|
|
_subPanels[kPanelGeneral] = panel;
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
// settings panel
|
2020-03-05 11:16:47 +01:00
|
|
|
{
|
2020-03-05 16:41:59 +01:00
|
|
|
panel = new CViewContainer(bounds);
|
|
|
|
|
frame->addView(panel);
|
|
|
|
|
panel->setTransparency(true);
|
2020-03-05 11:16:47 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Settings");
|
|
|
|
|
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
panel->addView(topLeftLabel);
|
2020-03-05 11:16:47 +01:00
|
|
|
|
2020-03-05 18:21:46 +01:00
|
|
|
CRect row = topRow;
|
|
|
|
|
row.top += 200.0;
|
|
|
|
|
row.bottom += 200.0;
|
|
|
|
|
row.left += 100.0;
|
|
|
|
|
row.right -= 100.0;
|
|
|
|
|
|
|
|
|
|
CCoord interRow = 35.0;
|
|
|
|
|
|
|
|
|
|
auto leftSide = [&row]() -> CRect {
|
|
|
|
|
CRect div = row;
|
|
|
|
|
div.right = 0.5 * (div.left + div.right);
|
|
|
|
|
return div;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto rightSide = [&row]() -> CRect {
|
|
|
|
|
CRect div = row;
|
|
|
|
|
div.left = 0.5 * (div.left + div.right);
|
|
|
|
|
return div;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CTextLabel* label;
|
|
|
|
|
SimpleSlider* slider;
|
|
|
|
|
|
|
|
|
|
label = new CTextLabel(leftSide(), "Volume");
|
|
|
|
|
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
label->setHoriAlign(kLeftText);
|
|
|
|
|
panel->addView(label);
|
|
|
|
|
slider = new SimpleSlider(rightSide(), this, kTagSetVolume);
|
|
|
|
|
panel->addView(slider);
|
2020-03-06 11:46:49 +01:00
|
|
|
adjustMinMaxToRangeParam(slider, kPidVolume);
|
2020-03-05 18:21:46 +01:00
|
|
|
_volumeSlider = slider;
|
|
|
|
|
|
2020-03-06 11:46:49 +01:00
|
|
|
row.top += interRow;
|
|
|
|
|
row.bottom += interRow;
|
2020-03-05 18:21:46 +01:00
|
|
|
|
2020-03-06 11:46:49 +01:00
|
|
|
label = new CTextLabel(leftSide(), "Polyphony");
|
|
|
|
|
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
label->setHoriAlign(kLeftText);
|
|
|
|
|
panel->addView(label);
|
|
|
|
|
slider = new SimpleSlider(rightSide(), this, kTagSetNumVoices);
|
|
|
|
|
panel->addView(slider);
|
|
|
|
|
adjustMinMaxToRangeParam(slider, kPidNumVoices);
|
|
|
|
|
_numVoicesSlider = slider;
|
2020-03-05 18:21:46 +01:00
|
|
|
|
|
|
|
|
// row.top += interRow;
|
|
|
|
|
// row.bottom += interRow;
|
|
|
|
|
|
|
|
|
|
// label = new CTextLabel(leftSide(), "Oversampling");
|
|
|
|
|
// label->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
// label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
// label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
// label->setHoriAlign(kLeftText);
|
|
|
|
|
// panel->addView(label);
|
|
|
|
|
// slider = new SimpleSlider(rightSide(), this, -1);
|
|
|
|
|
// panel->addView(slider);
|
|
|
|
|
|
|
|
|
|
// row.top += interRow;
|
|
|
|
|
// row.bottom += interRow;
|
|
|
|
|
|
|
|
|
|
// label = new CTextLabel(leftSide(), "Preload size");
|
|
|
|
|
// label->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
// label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
// label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
// label->setHoriAlign(kLeftText);
|
|
|
|
|
// panel->addView(label);
|
|
|
|
|
// slider = new SimpleSlider(rightSide(), this, -1);
|
|
|
|
|
// panel->addView(slider);
|
|
|
|
|
|
|
|
|
|
// row.top += interRow;
|
|
|
|
|
// row.bottom += interRow;
|
|
|
|
|
|
|
|
|
|
// label = new CTextLabel(leftSide(), "Freewheel");
|
|
|
|
|
// label->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
// label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
// label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
// label->setHoriAlign(kLeftText);
|
|
|
|
|
// panel->addView(label);
|
|
|
|
|
// slider = new SimpleSlider(rightSide(), this, -1);
|
|
|
|
|
// panel->addView(slider);
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
_subPanels[kPanelSettings] = panel;
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
// all panels
|
|
|
|
|
for (unsigned currentPanel = 0; currentPanel < kNumPanels; ++currentPanel) {
|
|
|
|
|
panel = _subPanels[currentPanel];
|
2020-03-05 11:16:47 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
CTextLabel* descLabel = new CTextLabel(
|
|
|
|
|
bottomRow, "Paul Ferrand and the SFZ Tools work group");
|
|
|
|
|
descLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
|
|
|
|
descLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
|
|
|
|
panel->addView(descLabel);
|
2020-03-05 11:16:47 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
for (unsigned i = 0; i < kNumPanels; ++i) {
|
|
|
|
|
CRect btnRect = topRow;
|
|
|
|
|
btnRect.left = topRow.right - (kNumPanels - i) * 20;
|
|
|
|
|
btnRect.right = btnRect.left + 20;
|
2020-03-05 15:53:01 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
const char *text;
|
|
|
|
|
switch (i) {
|
|
|
|
|
case kPanelGeneral: text = "G"; break;
|
|
|
|
|
case kPanelSettings: text = "S"; break;
|
|
|
|
|
default: text = "?"; break;
|
|
|
|
|
}
|
2020-03-05 15:53:01 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
CTextButton* changePanelButton = new CTextButton(btnRect, this, kTagFirstChangePanel + i, text);
|
|
|
|
|
panel->addView(changePanelButton);
|
2020-03-05 15:53:01 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
changePanelButton->setRoundRadius(0.0);
|
|
|
|
|
}
|
2020-03-05 15:53:01 +01:00
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
panel->setVisible(currentPanel == _activePanel);
|
|
|
|
|
}
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SfizzVstEditor::updateStateDisplay()
|
|
|
|
|
{
|
|
|
|
|
if (!frame)
|
|
|
|
|
return;
|
|
|
|
|
|
2020-03-05 18:21:46 +01:00
|
|
|
SfizzVstController* controller = getController();
|
|
|
|
|
const SfizzVstState& state = controller->getSfizzState();
|
|
|
|
|
const SfizzUiState& uiState = controller->getSfizzUiState();
|
2020-03-05 11:16:47 +01:00
|
|
|
|
2020-03-05 15:53:01 +01:00
|
|
|
if (_fileLabel)
|
|
|
|
|
_fileLabel->setText(("File: " + state.sfzFile).c_str());
|
2020-03-05 18:21:46 +01:00
|
|
|
if (_volumeSlider)
|
|
|
|
|
_volumeSlider->setValue(state.volume);
|
2020-03-06 11:46:49 +01:00
|
|
|
if (_numVoicesSlider)
|
|
|
|
|
_numVoicesSlider->setValue(state.numVoices);
|
2020-03-05 18:21:46 +01:00
|
|
|
|
|
|
|
|
setActivePanel(uiState.activePanel);
|
2020-03-05 11:16:47 +01:00
|
|
|
}
|
2020-03-05 16:41:59 +01:00
|
|
|
|
|
|
|
|
void SfizzVstEditor::setActivePanel(unsigned panelId)
|
|
|
|
|
{
|
2020-03-05 18:21:46 +01:00
|
|
|
panelId = std::max(0, std::min(kNumPanels - 1, static_cast<int>(panelId)));
|
|
|
|
|
|
|
|
|
|
getController()->getSfizzUiState().activePanel = panelId;
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
if (_activePanel != panelId) {
|
2020-03-05 18:21:46 +01:00
|
|
|
if (frame)
|
|
|
|
|
_subPanels[_activePanel]->setVisible(false);
|
|
|
|
|
|
2020-03-05 16:41:59 +01:00
|
|
|
_activePanel = panelId;
|
2020-03-05 18:21:46 +01:00
|
|
|
|
|
|
|
|
if (frame)
|
|
|
|
|
_subPanels[panelId]->setVisible(true);
|
2020-03-05 16:41:59 +01:00
|
|
|
}
|
|
|
|
|
}
|