Vital
Loading...
Searching...
No Matches
lfo_section.cpp
Go to the documentation of this file.
1#include "lfo_section.h"
2
3#include "load_save.h"
4#include "skin.h"
5#include "paths.h"
6#include "lfo_editor.h"
7#include "modulation_button.h"
8#include "synth_strings.h"
9#include "tempo_selector.h"
10#include "text_selector.h"
11#include "text_look_and_feel.h"
12
13
21LfoSection::LfoSection(String name, std::string value_prepend, LineGenerator* lfo_source,
22 const vital::output_map& mono_modulations, const vital::output_map& poly_modulations) :
23 SynthSection(std::move(name)), current_preset_(0) {
24 static constexpr double kTempoDragSensitivity = 0.5;
25 static constexpr int kDefaultGridSizeX = 8;
26 static constexpr int kDefaultGridSizeY = 1;
27
28 smooth_mode_control_name_ = value_prepend + "_smooth_mode";
29
30 frequency_ = std::make_unique<SynthSlider>(value_prepend + "_frequency");
31 addSlider(frequency_.get());
32 frequency_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
33 frequency_->setLookAndFeel(TextLookAndFeel::instance());
34
35 tempo_ = std::make_unique<SynthSlider>(value_prepend + "_tempo");
36 addSlider(tempo_.get());
37 tempo_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
38 tempo_->setLookAndFeel(TextLookAndFeel::instance());
39 tempo_->setSensitivity(kTempoDragSensitivity);
40 tempo_->setTextEntrySizePercent(1.0f, 0.7f);
41
42 keytrack_transpose_ = std::make_unique<SynthSlider>(value_prepend + "_keytrack_transpose");
43 addSlider(keytrack_transpose_.get());
44 keytrack_transpose_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
45 keytrack_transpose_->setLookAndFeel(TextLookAndFeel::instance());
46 keytrack_transpose_->setSensitivity(kTransposeMouseSensitivity);
47 keytrack_transpose_->setBipolar();
48 keytrack_transpose_->setShiftIndexAmount(vital::kNotesPerOctave);
49
50 keytrack_tune_ = std::make_unique<SynthSlider>(value_prepend + "_keytrack_tune");
51 addSlider(keytrack_tune_.get());
52 keytrack_tune_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
53 keytrack_tune_->setLookAndFeel(TextLookAndFeel::instance());
54 keytrack_tune_->setBipolar();
55 keytrack_tune_->setMaxDisplayCharacters(3);
56 keytrack_tune_->setMaxDecimalPlaces(0);
57
58 sync_ = std::make_unique<TempoSelector>(value_prepend + "_sync");
59 addSlider(sync_.get());
60 sync_->setSliderStyle(Slider::LinearBar);
61 sync_->setTempoSlider(tempo_.get());
62 sync_->setKeytrackTransposeSlider(keytrack_transpose_.get());
63 sync_->setKeytrackTuneSlider(keytrack_tune_.get());
64 sync_->setFreeSlider(frequency_.get());
65
66 sync_type_ = std::make_unique<TextSelector>(value_prepend + "_sync_type");
67 addSlider(sync_type_.get());
68 sync_type_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
69 sync_type_->setLookAndFeel(TextLookAndFeel::instance());
70 sync_type_->setLongStringLookup(strings::kSyncNames);
71
72 paint_pattern_ = std::make_unique<PaintPatternSelector>("paint_pattern");
73 addSlider(paint_pattern_.get());
74 paint_pattern_->setRange(0.0f, kNumPaintPatterns - 1.0f, 1.0f);
75 paint_pattern_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
76 paint_pattern_->setStringLookup(strings::kPaintPatternNames);
77 paint_pattern_->setLookAndFeel(TextLookAndFeel::instance());
78 paint_pattern_->setLongStringLookup(strings::kPaintPatternNames);
79 paint_pattern_->setTextHeightPercentage(0.45f);
80 paint_pattern_->setActive(false);
81 paint_pattern_->overrideValue(Skin::kTextComponentOffset, 0.0f);
82
83 transpose_tune_divider_ = std::make_unique<OpenGlQuad>(Shaders::kColorFragment);
84 addOpenGlComponent(transpose_tune_divider_.get());
85 transpose_tune_divider_->setInterceptsMouseClicks(false, false);
86
87 phase_ = std::make_unique<SynthSlider>(value_prepend + "_phase");
88 addSlider(phase_.get());
89 phase_->setSliderStyle(Slider::LinearBar);
90 phase_->setModulationPlacement(BubbleComponent::above);
91
92 fade_ = std::make_unique<SynthSlider>(value_prepend + "_fade_time");
93 addSlider(fade_.get());
94 fade_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
95 fade_->setPopupPlacement(BubbleComponent::below);
96 fade_->setVisible(false);
97
98 smooth_ = std::make_unique<SynthSlider>(value_prepend + "_smooth_time");
99 addSlider(smooth_.get());
100 smooth_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
101 smooth_->setPopupPlacement(BubbleComponent::below);
102
103 smooth_mode_text_ = std::make_unique<PlainTextComponent>("Smooth Mode Text", "---");
104 addOpenGlComponent(smooth_mode_text_.get());
105 smooth_mode_text_->setText(strings::kSmoothModeNames[0]);
106
107 smooth_mode_type_selector_ = std::make_unique<ShapeButton>("Smooth Mode", Colours::black,
108 Colours::black, Colours::black);
109 addAndMakeVisible(smooth_mode_type_selector_.get());
110 smooth_mode_type_selector_->addListener(this);
111 smooth_mode_type_selector_->setTriggeredOnMouseDown(true);
112
113 delay_ = std::make_unique<SynthSlider>(value_prepend + "_delay_time");
114 addSlider(delay_.get());
115 delay_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
116 delay_->setPopupPlacement(BubbleComponent::below);
117
118 stereo_ = std::make_unique<SynthSlider>(value_prepend + "_stereo");
119 addSlider(stereo_.get());
120 stereo_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
121 stereo_->setPopupPlacement(BubbleComponent::below);
122 stereo_->setBipolar(true);
123 stereo_->snapToValue(true, 0.0);
124
125 grid_size_x_ = std::make_unique<SynthSlider>("grid_size_x");
126 grid_size_x_->setRange(1.0, LfoEditor::kMaxGridSizeX, 1.0);
127 grid_size_x_->setValue(kDefaultGridSizeX);
128 grid_size_x_->setLookAndFeel(TextLookAndFeel::instance());
129 grid_size_x_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
130 addSlider(grid_size_x_.get());
131 grid_size_x_->setDoubleClickReturnValue(true, kDefaultGridSizeX);
132 grid_size_x_->setMaxDecimalPlaces(0);
133 grid_size_x_->setSensitivity(0.2f);
134 grid_size_x_->overrideValue(Skin::kTextComponentOffset, 0.0f);
135 grid_size_x_->setTextHeightPercentage(0.6f);
136 grid_size_x_->setPopupPrefix("X Grid");
137
138 grid_size_y_ = std::make_unique<SynthSlider>("grid_size_y");
139 grid_size_y_->setRange(1.0, LfoEditor::kMaxGridSizeY, 1.0);
140 grid_size_y_->setValue(kDefaultGridSizeY);
141 grid_size_y_->setLookAndFeel(TextLookAndFeel::instance());
142 grid_size_y_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
143 addSlider(grid_size_y_.get());
144 grid_size_y_->setDoubleClickReturnValue(true, kDefaultGridSizeY);
145 grid_size_y_->setMaxDecimalPlaces(0);
146 grid_size_y_->setSensitivity(0.2f);
147 grid_size_y_->overrideValue(Skin::kTextComponentOffset, 0.0f);
148 grid_size_y_->setTextHeightPercentage(0.6f);
149 grid_size_y_->setPopupPrefix("Y Grid");
150
151 paint_ = std::make_unique<OpenGlShapeButton>("paint");
152 paint_->useOnColors(true);
153 paint_->setClickingTogglesState(true);
154 addAndMakeVisible(paint_.get());
155 addOpenGlComponent(paint_->getGlComponent());
156 paint_->addListener(this);
157 paint_->setShape(Paths::paintBrush());
158
159 lfo_smooth_ = std::make_unique<OpenGlShapeButton>("smooth");
160 lfo_smooth_->useOnColors(true);
161 lfo_smooth_->setClickingTogglesState(true);
162 addAndMakeVisible(lfo_smooth_.get());
163 addOpenGlComponent(lfo_smooth_->getGlComponent());
164 lfo_smooth_->addListener(this);
165 lfo_smooth_->setShape(Paths::halfSinCurve());
166
167 editor_ = std::make_unique<LfoEditor>(lfo_source, value_prepend, mono_modulations, poly_modulations);
168 editor_->addListener(this);
169 editor_->setGridSizeX(kDefaultGridSizeX);
170 editor_->setGridSizeY(kDefaultGridSizeY);
171 addOpenGlComponent(editor_.get());
172 addOpenGlComponent(editor_->getTextEditorComponent());
173 lfo_smooth_->setToggleState(editor_->getModel()->smooth(), dontSendNotification);
174
175 paint_pattern_->setValue(kDown);
176
177 preset_selector_ = std::make_unique<PresetSelector>();
178 addSubSection(preset_selector_.get());
179 preset_selector_->addListener(this);
180 setPresetSelector(preset_selector_.get());
181 preset_selector_->setText(editor_->getModel()->getName());
182
184}
185
189LfoSection::~LfoSection() = default;
190
200 if (getWidth() <= 0)
201 return;
202
203 float tempo_width = sync_->getRight() - tempo_->getX();
204
205 drawTextComponentBackground(g, sync_type_->getBounds(), true);
206 Rectangle<int> frequency_bounds(tempo_->getX(), tempo_->getY(), tempo_width, tempo_->getHeight());
207 drawTextComponentBackground(g, frequency_bounds, true);
208 drawTempoDivider(g, sync_.get());
209
210 setLabelFont(g);
211 drawLabel(g, TRANS("MODE"), sync_type_->getBounds(), true);
212 drawLabel(g, TRANS("FREQUENCY"), frequency_bounds, true);
213
214 drawLabelForComponent(g, "DELAY", delay_.get());
215 drawLabelForComponent(g, "STEREO", stereo_.get());
216 drawLabelForComponent(g, TRANS(""), fade_.get());
217 int title_width = getTitleWidth();
218
219 int widget_margin = getWidgetMargin();
220 int rounding = getWidgetRounding();
221 int grid_label_x = grid_size_x_->getX();
222 int grid_size_width = grid_size_y_->getRight() - grid_label_x;
223 g.setColour(findColour(Skin::kPopupSelectorBackground, true));
224 int background_height = title_width - 2 * widget_margin;
225 g.fillRoundedRectangle(grid_label_x, widget_margin, grid_size_width, background_height, rounding);
226 g.fillRoundedRectangle(widget_margin, widget_margin, grid_label_x - 2 * widget_margin, background_height, rounding);
227
228 Colour body_text = findColour(Skin::kBodyText, true);
229 g.setColour(body_text);
230 g.drawText("-", grid_label_x, widget_margin, grid_size_width, title_width - 2 * widget_margin,
231 Justification::centred, false);
232
233 transpose_tune_divider_->setColor(findColour(Skin::kLightenScreen, true));
234 smooth_mode_text_->setColor(body_text);
237}
238
246 int title_width = getTitleWidth();
247 int knob_section_height = getKnobSectionHeight();
248 int slider_width = getSliderWidth();
249
250 int slider_overlap = getSliderOverlap();
251
252 int widget_margin = findValue(Skin::kWidgetMargin);
253 int wave_height = getHeight() - slider_width - widget_margin -
254 title_width - knob_section_height + 2 * slider_overlap;
255 int wave_width = getWidth() - 2 * widget_margin;
256 editor_->setBounds(widget_margin, title_width, wave_width, wave_height);
257 phase_->setBounds(0, editor_->getBottom() - slider_overlap + widget_margin, getWidth(), slider_width);
258
259 int knobs_width = 4 * (int)findValue(Skin::kModulationButtonWidth) + widget_margin + findValue(Skin::kPadding);
260 int style_width = getWidth() - knobs_width;
261
262 int knob_y = getHeight() - knob_section_height;
263 int text_component_width = style_width / 2 - widget_margin;
264 sync_type_->setBounds(widget_margin, knob_y + widget_margin,
265 text_component_width, knob_section_height - 2 * widget_margin);
266 int tempo_x = sync_type_->getRight() + widget_margin;
267 placeTempoControls(tempo_x, knob_y + widget_margin, style_width - tempo_x, knob_section_height - 2 * widget_margin,
268 frequency_.get(), sync_.get());
269 tempo_->setBounds(frequency_->getBounds());
270 Rectangle<int> divider_bounds = frequency_->getModulationArea() + frequency_->getBounds().getTopLeft();
271 divider_bounds = divider_bounds.reduced(divider_bounds.getHeight() / 4);
272 divider_bounds.setX(divider_bounds.getCentreX());
273 divider_bounds.setWidth(1);
274 transpose_tune_divider_->setBounds(divider_bounds);
275 tempo_->setModulationArea(frequency_->getModulationArea());
276
277 Rectangle<int> frequency_bounds = frequency_->getBounds();
278 keytrack_transpose_->setBounds(frequency_bounds.withWidth(frequency_bounds.getWidth() / 2));
279 keytrack_tune_->setBounds(frequency_bounds.withLeft(keytrack_transpose_->getRight()));
280 keytrack_transpose_->setModulationArea(frequency_->getModulationArea().withWidth(keytrack_transpose_->getWidth()));
281 keytrack_tune_->setModulationArea(frequency_->getModulationArea().withWidth(keytrack_tune_->getWidth()));
282
283 placeKnobsInArea(Rectangle<int>(style_width, knob_y, knobs_width, knob_section_height),
284 { fade_.get(), delay_.get(), stereo_.get() });
285 smooth_->setBounds(fade_->getBounds());
286
287 Rectangle<int> smooth_label_bounds = getLabelBackgroundBounds(fade_->getBounds());
288 smooth_mode_text_->setBounds(smooth_label_bounds);
289 smooth_mode_text_->setTextSize(findValue(Skin::kLabelHeight));
290 smooth_mode_type_selector_->setBounds(smooth_label_bounds);
291
292 Rectangle<int> browser_bounds = getPresetBrowserBounds();
293 int top_height = title_width - 2 * widget_margin;
294
295 lfo_smooth_->setBounds(browser_bounds.getX() - title_width - widget_margin, widget_margin, title_width, top_height);
296 grid_size_y_->setBounds(lfo_smooth_->getX() - title_width - widget_margin, widget_margin, title_width, top_height);
297 grid_size_x_->setBounds(grid_size_y_->getX() - title_width - widget_margin, widget_margin, title_width, top_height);
298
299 paint_->setBounds(widget_margin, widget_margin, top_height, top_height);
300 int pattern_width = grid_size_x_->getX() - paint_->getRight() - widget_margin;
301 paint_pattern_->setPadding(getWidgetMargin());
302 paint_pattern_->setBounds(paint_->getRight(), widget_margin, pattern_width, top_height);
303
305 editor_->setSizeRatio(getSizeRatio());
306}
307
313 preset_selector_->setText(editor_->getModel()->getName());
314 editor_->resetPositions();
315}
316
324 lfo_smooth_->setToggleState(editor_->getSmooth(), dontSendNotification);
325 transpose_tune_divider_->setVisible(sync_->isKeytrack());
326
327 int smooth_mode = controls[smooth_mode_control_name_]->value();
328 smooth_mode_text_->setText(strings::kSmoothModeNames[smooth_mode]);
329 smooth_->setVisible(smooth_mode);
330 fade_->setVisible(smooth_mode == 0);
331}
332
341void LfoSection::sliderValueChanged(Slider* changed_slider) {
342 if (changed_slider == grid_size_x_.get())
343 editor_->setGridSizeX(grid_size_x_->getValue());
344 else if (changed_slider == grid_size_y_.get())
345 editor_->setGridSizeY(grid_size_y_->getValue());
346 else if (changed_slider == paint_pattern_.get())
347 editor_->setPaintPattern(getPaintPattern(paint_pattern_->getValue()));
348 else
349 SynthSection::sliderValueChanged(changed_slider);
350
351 transpose_tune_divider_->setVisible(sync_->isKeytrack());
352}
353
362void LfoSection::buttonClicked(Button* clicked_button) {
363 if (clicked_button == paint_.get()) {
364 editor_->setPaint(paint_->getToggleState());
365 paint_pattern_->setActive(paint_->getToggleState());
366 }
367 else if (clicked_button == lfo_smooth_.get())
368 editor_->setSmooth(lfo_smooth_->getToggleState());
369 else if (clicked_button == smooth_mode_type_selector_.get()) {
370 PopupItems options;
371
372 for (int i = 0; i < 2; ++i)
373 options.addItem(i, strings::kSmoothModeNames[i]);
374
375 showPopupSelector(this, Point<int>(clicked_button->getX(), clicked_button->getBottom()), options,
376 [=](int selection) { setSmoothModeSelected(selection); });
377 }
378 else
379 SynthSection::buttonClicked(clicked_button);
380}
381
390void LfoSection::lineEditorScrolled(const MouseEvent& e, const MouseWheelDetails& wheel) {
391 if (paint_->getToggleState())
392 paint_pattern_->mouseWheelMove(e, wheel);
393 else
394 grid_size_x_->mouseWheelMove(e, wheel);
395}
396
403void LfoSection::togglePaintMode(bool enabled, bool temporary_switch) {
404 paint_->setToggleState(enabled != temporary_switch, dontSendNotification);
405 paint_pattern_->setActive(enabled != temporary_switch);
406}
407
412 FileChooser import_box("Import LFO", LoadSave::getUserLfoDirectory(), String("*.") + vital::kLfoExtension);
413 if (!import_box.browseForFileToOpen())
414 return;
415
416 File choice = import_box.getResult();
417 loadFile(choice.withFileExtension(vital::kLfoExtension));
418}
419
424 FileChooser export_box("Export LFO", LoadSave::getUserLfoDirectory(), String("*.") + vital::kLfoExtension);
425 if (!export_box.browseForFileToSave(true))
426 return;
427
428 File choice = export_box.getResult();
429 choice = choice.withFileExtension(vital::kLfoExtension);
430 if (!choice.exists())
431 choice.create();
432 choice.replaceWithText(editor_->getModel()->stateToJson().dump());
433
434 String name = choice.getFileNameWithoutExtension();
435 editor_->getModel()->setName(name.toStdString());
436 preset_selector_->setText(name);
437}
438
445 lfo_smooth_->setToggleState(editor_->getModel()->smooth(), dontSendNotification);
446}
447
453 "", getCurrentFile(), -1);
454 if (lfo_file.exists())
455 loadFile(lfo_file);
456
457 updatePopupBrowser(this);
458}
459
465 "", getCurrentFile(), 1);
466 if (lfo_file.exists())
467 loadFile(lfo_file);
468
469 updatePopupBrowser(this);
470}
471
479void LfoSection::textMouseDown(const MouseEvent& e) {
480 static constexpr int kBrowserWidth = 500;
481 static constexpr int kBrowserHeight = 250;
482
483 int browser_width = kBrowserWidth * size_ratio_;
484 int browser_height = kBrowserHeight * size_ratio_;
485 Rectangle<int> bounds(preset_selector_->getRight() - browser_width, -browser_height,
486 browser_width, browser_height);
487 bounds = getLocalArea(this, bounds);
490}
491
500 smooth_mode_text_->setText(strings::kSmoothModeNames[result]);
501 smooth_->setVisible(result);
502 fade_->setVisible(result == 0);
503
504 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
505 if (parent)
506 parent->getSynth()->valueChangedInternal(smooth_mode_control_name_, result);
507}
508
516void LfoSection::loadFile(const File& file) {
517 if (!file.exists())
518 return;
519
520 current_file_ = file;
521 try {
522 json parsed_file = json::parse(file.loadFileAsString().toStdString(), nullptr, false);
523 editor_->getModel()->jsonToState(parsed_file);
524 }
525 catch (const json::exception& e) {
526 return;
527 }
528
529 String name = file.getFileNameWithoutExtension();
530 editor_->getModel()->setName(name.toStdString());
531 editor_->getModel()->setLastBrowsedFile(file.getFullPathName().toStdString());
532 preset_selector_->setText(name);
533
534 editor_->resetPositions();
535 lfo_smooth_->setToggleState(editor_->getModel()->smooth(), dontSendNotification);
536}
static std::vector< std::pair< float, float > > getPaintPattern(int pattern)
Retrieves a paint pattern as a vector of (x, y) pairs.
Definition lfo_section.h:54
void textMouseDown(const MouseEvent &e) override
Handles mouse-down events on the text component, usually to open a file browser.
Definition lfo_section.cpp:479
void prevClicked() override
Loads the previous LFO preset.
Definition lfo_section.cpp:451
void nextClicked() override
Loads the next LFO preset.
Definition lfo_section.cpp:463
void loadFile(const File &file) override
Loads the LFO configuration from the specified file.
Definition lfo_section.cpp:516
File getCurrentFile() override
Retrieves the current LFO file.
Definition lfo_section.h:199
void lineEditorScrolled(const MouseEvent &e, const MouseWheelDetails &wheel) override
Responds to scrolling events in the line editor component.
Definition lfo_section.cpp:390
~LfoSection()
Destructor.
void reset() override
Resets all LFO settings to their default states.
Definition lfo_section.cpp:311
void importLfo() override
Imports an LFO from a user-selected file.
Definition lfo_section.cpp:411
void resized() override
Called when the component is resized.
Definition lfo_section.cpp:245
void setAllValues(vital::control_map &controls) override
Updates all control values in this section from the given map of controls.
Definition lfo_section.cpp:322
void exportLfo() override
Exports the current LFO configuration to a user-selected file.
Definition lfo_section.cpp:423
LfoSection(String name, std::string value_prepend, LineGenerator *lfo_source, const vital::output_map &mono_modulations, const vital::output_map &poly_modulations)
Constructs a new LfoSection.
Definition lfo_section.cpp:21
@ kDown
A downward linear ramp.
Definition lfo_section.h:42
@ kNumPaintPatterns
The number of available paint patterns.
Definition lfo_section.h:45
void buttonClicked(Button *clicked_button) override
Responds to a button click event.
Definition lfo_section.cpp:362
void setSmoothModeSelected(int result)
Sets the selected smooth mode.
Definition lfo_section.cpp:499
void fileLoaded() override
Called when an LFO file has been successfully loaded.
Definition lfo_section.cpp:444
void togglePaintMode(bool enabled, bool temporary_switch) override
Toggles paint mode for the LFO editor.
Definition lfo_section.cpp:403
void sliderValueChanged(Slider *changed_slider) override
Responds to a slider value change event.
Definition lfo_section.cpp:341
void paintBackground(Graphics &g) override
Paints the background of the LFO section.
Definition lfo_section.cpp:199
static constexpr int kMaxGridSizeY
Definition line_editor.h:51
static constexpr int kMaxGridSizeX
Maximum grid sizes for horizontal and vertical lines.
Definition line_editor.h:50
A class for generating and storing a line shape, defined by a series of points and associated powers.
Definition line_generator.h:20
static std::vector< File > getLfoDirectories()
Gets directories that should contain LFO shapes.
Definition load_save.cpp:1780
static File getShiftedFile(const String directory_name, const String &extensions, const std::string &additional_folders_name, const File &current_file, int shift)
Given a directory name and extensions, returns a file shifted by some offset from the current file.
Definition load_save.cpp:1921
static const std::string kLfoFolderName
Definition load_save.h:78
static File getUserLfoDirectory()
Retrieves the user's LFO directory.
Definition load_save.cpp:1819
static Path halfSinCurve()
Definition paths.h:751
static Path paintBrush()
Definition paths.h:804
@ kColorFragment
Definition shaders.h:63
@ kWidgetMargin
Definition skin.h:103
@ kLabelHeight
Definition skin.h:72
@ kTextComponentOffset
Definition skin.h:85
@ kModulationButtonWidth
Definition skin.h:101
@ kPadding
Definition skin.h:81
@ kBodyText
Definition skin.h:133
@ kLightenScreen
Definition skin.h:141
@ kPopupSelectorBackground
Definition skin.h:143
@ kLfo
Definition skin.h:40
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
An interface class linking the Vital synthesizer backend (SynthBase) with a GUI.
Definition synth_gui_interface.h:56
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
float getSliderWidth()
Definition synth_section.cpp:637
void placeKnobsInArea(Rectangle< int > area, std::vector< Component * > knobs)
Definition synth_section.cpp:601
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 drawLabel(Graphics &g, String text, Rectangle< int > component_bounds, bool text_component=false)
Draws a label text below a component.
Definition synth_section.cpp:789
void drawTempoDivider(Graphics &g, Component *sync)
Draws a divider line for tempo-related controls.
Definition synth_section.cpp:339
virtual void resized() override
Called when the component is resized. Arranges layout of child components.
Definition synth_section.cpp:35
void placeTempoControls(int x, int y, int width, int height, SynthSlider *tempo, SynthSlider *sync)
Definition synth_section.cpp:584
float getWidgetRounding()
Definition synth_section.cpp:680
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 updatePopupBrowser(SynthSection *owner)
Updates the currently visible popup browser if any.
Definition synth_section.cpp:113
void paintKnobShadows(Graphics &g)
Paints knob shadows for all sliders.
Definition synth_section.cpp:253
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
float getSliderOverlap()
Definition synth_section.cpp:641
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
float size_ratio_
Definition synth_section.h:821
Rectangle< int > getLabelBackgroundBounds(Rectangle< int > bounds, bool text_component=false)
Gets the background bounds for a label.
Definition synth_section.cpp:782
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 addOpenGlComponent(OpenGlComponent *open_gl_component, bool to_beginning=false)
Definition synth_section.cpp:489
float getSizeRatio() const
Definition synth_section.h:765
virtual void sliderValueChanged(Slider *moved_slider) override
Called when a slider value changes. Updates the synth parameter accordingly.
Definition synth_section.cpp:391
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
void setPresetSelector(PresetSelector *preset_selector, bool half=false)
Definition synth_section.h:779
float getTitleWidth()
Definition synth_section.cpp:629
void setSkinOverride(Skin::SectionOverride skin_override)
Definition synth_section.h:303
Rectangle< int > getPresetBrowserBounds()
Definition synth_section.cpp:684
void showPopupBrowser(SynthSection *owner, Rectangle< int > bounds, std::vector< File > directories, String extensions, std::string passthrough_name, std::string additional_folders_name)
Shows a file browser popup (e.g., for loading samples or wavetables).
Definition synth_section.cpp:105
float getWidgetMargin()
Definition synth_section.cpp:676
static TextLookAndFeel * instance()
Singleton instance access.
Definition text_look_and_feel.h:106
nlohmann::json json
Definition line_generator.h:7
const std::string kPaintPatternNames[]
Names for painting patterns in wavetable or LFO editing.
Definition synth_strings.h:327
const std::string kSyncNames[]
Full names for different sync/re-triggering modes of modulators.
Definition synth_strings.h:292
const std::string kSmoothModeNames[]
Names for smoothing modes in parameters or LFO shapes.
Definition synth_strings.h:270
std::map< std::string, Output * > output_map
Maps parameter names to Output pointers, representing output signals from various modules.
Definition synth_types.h:229
constexpr int kNotesPerOctave
Number of semitones per octave.
Definition common.h:51
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
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
Declares the TempoSelector class, a specialized slider for selecting tempo-related modes.
Declares the TextSelector class and PaintPatternSelector class for selecting text-based options and d...