Vital
Loading...
Searching...
No Matches
full_interface.cpp
Go to the documentation of this file.
1#include "full_interface.h"
2
3#include "about_section.h"
4#include "bank_exporter.h"
5#include "bend_section.h"
6#include "delete_section.h"
7#include "download_section.h"
8#include "expired_section.h"
9#include "extra_mod_section.h"
10#include "skin.h"
11#include "effects_interface.h"
12#include "fonts.h"
13#include "sound_engine.h"
14#include "keyboard_interface.h"
15#include "load_save.h"
18#include "modulation_manager.h"
19#include "modulation_matrix.h"
20#include "modulation_meter.h"
22#include "overlay.h"
23#include "portamento_section.h"
24#include "preset_browser.h"
25#include "synthesis_interface.h"
26#include "synth_gui_interface.h"
27#include "text_look_and_feel.h"
29#include "voice_section.h"
30
31FullInterface::FullInterface(SynthGuiData* synth_data) : SynthSection("full_interface"), width_(0), resized_width_(0),
32 last_render_scale_(0.0f), display_scale_(1.0f),
33 pixel_multiple_(1), setting_all_values_(false),
34 unsupported_(false), animate_(true),
35 enable_redo_background_(true), needs_download_(false),
36 open_gl_(open_gl_context_) {
37 full_screen_section_ = nullptr;
38 Skin default_skin;
39 setSkinValues(default_skin, true);
41
42 bool synth = synth_data->wavetable_creators[0];
43 if (synth) {
44 synthesis_interface_ = std::make_unique<SynthesisInterface>(&auth_,
45 synth_data->mono_modulations,
46 synth_data->poly_modulations);
47
48 for (int i = 0; i < vital::kNumOscillators; ++i) {
49 wavetable_edits_[i] = std::make_unique<WavetableEditSection>(i, synth_data->wavetable_creators[i]);
50 addSubSection(wavetable_edits_[i].get());
51 wavetable_edits_[i]->setVisible(false);
52 wavetable_edits_[i]->setWaveFrameSlider(synthesis_interface_->getWaveFrameSlider(i));
53 }
54
55 addSubSection(synthesis_interface_.get());
56 }
57
58 effects_interface_ = std::make_unique<EffectsInterface>(synth_data->mono_modulations);
59 addSubSection(effects_interface_.get());
60 effects_interface_->setVisible(false);
61 effects_interface_->addListener(this);
62
63 master_controls_interface_ = std::make_unique<MasterControlsInterface>(synth_data->mono_modulations,
64 synth_data->poly_modulations,
65 synth);
66 addSubSection(master_controls_interface_.get());
67 master_controls_interface_->setVisible(false);
68
69 if (synthesis_interface_) {
70 for (int i = 0; i < vital::kNumOscillators; ++i)
71 master_controls_interface_->passOscillatorSection(i, synthesis_interface_->getOscillatorSection(i));
72 }
73
74 header_ = std::make_unique<HeaderSection>();
75 addSubSection(header_.get());
76 header_->addListener(this);
77
78 modulation_interface_ = std::make_unique<ModulationInterface>(synth_data);
79 addSubSection(modulation_interface_.get());
80
81 extra_mod_section_ = std::make_unique<ExtraModSection>("extra_mod_section", synth_data);
82 addSubSection(extra_mod_section_.get());
83
84 keyboard_interface_ = std::make_unique<KeyboardInterface>(synth_data->synth->getKeyboardState());
85 addSubSection(keyboard_interface_.get());
86
87 bend_section_ = std::make_unique<BendSection>("BEND");
88 addSubSection(bend_section_.get());
89
90 portamento_section_ = std::make_unique<PortamentoSection>("PORTAMENTO");
91 addSubSection(portamento_section_.get());
92
93 voice_section_ = std::make_unique<VoiceSection>("VOICE");
94 addSubSection(voice_section_.get());
95
96 modulation_matrix_ = std::make_unique<ModulationMatrix>(synth_data->modulation_sources, synth_data->mono_modulations);
97 addSubSection(modulation_matrix_.get());
98 modulation_matrix_->setVisible(false);
99 modulation_matrix_->addListener(this);
101
102 preset_browser_ = std::make_unique<PresetBrowser>();
103 addSubSection(preset_browser_.get());
104 preset_browser_->setVisible(false);
105
106 popup_browser_ = std::make_unique<PopupBrowser>();
107 addSubSection(popup_browser_.get());
108 popup_browser_->setVisible(false);
109
110 popup_selector_ = std::make_unique<SinglePopupSelector>();
111 addSubSection(popup_selector_.get());
112 popup_selector_->setVisible(false);
113 popup_selector_->setAlwaysOnTop(true);
114 popup_selector_->setWantsKeyboardFocus(true);
115
116 dual_popup_selector_ = std::make_unique<DualPopupSelector>();
117 addSubSection(dual_popup_selector_.get());
118 dual_popup_selector_->setVisible(false);
119 dual_popup_selector_->setAlwaysOnTop(true);
120 dual_popup_selector_->setWantsKeyboardFocus(true);
121
122 popup_display_1_ = std::make_unique<PopupDisplay>();
123 addSubSection(popup_display_1_.get());
124 popup_display_1_->setVisible(false);
125 popup_display_1_->setAlwaysOnTop(true);
126 popup_display_1_->setWantsKeyboardFocus(false);
127
128 popup_display_2_ = std::make_unique<PopupDisplay>();
129 addSubSection(popup_display_2_.get());
130 popup_display_2_->setVisible(false);
131 popup_display_2_->setAlwaysOnTop(true);
132 popup_display_2_->setWantsKeyboardFocus(false);
133
134 bank_exporter_ = std::make_unique<BankExporter>();
135 addSubSection(bank_exporter_.get());
136 bank_exporter_->setVisible(false);
137 header_->setBankExporter(bank_exporter_.get());
138
139 save_section_ = std::make_unique<SaveSection>("save_section");
140 addSubSection(save_section_.get(), false);
141 addChildComponent(save_section_.get());
142 preset_browser_->setSaveSection(save_section_.get());
143 header_->setSaveSection(save_section_.get());
144 header_->setBrowser(preset_browser_.get());
145
146 delete_section_ = std::make_unique<DeleteSection>("delete_section");
147 addSubSection(delete_section_.get(), false);
148 addChildComponent(delete_section_.get());
149 preset_browser_->setDeleteSection(delete_section_.get());
150
151 download_section_ = std::make_unique<DownloadSection>("download_section", &auth_);
152 addSubSection(download_section_.get(), false);
153 addChildComponent(download_section_.get());
154 download_section_->setAlwaysOnTop(true);
155 download_section_->addListener(this);
156
157 about_section_ = std::make_unique<AboutSection>("about");
158 addSubSection(about_section_.get(), false);
159 addChildComponent(about_section_.get());
160
161 if (synthesis_interface_)
162 synthesis_interface_->toFront(true);
163
164 master_controls_interface_->toFront(true);
165 effects_interface_->toFront(true);
166 modulation_interface_->toFront(true);
167 extra_mod_section_->toFront(true);
168 keyboard_interface_->toFront(true);
169 bend_section_->toFront(true);
170 portamento_section_->toFront(true);
171 voice_section_->toFront(true);
172 modulation_manager_->toFront(false);
173 preset_browser_->toFront(false);
174 bank_exporter_->toFront(false);
175 about_section_->toFront(true);
176 save_section_->toFront(true);
177 delete_section_->toFront(true);
178 popup_browser_->toFront(true);
179 popup_selector_->toFront(true);
180 dual_popup_selector_->toFront(true);
181 popup_display_1_->toFront(true);
182 popup_display_2_->toFront(true);
183 download_section_->toFront(true);
184
185 update_check_section_ = std::make_unique<UpdateCheckSection>("update_check");
186 addSubSection(update_check_section_.get(), false);
187 addChildComponent(update_check_section_.get());
188 update_check_section_->setAlwaysOnTop(true);
189 update_check_section_->addListener(this);
190
191 if (LoadSave::isExpired()) {
192 expired_section_ = std::make_unique<ExpiredSection>("expired");
193 addSubSection(expired_section_.get());
194 expired_section_->setAlwaysOnTop(true);
195 }
196
197#if NDEBUG && !NO_AUTH
198 bool authenticated = LoadSave::authenticated();
199 bool work_offline = LoadSave::shouldWorkOffline();
200 authentication_ = std::make_unique<AuthenticationSection>(&auth_);
201 authentication_->addListener(this);
202 addSubSection(authentication_.get(), false);
203 addChildComponent(authentication_.get());
204 authentication_->setVisible(!authenticated && !work_offline);
205 authentication_->init();
206 if (!work_offline)
207 authentication_->create();
208#endif
209
210 setAllValues(synth_data->controls);
211 setOpaque(true);
212 setSkinValues(default_skin, true);
213
214 needs_download_ = UpdateMemory::getInstance()->incrementChecker();
215
216 open_gl_context_.setContinuousRepainting(true);
217 open_gl_context_.setOpenGLVersionRequired(OpenGLContext::openGL3_2);
218 open_gl_context_.setSwapInterval(0);
219 open_gl_context_.setRenderer(this);
220 open_gl_context_.setComponentPaintingEnabled(false);
221 open_gl_context_.attachTo(*this);
222}
223
224FullInterface::FullInterface() : SynthSection("EMPTY"), open_gl_(open_gl_context_) {
225 Skin default_skin;
226 setSkinValues(default_skin, true);
227
228 open_gl_context_.setContinuousRepainting(true);
229 open_gl_context_.setOpenGLVersionRequired(OpenGLContext::openGL3_2);
230 open_gl_context_.setSwapInterval(0);
231 open_gl_context_.setRenderer(this);
232 open_gl_context_.setComponentPaintingEnabled(false);
233 open_gl_context_.attachTo(*this);
234
235 reset();
236 setOpaque(true);
237}
238
240 UpdateMemory::getInstance()->decrementChecker();
241
242 open_gl_context_.detach();
243 open_gl_context_.setRenderer(nullptr);
244}
245
247 g.fillAll(findColour(Skin::kBackground, true));
249
250 if (effects_interface_ == nullptr)
251 return;
252
253 int padding = getPadding();
254 int bar_width = 6 * padding;
255 g.setColour(header_->findColour(Skin::kBody, true));
256 int y = header_->getBottom();
257 int height = keyboard_interface_->getY() - y;
258 int x1 = extra_mod_section_->getRight() + padding;
259 g.fillRect(x1, y, bar_width, height);
260
261 if (synthesis_interface_) {
262 int x2 = synthesis_interface_->getRight() + padding;
263 g.fillRect(x2, y, bar_width, height);
264 }
265
268}
269
271 ScopedLock open_gl_lock(open_gl_critical_section_);
273 setSkinValues(skin, true);
274}
275
277 copySkinValues(skin);
278 Rectangle<int> bounds = getBounds();
279 setBounds(0, 0, bounds.getWidth() / 4, bounds.getHeight() / 4);
280 setBounds(bounds);
281}
282
284 preset_browser_->loadPresets();
285}
286
288 update_check_section_->startCheck();
289}
290
292 if (!download_section_->isVisible() && !update_check_section_->isVisible())
293 update_check_section_->setVisible(true);
294}
295
297#if !defined(NO_TEXT_ENTRY)
298 if (needs_download_)
299 download_section_->triggerDownload();
300#endif
301}
302
304 if (!background_image_.isValid() || setting_all_values_)
305 return;
306
307 if (child->getParentComponent() == synthesis_interface_.get()) {
309 return;
310 }
311
312 if (effects_interface_ != nullptr && effects_interface_->isParentOf(child))
313 child = effects_interface_.get();
314
315 background_.lock();
316 Graphics g(background_image_);
317 paintChildBackground(g, child);
318 background_.updateBackgroundImage(background_image_);
319 background_.unlock();
320}
321
323 if (synthesis_interface_ == nullptr || !synthesis_interface_->isVisible() || !background_image_.isValid())
324 return;
325
326 background_.lock();
327 Graphics g(background_image_);
328 int padding = findValue(Skin::kPadding);
329 g.setColour(findColour(Skin::kBackground, true));
330 g.fillRect(synthesis_interface_->getBounds().expanded(padding));
331 paintChildShadow(g, synthesis_interface_.get());
332 paintChildBackground(g, synthesis_interface_.get());
333
334 background_.updateBackgroundImage(background_image_);
335 background_.unlock();
336}
337
339 if (!background_image_.isValid())
340 return;
341
342 background_.lock();
343 Graphics g(background_image_);
344 paintOpenGlBackground(g, component);
345 background_.updateBackgroundImage(background_image_);
346 background_.unlock();
347}
348
350 int width = std::ceil(display_scale_ * getWidth());
351 int height = std::ceil(display_scale_ * getHeight());
352 if (width < vital::kMinWindowWidth || height < vital::kMinWindowHeight)
353 return;
354
355 ScopedLock open_gl_lock(open_gl_critical_section_);
356
357 background_.lock();
358 background_image_ = Image(Image::RGB, width, height, true);
359 Graphics g(background_image_);
361 background_.updateBackgroundImage(background_image_);
362 background_.unlock();
363}
364
366 float old_scale = display_scale_;
367 int old_pixel_multiple = pixel_multiple_;
368 display_scale_ = getDisplayScale();
369 pixel_multiple_ = std::max<int>(1, display_scale_);
370
371 if (resize && (old_scale != display_scale_ || old_pixel_multiple != pixel_multiple_))
372 resized();
373}
374
376
377
379
380 width_ = getWidth();
381 if (!enable_redo_background_)
382 return;
383
384 resized_width_ = width_;
385
386 ScopedLock lock(open_gl_critical_section_);
387 static constexpr int kTopHeight = 48;
388
389 if (effects_interface_ == nullptr)
390 return;
391
392 int left = 0;
393 int top = 0;
394 int width = std::ceil(getWidth() * display_scale_);
395 int height = std::ceil(getHeight() * display_scale_);
396 Rectangle<int> bounds(0, 0, width, height);
397
398 float width_ratio = getWidth() / (1.0f * vital::kDefaultWindowWidth);
399 float ratio = width_ratio * display_scale_;
400 float height_ratio = getHeight() / (1.0f * vital::kDefaultWindowHeight);
401 if (width_ratio > height_ratio + 1.0f / vital::kDefaultWindowHeight) {
402 ratio = height_ratio;
403 width = height_ratio * vital::kDefaultWindowWidth * display_scale_;
404 left = (getWidth() - width) / 2;
405 }
406 if (height_ratio > width_ratio + 1.0f / vital::kDefaultWindowHeight) {
407 ratio = width_ratio;
408 height = ratio * vital::kDefaultWindowHeight * display_scale_;
409 top = (getHeight() - height) / 2;
410 }
411
412 setSizeRatio(ratio);
413
414 if (expired_section_)
415 expired_section_->setBounds(bounds);
416
417 if (authentication_)
418 authentication_->setBounds(bounds);
419
420 popup_browser_->setBounds(bounds);
421
422 int padding = getPadding();
423 int voice_padding = findValue(Skin::kLargePadding);
424 int extra_mod_width = findValue(Skin::kModulationButtonWidth);
425 int main_x = left + extra_mod_width + 2 * voice_padding;
426 int top_height = kTopHeight * ratio;
427
428 int knob_section_height = getKnobSectionHeight();
429 int keyboard_section_height = knob_section_height * 0.7f;
430 int voice_height = height - top_height - keyboard_section_height;
431
432 int section_one_width = 350 * ratio;
433 int section_two_width = section_one_width;
434 int audio_width = section_one_width + section_two_width + padding;
435 int modulation_width = width - audio_width - extra_mod_width - 4 * voice_padding;
436
437 header_->setTabOffset(extra_mod_width + 2 * voice_padding);
438 header_->setBounds(left, top, width, top_height);
439 Rectangle<int> main_bounds(main_x, top + top_height, audio_width, voice_height);
440
441 if (synthesis_interface_)
442 synthesis_interface_->setBounds(main_bounds);
443 effects_interface_->setBounds(main_bounds.withRight(main_bounds.getRight() + voice_padding));
444 modulation_matrix_->setBounds(main_bounds);
445 int modulation_height = voice_height - knob_section_height - padding;
446 modulation_interface_->setBounds(main_bounds.getRight() + voice_padding,
447 main_bounds.getY(), modulation_width, modulation_height);
448
449 int voice_y = top + height - knob_section_height - keyboard_section_height;
450
451 int portamento_width = 4 * (int)findValue(Skin::kModulationButtonWidth);
452 int portamento_x = modulation_interface_->getRight() - portamento_width;
453 portamento_section_->setBounds(portamento_x, voice_y, portamento_width, knob_section_height);
454
455 int voice_width = modulation_interface_->getWidth() - portamento_width - padding;
456 voice_section_->setBounds(modulation_interface_->getX(), voice_y, voice_width, knob_section_height);
457
458 bend_section_->setBounds(left + voice_padding, top + height - knob_section_height - padding,
459 extra_mod_width, knob_section_height);
460
461 int extra_mod_height = height - top_height - knob_section_height - padding - 1;
462 extra_mod_section_->setBounds(left + voice_padding, top + top_height, extra_mod_width, extra_mod_height);
463
464 int keyboard_height = keyboard_section_height - voice_padding - padding;
465 int keyboard_x = extra_mod_section_->getRight() + voice_padding;
466 int keyboard_width = modulation_interface_->getRight() - keyboard_x;
467 keyboard_interface_->setBounds(keyboard_x, top + height - keyboard_height - padding, keyboard_width, keyboard_height);
468
469 about_section_->setBounds(bounds);
470 update_check_section_->setBounds(bounds);
471 save_section_->setBounds(bounds);
472 delete_section_->setBounds(bounds);
473 download_section_->setBounds(bounds);
474
475 Rectangle<int> browse_bounds(main_bounds.getX(), main_bounds.getY(),
476 width - main_bounds.getX(), main_bounds.getHeight());
477 preset_browser_->setBounds(browse_bounds);
478 bank_exporter_->setBounds(browse_bounds);
480
481 modulation_manager_->setBounds(bounds);
482
483 for (int i = 0; i < vital::kNumOscillators; ++i) {
484 if (wavetable_edits_[i])
485 wavetable_edits_[i]->setBounds(left, 0, width, height);
486 }
487
488 if (synthesis_interface_) {
489 for (int i = 0; i < vital::kNumOscillators; ++i)
490 master_controls_interface_->setOscillatorBounds(i, synthesis_interface_->getOscillatorBounds(i));
491 }
492 master_controls_interface_->setBounds(main_bounds);
493
494 if (full_screen_section_) {
495 Rectangle<float> relative = synthesis_interface_->getOscillatorSection(0)->getWavetableRelativeBounds();
496 int total_width = getWidth() / relative.getWidth();
497 full_screen_section_->setBounds(-total_width * relative.getX(), 0, total_width, getHeight());
498 }
499
500 if (getWidth() && getHeight())
502}
503
505 if (header_)
506 header_->setOscilloscopeMemory(memory);
507 if (master_controls_interface_)
508 master_controls_interface_->setOscilloscopeMemory(memory);
509}
510
512 if (header_)
513 header_->setAudioMemory(memory);
514 if (master_controls_interface_)
515 master_controls_interface_->setAudioMemory(memory);
516}
517
519 const vital::output_map& poly_modulations) {
520 std::map<std::string, SynthSlider*> all_sliders = getAllSliders();
521 std::map<std::string, SynthSlider*> modulatable_sliders;
522
523 for (auto& destination : mono_modulations) {
524 if (all_sliders.count(destination.first))
525 modulatable_sliders[destination.first] = all_sliders[destination.first];
526 }
527
528 modulation_manager_ = std::make_unique<ModulationManager>(getAllModulationButtons(),
529 modulatable_sliders, mono_modulations, poly_modulations);
530 modulation_manager_->setOpaque(false);
531 addSubSection(modulation_manager_.get());
532}
533
534void FullInterface::animate(bool animate) {
535 if (animate_ != animate)
536 open_gl_context_.setContinuousRepainting(animate);
537
538 animate_ = animate;
540}
541
543 ScopedLock lock(open_gl_critical_section_);
544
545 if (modulation_interface_)
546 modulation_interface_->reset();
547
548 setting_all_values_ = true;
551 if (effects_interface_ && effects_interface_->isVisible())
552 effects_interface_->redoBackgroundImage();
553
555 setting_all_values_ = false;
557}
558
560 ScopedLock lock(open_gl_critical_section_);
561 setting_all_values_ = true;
563 setting_all_values_ = false;
564}
565
567 for (int i = 0; i < vital::kNumOscillators; ++i) {
568 if (wavetable_edits_[i])
569 synthesis_interface_->setWavetableName(i, wavetable_edits_[i]->getName());
570 }
571}
572
574 if (auth_.loggedIn() || authentication_ == nullptr)
575 download_section_->triggerDownload();
576 else
577 authentication_->setVisible(true);
578}
579
581 double version_supported = OpenGLShaderProgram::getLanguageVersion();
582 unsupported_ = version_supported < kMinOpenGlVersion;
583 if (unsupported_) {
584 NativeMessageBox::showMessageBoxAsync(AlertWindow::WarningIcon, "Unsupported OpenGl Version",
585 String("Vial requires OpenGL version: ") + String(kMinOpenGlVersion) +
586 String("\nSupported version: ") + String(version_supported));
587 return;
588 }
589
590 shaders_ = std::make_unique<Shaders>(open_gl_context_);
591 open_gl_.shaders = shaders_.get();
592 open_gl_.display_scale = display_scale_;
593 last_render_scale_ = display_scale_;
594
595 background_.init(open_gl_);
596 initOpenGlComponents(open_gl_);
597}
598
600 if (unsupported_)
601 return;
602
603 float render_scale = open_gl_.context.getRenderingScale();
604 if (render_scale != last_render_scale_) {
605 last_render_scale_ = render_scale;
606 MessageManager::callAsync([=] { checkShouldReposition(true); });
607 }
608
609 ScopedLock lock(open_gl_critical_section_);
610 open_gl_.display_scale = display_scale_;
611 background_.render(open_gl_);
612 modulation_manager_->renderMeters(open_gl_, animate_);
613 renderOpenGlComponents(open_gl_, animate_);
614}
615
617 if (unsupported_)
618 return;
619
620 background_.destroy(open_gl_);
621 destroyOpenGlComponents(open_gl_);
622 open_gl_.shaders = nullptr;
623 shaders_ = nullptr;
624}
625
627 ScopedLock lock(open_gl_critical_section_);
628 about_section_->setVisible(true);
629}
630
632 delete_section_->setFileToDelete(preset);
633 delete_section_->setVisible(true);
634}
635
637 ScopedLock lock(open_gl_critical_section_);
638 bool make_visible = !preset_browser_->isVisible() && !bank_exporter_->isVisible();
639
640 if (synthesis_interface_)
641 synthesis_interface_->setVisible(index == 0 && make_visible);
642
643 effects_interface_->setVisible(index == 1 && make_visible);
644 modulation_matrix_->setVisible(index == 2 && make_visible);
645 master_controls_interface_->setVisible(index == 3 && make_visible);
646 modulation_manager_->setModulationAmounts();
647 modulation_manager_->resized();
648 modulation_manager_->setVisibleMeterBounds();
649 modulation_manager_->hideUnusedHoverModulations();
651}
652
653void FullInterface::clearTemporaryTab(int current_tab) {
654 ScopedLock lock(open_gl_critical_section_);
655 preset_browser_->setVisible(false);
656 bank_exporter_->setVisible(false);
657 modulation_interface_->setVisible(true);
658 portamento_section_->setVisible(true);
659 voice_section_->setVisible(true);
660 tabSelected(current_tab);
661}
662
663void FullInterface::setPresetBrowserVisibility(bool visible, int current_tab) {
664 ScopedLock lock(open_gl_critical_section_);
665 preset_browser_->setVisible(visible);
666 modulation_interface_->setVisible(!visible);
667 portamento_section_->setVisible(!visible);
668 voice_section_->setVisible(!visible);
669 synthesis_interface_->setVisible(!visible);
670
671 if (visible) {
672 tabSelected(-1);
673 bank_exporter_->setVisible(false);
674 preset_browser_->repaintBackground();
675 preset_browser_->grabKeyboardFocus();
676 header_->setTemporaryTab("PRESET BROWSER");
677 }
678 else {
679 tabSelected(current_tab);
680 header_->setTemporaryTab("");
681 }
682}
683
684void FullInterface::setBankExporterVisibility(bool visible, int current_tab) {
685 ScopedLock lock(open_gl_critical_section_);
686 bank_exporter_->setVisible(visible);
687 modulation_interface_->setVisible(!visible);
688 portamento_section_->setVisible(!visible);
689 voice_section_->setVisible(!visible);
690 synthesis_interface_->setVisible(!visible);
691
692 if (visible) {
693 tabSelected(-1);
694 preset_browser_->setVisible(false);
695 bank_exporter_->repaintBackground();
696 header_->setTemporaryTab("EXPORT BANK");
697 }
698 else {
699 tabSelected(current_tab);
700 header_->setTemporaryTab("");
701 }
702}
703
705 preset_browser_->loadPresets();
706}
707
709 modulation_manager_->setVisibleMeterBounds();
710}
711
713 modulation_manager_->setVisibleMeterBounds();
714}
715
717 if (authentication_ && authentication_->isShowing())
718 authentication_->setFocus();
719 else if (synthesis_interface_ && synthesis_interface_->isShowing())
720 synthesis_interface_->setFocus();
721}
722
724 if (header_)
725 header_->notifyChange();
726}
727
729 if (header_)
730 header_->notifyFresh();
731}
732
733void FullInterface::externalPresetLoaded(const File& preset) {
734 if (preset_browser_)
735 preset_browser_->externalPresetLoaded(preset);
736}
737
739 ScopedLock lock(open_gl_critical_section_);
740 full_screen_section_ = full_screen;
741
742 if (full_screen_section_) {
743 addSubSection(full_screen_section_);
744 full_screen_section_->setBounds(getLocalBounds());
745 }
746
747 for (int i = 0; i < vital::kNumOscillators; ++i)
748 wavetable_edits_[i]->setVisible(false);
749
750 bool show_rest = full_screen == nullptr;
751 header_->setVisible(show_rest);
752 synthesis_interface_->setVisible(show_rest);
753 modulation_interface_->setVisible(show_rest);
754 keyboard_interface_->setVisible(show_rest);
755 extra_mod_section_->setVisible(show_rest);
756 modulation_manager_->setVisible(show_rest);
757 voice_section_->setVisible(show_rest);
758 bend_section_->setVisible(show_rest);
759 portamento_section_->setVisible(show_rest);
761}
762
764 if (!wavetableEditorsInitialized())
765 return;
766
767 ScopedLock lock(open_gl_critical_section_);
768 for (int i = 0; i < vital::kNumOscillators; ++i)
769 wavetable_edits_[i]->setVisible(i == index);
770
771 bool show_rest = index < 0;
772 header_->setVisible(show_rest);
773 synthesis_interface_->setVisible(show_rest);
774 modulation_interface_->setVisible(show_rest);
775 keyboard_interface_->setVisible(show_rest);
776 extra_mod_section_->setVisible(show_rest);
777 modulation_manager_->setVisible(show_rest);
778 voice_section_->setVisible(show_rest);
779 bend_section_->setVisible(show_rest);
780 portamento_section_->setVisible(show_rest);
782}
783
785 return wavetable_edits_[index]->getLastBrowsedWavetable();
786}
787
788std::string FullInterface::getWavetableName(int index) {
789 return wavetable_edits_[index]->getName();
790}
791
793 if (authentication_ == nullptr || !auth_.loggedIn())
794 return "";
795
796 return authentication_->getSignedInName();
797}
798
800 if (authentication_)
801 authentication_->signOut();
802}
803
805 if (authentication_) {
806 authentication_->create();
807 authentication_->setVisible(true);
808 }
809}
810
814
815void FullInterface::loadWavetableFile(int index, const File& wavetable) {
816 if (wavetable_edits_[index])
817 wavetable_edits_[index]->loadFile(wavetable);
818}
819
820void FullInterface::loadWavetable(int index, json& wavetable_data) {
821 if (wavetable_edits_[index])
822 wavetable_edits_[index]->loadWavetable(wavetable_data);
823}
824
826 if (wavetable_edits_[index])
827 wavetable_edits_[index]->loadDefaultWavetable();
828}
829
831 if (wavetable_edits_[index])
832 wavetable_edits_[index]->resynthesizeToWavetable();
833}
834
836 save_section_->setIsPreset(false);
837 save_section_->setSaveBounds();
838 save_section_->setFileExtension(vital::kWavetableExtension);
839 save_section_->setFileType("Wavetable");
840 File destination = LoadSave::getUserWavetableDirectory();
841 if (!destination.exists())
842 destination.createDirectory();
843 save_section_->setDirectory(destination);
844 save_section_->setFileData(getWavetableJson(index));
845 save_section_->setVisible(true);
846}
847
848void FullInterface::saveLfo(const json& data) {
849 save_section_->setIsPreset(false);
850 save_section_->setFileExtension(vital::kLfoExtension);
851 save_section_->setFileType("LFO");
852 save_section_->setDirectory(LoadSave::getUserLfoDirectory());
853 save_section_->setFileData(data);
854 save_section_->setVisible(true);
855}
856
858 if (wavetable_edits_[index])
859 return wavetable_edits_[index]->getWavetableJson();
860 return json();
861}
862
863bool FullInterface::loadAudioAsWavetable(int index, const String& name, InputStream* audio_stream,
865 if (wavetable_edits_[index])
866 return wavetable_edits_[index]->loadAudioAsWavetable(name, audio_stream, style);
867
868 delete audio_stream;
869 return true;
870}
871
872void FullInterface::popupBrowser(SynthSection* owner, Rectangle<int> bounds, std::vector<File> directories,
873 String extensions, std::string passthrough_name,
874 std::string additional_folders_name) {
875 popup_browser_->setIgnoreBounds(getLocalArea(owner, owner->getLocalBounds()));
876 popup_browser_->setBrowserBounds(getLocalArea(owner, bounds));
877 popup_browser_->setVisible(true);
878 popup_browser_->grabKeyboardFocus();
879 popup_browser_->setOwner(owner);
880 popup_browser_->loadPresets(directories, extensions, passthrough_name, additional_folders_name);
881}
882
884 if (popup_browser_)
885 popup_browser_->setOwner(owner);
886}
887
888void FullInterface::popupSelector(Component* source, Point<int> position, const PopupItems& options,
889 std::function<void(int)> callback, std::function<void()> cancel) {
890 popup_selector_->setCallback(callback);
891 popup_selector_->setCancelCallback(cancel);
892 popup_selector_->showSelections(options);
893 Rectangle<int> bounds(0, 0, std::ceil(display_scale_ * getWidth()), std::ceil(display_scale_ * getHeight()));
894 popup_selector_->setPosition(getLocalPoint(source, position), bounds);
895 popup_selector_->setVisible(true);
896}
897
898void FullInterface::dualPopupSelector(Component* source, Point<int> position, int width,
899 const PopupItems& options, std::function<void(int)> callback) {
900 dual_popup_selector_->setCallback(callback);
901 dual_popup_selector_->showSelections(options);
902 Rectangle<int> bounds(0, 0, std::ceil(display_scale_ * getWidth()), std::ceil(display_scale_ * getHeight()));
903 dual_popup_selector_->setPosition(getLocalPoint(source, position), width, bounds);
904 dual_popup_selector_->setVisible(true);
905}
906
907void FullInterface::popupDisplay(Component* source, const std::string& text,
908 BubbleComponent::BubblePlacement placement, bool primary) {
909 PopupDisplay* display = primary ? popup_display_1_.get() : popup_display_2_.get();
910 display->setContent(text, getLocalArea(source, source->getLocalBounds()), placement);
911 display->setVisible(true);
912}
913
914void FullInterface::hideDisplay(bool primary) {
915 PopupDisplay* display = primary ? popup_display_1_.get() : popup_display_2_.get();
916 if (display)
917 display->setVisible(false);
918}
919
921 if (modulation_matrix_)
922 modulation_matrix_->updateModulations();
923 if (modulation_interface_)
924 modulation_interface_->checkNumShown();
925 if (modulation_manager_)
926 modulation_manager_->reset();
927}
928
930 if (modulation_matrix_)
931 modulation_matrix_->updateModulationValue(index);
932 if (modulation_manager_)
933 modulation_manager_->setModulationAmounts();
934}
935
937 if (full_screen_section_)
938 showFullScreenSection(nullptr);
939 else
940 showFullScreenSection(synthesis_interface_->getOscillatorSection(index));
941}
942
944 if (full_screen_section_)
945 showFullScreenSection(nullptr);
946 else
947 showFullScreenSection(synthesis_interface_->getFilterSection1());
948}
949
951 if (full_screen_section_)
952 showFullScreenSection(nullptr);
953 else
954 showFullScreenSection(synthesis_interface_->getFilterSection2());
955}
Declares the AboutSection class, which displays information about the application and allows configur...
Declares the ContentList and BankExporter classes for exporting banks of presets, wavetables,...
Declares classes for pitch and modulation wheels, and the BendSection container.
bool loggedIn()
Always returns false, indicating no user is logged in.
Definition authentication.h:180
static DefaultLookAndFeel * instance()
Singleton instance accessor.
Definition default_look_and_feel.h:157
void hideDisplay(bool primary)
Hides a previously shown popup display.
Definition full_interface.cpp:914
void createModulationSliders(const vital::output_map &mono_modulations, const vital::output_map &poly_modulations)
Creates modulation sliders for both mono and poly modulations.
Definition full_interface.cpp:518
std::string getWavetableName(int index)
Gets the current wavetable name for a given oscillator.
Definition full_interface.cpp:788
void repaintOpenGlBackground(OpenGlComponent *component)
Repaints the background that shows behind OpenGL components.
Definition full_interface.cpp:338
void setWavetableNames()
Updates displayed wavetable names from the current wavetable data.
Definition full_interface.cpp:566
void modulationValueChanged(int index)
Called when a particular modulation value changes.
Definition full_interface.cpp:929
void renderOpenGL() override
Renders the GUI using OpenGL.
Definition full_interface.cpp:599
void effectsMoved() override
Called when the effects interface is moved, to update meter positions.
Definition full_interface.cpp:708
void newOpenGLContextCreated() override
Called when a new OpenGL context is created.
Definition full_interface.cpp:580
std::string getSignedInName()
Gets the name of the currently signed-in user, if any.
Definition full_interface.cpp:792
void animate(bool animate) override
Enables or disables animations (like continuous OpenGL repainting).
Definition full_interface.cpp:534
void setAudioMemory(const vital::StereoMemory *memory)
Assigns stereo audio memory for visualization.
Definition full_interface.cpp:511
void saveLfo(const json &data)
Opens a save dialog to save a given LFO shape.
Definition full_interface.cpp:848
void toggleFilter1Zoom()
Definition full_interface.cpp:943
bool loadAudioAsWavetable(int index, const String &name, InputStream *audio_stream, WavetableCreator::AudioFileLoadStyle style)
Loads an audio file as a wavetable into the given oscillator editor.
Definition full_interface.cpp:863
void copySkinValues(const Skin &skin)
Copies skin values from a Skin instance into the interface and look-and-feel.
Definition full_interface.cpp:270
void showFullScreenSection(SynthSection *full_screen)
Displays a full-screen section overlay, hiding other sections.
Definition full_interface.cpp:738
void tabSelected(int index) override
Handles user selecting a main tab (e.g., Synthesis, Effects, etc.)
Definition full_interface.cpp:636
void repaintSynthesisSection()
Repaints only the synthesis (oscillator/filter) section background.
Definition full_interface.cpp:322
void hideWavetableEditSection()
Hides any open wavetable editing section, returning to the normal view.
Definition full_interface.cpp:811
void notifyChange()
Notifies that a parameter or state has changed.
Definition full_interface.cpp:723
void toggleOscillatorZoom(int index)
Definition full_interface.cpp:936
void reset() override
Resets the entire interface to a default state.
Definition full_interface.cpp:542
virtual ~FullInterface()
Destructor.
Definition full_interface.cpp:239
void showAboutSection() override
Shows the "About" section overlay.
Definition full_interface.cpp:626
void dualPopupSelector(Component *source, Point< int > position, int width, const PopupItems &options, std::function< void(int)> callback)
Opens a dual popup selector for choosing from a hierarchical list of items.
Definition full_interface.cpp:898
virtual void resized() override
Adjusts layout and sizes of child components after the interface is resized.
Definition full_interface.cpp:375
void noDownloadNeeded() override
Indicates that no download is needed after checking updates.
Definition full_interface.cpp:287
void repaintChildBackground(SynthSection *child)
Repaints the background of a child section.
Definition full_interface.cpp:303
void notifyFresh()
Notifies that the interface is in a fresh state (no unsaved changes).
Definition full_interface.cpp:728
void resynthesizeToWavetable(int index)
Performs resynthesis of the current wavetable for the given oscillator.
Definition full_interface.cpp:830
void toggleFilter2Zoom()
Definition full_interface.cpp:950
void loadDefaultWavetable(int index)
Loads a default wavetable into the given oscillator editor.
Definition full_interface.cpp:825
void reloadSkin(const Skin &skin)
Reloads and applies a new skin, then adjusts layout accordingly.
Definition full_interface.cpp:276
void clearTemporaryTab(int current_tab) override
Clears temporary overlay tabs such as the preset browser.
Definition full_interface.cpp:653
void redoBackground()
Redraws the entire background image for the interface.
Definition full_interface.cpp:349
void saveWavetable(int index)
Opens a save dialog to save the current wavetable of an oscillator.
Definition full_interface.cpp:835
json getWavetableJson(int index)
Retrieves the JSON data representing the current wavetable for an oscillator.
Definition full_interface.cpp:857
void showWavetableEditSection(int index)
Shows the wavetable edit section for a given oscillator index.
Definition full_interface.cpp:763
void signIn()
Opens the sign-in interface, if available.
Definition full_interface.cpp:804
void loadWavetableFile(int index, const File &wavetable)
Loads a wavetable from a file into the given oscillator editor.
Definition full_interface.cpp:815
void setOscilloscopeMemory(const vital::poly_float *memory)
Assigns memory for oscilloscope visualization.
Definition full_interface.cpp:504
void startDownload()
Starts a download of additional content if needed.
Definition full_interface.cpp:573
void setAllValues(vital::control_map &controls) override
Sets all parameter values on the interface.
Definition full_interface.cpp:559
void deleteRequested(File preset) override
Handles a request to delete a preset file.
Definition full_interface.cpp:631
static constexpr double kMinOpenGlVersion
Minimum required OpenGL version for the interface to function properly.
Definition full_interface.h:66
void externalPresetLoaded(const File &preset)
Handles loading an external preset file into the interface.
Definition full_interface.cpp:733
void setPresetBrowserVisibility(bool visible, int current_tab) override
Toggles the visibility of the preset browser.
Definition full_interface.cpp:663
void dataDirectoryChanged() override
Called when the data directory changes.
Definition full_interface.cpp:283
void signOut()
Signs out the current user, if signed in.
Definition full_interface.cpp:799
void setBankExporterVisibility(bool visible, int current_tab) override
Toggles the visibility of the bank exporter.
Definition full_interface.cpp:684
void popupBrowser(SynthSection *owner, Rectangle< int > bounds, std::vector< File > directories, String extensions, std::string passthrough_name, std::string additional_folders_name)
Opens a popup browser for file browsing.
Definition full_interface.cpp:872
void popupDisplay(Component *source, const std::string &text, BubbleComponent::BubblePlacement placement, bool primary)
Shows a popup display (a tooltip-like bubble) with provided text.
Definition full_interface.cpp:907
void modulationsScrolled() override
Called when modulations are scrolled, to update meter positions.
Definition full_interface.cpp:712
void bankImported() override
Called when a new bank of presets has been imported, to refresh lists.
Definition full_interface.cpp:704
void checkShouldReposition(bool resize=true)
Checks if the interface should be repositioned or resized based on scaling or display changes.
Definition full_interface.cpp:365
void setFocus()
Sets keyboard focus to a relevant component (e.g., authentication).
Definition full_interface.cpp:716
std::string getLastBrowsedWavetable(int index)
Gets the last browsed wavetable file path for a given oscillator.
Definition full_interface.cpp:784
void loggedIn() override
Called when the user has successfully logged in.
Definition full_interface.cpp:296
virtual void paintBackground(Graphics &g) override
Paints the background of the entire interface.
Definition full_interface.cpp:246
void popupSelector(Component *source, Point< int > position, const PopupItems &options, std::function< void(int)> callback, std::function< void()> cancel)
Opens a popup selector for choosing from a list of items.
Definition full_interface.cpp:888
void openGLContextClosing() override
Called when the OpenGL context is closing, allowing cleanup of resources.
Definition full_interface.cpp:616
void needsUpdate() override
Indicates that a software update is available and needs action.
Definition full_interface.cpp:291
void modulationChanged()
Called when modulations have changed, updating the modulation matrix and related components.
Definition full_interface.cpp:920
void popupBrowserUpdate(SynthSection *owner)
Updates the popup browser's ownership, useful if the owner changed.
Definition full_interface.cpp:883
FullInterface()
Constructs a minimal, empty full interface.
Definition full_interface.cpp:224
void loadWavetable(int index, json &wavetable_data)
Loads a wavetable from a JSON object into the given oscillator editor.
Definition full_interface.cpp:820
static bool shouldWorkOffline()
Checks if Vital should operate in offline mode.
Definition load_save.cpp:1563
static File getUserWavetableDirectory()
Retrieves the user's wavetable directory.
Definition load_save.cpp:1798
static bool authenticated()
Checks if the user is authenticated.
Definition load_save.cpp:1599
static bool isExpired()
Checks if this build of Vital has expired.
Definition load_save.cpp:1529
static File getUserLfoDirectory()
Retrieves the user's LFO directory.
Definition load_save.cpp:1819
void unlock()
Unlocks the mutex previously locked by lock().
Definition open_gl_background.h:67
void updateBackgroundImage(Image background)
Updates the background image to a new one.
Definition open_gl_background.cpp:135
virtual void destroy(OpenGlWrapper &open_gl)
Cleans up OpenGL resources when the background is no longer needed.
Definition open_gl_background.cpp:52
virtual void init(OpenGlWrapper &open_gl)
Initializes OpenGL buffers and shader resources.
Definition open_gl_background.cpp:15
void lock()
Locks the mutex for thread-safe operations.
Definition open_gl_background.h:62
virtual void render(OpenGlWrapper &open_gl)
Renders the background image.
Definition open_gl_background.cpp:93
A base component class that integrates JUCE's Component with OpenGL rendering.
Definition open_gl_component.h:20
A small popup component that displays text in a styled bubble.
Definition popup_browser.h:21
void setContent(const std::string &text, Rectangle< int > bounds, BubbleComponent::BubblePlacement placement)
Sets the content of the popup display.
Definition popup_browser.cpp:82
Manages the overall color and value theme (or "skin") of the user interface.
Definition skin.h:24
@ kModulationButtonWidth
Definition skin.h:101
@ kPadding
Definition skin.h:81
@ kLargePadding
Definition skin.h:82
@ kBackground
Definition skin.h:128
@ kBody
Definition skin.h:129
void copyValuesToLookAndFeel(LookAndFeel *look_and_feel) const
Copies global skin values into a LookAndFeel instance.
Definition skin.cpp:258
MidiKeyboardState * getKeyboardState()
Retrieves the keyboard state (for processing MIDI note events from a virtual keyboard).
Definition synth_base.h:491
Base class for all synthesizer sections, providing UI layout, painting, and interaction logic.
Definition synth_section.h:193
virtual void renderOpenGlComponents(OpenGlWrapper &open_gl, bool animate)
Renders all OpenGL components in this section and sub-sections.
Definition synth_section.cpp:357
float getPadding()
Definition synth_section.cpp:660
virtual void animate(bool animate)
Triggers animation state change in sub-sections if needed.
Definition synth_section.cpp:822
void addSubSection(SynthSection *section, bool show=true)
Adds a subsection (another SynthSection) as a child.
Definition synth_section.cpp:457
virtual void setSkinValues(const Skin &skin, bool top_level)
Sets skin values (colors, sizes) and applies them to sub-sections.
Definition synth_section.cpp:86
virtual void resized() override
Called when the component is resized. Arranges layout of child components.
Definition synth_section.cpp:35
std::map< std::string, ModulationButton * > getAllModulationButtons()
Gets all modulation buttons registered in this section.
Definition synth_section.h:669
void paintChildBackground(Graphics &g, SynthSection *child)
Paints a child's background specifically.
Definition synth_section.cpp:292
void paintChildrenBackgrounds(Graphics &g)
Paints the backgrounds for all child sections.
Definition synth_section.cpp:274
virtual void paintChildrenShadows(Graphics &g)
Paints shadows for child sections.
Definition synth_section.cpp:260
void paintKnobShadows(Graphics &g)
Paints knob shadows for all sliders.
Definition synth_section.cpp:253
virtual void destroyOpenGlComponents(OpenGlWrapper &open_gl)
Destroys all OpenGL components in this section and sub-sections.
Definition synth_section.cpp:383
virtual void setSizeRatio(float ratio)
Sets the size ratio for scaling UI elements.
Definition synth_section.cpp:246
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
float getKnobSectionHeight()
Definition synth_section.cpp:633
void paintChildShadow(Graphics &g, SynthSection *child)
Paints a child's shadow specifically.
Definition synth_section.cpp:301
std::map< std::string, SynthSlider * > getAllSliders()
Gets all sliders registered in this section.
Definition synth_section.h:657
virtual void setAllValues(vital::control_map &controls)
Sets values for all known parameters from a control map.
Definition synth_section.cpp:827
virtual void reset()
Resets the section and all sub-sections.
Definition synth_section.cpp:30
virtual void initOpenGlComponents(OpenGlWrapper &open_gl)
Initializes all OpenGL components in this section and sub-sections.
Definition synth_section.cpp:349
float getDisplayScale() const
Definition synth_section.cpp:719
void paintOpenGlBackground(Graphics &g, OpenGlComponent *child)
Paints the background of an OpenGlComponent child.
Definition synth_section.cpp:310
AudioFileLoadStyle
Defines how audio files are interpreted when loading into a wavetable.
Definition wavetable_creator.h:33
A specialized MemoryTemplate for two-channel (stereo) audio.
Definition memory.h:216
Declares the DeleteSection class, which provides a confirmation overlay for deleting a preset file.
Declares the DownloadSection class, providing a UI for downloading and installing preset packs.
Declares the EffectsInterface class and related components for managing and displaying multiple effec...
nlohmann::json json
Definition line_generator.h:7
constexpr int kNumOscillators
Number of oscillators available in Vital.
Definition synth_constants.h:16
constexpr int kDefaultWindowHeight
Default height of the Vital window (in pixels).
Definition synth_constants.h:64
constexpr int kMinWindowWidth
Minimum allowable window width.
Definition synth_constants.h:67
constexpr int kDefaultWindowWidth
Default width of the Vital window (in pixels).
Definition synth_constants.h:61
std::map< std::string, Output * > output_map
Maps parameter names to Output pointers, representing output signals from various modules.
Definition synth_types.h:229
const std::string kWavetableExtension
File extension for Vital wavetable files.
Definition synth_constants.h:88
constexpr int kMinWindowHeight
Minimum allowable window height.
Definition synth_constants.h:70
std::map< std::string, Value * > control_map
Maps parameter names to Value pointers representing synth control parameters.
Definition synth_types.h:214
const std::string kLfoExtension
File extension for Vital LFO shape files.
Definition synth_constants.h:100
OpenGLContext & context
The OpenGLContext for current rendering.
Definition shaders.h:181
float display_scale
Display scaling factor for high-DPI rendering.
Definition shaders.h:183
Shaders * shaders
Pointer to the Shaders instance providing compiled shaders.
Definition shaders.h:182
A hierarchical structure of popup menu items for a selector component.
Definition synth_section.h:29
A struct holding references and data used by the GUI to interact with the SynthBase.
Definition synth_gui_interface.h:27
vital::output_map poly_modulations
Polyphonic modulation values.
Definition synth_gui_interface.h:37
vital::control_map controls
Current set of parameter controls from the synth.
Definition synth_gui_interface.h:35
vital::output_map modulation_sources
All available modulation sources.
Definition synth_gui_interface.h:38
vital::output_map mono_modulations
Mono (global) modulation values.
Definition synth_gui_interface.h:36
SynthBase * synth
Pointer back to the associated SynthBase.
Definition synth_gui_interface.h:40
WavetableCreator * wavetable_creators[vital::kNumOscillators]
Array of pointers to wavetable creators for each oscillator.
Definition synth_gui_interface.h:39
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600