Vital
Loading...
Searching...
No Matches
master_controls_interface.cpp
Go to the documentation of this file.
2
4#include "oscilloscope.h"
5#include "fonts.h"
6#include "full_interface.h"
7#include "skin.h"
8#include "load_save.h"
10#include "synth_button.h"
11#include "synth_slider.h"
12#include "synth_strings.h"
13#include "text_look_and_feel.h"
14#include "text_selector.h"
15
16namespace {
17 const std::string kTuningNames[] = {
18 "Default",
19 "Just - 7 Limit",
20 "Just - 5 Limit",
21 "Pythagorean",
22 "Custom"
23 };
24
25 const std::string kFrequencyDisplayNames[] = {
26 "Semitones",
27 "Hz"
28 };
29}
30
32 setRange(0, kNumTunings, 1.0);
33 for (int i = 0; i <= kNumTunings; ++i)
34 strings_[i] = kTuningNames[i];
35
36 setStringLookup(strings_);
37 setValue(kNumTunings);
38}
39
41
42void TuningSelector::mouseDown(const MouseEvent& e) {
43 if (e.mods.isPopupMenu()) {
45 return;
46 }
47
48 const std::string* lookup = string_lookup_;
49 if (long_lookup_)
50 lookup = long_lookup_;
51
52 PopupItems options;
53
54 for (int i = 0; i < kNumTunings; ++i)
55 options.addItem(i, lookup[i]);
56
57 options.addItem(-1, "");
58 options.addItem(kNumTunings, "Load Tuning File...");
59
60 parent_->showPopupSelector(this, e.getPosition(), options, [=](int selection) { setTuning(selection); });
61}
62
65 if (findParentComponentOfClass<SynthGuiInterface>())
66 loadTuning(static_cast<TuningStyle>((int)getValue()));
67}
68
70 setCustomString(getTuningName().toStdString());
72}
73
74void TuningSelector::setTuning(int tuning) {
75 if (tuning != getValue())
76 setValue(tuning);
77 else if (tuning == kNumTunings)
78 loadTuning(kNumTunings);
79}
80
81void TuningSelector::loadTuning(TuningStyle tuning) {
82 if (tuning == kNumTunings) {
83 loadTuningFile();
84 return;
85 }
86 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
87 parent->getSynth()->getTuning()->setName(kTuningNames[tuning]);
88
89 String text;
90 StringArray lines;
91 switch (tuning) {
92 case k7Limit:
93 text = String(BinaryData::_7_Limit_scl, BinaryData::_7_Limit_sclSize);
94 lines.addTokens(text, "\n", "");
95 parent->getSynth()->getTuning()->loadScalaFile(lines);
96 break;
97 case k5Limit:
98 text = String(BinaryData::_5_Limit_scl, BinaryData::_5_Limit_sclSize);
99 lines.addTokens(text, "\n", "");
100 parent->getSynth()->getTuning()->loadScalaFile(lines);
101 break;
102 case kPythagorean:
103 text = String(BinaryData::Pythagorean_scl, BinaryData::Pythagorean_sclSize);
104 lines.addTokens(text, "\n", "");
105 parent->getSynth()->getTuning()->loadScalaFile(lines);
106 break;
107 default:
108 parent->getSynth()->getTuning()->setDefaultTuning();
109 break;
110 }
111}
112
113void TuningSelector::loadTuningFile() {
114 setCustomString("Custom");
115 FileChooser load_box("Load Tuning", File(), Tuning::allFileExtensions());
116 if (load_box.browseForFileToOpen())
117 loadTuningFile(load_box.getResult());
118
119 setCustomString(getTuningName().toStdString());
120}
121
122void TuningSelector::loadTuningFile(const File& file) {
123 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
124 parent->getSynth()->loadTuningFile(file);
125}
126
127String TuningSelector::getTuningName() {
128 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
129 if (parent) {
130 String name = parent->getSynth()->getTuning()->getName();
131 if (name.isEmpty())
132 return "Default";
133 return name;
134 }
135 return "Custom";
136}
137
139 public:
141 setSidewaysHeading(false);
142
143 mpe_enabled_ = std::make_unique<SynthButton>("mpe_enabled");
144 addButton(mpe_enabled_.get());
145 mpe_enabled_->setLookAndFeel(TextLookAndFeel::instance());
146 mpe_enabled_->setButtonText("MPE ENABLED");
147
148 voice_priority_ = std::make_unique<TextSelector>("voice_priority");
149 addSlider(voice_priority_.get());
150 voice_priority_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
151 voice_priority_->setLookAndFeel(TextLookAndFeel::instance());
152 voice_priority_->setLongStringLookup(strings::kVoicePriorityNames);
153
154 voice_override_ = std::make_unique<TextSelector>("voice_override");
155 addSlider(voice_override_.get());
156 voice_override_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
157 voice_override_->setLookAndFeel(TextLookAndFeel::instance());
158 voice_override_->setLongStringLookup(strings::kVoiceOverrideNames);
159
160 tuning_ = std::make_unique<TuningSelector>("tuning");
161 addAndMakeVisible(tuning_.get());
162 addOpenGlComponent(tuning_->getImageComponent());
163 addOpenGlComponent(tuning_->getQuadComponent());
164 tuning_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
165 tuning_->setLookAndFeel(TextLookAndFeel::instance());
166 tuning_->setLongStringLookup(kTuningNames);
167
168 voice_tune_ = std::make_unique<SynthSlider>("voice_tune");
169 addSlider(voice_tune_.get());
170 voice_tune_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
171 voice_tune_->setLookAndFeel(TextLookAndFeel::instance());
172
173 voice_transpose_ = std::make_unique<SynthSlider>("voice_transpose");
174 addSlider(voice_transpose_.get());
175 voice_transpose_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
176 voice_transpose_->setLookAndFeel(TextLookAndFeel::instance());
177 voice_transpose_->setSensitivity(kTransposeMouseSensitivity);
178 }
179
180 void paintBackground(Graphics& g) override {
182
183 g.setColour(findColour(Skin::kTextComponentBackground, true));
184 g.fillRoundedRectangle(mpe_enabled_->getBounds().toFloat(), findValue(Skin::kLabelBackgroundRounding));
185
186 drawTextComponentBackground(g, voice_priority_->getBounds(), true);
187 drawTextComponentBackground(g, voice_override_->getBounds(), true);
188 drawTextComponentBackground(g, tuning_->getBounds(), true);
189 drawTextComponentBackground(g, voice_tune_->getBounds(), true);
190 drawTextComponentBackground(g, voice_transpose_->getBounds(), true);
191
192 setLabelFont(g);
193 drawLabelForComponent(g, "NOTE PRIORITY", voice_priority_.get(), true);
194 drawLabelForComponent(g, "VOICE OVERRIDE", voice_override_.get(), true);
195 drawLabelForComponent(g, "TUNING", tuning_.get(), true);
196 drawLabelForComponent(g, "TUNE", voice_tune_.get(), true);
197 drawLabelForComponent(g, "TRANSPOSE", voice_transpose_.get(), true);
198 }
199
200 void paintBackgroundShadow(Graphics& g) override { paintTabShadow(g); }
201
202 void resized() override {
204
205 int widget_margin = getWidgetMargin();
206 int title_width = getTitleWidth();
207 int component_height = getKnobSectionHeight() - widget_margin;
208 int width = getWidth() - 2 * widget_margin;
209 int x = widget_margin;
210 int y = title_width + widget_margin;
211
212 int width_left = (width - widget_margin) / 2;
213 int voice_y = getHeight() - widget_margin - component_height;
214 voice_tune_->setBounds(x, voice_y, width_left, component_height);
215
216 int x_right = x + width_left + widget_margin;
217 int width_right = getWidth() - x_right - widget_margin;
218 voice_transpose_->setBounds(x_right, voice_y, width_right, component_height);
219
220 int mpe_height = findValue(Skin::kTextButtonHeight);
221 mpe_enabled_->setBounds(x, voice_y - mpe_height - widget_margin, width, mpe_height);
222
223 int remaining_height = mpe_enabled_->getY() - y;
224 int override_y = y + remaining_height / 3;
225 int tuning_y = y + (2 * remaining_height) / 3;
226 voice_priority_->setBounds(x, y, width, override_y - y - widget_margin);
227 voice_override_->setBounds(x, override_y, width, tuning_y - override_y - widget_margin);
228 tuning_->setBounds(x, tuning_y, width, mpe_enabled_->getY() - tuning_y - widget_margin);
229 }
230
231 void buttonClicked(Button* clicked_button) override {
232 if (clicked_button == mpe_enabled_.get())
233 setMpeEnabled(mpe_enabled_->getToggleState());
234
235 SynthSection::buttonClicked(clicked_button);
236 }
237
238 void setAllValues(vital::control_map& controls) override {
240 setMpeEnabled(mpe_enabled_->getToggleState());
241 }
242
243 private:
244 void setMpeEnabled(bool enabled) {
245 mpe_enabled_->setToggleState(enabled, NotificationType::dontSendNotification);
246
247 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
248 if (parent)
249 parent->getSynth()->setMpeEnabled(enabled);
250 }
251
252 std::unique_ptr<SynthButton> mpe_enabled_;
253 std::unique_ptr<TextSelector> voice_priority_;
254 std::unique_ptr<TextSelector> voice_override_;
255 std::unique_ptr<TuningSelector> tuning_;
256
257 std::unique_ptr<SynthSlider> voice_tune_;
258 std::unique_ptr<SynthSlider> voice_transpose_;
259
260 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VoiceSettings)
261};
262
264 public:
265 OversampleSettings() : SynthSection("OVERSAMPLING") {
266 setSidewaysHeading(false);
267
268 oversampling_1x_ = std::make_unique<OpenGlToggleButton>("");
269 oversampling_1x_->addListener(this);
270 oversampling_1x_->setLookAndFeel(TextLookAndFeel::instance());
271 oversampling_1x_->setButtonText("1x (Draft)");
272 addAndMakeVisible(oversampling_1x_.get());
273 addOpenGlComponent(oversampling_1x_->getGlComponent());
274
275 oversampling_2x_ = std::make_unique<OpenGlToggleButton>("");
276 oversampling_2x_->addListener(this);
277 oversampling_2x_->setLookAndFeel(TextLookAndFeel::instance());
278 oversampling_2x_->setButtonText("2x (Recommended)");
279 addAndMakeVisible(oversampling_2x_.get());
280 addOpenGlComponent(oversampling_2x_->getGlComponent());
281
282 oversampling_4x_ = std::make_unique<OpenGlToggleButton>("");
283 oversampling_4x_->addListener(this);
284 oversampling_4x_->setLookAndFeel(TextLookAndFeel::instance());
285 oversampling_4x_->setButtonText("4x (High CPU)");
286 addAndMakeVisible(oversampling_4x_.get());
287 addOpenGlComponent(oversampling_4x_->getGlComponent());
288
289 oversampling_8x_ = std::make_unique<OpenGlToggleButton>("");
290 oversampling_8x_->addListener(this);
291 oversampling_8x_->setLookAndFeel(TextLookAndFeel::instance());
292 oversampling_8x_->setButtonText("8x (Ultra CPU)");
293 addAndMakeVisible(oversampling_8x_.get());
294 addOpenGlComponent(oversampling_8x_->getGlComponent());
295 }
296
297 void setAllValues(vital::control_map& controls) override {
299 setSelectedOversamplingButton(controls["oversampling"]->value());
300 }
301
302 void paintBackground(Graphics& g) override {
304
305 g.setColour(findColour(Skin::kTextComponentBackground, true));
307 g.fillRoundedRectangle(oversampling_1x_->getBounds().toFloat(), rounding);
308 g.fillRoundedRectangle(oversampling_2x_->getBounds().toFloat(), rounding);
309 g.fillRoundedRectangle(oversampling_4x_->getBounds().toFloat(), rounding);
310 g.fillRoundedRectangle(oversampling_8x_->getBounds().toFloat(), rounding);
311 }
312
313 void paintBackgroundShadow(Graphics& g) override { paintTabShadow(g); }
314
315 void resized() override {
317
318 int widget_margin = getWidgetMargin();
319 int title_width = getTitleWidth();
320 int width = getWidth() - 2 * widget_margin;
321 int x = widget_margin;
322 int y = title_width + widget_margin;
323 int oversampling_bottom = getHeight();
324 int oversampling_height = oversampling_bottom - y;
325 int oversample_2x_y = y + oversampling_height / 4;
326 int oversample_4x_y = y + (2 * oversampling_height) / 4;
327 int oversample_8x_y = y + (3 * oversampling_height) / 4;
328 oversampling_1x_->setBounds(x, y, width, oversample_2x_y - y - widget_margin);
329 oversampling_2x_->setBounds(x, oversample_2x_y, width, oversample_4x_y - oversample_2x_y - widget_margin);
330 oversampling_4x_->setBounds(x, oversample_4x_y, width, oversample_8x_y - oversample_4x_y - widget_margin);
331 oversampling_8x_->setBounds(x, oversample_8x_y, width, oversampling_bottom - oversample_8x_y - widget_margin);
332 }
333
334 void buttonClicked(Button* clicked_button) override {
335 if (clicked_button == oversampling_1x_.get())
336 setOversamplingAmount(0);
337 else if (clicked_button == oversampling_2x_.get())
338 setOversamplingAmount(1);
339 else if (clicked_button == oversampling_4x_.get())
340 setOversamplingAmount(2);
341 else if (clicked_button == oversampling_8x_.get())
342 setOversamplingAmount(3);
343 }
344
345 private:
346 void setSelectedOversamplingButton(int oversampling_amount) {
347 oversampling_1x_->setToggleState(oversampling_amount == 0, NotificationType::dontSendNotification);
348 oversampling_2x_->setToggleState(oversampling_amount == 1, NotificationType::dontSendNotification);
349 oversampling_4x_->setToggleState(oversampling_amount == 2, NotificationType::dontSendNotification);
350 oversampling_8x_->setToggleState(oversampling_amount == 3, NotificationType::dontSendNotification);
351 }
352
353 void setOversamplingAmount(int oversampling_amount) {
354 setSelectedOversamplingButton(oversampling_amount);
355
356 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
357 if (parent) {
358 parent->getSynth()->valueChangedInternal("oversampling", oversampling_amount);
360 }
361 }
362
363 std::unique_ptr<OpenGlToggleButton> oversampling_1x_;
364 std::unique_ptr<OpenGlToggleButton> oversampling_2x_;
365 std::unique_ptr<OpenGlToggleButton> oversampling_4x_;
366 std::unique_ptr<OpenGlToggleButton> oversampling_8x_;
367
368 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OversampleSettings)
369};
370
372 public:
374 setSidewaysHeading(false);
375
376 frequency_display_ = std::make_unique<TextSelector>("frequency_display");
377 frequency_display_->setRange(0.0, 1.0, 1.0);
378 frequency_display_->setValue(LoadSave::displayHzFrequency());
379 addSlider(frequency_display_.get());
380 frequency_display_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
381 frequency_display_->setLookAndFeel(TextLookAndFeel::instance());
382 frequency_display_->setStringLookup(kFrequencyDisplayNames);
383 frequency_display_->setLongStringLookup(kFrequencyDisplayNames);
384
385 LoadSave::getAllSkins(skins_);
386 File default_skin = LoadSave::getDefaultSkin();
387 skin_value_ = 0;
388 if (default_skin.exists()) {
389 String skin_name = LoadSave::getLoadedSkin();
390 for (int i = 0; i < skins_.size(); ++i) {
391 if (skins_[i].getFileNameWithoutExtension() == skin_name)
392 skin_value_ = i + 1;
393 }
394 if (skin_value_ == 0)
395 skin_value_ = skins_.size() + 1;
396 }
397
398 short_skin_strings_ = std::make_unique<std::string[]>(skins_.size() + 2);
399 long_skin_strings_ = std::make_unique<std::string[]>(skins_.size() + 2);
400 short_skin_strings_[0] = "Default";
401 long_skin_strings_[0] = "Default";
402 short_skin_strings_[skins_.size() + 1] = "Custom";
403 long_skin_strings_[skins_.size() + 1] = "Load Custom Skin...";
404
405 for (int i = 0; i < skins_.size(); ++i) {
406 short_skin_strings_[i + 1] = skins_[i].getFileNameWithoutExtension().toStdString();
407 long_skin_strings_[i + 1] = skins_[i].getFileNameWithoutExtension().toStdString();
408 }
409
410 skin_ = std::make_unique<TextSelector>("skin");
411 skin_->setRange(0.0, skins_.size() + 1, 1);
412 skin_->setValue(skin_value_, dontSendNotification);
413 skin_->setScrollEnabled(false);
414 addSlider(skin_.get());
415 skin_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
416 skin_->setLookAndFeel(TextLookAndFeel::instance());
417 skin_->setStringLookup(short_skin_strings_.get());
418 skin_->setLongStringLookup(long_skin_strings_.get());
419 }
420
421 void paintBackgroundShadow(Graphics& g) override { paintTabShadow(g); }
422 void paintBackground(Graphics& g) override {
424
425 drawTextComponentBackground(g, frequency_display_->getBounds(), true);
426 drawTextComponentBackground(g, skin_->getBounds(), true);
427 setLabelFont(g);
428 drawLabelForComponent(g, "FREQUENCY UNITS", frequency_display_.get(), true);
429 drawLabelForComponent(g, "SKIN", skin_.get(), true);
430 }
431
432 void resized() override {
434
435 int widget_margin = getWidgetMargin();
436 int title_width = getTitleWidth();
437 int width = getWidth() - 2 * widget_margin;
438 int x = widget_margin;
439
440 int y = title_width + widget_margin;
441 int bottom = getHeight() - widget_margin;
442
443 int frequency_height = (bottom - y - widget_margin) / 2;
444
445 frequency_display_->setBounds(x, y, width, frequency_height);
446 int skin_y = y + frequency_height + widget_margin;
447 skin_->setBounds(x, skin_y, width, bottom - skin_y);
448 }
449
450 void setDisplayValue(Skin::ValueId id, float value) {
451 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
452 if (parent && parent->getGui())
453 parent->getGui()->setSkinValue(id, value);
454 }
455
456 void parentHierarchyChanged() override {
457 SynthSection::parentHierarchyChanged();
458 setDisplayValue(Skin::kFrequencyDisplay, frequency_display_->getValue());
459 }
460
461 void loadSkin(Skin& skin) {
462 FullInterface* full_interface = findParentComponentOfClass<FullInterface>();
463 full_interface->reloadSkin(skin);
464 }
465
466 void sliderValueChanged(Slider* changed_slider) override {
467 if (changed_slider == frequency_display_.get()) {
468 setDisplayValue(Skin::kFrequencyDisplay, frequency_display_->getValue());
469 LoadSave::saveDisplayHzFrequency(frequency_display_->getValue() != 0.0f);
470 }
471 else if (changed_slider == skin_.get()) {
472 File default_skin = LoadSave::getDefaultSkin();
473 if (skin_->getValue() == 0.0f) {
474 if (default_skin.exists() && default_skin.hasWriteAccess())
475 default_skin.deleteFile();
476
477 Skin skin;
478 skin.loadDefaultSkin();
479 loadSkin(skin);
480 }
481 else if (skin_->getValue() == skins_.size() + 1) {
482 FileChooser open_box("Open Skin", File(), String("*.") + vital::kSkinExtension);
483 if (open_box.browseForFileToOpen()) {
484 File skin_file = open_box.getResult();
485 skin_file.copyFileTo(LoadSave::getDefaultSkin());
486 Skin skin;
487
488 skin.loadFromFile(skin_file);
489 loadSkin(skin);
490 }
491 }
492 else {
493 Skin skin;
494 File skin_file = skins_[skin_->getValue() - 1];
495 if (!skin_file.exists())
496 return;
497
498 LoadSave::saveLoadedSkin(skin_file.getFileNameWithoutExtension().toStdString());
499 skin_file.copyFileTo(default_skin);
500 skin.loadFromFile(skin_file);
501 loadSkin(skin);
502 }
503 skin_value_ = skin_->getValue();
504 }
505 }
506
507 private:
508 std::unique_ptr<TextSelector> frequency_display_;
509 std::unique_ptr<TextSelector> skin_;
510 int skin_value_;
511
512 Array<File> skins_;
513 std::unique_ptr<std::string[]> short_skin_strings_;
514 std::unique_ptr<std::string[]> long_skin_strings_;
515
516 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DisplaySettings)
517};
518
520 public:
521 OutputDisplays() : SynthSection("ANALYSIS") {
522 setSidewaysHeading(false);
523
524 oscilloscope_ = std::make_unique<Oscilloscope>();
525 addOpenGlComponent(oscilloscope_.get());
526
527 spectrogram_ = std::make_unique<Spectrogram>();
528 addOpenGlComponent(spectrogram_.get());
529 }
530
531 void paintBackgroundShadow(Graphics& g) override { paintTabShadow(g); }
532
533 void resized() override {
535
536 int widget_margin = getWidgetMargin();
537 int x = widget_margin;
538 int width = getWidth() - 2 * widget_margin;
539 int oscilloscope_y = getTitleWidth() + widget_margin;
540 int oscilloscope_height = (getHeight() - oscilloscope_y) / 2;
541 oscilloscope_->setBounds(x, oscilloscope_y, width, oscilloscope_height);
542
543 int spectrogram_y = oscilloscope_->getBottom() + widget_margin;
544 int spectrogram_height = getHeight() - spectrogram_y - widget_margin;
545 spectrogram_->setBounds(x, spectrogram_y, width, spectrogram_height);
546 }
547
549 oscilloscope_->setOscilloscopeMemory(memory);
550 }
551
553 spectrogram_->setAudioMemory(memory);
554 }
555
556 private:
557 std::unique_ptr<Oscilloscope> oscilloscope_;
558 std::unique_ptr<Spectrogram> spectrogram_;
559
560 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OutputDisplays)
561};
562
564 const vital::output_map& mono_modulations,
565 const vital::output_map& poly_modulations, bool synth) : SynthSection("master_controls") {
566
567 // If synth mode is enabled, create advanced oscillator sections.
568 if (synth) {
569 for (int i = 0; i < vital::kNumOscillators; ++i) {
570 oscillator_advanceds_[i] = std::make_unique<OscillatorAdvancedSection>(i + 1, mono_modulations,
571 poly_modulations);
572 addSubSection(oscillator_advanceds_[i].get());
573 }
574 }
575
576 // Create and add sub-sections for voice, oversampling, display, and output analysis.
577 voice_settings_ = std::make_unique<VoiceSettings>();
578 addSubSection(voice_settings_.get());
579
580 oversample_settings_ = std::make_unique<OversampleSettings>();
581 addSubSection(oversample_settings_.get());
582
583 display_settings_ = std::make_unique<DisplaySettings>();
584 addSubSection(display_settings_.get());
585
586 output_displays_ = std::make_unique<OutputDisplays>();
587 addSubSection(output_displays_.get());
588
589 setOpaque(false);
591}
592
594
598
601 int large_padding = findValue(Skin::kLargePadding);
602 int padding = findValue(Skin::kPadding);
603 int settings_top = padding;
604
605 // If oscillator sections are present, position settings sections below them.
606 if (oscillator_advanceds_[vital::kNumOscillators - 1])
607 settings_top = oscillator_advanceds_[vital::kNumOscillators - 1]->getBottom() + large_padding;
608
609 int settings_height = getHeight() - settings_top;
610 int panel_width = getWidth() * 0.22f;
611
612 // Layout voice settings to the left.
613 voice_settings_->setBounds(0, settings_top, panel_width, settings_height);
614
615 int oversample_x = voice_settings_->getRight() + padding;
616 int display_height = getTitleWidth() + getWidgetMargin() + 1.5 * getKnobSectionHeight();
617 int oversample_height = settings_height - display_height - padding;
618
619 // Place oversampling settings above display settings.
620 oversample_settings_->setBounds(oversample_x, settings_top, panel_width, oversample_height);
621
622 int display_y = oversample_settings_->getBottom() + padding;
623 display_settings_->setBounds(oversample_x, display_y, panel_width, display_height);
624
625 int displays_x = display_settings_->getRight() + padding;
626 int displays_width = getWidth() - displays_x;
627 // Output displays occupy the remaining right side.
628 output_displays_->setBounds(displays_x, settings_top, displays_width, settings_height);
629}
630
632 oscillator_advanceds_[index]->passOscillatorSection(oscillator);
633}
634
636 output_displays_->setOscilloscopeMemory(memory);
637}
638
640 output_displays_->setAudioMemory(memory);
641}
Definition master_controls_interface.cpp:371
void loadSkin(Skin &skin)
Definition master_controls_interface.cpp:461
DisplaySettings()
Definition master_controls_interface.cpp:373
void parentHierarchyChanged() override
Definition master_controls_interface.cpp:456
void paintBackground(Graphics &g) override
Paints the background of the section. Calls paintContainer, heading, knobs, children.
Definition master_controls_interface.cpp:422
void resized() override
Called when the component is resized. Arranges layout of child components.
Definition master_controls_interface.cpp:432
void paintBackgroundShadow(Graphics &g) override
Stub for painting background shadows. Overridden by subclasses if needed.
Definition master_controls_interface.cpp:421
void sliderValueChanged(Slider *changed_slider) override
Called when a slider value changes. Updates the synth parameter accordingly.
Definition master_controls_interface.cpp:466
void setDisplayValue(Skin::ValueId id, float value)
Definition master_controls_interface.cpp:450
The main GUI container for the entire synthesizer interface.
Definition full_interface.h:61
void reloadSkin(const Skin &skin)
Reloads and applies a new skin, then adjusts layout accordingly.
Definition full_interface.cpp:276
static std::string getLoadedSkin()
Retrieves the currently loaded skin name.
Definition load_save.cpp:1572
static bool displayHzFrequency()
Determines if frequencies should be displayed in Hz.
Definition load_save.cpp:1590
static void getAllSkins(Array< File > &skins)
Retrieves all skins from skin directories.
Definition load_save.cpp:1843
static void saveDisplayHzFrequency(bool display_hz)
Saves the preference to display frequency in Hz.
Definition load_save.cpp:1312
static File getDefaultSkin()
Retrieves the file specifying the default skin.
Definition load_save.cpp:1168
static void saveLoadedSkin(const std::string &name)
Saves the currently loaded skin name to the config.
Definition load_save.cpp:1300
MasterControlsInterface(const vital::output_map &mono_modulations, const vital::output_map &poly_modulations, bool synth)
Constructs a MasterControlsInterface.
Definition master_controls_interface.cpp:563
void paintBackground(Graphics &g) override
Paints the background of the interface.
Definition master_controls_interface.cpp:595
void setOscilloscopeMemory(const vital::poly_float *memory)
Sets the oscilloscope memory for audio visualization.
Definition master_controls_interface.cpp:635
void resized() override
Resizes and lays out all child components (oscillators, voice settings, etc.).
Definition master_controls_interface.cpp:599
void passOscillatorSection(int index, const OscillatorSection *oscillator)
Passes an oscillator section model to the corresponding advanced section UI.
Definition master_controls_interface.cpp:631
virtual ~MasterControlsInterface()
Destructor.
Definition master_controls_interface.cpp:593
void setAudioMemory(const vital::StereoMemory *memory)
Sets the audio memory for spectrogram analysis.
Definition master_controls_interface.cpp:639
virtual void valueChanged() override
Called when the slider value changes. Redraws the image to reflect the new value.
Definition synth_slider.h:80
void parentHierarchyChanged() override
Called when the parent hierarchy changes. Used for retrieving parent sections.
Definition synth_slider.h:86
SynthSection * parent_
The parent SynthSection.
Definition synth_slider.h:289
A UI section representing an oscillator in the synthesizer.
Definition oscillator_section.h:32
Definition master_controls_interface.cpp:519
void resized() override
Called when the component is resized. Arranges layout of child components.
Definition master_controls_interface.cpp:533
void paintBackgroundShadow(Graphics &g) override
Stub for painting background shadows. Overridden by subclasses if needed.
Definition master_controls_interface.cpp:531
void setAudioMemory(const vital::StereoMemory *memory)
Definition master_controls_interface.cpp:552
OutputDisplays()
Definition master_controls_interface.cpp:521
void setOscilloscopeMemory(const vital::poly_float *memory)
Definition master_controls_interface.cpp:548
Definition master_controls_interface.cpp:263
void paintBackgroundShadow(Graphics &g) override
Stub for painting background shadows. Overridden by subclasses if needed.
Definition master_controls_interface.cpp:313
void resized() override
Called when the component is resized. Arranges layout of child components.
Definition master_controls_interface.cpp:315
void paintBackground(Graphics &g) override
Paints the background of the section. Calls paintContainer, heading, knobs, children.
Definition master_controls_interface.cpp:302
OversampleSettings()
Definition master_controls_interface.cpp:265
void buttonClicked(Button *clicked_button) override
Called when a button is clicked. Updates the synth parameter accordingly.
Definition master_controls_interface.cpp:334
void setAllValues(vital::control_map &controls) override
Sets values for all known parameters from a control map.
Definition master_controls_interface.cpp:297
Manages the overall color and value theme (or "skin") of the user interface.
Definition skin.h:24
bool loadFromFile(File source)
Loads skin state from a file.
Definition skin.cpp:435
ValueId
Identifiers for various UI scaling/spacing values and configuration constants.
Definition skin.h:70
@ kPadding
Definition skin.h:81
@ kLargePadding
Definition skin.h:82
@ kTextButtonHeight
Definition skin.h:87
@ kLabelBackgroundRounding
Definition skin.h:74
@ kFrequencyDisplay
Definition skin.h:116
@ kTextComponentBackground
Definition skin.h:147
@ kAdvanced
Definition skin.h:59
void loadDefaultSkin()
Loads a default built-in skin.
Definition skin.cpp:195
void valueChangedInternal(const std::string &name, vital::mono_float value)
Handles internal value changes, updating the parameter and optionally notifying the host.
Definition synth_base.cpp:54
Tuning * getTuning()
Returns a pointer to the synth's Tuning object.
Definition synth_base.h:554
void setMpeEnabled(bool enabled)
Enables or disables MPE (MIDI Polyphonic Expression) mode.
Definition synth_base.cpp:560
void loadTuningFile(const File &file)
Loads a tuning file into the synthesizer’s tuning system.
Definition synth_base.cpp:312
void notifyOversamplingChanged()
Notifies that oversampling settings have changed, reinitializing the engine if needed.
Definition synth_base.cpp:734
An interface class linking the Vital synthesizer backend (SynthBase) with a GUI.
Definition synth_gui_interface.h:56
FullInterface * getGui()
Gets the FullInterface GUI component if it exists.
Definition synth_gui_interface.h:223
SynthBase * getSynth()
Returns the SynthBase instance this interface is managing.
Definition synth_gui_interface.h:85
Base class for all synthesizer sections, providing UI layout, painting, and interaction logic.
Definition synth_section.h:193
void drawTextComponentBackground(Graphics &g, Rectangle< int > bounds, bool extend_to_label)
Draws a background for a text component area.
Definition synth_section.cpp:319
virtual void buttonClicked(Button *clicked_button) override
Called when a button is clicked. Updates the synth parameter accordingly.
Definition synth_section.cpp:398
void addSlider(SynthSlider *slider, bool show=true, bool listen=true)
Definition synth_section.cpp:445
void addSubSection(SynthSection *section, bool show=true)
Adds a subsection (another SynthSection) as a child.
Definition synth_section.cpp:457
void setSidewaysHeading(bool sideways)
Definition synth_section.h:771
virtual void resized() override
Called when the component is resized. Arranges layout of child components.
Definition synth_section.cpp:35
static constexpr double kTransposeMouseSensitivity
Definition synth_section.h:204
void paintChildrenBackgrounds(Graphics &g)
Paints the backgrounds for all child sections.
Definition synth_section.cpp:274
void drawLabelForComponent(Graphics &g, String text, Component *component, bool text_component=false)
Draws a label for a given component.
Definition synth_section.h:548
void setLabelFont(Graphics &g)
Sets the Graphics context font and color for labels.
Definition synth_section.cpp:740
void showPopupSelector(Component *source, Point< int > position, const PopupItems &options, std::function< void(int)> callback, std::function< void()> cancel={ })
Shows a popup selector with options.
Definition synth_section.cpp:119
void addButton(OpenGlToggleButton *button, bool show=true)
Definition synth_section.cpp:428
float findValue(Skin::ValueId value_id) const
Finds a value in the skin overrides or from the parent if not found locally.
Definition synth_section.cpp:18
virtual void paintBackground(Graphics &g)
Paints the background of the section. Calls paintContainer, heading, knobs, children.
Definition synth_section.cpp:77
float getKnobSectionHeight()
Definition synth_section.cpp:633
void addOpenGlComponent(OpenGlComponent *open_gl_component, bool to_beginning=false)
Definition synth_section.cpp:489
virtual void setAllValues(vital::control_map &controls)
Sets values for all known parameters from a control map.
Definition synth_section.cpp:827
float getTitleWidth()
Definition synth_section.cpp:629
void setSkinOverride(Skin::SectionOverride skin_override)
Definition synth_section.h:303
void setSkinValue(Skin::ValueId id, float value)
Sets a single skin value override.
Definition synth_section.h:748
virtual void paintTabShadow(Graphics &g)
Paints a tab-like shadow effect around the component.
Definition synth_section.cpp:188
float getWidgetMargin()
Definition synth_section.cpp:676
void setStringLookup(const std::string *lookup)
Definition synth_slider.h:470
virtual void mouseDown(const MouseEvent &e) override
Mouse event overrides for custom behavior.
Definition synth_slider.cpp:234
const std::string * string_lookup_
Definition synth_slider.h:763
static TextLookAndFeel * instance()
Singleton instance access.
Definition text_look_and_feel.h:106
A specialized SynthSlider that displays a popup menu of text options.
Definition text_selector.h:14
const std::string * long_lookup_
Optional alternate lookup table for longer strings.
Definition text_selector.h:37
void setName(const std::string &name)
Sets a custom name for the current tuning, clearing any mapping name.
Definition tuning.h:170
static String allFileExtensions()
Returns a string listing all supported tuning file extensions.
Definition tuning.cpp:93
void loadScalaFile(const StringArray &scala_lines)
Loads a Scala (.scl) file from a set of lines.
Definition tuning.cpp:160
std::string getName() const
Gets the name of the current tuning, combining tuning and mapping names if both exist.
Definition tuning.h:157
void setDefaultTuning()
Resets the tuning to the default 12-tone equal temperament with a standard reference pitch.
Definition tuning.cpp:354
void mouseDown(const MouseEvent &e) override
Handles mouse down events, including showing a popup menu for selecting tunings.
Definition master_controls_interface.cpp:42
void valueChanged() override
Called when the value of the selector changes.
Definition master_controls_interface.cpp:63
void setTuning(int tuning)
Sets the current tuning style.
Definition master_controls_interface.cpp:74
TuningSelector(String name)
Constructs a TuningSelector with a given name.
Definition master_controls_interface.cpp:31
virtual ~TuningSelector()
Destructor.
Definition master_controls_interface.cpp:40
void parentHierarchyChanged() override
Called when the component's parent hierarchy changes.
Definition master_controls_interface.cpp:69
TuningStyle
Enumerates the available tuning styles.
Definition master_controls_interface.h:30
@ k5Limit
Just intonation with a 5-limit scale.
Definition master_controls_interface.h:33
@ kNumTunings
Number of available tuning styles.
Definition master_controls_interface.h:35
@ k7Limit
Just intonation with a 7-limit scale.
Definition master_controls_interface.h:32
@ kPythagorean
Pythagorean tuning.
Definition master_controls_interface.h:34
Definition master_controls_interface.cpp:138
void resized() override
Called when the component is resized. Arranges layout of child components.
Definition master_controls_interface.cpp:202
void buttonClicked(Button *clicked_button) override
Called when a button is clicked. Updates the synth parameter accordingly.
Definition master_controls_interface.cpp:231
VoiceSettings()
Definition master_controls_interface.cpp:140
void setAllValues(vital::control_map &controls) override
Sets values for all known parameters from a control map.
Definition master_controls_interface.cpp:238
void paintBackground(Graphics &g) override
Paints the background of the section. Calls paintContainer, heading, knobs, children.
Definition master_controls_interface.cpp:180
void paintBackgroundShadow(Graphics &g) override
Stub for painting background shadows. Overridden by subclasses if needed.
Definition master_controls_interface.cpp:200
A specialized MemoryTemplate for two-channel (stereo) audio.
Definition memory.h:216
const std::string kVoicePriorityNames[]
Voice allocation priority modes (e.g., newest, oldest note).
Definition synth_strings.h:339
const std::string kVoiceOverrideNames[]
Behavior of what happens when voice limit is exceeded (kill or steal).
Definition synth_strings.h:351
constexpr int kNumOscillators
Number of oscillators available in Vital.
Definition synth_constants.h:16
const std::string kSkinExtension
File extension for Vital skin/theme files.
Definition synth_constants.h:97
std::map< std::string, Output * > output_map
Maps parameter names to Output pointers, representing output signals from various modules.
Definition synth_types.h:229
std::map< std::string, Value * > control_map
Maps parameter names to Value pointers representing synth control parameters.
Definition synth_types.h:214
A hierarchical structure of popup menu items for a selector component.
Definition synth_section.h:29
void addItem(int sub_id, const std::string &sub_name, bool sub_selected=false)
Adds a new item as a submenu entry.
Definition synth_section.h:51
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
Declares classes for OpenGL-based buttons used in the Vital synth UI.
Declares the SynthSlider and related classes, providing various slider styles and functionality in th...
Declares the TextSelector class and PaintPatternSelector class for selecting text-based options and d...