Merge pull request #495 from jpcima/editor-improvement-2

editor: file operations popup
This commit is contained in:
JP Cimalando 2020-10-13 17:42:22 +02:00 committed by GitHub
commit c69c054f44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 308 additions and 123 deletions

View file

@ -70,24 +70,19 @@ widget_class mainView {open
class Label
}
Fl_Button {} {
comment {tag=kTagPreviousSfzFile} selected
xywh {455 14 25 25} labelsize 24
comment {tag=kTagPreviousSfzFile}
xywh {480 14 25 25} labelsize 24
class PreviousFileButton
}
Fl_Button {} {
comment {tag=kTagNextSfzFile}
xywh {480 14 25 25} labelsize 24
xywh {505 14 25 25} labelsize 24
class NextFileButton
}
Fl_Button {} {
comment {tag=kTagLoadSfzFile}
xywh {505 14 25 25} labelsize 24
class LoadFileButton
}
Fl_Button {} {
comment {tag=kTagEditSfzFile}
Fl_Button fileOperationsMenu_ {
comment {tag=kTagFileOperations} selected
xywh {530 14 25 25} labelsize 24
class EditFileButton
class ChevronDropDown
}
Fl_Box infoVoicesLabel_ {
xywh {260 76 50 25} labelsize 12 align 16

View file

@ -53,6 +53,7 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
kTagEditSfzFile,
kTagPreviousSfzFile,
kTagNextSfzFile,
kTagFileOperations,
kTagSetVolume,
kTagSetNumVoices,
kTagSetOversampling,
@ -93,6 +94,8 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
CTextLabel* memoryLabel_ = nullptr;
SActionMenu* fileOperationsMenu_ = nullptr;
void uiReceiveValue(EditId id, const EditValue& v) override;
void createFrameContents();
@ -390,6 +393,7 @@ void Editor::Impl::createFrameContents()
typedef STextButton PreviousFileButton;
typedef STextButton NextFileButton;
typedef SPiano Piano;
typedef SActionMenu ChevronDropDown;
auto createLogicalGroup = [](const CRect& bounds, int, const char*, CHoriTxtAlign, int) {
CViewContainer* container = new CViewContainer(bounds);
@ -527,6 +531,16 @@ void Editor::Impl::createFrameContents()
SPiano* piano = new SPiano(bounds);
return piano;
};
auto createChevronDropDown = [this, &theme](const CRect& bounds, int, const char*, CHoriTxtAlign, int fontsize) {
SActionMenu* menu = new SActionMenu(bounds, this);
menu->setTitle(u8"\ue0d7");
menu->setFont(new CFontDesc("Sfizz Fluent System R20", fontsize));
menu->setFontColor(theme->icon);
menu->setHoverColor(theme->iconHighlight);
menu->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
menu->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
return menu;
};
auto createBackground = [&background](const CRect& bounds, int, const char*, CHoriTxtAlign, int) {
CViewContainer* container = new CViewContainer(bounds);
container->setBackground(background);
@ -647,6 +661,11 @@ void Editor::Impl::createFrameContents()
return true;
});
if (SActionMenu* menu = fileOperationsMenu_) {
menu->addEntry("Load file", kTagLoadSfzFile);
menu->addEntry("Edit file", kTagEditSfzFile);
}
///
CViewContainer* panel;
activePanel_ = 0;

View file

@ -429,6 +429,130 @@ void SValueMenu::onItemClicked(int32_t index)
valueChanged();
}
///
SActionMenu::SActionMenu(const CRect& bounds, IControlListener* listener)
: CParamDisplay(bounds), menuListener_(owned(new MenuListener(*this)))
{
setListener(listener);
auto toString = [](float, std::string& result, CParamDisplay* display) {
result = static_cast<SActionMenu*>(display)->getTitle();
return true;
};
setValueToStringFunction2(toString);
}
void SActionMenu::setTitle(std::string title)
{
title_ = std::move(title);
invalid();
}
void SActionMenu::setHoverColor(const CColor& color)
{
hoverColor_ = color;
}
CMenuItem* SActionMenu::addEntry(CMenuItem* item, int32_t tag, int32_t index)
{
if (index < 0 || index > getNbEntries()) {
menuItems_.emplace_back(owned(item));
menuItemTags_.emplace_back(tag);
}
else
{
menuItems_.insert(menuItems_.begin() + index, owned(item));
menuItemTags_.insert(menuItemTags_.begin() + index, tag);
}
return item;
}
CMenuItem* SActionMenu::addEntry(const UTF8String& title, int32_t tag, int32_t index, int32_t itemFlags)
{
if (title == "-")
return addSeparator(index);
CMenuItem* item = new CMenuItem(title, nullptr, 0, nullptr, itemFlags);
return addEntry(item, tag, index);
}
CMenuItem* SActionMenu::addSeparator(int32_t index)
{
CMenuItem* item = new CMenuItem("", nullptr, 0, nullptr, CMenuItem::kSeparator);
return addEntry(item, 0.0f, index);
}
int32_t SActionMenu::getNbEntries() const
{
return static_cast<int32_t>(menuItems_.size());
}
void SActionMenu::draw(CDrawContext* dc)
{
CColor backupColor = fontColor;
if (hovered_)
fontColor = hoverColor_;
CParamDisplay::draw(dc);
if (hovered_)
fontColor = backupColor;
}
CMouseEventResult SActionMenu::onMouseEntered(CPoint& where, const CButtonState& buttons)
{
hovered_ = true;
invalid();
return CParamDisplay::onMouseEntered(where, buttons);
}
CMouseEventResult SActionMenu::onMouseExited(CPoint& where, const CButtonState& buttons)
{
hovered_ = false;
invalid();
return CParamDisplay::onMouseExited(where, buttons);
}
CMouseEventResult SActionMenu::onMouseDown(CPoint& where, const CButtonState& buttons)
{
(void)where;
if (buttons & (kLButton|kRButton|kApple)) {
CFrame* frame = getFrame();
CRect bounds = getViewSize();
CPoint frameWhere = bounds.getBottomLeft();
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));
for (const SharedPointer<CMenuItem>& item : self->menuItems_) {
menu->addEntry(item);
item->remember(); // above call does not increment refcount
}
menu->setFont(self->getFont());
menu->setFontColor(self->getFontColor());
menu->setBackColor(self->getBackColor());
menu->popup(frame, frameWhere + CPoint(0.0, 1.0));
}
});
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}
return kMouseEventNotHandled;
}
void SActionMenu::onItemClicked(int32_t index)
{
setTag(menuItemTags_[index]);
setValue(1.0f);
if (listener)
listener->valueChanged(this);
setValue(0.0f);
if (listener)
listener->valueChanged(this);
}
///
void STextButton::setHoverColor (const CColor& color)
{

View file

@ -122,7 +122,7 @@ public:
int32_t getNbEntries() const;
protected:
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons);
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons) override;
private:
class MenuListener;
@ -148,12 +148,60 @@ private:
};
};
///
class SActionMenu : public CParamDisplay {
public:
explicit SActionMenu(const CRect& bounds, IControlListener* listener);
std::string getTitle() const { return title_; }
void setTitle(std::string title);
CColor getHoverColor() const { return hoverColor_; }
void setHoverColor(const CColor& color);
CMenuItem* addEntry(CMenuItem* item, int32_t tag, int32_t index = -1);
CMenuItem* addEntry(const UTF8String& title, int32_t tag, int32_t index = -1, int32_t itemFlags = CMenuItem::kNoFlags);
CMenuItem* addSeparator(int32_t index = -1);
int32_t getNbEntries() const;
protected:
void draw(CDrawContext* dc) override;
CMouseEventResult onMouseEntered(CPoint& where, const CButtonState& buttons) override;
CMouseEventResult onMouseExited(CPoint& where, const CButtonState& buttons) override;
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons) override;
private:
std::string title_;
CColor hoverColor_;
bool hovered_ = false;
class MenuListener;
//
void onItemClicked(int32_t index);
//
CMenuItemList menuItems_;
std::vector<int32_t> menuItemTags_;
SharedPointer<MenuListener> menuListener_;
//
class MenuListener : public IControlListener, public NonAtomicReferenceCounted {
public:
explicit MenuListener(SActionMenu& menu) : menu_(menu) {}
void valueChanged(CControl* control) override
{
menu_.onItemClicked(static_cast<int32_t>(control->getValue()));
}
private:
SActionMenu& menu_;
};
};
///
class STextButton: public CTextButton {
public:
STextButton(const CRect& size, IControlListener* listener = nullptr, int32_t tag = -1, UTF8StringPtr title = nullptr)
: CTextButton(size, listener, tag, title) {}
CColor getHoverColor() const { return hoverColor_; }
void setHoverColor(const CColor& color);
CMouseEventResult onMouseEntered (CPoint& where, const CButtonState& buttons) override;
CMouseEventResult onMouseExited (CPoint& where, const CButtonState& buttons) override;

View file

@ -29,127 +29,126 @@ Label* const view__12 = createLabel(CRect(10, 39, 260, 69), -1, "Key switch:", k
view__8->addView(view__12);
Label* const view__13 = createLabel(CRect(10, 71, 70, 96), -1, "Voices:", kRightText, 12);
view__8->addView(view__13);
PreviousFileButton* const view__14 = createPreviousFileButton(CRect(270, 9, 295, 34), kTagPreviousSfzFile, "", kCenterText, 24);
PreviousFileButton* const view__14 = createPreviousFileButton(CRect(295, 9, 320, 34), kTagPreviousSfzFile, "", kCenterText, 24);
view__8->addView(view__14);
NextFileButton* const view__15 = createNextFileButton(CRect(295, 9, 320, 34), kTagNextSfzFile, "", kCenterText, 24);
NextFileButton* const view__15 = createNextFileButton(CRect(320, 9, 345, 34), kTagNextSfzFile, "", kCenterText, 24);
view__8->addView(view__15);
LoadFileButton* const view__16 = createLoadFileButton(CRect(320, 9, 345, 34), kTagLoadSfzFile, "", kCenterText, 24);
ChevronDropDown* const view__16 = createChevronDropDown(CRect(345, 9, 370, 34), kTagFileOperations, "", kCenterText, 24);
fileOperationsMenu_ = view__16;
view__8->addView(view__16);
EditFileButton* const view__17 = createEditFileButton(CRect(345, 9, 370, 34), kTagEditSfzFile, "", kCenterText, 24);
Label* const view__17 = createLabel(CRect(75, 71, 125, 96), -1, "", kCenterText, 12);
infoVoicesLabel_ = view__17;
view__8->addView(view__17);
Label* const view__18 = createLabel(CRect(75, 71, 125, 96), -1, "", kCenterText, 12);
infoVoicesLabel_ = view__18;
Label* const view__18 = createLabel(CRect(130, 71, 190, 96), -1, "Max:", kRightText, 12);
view__8->addView(view__18);
Label* const view__19 = createLabel(CRect(130, 71, 190, 96), -1, "Max:", kRightText, 12);
Label* const view__19 = createLabel(CRect(195, 71, 245, 96), -1, "", kCenterText, 12);
numVoicesLabel_ = view__19;
view__8->addView(view__19);
Label* const view__20 = createLabel(CRect(195, 71, 245, 96), -1, "", kCenterText, 12);
numVoicesLabel_ = view__20;
Label* const view__20 = createLabel(CRect(250, 71, 310, 96), -1, "Memory:", kRightText, 12);
view__8->addView(view__20);
Label* const view__21 = createLabel(CRect(250, 71, 310, 96), -1, "Memory:", kRightText, 12);
Label* const view__21 = createLabel(CRect(315, 71, 365, 96), -1, "", kCenterText, 12);
memoryLabel_ = view__21;
view__8->addView(view__21);
Label* const view__22 = createLabel(CRect(315, 71, 365, 96), -1, "", kCenterText, 12);
memoryLabel_ = view__22;
view__8->addView(view__22);
RoundedGroup* const view__23 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14);
view__2->addView(view__23);
Knob48* const view__24 = createKnob48(CRect(45, 15, 93, 63), -1, "", kCenterText, 14);
view__23->addView(view__24);
RoundedGroup* const view__22 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14);
view__2->addView(view__22);
Knob48* const view__23 = createKnob48(CRect(45, 15, 93, 63), -1, "", kCenterText, 14);
view__22->addView(view__23);
view__23->setVisible(false);
ValueLabel* const view__24 = createValueLabel(CRect(40, 65, 100, 70), -1, "Center", kCenterText, 12);
view__22->addView(view__24);
view__24->setVisible(false);
ValueLabel* const view__25 = createValueLabel(CRect(40, 65, 100, 70), -1, "Center", kCenterText, 12);
view__23->addView(view__25);
view__25->setVisible(false);
StyledKnob* const view__26 = createStyledKnob(CRect(110, 15, 158, 63), kTagSetVolume, "", kCenterText, 14);
volumeSlider_ = view__26;
view__23->addView(view__26);
ValueLabel* const view__27 = createValueLabel(CRect(105, 65, 165, 87), -1, "0.0 dB", kCenterText, 12);
volumeLabel_ = view__27;
view__23->addView(view__27);
VMeter* const view__28 = createVMeter(CRect(175, 15, 210, 70), -1, "", kCenterText, 14);
view__23->addView(view__28);
StyledKnob* const view__25 = createStyledKnob(CRect(110, 15, 158, 63), kTagSetVolume, "", kCenterText, 14);
volumeSlider_ = view__25;
view__22->addView(view__25);
ValueLabel* const view__26 = createValueLabel(CRect(105, 65, 165, 87), -1, "0.0 dB", kCenterText, 12);
volumeLabel_ = view__26;
view__22->addView(view__26);
VMeter* const view__27 = createVMeter(CRect(175, 15, 210, 70), -1, "", kCenterText, 14);
view__22->addView(view__27);
enterTheme(defaultTheme);
LogicalGroup* const view__29 = createLogicalGroup(CRect(5, 110, 796, 395), -1, "", kCenterText, 14);
subPanels_[kPanelGeneral] = view__29;
view__0->addView(view__29);
view__29->setVisible(false);
RoundedGroup* const view__30 = createRoundedGroup(CRect(0, 0, 175, 280), -1, "", kCenterText, 14);
LogicalGroup* const view__28 = createLogicalGroup(CRect(5, 110, 796, 395), -1, "", kCenterText, 14);
subPanels_[kPanelGeneral] = view__28;
view__0->addView(view__28);
view__28->setVisible(false);
RoundedGroup* const view__29 = createRoundedGroup(CRect(0, 0, 175, 280), -1, "", kCenterText, 14);
view__28->addView(view__29);
Label* const view__30 = createLabel(CRect(15, 10, 75, 35), -1, "Curves:", kLeftText, 14);
view__29->addView(view__30);
Label* const view__31 = createLabel(CRect(15, 10, 75, 35), -1, "Curves:", kLeftText, 14);
view__30->addView(view__31);
Label* const view__32 = createLabel(CRect(15, 35, 75, 60), -1, "Masters:", kLeftText, 14);
view__30->addView(view__32);
Label* const view__33 = createLabel(CRect(15, 60, 75, 85), -1, "Groups:", kLeftText, 14);
view__30->addView(view__33);
Label* const view__34 = createLabel(CRect(15, 85, 75, 110), -1, "Regions:", kLeftText, 14);
view__30->addView(view__34);
Label* const view__35 = createLabel(CRect(15, 110, 75, 135), -1, "Samples:", kLeftText, 14);
view__30->addView(view__35);
Label* const view__36 = createLabel(CRect(115, 10, 155, 35), -1, "0", kCenterText, 14);
infoCurvesLabel_ = view__36;
view__30->addView(view__36);
Label* const view__37 = createLabel(CRect(115, 35, 155, 60), -1, "0", kCenterText, 14);
infoMastersLabel_ = view__37;
view__30->addView(view__37);
Label* const view__38 = createLabel(CRect(115, 60, 155, 85), -1, "0", kCenterText, 14);
infoGroupsLabel_ = view__38;
view__30->addView(view__38);
Label* const view__39 = createLabel(CRect(115, 85, 155, 110), -1, "0", kCenterText, 14);
infoRegionsLabel_ = view__39;
view__30->addView(view__39);
Label* const view__40 = createLabel(CRect(115, 110, 155, 135), -1, "0", kCenterText, 14);
infoSamplesLabel_ = view__40;
view__30->addView(view__40);
LogicalGroup* const view__41 = createLogicalGroup(CRect(5, 110, 795, 395), -1, "", kCenterText, 14);
subPanels_[kPanelControls] = view__41;
view__0->addView(view__41);
view__41->setVisible(false);
RoundedGroup* const view__42 = createRoundedGroup(CRect(0, 0, 790, 285), -1, "", kCenterText, 14);
Label* const view__31 = createLabel(CRect(15, 35, 75, 60), -1, "Masters:", kLeftText, 14);
view__29->addView(view__31);
Label* const view__32 = createLabel(CRect(15, 60, 75, 85), -1, "Groups:", kLeftText, 14);
view__29->addView(view__32);
Label* const view__33 = createLabel(CRect(15, 85, 75, 110), -1, "Regions:", kLeftText, 14);
view__29->addView(view__33);
Label* const view__34 = createLabel(CRect(15, 110, 75, 135), -1, "Samples:", kLeftText, 14);
view__29->addView(view__34);
Label* const view__35 = createLabel(CRect(115, 10, 155, 35), -1, "0", kCenterText, 14);
infoCurvesLabel_ = view__35;
view__29->addView(view__35);
Label* const view__36 = createLabel(CRect(115, 35, 155, 60), -1, "0", kCenterText, 14);
infoMastersLabel_ = view__36;
view__29->addView(view__36);
Label* const view__37 = createLabel(CRect(115, 60, 155, 85), -1, "0", kCenterText, 14);
infoGroupsLabel_ = view__37;
view__29->addView(view__37);
Label* const view__38 = createLabel(CRect(115, 85, 155, 110), -1, "0", kCenterText, 14);
infoRegionsLabel_ = view__38;
view__29->addView(view__38);
Label* const view__39 = createLabel(CRect(115, 110, 155, 135), -1, "0", kCenterText, 14);
infoSamplesLabel_ = view__39;
view__29->addView(view__39);
LogicalGroup* const view__40 = createLogicalGroup(CRect(5, 110, 795, 395), -1, "", kCenterText, 14);
subPanels_[kPanelControls] = view__40;
view__0->addView(view__40);
view__40->setVisible(false);
RoundedGroup* const view__41 = createRoundedGroup(CRect(0, 0, 790, 285), -1, "", kCenterText, 14);
view__40->addView(view__41);
Label* const view__42 = createLabel(CRect(0, 0, 790, 285), -1, "Controls not available", kCenterText, 40);
view__41->addView(view__42);
Label* const view__43 = createLabel(CRect(0, 0, 790, 285), -1, "Controls not available", kCenterText, 40);
view__42->addView(view__43);
LogicalGroup* const view__44 = createLogicalGroup(CRect(5, 109, 795, 395), -1, "", kCenterText, 14);
subPanels_[kPanelSettings] = view__44;
view__0->addView(view__44);
TitleGroup* const view__45 = createTitleGroup(CRect(255, 26, 535, 126), -1, "Engine", kCenterText, 12);
LogicalGroup* const view__43 = createLogicalGroup(CRect(5, 109, 795, 395), -1, "", kCenterText, 14);
subPanels_[kPanelSettings] = view__43;
view__0->addView(view__43);
TitleGroup* const view__44 = createTitleGroup(CRect(255, 26, 535, 126), -1, "Engine", kCenterText, 12);
view__43->addView(view__44);
ValueMenu* const view__45 = createValueMenu(CRect(25, 60, 85, 85), kTagSetNumVoices, "", kCenterText, 12);
numVoicesSlider_ = view__45;
view__44->addView(view__45);
ValueMenu* const view__46 = createValueMenu(CRect(25, 60, 85, 85), kTagSetNumVoices, "", kCenterText, 12);
numVoicesSlider_ = view__46;
view__45->addView(view__46);
ValueLabel* const view__47 = createValueLabel(CRect(15, 20, 95, 45), -1, "Polyphony", kCenterText, 12);
view__45->addView(view__47);
ValueMenu* const view__48 = createValueMenu(CRect(110, 60, 170, 85), kTagSetOversampling, "", kCenterText, 12);
oversamplingSlider_ = view__48;
view__45->addView(view__48);
ValueLabel* const view__49 = createValueLabel(CRect(100, 20, 180, 45), -1, "Oversampling", kCenterText, 12);
view__45->addView(view__49);
ValueLabel* const view__50 = createValueLabel(CRect(185, 20, 265, 45), -1, "Preload size", kCenterText, 12);
view__45->addView(view__50);
ValueMenu* const view__51 = createValueMenu(CRect(195, 60, 255, 85), kTagSetPreloadSize, "", kCenterText, 12);
preloadSizeSlider_ = view__51;
view__45->addView(view__51);
TitleGroup* const view__52 = createTitleGroup(CRect(200, 161, 590, 261), -1, "Tuning", kCenterText, 12);
view__44->addView(view__52);
ValueLabel* const view__53 = createValueLabel(CRect(125, 20, 205, 45), -1, "Root key", kCenterText, 12);
view__52->addView(view__53);
ValueMenu* const view__54 = createValueMenu(CRect(220, 60, 280, 85), kTagSetTuningFrequency, "", kCenterText, 12);
tuningFrequencySlider_ = view__54;
view__52->addView(view__54);
ValueLabel* const view__55 = createValueLabel(CRect(210, 20, 290, 45), -1, "Frequency", kCenterText, 12);
view__52->addView(view__55);
StyledKnob* const view__56 = createStyledKnob(CRect(310, 45, 358, 93), kTagSetStretchedTuning, "", kCenterText, 14);
stretchedTuningSlider_ = view__56;
view__52->addView(view__56);
ValueLabel* const view__57 = createValueLabel(CRect(295, 20, 375, 45), -1, "Stretch", kCenterText, 12);
view__52->addView(view__57);
ValueLabel* const view__58 = createValueLabel(CRect(20, 20, 120, 45), -1, "Scala file", kCenterText, 12);
view__52->addView(view__58);
ValueButton* const view__59 = createValueButton(CRect(20, 60, 120, 85), kTagLoadScalaFile, "DefaultScale", kCenterText, 12);
scalaFileButton_ = view__59;
view__52->addView(view__59);
ValueMenu* const view__60 = createValueMenu(CRect(135, 60, 170, 85), kTagSetScalaRootKey, "", kCenterText, 12);
scalaRootKeySlider_ = view__60;
view__52->addView(view__60);
ValueMenu* const view__61 = createValueMenu(CRect(170, 60, 200, 85), kTagSetScalaRootKey, "", kCenterText, 12);
scalaRootOctaveSlider_ = view__61;
view__52->addView(view__61);
Piano* const view__62 = createPiano(CRect(5, 400, 795, 470), -1, "", kCenterText, 14);
view__0->addView(view__62);
ValueLabel* const view__46 = createValueLabel(CRect(15, 20, 95, 45), -1, "Polyphony", kCenterText, 12);
view__44->addView(view__46);
ValueMenu* const view__47 = createValueMenu(CRect(110, 60, 170, 85), kTagSetOversampling, "", kCenterText, 12);
oversamplingSlider_ = view__47;
view__44->addView(view__47);
ValueLabel* const view__48 = createValueLabel(CRect(100, 20, 180, 45), -1, "Oversampling", kCenterText, 12);
view__44->addView(view__48);
ValueLabel* const view__49 = createValueLabel(CRect(185, 20, 265, 45), -1, "Preload size", kCenterText, 12);
view__44->addView(view__49);
ValueMenu* const view__50 = createValueMenu(CRect(195, 60, 255, 85), kTagSetPreloadSize, "", kCenterText, 12);
preloadSizeSlider_ = view__50;
view__44->addView(view__50);
TitleGroup* const view__51 = createTitleGroup(CRect(200, 161, 590, 261), -1, "Tuning", kCenterText, 12);
view__43->addView(view__51);
ValueLabel* const view__52 = createValueLabel(CRect(125, 20, 205, 45), -1, "Root key", kCenterText, 12);
view__51->addView(view__52);
ValueMenu* const view__53 = createValueMenu(CRect(220, 60, 280, 85), kTagSetTuningFrequency, "", kCenterText, 12);
tuningFrequencySlider_ = view__53;
view__51->addView(view__53);
ValueLabel* const view__54 = createValueLabel(CRect(210, 20, 290, 45), -1, "Frequency", kCenterText, 12);
view__51->addView(view__54);
StyledKnob* const view__55 = createStyledKnob(CRect(310, 45, 358, 93), kTagSetStretchedTuning, "", kCenterText, 14);
stretchedTuningSlider_ = view__55;
view__51->addView(view__55);
ValueLabel* const view__56 = createValueLabel(CRect(295, 20, 375, 45), -1, "Stretch", kCenterText, 12);
view__51->addView(view__56);
ValueLabel* const view__57 = createValueLabel(CRect(20, 20, 120, 45), -1, "Scala file", kCenterText, 12);
view__51->addView(view__57);
ValueButton* const view__58 = createValueButton(CRect(20, 60, 120, 85), kTagLoadScalaFile, "DefaultScale", kCenterText, 12);
scalaFileButton_ = view__58;
view__51->addView(view__58);
ValueMenu* const view__59 = createValueMenu(CRect(135, 60, 170, 85), kTagSetScalaRootKey, "", kCenterText, 12);
scalaRootKeySlider_ = view__59;
view__51->addView(view__59);
ValueMenu* const view__60 = createValueMenu(CRect(170, 60, 200, 85), kTagSetScalaRootKey, "", kCenterText, 12);
scalaRootOctaveSlider_ = view__60;
view__51->addView(view__60);
Piano* const view__61 = createPiano(CRect(5, 400, 795, 470), -1, "", kCenterText, 14);
view__0->addView(view__61);