16 template<
class Comparator>
17 void sortFileArray(Array<File>& file_array) {
18 Comparator comparator;
19 file_array.sort(comparator,
true);
22 template<
class Comparator>
23 void sortFileArrayWithCache(Array<File>& file_array,
PresetInfoCache* cache) {
24 Comparator comparator(cache);
25 file_array.sort(comparator,
true);
28 const std::string kPresetStoreUrl =
"";
30 class FileNameFilter :
public TextEditor::InputFilter {
32 FileNameFilter() : TextEditor::InputFilter() { }
34 String filterNewText(TextEditor& editor,
const String& new_input)
override {
35 return new_input.removeCharacters(
"<>?*/|\\[]\":");
41 num_view_presets_(0), hover_preset_(-1), click_preset_(-1), cache_position_(0),
42 highlight_(
Shaders::kColorFragment), hover_(
Shaders::kColorFragment),
43 view_position_(0), sort_column_(kName), sort_ascending_(true) {
44 addAndMakeVisible(browse_area_);
45 browse_area_.setInterceptsMouseClicks(
false,
false);
49 scroll_bar_ = std::make_unique<OpenGlScrollBar>();
50 addAndMakeVisible(scroll_bar_.get());
52 scroll_bar_->addListener(
this);
54#if !defined(NO_TEXT_ENTRY)
55 rename_editor_ = std::make_unique<OpenGlTextEditor>(
"Search");
56 rename_editor_->addListener(
this);
57 rename_editor_->setSelectAllWhenFocused(
true);
58 rename_editor_->setMultiLine(
false,
false);
59 rename_editor_->setJustification(Justification::centredLeft);
60 rename_editor_->setInputFilter(
new FileNameFilter(),
true);
61 addChildComponent(rename_editor_.get());
82 int text_padding = row_height / 2;
86 g.reduceClipRegion(getLocalBounds().removeFromTop(title_width));
87 Rectangle<float> top = getLocalBounds().toFloat().removeFromTop(title_width * 2.0f);
92 scroll_bar_->setColor(lighten);
94 g.fillRect(star_width, 0, 1, title_width);
95 g.fillRect(star_width + name_width, 0, 1, title_width);
96 g.fillRect(star_width + name_width + style_width, 0, 1, title_width);
97 g.fillRect(getWidth() - date_width, 0, 1, title_width);
100 g.setFont(
Fonts::instance()->proportional_regular().withPointHeight(title_width * 0.5f));
103 float star_draw_width = title_width * 0.8f;
104 float star_y = (title_width - star_draw_width) / 2.0f;
105 Rectangle<float> star_bounds((star_width - star_draw_width) / 2.0f, star_y, star_draw_width, star_draw_width);
106 g.fillPath(star, star.getTransformToScaleToFit(star_bounds,
true));
108 g.drawText(
"Name", text_padding + star_width, 0, name_width, title_width, Justification::centredLeft);
109 int style_x = star_width + name_width + text_padding;
110 g.drawText(
"Style", style_x, 0, style_width, title_width, Justification::centredLeft);
111 int author_x = star_width + name_width + text_padding + style_width;
112 g.drawText(
"Author", author_x, 0, author_width, title_width, Justification::centredLeft);
113 g.drawText(
"Date", getWidth() - date_width, 0, date_width - text_padding, title_width, Justification::centredRight);
116 setWantsKeyboardFocus(
true);
117 setMouseClickGrabsKeyboardFocus(
true);
121 static constexpr float kScrollBarWidth = 15.0f;
123 int scroll_bar_width = kScrollBarWidth *
getSizeRatio();
125 int scroll_bar_height = getHeight() - title_width;
126 scroll_bar_->setBounds(getWidth() - scroll_bar_width, title_width, scroll_bar_width, scroll_bar_height);
129 browse_area_.setBounds(0, title_width, getWidth(), getHeight() - title_width);
132void PresetList::sort() {
133 if (sort_column_ ==
kStar && sort_ascending_)
134 sortFileArray<FavoriteAscendingComparator>(presets_);
135 else if (sort_column_ ==
kStar && !sort_ascending_)
136 sortFileArray<FavoriteDescendingComparator>(presets_);
137 else if (sort_column_ ==
kName && sort_ascending_)
138 sortFileArray<FileNameAscendingComparator>(presets_);
139 else if (sort_column_ ==
kName && !sort_ascending_)
140 sortFileArray<FileNameDescendingComparator>(presets_);
141 else if (sort_column_ ==
kAuthor && sort_ascending_)
142 sortFileArrayWithCache<AuthorAscendingComparator>(presets_, &preset_info_cache_);
143 else if (sort_column_ ==
kAuthor && !sort_ascending_)
144 sortFileArrayWithCache<AuthorDescendingComparator>(presets_, &preset_info_cache_);
145 else if (sort_column_ ==
kStyle && sort_ascending_)
146 sortFileArrayWithCache<StyleAscendingComparator>(presets_, &preset_info_cache_);
147 else if (sort_column_ ==
kStyle && !sort_ascending_)
148 sortFileArrayWithCache<StyleDescendingComparator>(presets_, &preset_info_cache_);
149 else if (sort_column_ ==
kDate && sort_ascending_)
150 sortFileArray<FileDateAscendingComparator>(presets_);
151 else if (sort_column_ ==
kDate && !sort_ascending_)
152 sortFileArray<FileDateDescendingComparator>(presets_);
154 filter(filter_string_, filter_styles_);
165 view_position_ = std::max(0.0f, view_position_);
167 float scaled_height = getHeight() - title_width;
169 view_position_ = std::min(view_position_, 1.0f * scrollable_range - scaled_height);
170 viewPositionChanged();
178 return floorf((mouse_position + getViewPosition() - title_width) /
getRowHeight());
183 if (hover_preset_ >= filtered_presets_.size())
192 if (click_preset_ < 0 || click_preset_ >= filtered_presets_.size())
195 File preset = filtered_presets_[click_preset_];
197 preset.revealToUser();
198 else if (result ==
kRename && rename_editor_) {
199 renaming_preset_ = preset;
203 rename_editor_->setColour(TextEditor::textColourId, findColour(
Skin::kBodyText,
true));
204 rename_editor_->setColour(TextEditor::highlightedTextColourId, findColour(
Skin::kBodyText,
true));
206 rename_editor_->setText(renaming_preset_.getFileNameWithoutExtension());
207 rename_editor_->setVisible(
true);
208 rename_editor_->grabKeyboardFocus();
209 rename_editor_->selectAll();
212 for (
Listener* listener : listeners_)
213 listener->deleteRequested(preset);
218 float click_y_position = e.position.y;
221 if (row >= 0 && hover_preset_ >= 0) {
222 click_preset_ = hover_preset_;
226 File preset = filtered_presets_[click_preset_];
227 if (preset.exists() && preset.hasWriteAccess()) {
232 showPopupSelector(
this, e.getPosition(), options, [=](
int selection) { respondToMenuCallback(selection); });
238 float click_y_position = e.position.y;
239 float click_x_position = e.position.x;
243 if (click_y_position <= title_width) {
249 if (click_x_position < star_right)
250 clicked_column =
kStar;
251 else if (click_x_position < name_right)
252 clicked_column =
kName;
253 else if (click_x_position < style_right)
255 else if (click_x_position < author_right)
258 clicked_column =
kDate;
260 if (clicked_column == sort_column_)
261 sort_ascending_ = !sort_ascending_;
263 sort_ascending_ =
true;
264 sort_column_ = clicked_column;
268 else if (row < filtered_presets_.size() && row >= 0) {
269 File preset = filtered_presets_[row];
270 if (click_x_position < star_right) {
271 std::string path = preset.getFullPathName().toStdString();
272 if (favorites_.count(path)) {
273 favorites_.erase(path);
277 favorites_.insert(path);
283 selected_preset_ = preset;
285 for (
Listener* listener : listeners_)
286 listener->newPresetSelected(preset);
292 if (e.mods.isPopupMenu())
299 if (renaming_preset_.exists())
304 if (renaming_preset_.exists())
309 rename_editor_->setVisible(
false);
313 view_position_ = range_start;
314 viewPositionChanged();
318 static constexpr float kScrollStepRatio = 0.05f;
321 float scaled_height = getHeight() - title_width;
323 scroll_bar_->setCurrentRange(getViewPosition(), scaled_height, dontSendNotification);
324 scroll_bar_->setSingleStepSize(scroll_bar_->getHeight() * kScrollStepRatio);
325 scroll_bar_->cancelPendingUpdate();
329 String text = rename_editor_->getText();
330 rename_editor_->setVisible(
false);
331 if (text.trim().isEmpty() || !renaming_preset_.exists())
334 File parent = renaming_preset_.getParentDirectory();
335 File new_file = parent.getChildFile(text + renaming_preset_.getFileExtension());
336 renaming_preset_.moveFileTo(new_file);
337 renaming_preset_ = File();
344 if (current_folder_.exists() && current_folder_.isDirectory())
353 int num_presets =
static_cast<int>(filtered_presets_.size());
354 if (num_presets == 0)
358 selected_preset_ = filtered_presets_[new_index];
359 for (
Listener* listener : listeners_)
360 listener->newPresetSelected(selected_preset_);
364 if (getWidth() <= 0 || getHeight() <= 0)
367 int max =
static_cast<int>(filtered_presets_.size()) -
kNumCachedRows;
368 int position = std::max(0, std::min<int>(cache_position_, max));
373 filter_string_ = filter_string.toLowerCase();
374 filter_styles_ = styles;
376 tokens.addTokens(filter_string_,
" ",
"");
377 filtered_presets_.clear();
379 for (
const File& preset : presets_) {
381 std::string path = preset.getFullPathName().toStdString();
382 if (!styles.empty()) {
383 std::string style = preset_info_cache_.
getStyle(preset);
384 if (styles.count(style) == 0)
387 if (match && tokens.size()) {
388 String name = preset.getFileNameWithoutExtension().toLowerCase();
389 String author = String(preset_info_cache_.
getAuthor(preset)).toLowerCase();
391 for (
const String& token : tokens) {
392 if (!name.contains(token) && !author.contains(token))
397 filtered_presets_.push_back(preset);
399 num_view_presets_ =
static_cast<int>(filtered_presets_.size());
405 for (
int i = 0; i < filtered_presets_.size(); ++i) {
406 if (selected_preset_ == filtered_presets_[i])
415 int presets_height = row_height *
static_cast<int>(filtered_presets_.size());
416 return std::max(presets_height, getHeight() - title_width);
422 rows_[i].
init(open_gl);
426 highlight_.
init(open_gl);
427 hover_.
init(open_gl);
431void PresetList::viewPositionChanged() {
434 int last_cache_position = cache_position_;
435 cache_position_ = getViewPosition() / row_height;
436 int max =
static_cast<int>(filtered_presets_.size() -
kNumCachedRows);
437 cache_position_ = std::max(0, std::min<int>(cache_position_, max));
439 if (std::abs(cache_position_ - last_cache_position) >=
kNumCachedRows)
441 else if (last_cache_position < cache_position_)
443 else if (last_cache_position > cache_position_)
444 loadBrowserCache(cache_position_, last_cache_position);
447void PresetList::loadBrowserCache(
int start_index,
int end_index) {
450 int image_width = getWidth() * mult;
452 int text_padding = row_height / 2.0f;
453 int star_x = text_padding;
455 int name_x = star_x + star_width;
457 int style_x = name_x + name_width;
459 int author_x = style_x + style_width;
462 int date_x = image_width - date_width + text_padding;
464 end_index = std::min(
static_cast<int>(filtered_presets_.size()), end_index);
468 float star_draw_width = row_height * 0.8f;
469 float star_y = (row_height - star_draw_width) / 2.0f;
470 Rectangle<float> star_bounds((star_width - star_draw_width) / 2.0f, star_y, star_draw_width, star_draw_width);
471 star.applyTransform(star.getTransformToScaleToFit(star_bounds,
true));
472 PathStrokeType star_stroke(1.0f, PathStrokeType::curved);
475 Colour star_unselected = text_color.withMultipliedAlpha(0.5f);
478 for (
int i = start_index; i < end_index; ++i) {
479 Image row_image(Image::ARGB, image_width, row_height,
true);
480 Graphics g(row_image);
482 File preset = filtered_presets_[i];
483 String name = preset.getFileNameWithoutExtension();
484 String author = preset_info_cache_.
getAuthor(preset);
485 String style = preset_info_cache_.
getStyle(preset);
486 if (!style.isEmpty())
487 style = style.substring(0, 1).toUpperCase() + style.substring(1);
488 String date = preset.getCreationTime().toString(
true,
false,
false);
490 if (favorites_.count(preset.getFullPathName().toStdString())) {
491 g.setColour(star_selected);
495 g.setColour(star_unselected);
497 g.strokePath(star, star_stroke);
499 g.setColour(text_color);
501 g.drawText(name, name_x, 0, name_width - 2 * text_padding, row_height, Justification::centredLeft,
true);
502 g.drawText(style, style_x, 0, style_width - 2 * text_padding, row_height, Justification::centredLeft,
true);
503 g.drawText(author, author_x, 0, author_width - 2 * text_padding, row_height, Justification::centredLeft,
true);
504 g.drawText(date, date_x, 0, date_width - 2 * text_padding, row_height, Justification::centredRight,
true);
510void PresetList::moveQuadToRow(
OpenGlQuad& quad,
int row,
float y_offset) {
513 float open_gl_row_height = 2.0f * row_height / view_height;
514 float offset = row * open_gl_row_height;
516 float y = 1.0f + y_offset - offset;
517 quad.
setQuad(0, -1.0f, y - open_gl_row_height, 2.0f, open_gl_row_height);
522 float view_height = getHeight() - title_width;
524 int num_presets = num_view_presets_;
526 int view_position = getViewPosition();
527 float y_offset = 2.0f * view_position / view_height;
529 Rectangle<int> view_bounds(0, title_width, getWidth(), getHeight() - title_width);
534 float width_ratio = image_width / getWidth();
535 float height_ratio = image_height / row_height;
537 float open_gl_row_height = height_ratio * 2.0f * row_height / view_height;
538 int cache_position = std::max(0, std::min(cache_position_, num_presets -
kNumCachedRows));
540 int row = cache_position + i;
542 float offset = (2.0f * row_height * row) / view_height;
543 float y = 1.0f + y_offset - offset;
545 Rectangle<int> row_bounds(0, row_height * row - view_position + title_width, getWidth(), row_height);
549 rows_[cache_index].
setTopRight(-1.0f + 2.0f * width_ratio, y);
550 rows_[cache_index].
setBottomLeft(-1.0f, y - open_gl_row_height);
551 rows_[cache_index].
setBottomRight(-1.0f + 2.0f * width_ratio, y - open_gl_row_height);
556 if (selected_index >= 0) {
557 moveQuadToRow(highlight_, selected_index, y_offset);
562 if (hover_preset_ >= 0) {
563 moveQuadToRow(hover_, hover_preset_, y_offset);
573 rows_[i].destroy(open_gl);
581 save_section_ =
nullptr;
582 delete_section_ =
nullptr;
584 addKeyListener(
this);
586 preset_list_ = std::make_unique<PresetList>();
587 preset_list_->addListener(
this);
590 folder_list_ = std::make_unique<SelectionList>();
591 folder_list_->addFavoritesOption();
592 folder_list_->addListener(
this);
596 Array<File> selections;
597 for (
const File& directory : directories)
598 selections.add(directory);
599 folder_list_->setSelections(selections);
603 style_buttons_[i]->addListener(
this);
605 addAndMakeVisible(style_buttons_[i].get());
609 store_button_ = std::make_unique<OpenGlToggleButton>(
"Store");
611 store_button_->setUiButton(
true);
612 store_button_->setVisible(
false);
614 preset_text_ = std::make_unique<PlainTextComponent>(
"Preset",
"Preset name");
617 preset_text_->setJustification(Justification::centredLeft);
619 author_text_ = std::make_unique<PlainTextComponent>(
"Author",
"Author");
622 author_text_->setJustification(Justification::centredLeft);
624#if !defined(NO_TEXT_ENTRY)
625 search_box_ = std::make_unique<OpenGlTextEditor>(
"Search");
626 search_box_->addListener(
this);
627 search_box_->setSelectAllWhenFocused(
true);
628 search_box_->setMultiLine(
false,
false);
629 search_box_->setJustification(Justification::centredLeft);
630 addAndMakeVisible(search_box_.get());
633 comments_ = std::make_unique<OpenGlTextEditor>(
"Comments");
634 comments_->setSelectAllWhenFocused(
false);
635 comments_->setJustification(Justification::topLeft);
636 comments_->setReadOnly(
true);
637 addAndMakeVisible(comments_.get());
639 comments_->setMultiLine(
true,
true);
644 preset_list_->setPresets(presets);
646 setWantsKeyboardFocus(
true);
647 setMouseClickGrabsKeyboardFocus(
true);
665 int text_x = info_rect.getX() + left_padding;
666 int text_width = info_rect.getWidth() - 2 * left_padding;
667 int name_y = info_rect.getY() + top_padding;
669 int author_y = name_y + name_height + middle_padding;
671 int comments_y = author_y + author_height + 2 * middle_padding;
674 g.drawRect(text_x, author_y, text_width, 1);
675 g.drawRect(text_x, comments_y, text_width, 1);
679 Rectangle<float> folder_bounds = folder_list_->getBounds().toFloat().expanded(1);
680 g.fillRoundedRectangle(folder_bounds, rounding);
691 static constexpr float kBrowseWidthRatio = 0.68f;
692 static constexpr float kSearchBoxRowHeightRatio = 1.3f;
697 empty_color = empty_color.withAlpha(0.5f * empty_color.getFloatAlpha());
700 search_box_->setTextToShowWhenEmpty(TRANS(
"Search"), empty_color);
702 search_box_->setColour(TextEditor::textColourId, findColour(
Skin::kBodyText,
true));
703 search_box_->setColour(TextEditor::highlightedTextColourId, findColour(
Skin::kBodyText,
true));
707 comments_->setColour(TextEditor::textColourId, findColour(
Skin::kBodyText,
true));
708 comments_->setColour(TextEditor::highlightedTextColourId, findColour(
Skin::kBodyText,
true));
713 int preset_list_width = getWidth() * kBrowseWidthRatio;
714 preset_list_->setBounds(getWidth() - preset_list_width - padding, 0, preset_list_width, getHeight());
716 preset_list_->redoCache();
724 int name_y = info_rect.getY() + top_padding;
726 int author_y = name_y + name_height + middle_padding;
728 int text_x = info_rect.getX() + left_padding;
729 int text_width = info_rect.getWidth() - 2 * left_padding;
730 preset_text_->setTextSize(name_height);
731 preset_text_->setBounds(text_x, name_y - middle_padding, text_width, name_height + 2 * middle_padding);
732 author_text_->setTextSize(author_height);
733 author_text_->setBounds(text_x, author_y, text_width / 2, author_height + 2 * middle_padding);
735 int style_filter_y = search_rect.getY() + top_padding;
737 int search_box_height = kSearchBoxRowHeightRatio * preset_list_->getRowHeight();
738 int search_box_x = search_rect.getX() + left_padding;
739 search_box_->setBounds(search_box_x, search_rect.getY() + top_padding, text_width, search_box_height);
741 style_filter_y = search_box_->getBottom() + top_padding;
745 int style_button_height = preset_list_->getRowHeight();
746 int style_filter_x = search_rect.getX() + left_padding;
747 int style_filter_width = search_rect.getWidth() - 2 * left_padding + widget_margin;
751 int column = i % num_in_row;
752 int x = style_filter_x + (style_filter_width * column) / num_in_row;
753 int next_x = style_filter_x + (style_filter_width * (column + 1)) / num_in_row;
754 int width = next_x - x - widget_margin;
755 int y = style_filter_y + (i / num_in_row) * (style_button_height + widget_margin);
756 style_buttons_[i]->setBounds(x, y, width, style_button_height);
759 int folder_y = style_filter_y + 3 * style_button_height + 2 * widget_margin + top_padding + 1;
760 folder_list_->setBounds(style_filter_x, folder_y, text_width, search_rect.getBottom() - top_padding - folder_y - 1);
765void PresetBrowser::setCommentsBounds() {
770 int width = info_rect.getWidth() - 2 * left_padding;
772 int comments_x = info_rect.getX() + left_padding;
773 int comments_y = info_rect.getY() + top_info_height + top_padding;
774 int comments_height = info_rect.getBottom() - comments_y - top_padding;
775 if (store_button_->isVisible()) {
777 int store_y = info_rect.getBottom() - store_height - top_padding;
778 store_button_->setBounds(comments_x, store_y, width, store_height);
779 comments_height -= store_height + top_padding / 2;
782 comments_->setBounds(comments_x, comments_y, width, comments_height);
786 SynthSection::visibilityChanged();
788 search_box_->setText(
"");
791 preset_list_->redoCache();
792 folder_list_->redoCache();
793 more_author_presets_.clear();
797 json available_packs = available[
"packs"];
798 for (
auto& pack : available_packs) {
799 if (pack.count(
"Presets") == 0)
802 bool purchased =
false;
803 if (pack.count(
"Purchased"))
804 purchased = pack[
"Purchased"];
808 std::string author_data = pack[
"Author"];
810 authors.addTokens(author_data,
",",
"");
811 for (
const String& author : authors)
812 more_author_presets_.insert(author.removeCharacters(
" ._").toLowerCase().toStdString());
815 catch (
const json::exception& e) {
825 int y = info_rect.getBottom() + padding;
826 return Rectangle<int>(0, y, info_rect.getWidth(), getHeight() - y);
830 static constexpr float kInfoHeightRatio = 0.43f;
832 int height = getHeight() * kInfoHeightRatio;
833 return Rectangle<int>(0, 0, width, height);
838 search_box_->setText(
"");
839 preset_list_->reloadPresets();
840 preset_list_->filter(
"", std::set<std::string>());
843 Array<File> selections;
844 for (
const File& directory : directories)
845 selections.add(directory);
846 folder_list_->setSelections(selections);
850 std::set<std::string> styles;
852 if (style_buttons_[i]->getToggleState()) {
854 styles.insert(name.toLowerCase().toStdString());
858 preset_list_->filter(search_box_->getText(), styles);
859 preset_list_->redoCache();
879 if (clicked_button == store_button_.get()) {
880 String encoded_author = URL::addEscapeChars(author_text_->getText().toStdString(),
true);
881 encoded_author = encoded_author.replace(
"+",
"%2B");
883 URL url(String(kPresetStoreUrl) + encoded_author);
884 url.launchInDefaultBrowser();
892 return search_box_->hasKeyboardFocus(
true);
894 if (key.getKeyCode() == KeyPress::escapeKey) {
895 for (
Listener* listener : listeners_)
896 listener->hidePresetBrowser();
899 if (key.getKeyCode() == KeyPress::upKey || key.getKeyCode() == KeyPress::leftKey) {
903 if (key.getKeyCode() == KeyPress::downKey || key.getKeyCode() == KeyPress::rightKey) {
907 return search_box_->hasKeyboardFocus(
true);
912 return search_box_->hasKeyboardFocus(
true);
919 File parent = external_preset_.getParentDirectory();
920 if (parent.exists()) {
923 presets.sort(kFileSorter);
924 int index = presets.indexOf(external_preset_);
925 index = (index + indices + presets.size()) % presets.size();
927 File new_preset = presets[index];
928 loadFromFile(new_preset);
932 preset_list_->shiftSelectedPreset(indices);
944 external_preset_ = file;
948bool PresetBrowser::loadFromFile(File& preset) {
950 if (parent ==
nullptr)
956 setPresetInfo(preset);
963 comments_->setText(comments);
964 comments_->setFont(
Fonts::instance()->proportional_light().withPointHeight(comments_font_size));
965 comments_->redoImage();
972void PresetBrowser::loadPresetInfo() {
974 if (parent ==
nullptr)
979 lighten = background.overlaidWith(lighten);
983 if (preset.isEmpty()) {
984 preset_text_->setText(
"Preset name");
985 preset_text_->setColor(lighten);
988 preset_text_->setText(preset);
989 preset_text_->setColor(regular_text);
993 if (author.isEmpty()) {
994 author_text_->setText(
"Author");
995 author_text_->setColor(lighten);
998 author_text_->setText(author);
999 author_text_->setColor(regular_text);
1005 comments_->setText(comments);
1006 comments_->setFont(
Fonts::instance()->proportional_light().withPointHeight(comments_font_size));
1007 comments_->redoImage();
1011void PresetBrowser::setPresetInfo(File& preset) {
1012 if (preset.exists()) {
1014 json parsed_json_state = json::parse(preset.loadFileAsString().toStdString(),
nullptr,
false);
1018 catch (
const json::exception& e) {
1024 listeners_.push_back(listener);
1028 save_section_ = save_section;
1033 delete_section_ = delete_section;
1038 if (selection.exists() && selection.isDirectory())
1039 preset_list_->setCurrentFolder(selection);
1043 Array<File> presets;
1045 preset_list_->setPresets(presets);
1049 Array<File> presets;
1052 Array<File> favorites;
1055 for (
const File& file : presets) {
1056 if (favorite_lookup.count(file.getFullPathName().toStdString()))
1057 favorites.add(file);
1059 preset_list_->setPresets(favorites);
An overlay that asks the user to confirm deletion of a preset file.
Definition delete_section.h:15
void addDeleteListener(Listener *listener)
Definition delete_section.h:77
Font & proportional_light()
Returns a reference to the proportional light font.
Definition fonts.h:28
static Fonts * instance()
Gets the singleton instance of the Fonts class.
Definition fonts.h:52
A helper class for sorting files in ascending order based on their names.
Definition load_save.h:34
static const std::string kPresetFolderName
Definition load_save.h:74
static std::vector< File > getPresetDirectories()
Gets directories that should contain presets.
Definition load_save.cpp:1764
@ kNumPresetStyles
Definition load_save.h:66
static void addFavorite(const File &new_favorite)
Adds a new favorite preset or item to the favorites file.
Definition load_save.cpp:1219
static void getAllPresets(Array< File > &presets)
Retrieves all preset files from preset directories.
Definition load_save.cpp:1835
static std::string getLicense(json state)
Extracts the license information from a JSON state, if present.
Definition load_save.cpp:1107
static void removeFavorite(const File &old_favorite)
Removes a favorite item from the favorites.
Definition load_save.cpp:1225
static json getAvailablePacks()
Parses and returns JSON data about available packs.
Definition load_save.cpp:1441
static String getAuthorFromFile(const File &file)
Extracts the author's name from a given preset file.
Definition load_save.cpp:1039
static std::set< std::string > getFavorites()
Retrieves all favorites as a set of string paths.
Definition load_save.cpp:1235
static bool setViewPort(Component *component, Rectangle< int > bounds, OpenGlWrapper &open_gl)
Sets the OpenGL viewport to match a specified rectangle within a component.
Definition open_gl_component.cpp:42
static void setScissorBounds(Component *component, Rectangle< int > bounds, OpenGlWrapper &open_gl)
Sets the OpenGL scissor region to a specified rectangle within a component.
Definition open_gl_component.cpp:82
void setOwnImage(Image &image)
Sets the image from an owned copy.
Definition open_gl_image.h:69
void init(OpenGlWrapper &open_gl)
Initializes the OpenGL buffers and shader attributes needed for rendering the image.
Definition open_gl_image.cpp:33
void setBottomLeft(float x, float y)
Sets the bottom-left corner position of the image quad.
Definition open_gl_image.h:116
void drawImage(OpenGlWrapper &open_gl)
Draws the image to the current OpenGL context.
Definition open_gl_image.cpp:59
void setScissor(bool scissor)
Enables or disables scissor test when drawing the image.
Definition open_gl_image.h:156
void setBottomRight(float x, float y)
Sets the bottom-right corner position of the image quad.
Definition open_gl_image.h:121
void setTopLeft(float x, float y)
Sets the top-left corner position of the image quad.
Definition open_gl_image.h:111
void setTopRight(float x, float y)
Sets the top-right corner position of the image quad.
Definition open_gl_image.h:126
void setColor(Colour color)
Sets the color tint applied to the image.
Definition open_gl_image.h:92
virtual void init(OpenGlWrapper &open_gl) override
Initializes OpenGL buffers and shader attributes.
Definition open_gl_multi_quad.cpp:37
void setQuad(int i, float x, float y, float w, float h)
Sets the position and size of a quad in normalized device space.
Definition open_gl_multi_quad.h:313
void setTargetComponent(Component *target_component)
Sets a target component to help position the quads.
Definition open_gl_multi_quad.h:358
virtual void render(OpenGlWrapper &open_gl, bool animate) override
Renders the quads using OpenGL.
Definition open_gl_multi_quad.cpp:92
virtual void destroy(OpenGlWrapper &open_gl) override
Releases OpenGL resources when the component is destroyed.
Definition open_gl_multi_quad.cpp:69
force_inline void setColor(Colour color)
Sets the base color for the quads.
Definition open_gl_multi_quad.h:102
void setAdditive(bool additive)
Enables or disables additive blending for rendering.
Definition open_gl_multi_quad.h:377
A convenience class for a single quad rendered via OpenGL.
Definition open_gl_multi_quad.h:447
static Path star()
Definition paths.h:446
@ kLight
Definition open_gl_image_component.h:309
Interface for events from the PresetBrowser (e.g. preset selected, deleted, or browser hidden).
Definition preset_browser.h:427
static constexpr int kLeftPadding
Definition preset_browser.h:415
PresetBrowser()
Constructs a PresetBrowser.
Definition preset_browser.cpp:580
void resized() override
Called when the component is resized. Arranges layout of child components.
Definition preset_browser.cpp:690
static constexpr int kStoreHeight
Definition preset_browser.h:420
Rectangle< int > getInfoRect()
Returns the rectangle reserved for the preset info area.
Definition preset_browser.cpp:829
static constexpr int kTopPadding
Definition preset_browser.h:416
void newSelection(File selection) override
Called when a new File is selected.
Definition preset_browser.cpp:1037
bool keyStateChanged(bool is_key_down, Component *origin) override
Definition preset_browser.cpp:910
static constexpr int kCommentsFontHeight
Definition preset_browser.h:421
void externalPresetLoaded(File file)
Loads an external preset file and sets it as the current selection.
Definition preset_browser.cpp:943
void jumpToPreset(int indices)
Jumps to a preset a certain number of steps away.
Definition preset_browser.cpp:916
static constexpr int kNameFontHeight
Definition preset_browser.h:418
~PresetBrowser()
Destructor.
Definition preset_browser.cpp:651
void setDeleteSection(DeleteSection *delete_section)
Sets the DeleteSection for handling preset deletion.
Definition preset_browser.cpp:1032
void allSelected() override
Called when "All" special selection is made.
Definition preset_browser.cpp:1042
void textEditorEscapeKeyPressed(TextEditor &editor) override
Definition preset_browser.cpp:866
void loadNextPreset()
Loads the next preset in the list.
Definition preset_browser.cpp:939
void setSaveSection(SaveSection *save_section)
Sets the SaveSection for handling preset saving.
Definition preset_browser.cpp:1027
static constexpr int kAuthorFontHeight
Definition preset_browser.h:419
void paintBackground(Graphics &g) override
Paints the background of the section. Calls paintContainer, heading, knobs, children.
Definition preset_browser.cpp:653
void addListener(Listener *listener)
Adds a listener to receive events from the PresetBrowser.
Definition preset_browser.cpp:1023
void favoritesSelected() override
Called when "Favorites" special selection is made.
Definition preset_browser.cpp:1048
void filterPresets()
Filters the displayed presets based on search text and selected styles.
Definition preset_browser.cpp:849
bool keyPressed(const KeyPress &key, Component *origin) override
Definition preset_browser.cpp:890
static constexpr int kMiddlePadding
Definition preset_browser.h:417
void buttonClicked(Button *clicked_button) override
Called when a button is clicked. Updates the synth parameter accordingly.
Definition preset_browser.cpp:878
void loadPresets()
Loads all presets from known directories.
Definition preset_browser.cpp:836
void paintBackgroundShadow(Graphics &g) override
Stub for painting background shadows. Overridden by subclasses if needed.
Definition preset_browser.cpp:685
void textEditorTextChanged(TextEditor &editor) override
Definition preset_browser.cpp:862
void visibilityChanged() override
Definition preset_browser.cpp:785
void loadPrevPreset()
Loads the previous preset in the list.
Definition preset_browser.cpp:935
void fileDeleted(File deleted_file) override
Called after a file is deleted.
Definition preset_browser.cpp:874
void save(File preset) override
Called after saving a preset.
Definition preset_browser.cpp:870
Rectangle< int > getSearchRect()
Returns the rectangle reserved for the search area.
Definition preset_browser.cpp:822
A cache for preset metadata such as author and style for faster repeated lookups.
Definition preset_browser.h:21
std::string getStyle(const File &preset)
Retrieves the style of a given preset, caching the result.
Definition preset_browser.h:41
std::string getAuthor(const File &preset)
Retrieves the author of a given preset, caching the result.
Definition preset_browser.h:28
Interface for receiving preset selection and deletion requests.
Definition preset_browser.h:67
int getSelectedIndex()
Gets the index of the currently selected preset.
Definition preset_browser.cpp:404
void respondToMenuCallback(int result)
Handles actions from the preset context menu.
Definition preset_browser.cpp:191
void mouseExit(const MouseEvent &e) override
Definition preset_browser.cpp:187
void mouseDown(const MouseEvent &e) override
Definition preset_browser.cpp:291
void resized() override
Called when the component is resized. Arranges layout of child components.
Definition preset_browser.cpp:120
static constexpr float kScrollSensitivity
Definition preset_browser.h:112
static constexpr float kAuthorWidthPercent
Definition preset_browser.h:110
void leftClick(const MouseEvent &e)
Called on left-click to select, rename, or favorite a preset.
Definition preset_browser.cpp:236
void scrollBarMoved(ScrollBar *scroll_bar, double range_start) override
Definition preset_browser.cpp:312
void reloadPresets()
Reloads the currently displayed presets from disk.
Definition preset_browser.cpp:342
void menuClick(const MouseEvent &e)
Called on right-click to show a context menu.
Definition preset_browser.cpp:217
void mouseMove(const MouseEvent &e) override
Definition preset_browser.cpp:181
PresetList()
Constructs a PresetList.
Definition preset_browser.cpp:40
void renderOpenGlComponents(OpenGlWrapper &open_gl, bool animate) override
Renders all OpenGL components in this section and sub-sections.
Definition preset_browser.cpp:520
void redoCache()
Updates the cached images for rows after sorting or filtering.
Definition preset_browser.cpp:363
void textEditorFocusLost(TextEditor &text_editor) override
Definition preset_browser.cpp:303
void setScrollBarRange()
Definition preset_browser.cpp:317
void destroyOpenGlComponents(OpenGlWrapper &open_gl) override
Destroys all OpenGL components in this section and sub-sections.
Definition preset_browser.cpp:571
void initOpenGlComponents(OpenGlWrapper &open_gl) override
Initializes all OpenGL components in this section and sub-sections.
Definition preset_browser.cpp:419
void finishRename()
Finalizes a preset rename operation.
Definition preset_browser.cpp:328
static constexpr float kStyleWidthPercent
Definition preset_browser.h:109
Column
Definition preset_browser.h:85
@ kAuthor
Definition preset_browser.h:90
@ kDate
Definition preset_browser.h:91
@ kName
Definition preset_browser.h:88
@ kStyle
Definition preset_browser.h:89
@ kStar
Definition preset_browser.h:87
void textEditorReturnKeyPressed(TextEditor &text_editor) override
Definition preset_browser.cpp:298
void setPresets(Array< File > presets)
Sets the array of presets to display.
Definition preset_browser.cpp:157
void mouseWheelMove(const MouseEvent &e, const MouseWheelDetails &wheel) override
Definition preset_browser.cpp:163
void paintBackground(Graphics &g) override
Paints the background of the section. Calls paintContainer, heading, knobs, children.
Definition preset_browser.cpp:71
void shiftSelectedPreset(int indices)
Moves the selected preset up or down by a number of indices.
Definition preset_browser.cpp:352
int getRowHeight()
Gets the row height in pixels.
Definition preset_browser.h:269
static constexpr float kDateWidthPercent
Definition preset_browser.h:111
static constexpr float kNameWidthPercent
Definition preset_browser.h:108
static constexpr int kNumCachedRows
Definition preset_browser.h:105
void textEditorEscapeKeyPressed(TextEditor &editor) override
Definition preset_browser.cpp:308
@ kOpenFileLocation
Definition preset_browser.h:98
@ kRename
Definition preset_browser.h:99
@ kDelete
Definition preset_browser.h:100
void filter(String filter_string, const std::set< std::string > &styles)
Filters the displayed presets by name, author, and styles.
Definition preset_browser.cpp:372
static constexpr float kStarWidthPercent
Definition preset_browser.h:107
int getRowFromPosition(float mouse_position)
Converts a mouse Y position into a row index.
Definition preset_browser.cpp:175
int getScrollableRange()
Gets the scrollable height of the presets.
Definition preset_browser.cpp:412
A UI overlay for saving presets or other files.
Definition save_section.h:21
void addSaveListener(Listener *listener)
Adds a listener to be notified when saving occurs.
Definition save_section.h:161
Manages and provides access to vertex and fragment shaders used by the OpenGL rendering pipeline.
Definition shaders.h:19
@ kBodyRounding
Definition skin.h:71
@ kLargePadding
Definition skin.h:82
@ kWidgetRoundedCorner
Definition skin.h:104
@ kWidgetPrimary1
Definition skin.h:165
@ kWidgetBackground
Definition skin.h:173
@ kBodyText
Definition skin.h:133
@ kLightenScreen
Definition skin.h:141
@ kTextEditorSelection
Definition skin.h:203
@ kTextComponentText
Definition skin.h:148
@ kTextEditorCaret
Definition skin.h:202
@ kBody
Definition skin.h:129
@ kPresetBrowser
Definition skin.h:57
A base class providing foundational functionality for the Vital synthesizer’s engine,...
Definition synth_base.h:42
void setAuthor(const String &author)
Sets the author metadata of the current preset.
Definition synth_base.cpp:681
bool loadFromFile(File preset, std::string &error)
Attempts to load a preset from a file.
Definition synth_base.cpp:338
String getAuthor()
Gets the author of the current preset.
Definition synth_base.cpp:701
String getComments()
Gets the comments for the current preset.
Definition synth_base.cpp:705
String getPresetName()
Gets the current preset’s name.
Definition synth_base.cpp:713
void setPresetName(const String &preset_name)
Sets the preset name.
Definition synth_base.cpp:693
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
virtual void renderOpenGlComponents(OpenGlWrapper &open_gl, bool animate)
Renders all OpenGL components in this section and sub-sections.
Definition synth_section.cpp:357
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 resized() override
Called when the component is resized. Arranges layout of child components.
Definition synth_section.cpp:35
virtual void paintBody(Graphics &g, Rectangle< int > bounds)
Paints the body background within given bounds.
Definition synth_section.cpp:165
void paintChildrenBackgrounds(Graphics &g)
Paints the backgrounds for all child sections.
Definition synth_section.cpp:274
virtual int getPixelMultiple() const
Definition synth_section.cpp:729
virtual void destroyOpenGlComponents(OpenGlWrapper &open_gl)
Destroys all OpenGL components in this section and sub-sections.
Definition synth_section.cpp:383
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
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 paintBorder(Graphics &g, Rectangle< int > bounds)
Paints the border around given bounds.
Definition synth_section.cpp:170
void addOpenGlComponent(OpenGlComponent *open_gl_component, bool to_beginning=false)
Definition synth_section.cpp:489
float getSizeRatio() const
Definition synth_section.h:765
float getTitleWidth()
Definition synth_section.cpp:629
void setSkinOverride(Skin::SectionOverride skin_override)
Definition synth_section.h:303
virtual void initOpenGlComponents(OpenGlWrapper &open_gl)
Initializes all OpenGL components in this section and sub-sections.
Definition synth_section.cpp:349
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
static TextLookAndFeel * instance()
Singleton instance access.
Definition text_look_and_feel.h:106
nlohmann::json json
Definition line_generator.h:7
const std::string kPresetStyleNames[]
Names for preset categories or styles.
Definition synth_strings.h:81
force_inline int nextPowerOfTwo(mono_float value)
Finds the next power of two greater than or equal to a float value.
Definition utils.h:370
const std::string kPresetExtension
File extension for Vital preset files.
Definition synth_constants.h:85
A helper struct containing references to OpenGL context, shaders, and display scale.
Definition shaders.h:174