Skip to content

Commit

Permalink
Cleaned up corrupt settings dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
timothyschoen committed Nov 27, 2024
1 parent 34e4b0d commit 89a5c90
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 152 deletions.
7 changes: 6 additions & 1 deletion Source/Dialogs/AdvancedSettingsPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ class AdvancedSettingsPanel : public SettingsDialogPanel

commandClickSwitchesModeValue.referTo(settingsFile->getPropertyAsValue("cmd_click_switches_mode"));
commandClickSwitchesModeValue.addListener(this);
interfaceProperties.add(new PropertiesPanel::BoolComponent("Command/Ctrl + click on canvas switches mode", commandClickSwitchesModeValue, { "No", "Yes" }));
#if JUCE_MAC
String cmdName = "Command";
#else
String cmdName = "Ctrl";
#endif
interfaceProperties.add(new PropertiesPanel::BoolComponent(cmdName + " + click on canvas switches mode", commandClickSwitchesModeValue, { "No", "Yes" }));

showAllAudioDeviceValues.referTo(settingsFile->getPropertyAsValue("show_all_audio_device_rates"));
showAllAudioDeviceValues.addListener(this);
Expand Down
78 changes: 38 additions & 40 deletions Source/Dialogs/Dialogs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,52 +244,48 @@ void Dialogs::showMainMenu(PluginEditor* editor, Component* centre)
}
}

void Dialogs::showOkayCancelDialog(std::unique_ptr<Dialog>* target, Component* parent, String const& title, std::function<void(bool)> const& callback, StringArray const& options)
void Dialogs::showMultiChoiceDialog(std::unique_ptr<Dialog>* target, Component* parent, String const& title, std::function<void(int)> const& callback, StringArray const& options)
{

class OkayCancelDialog : public Component {
class MultiChoiceDialog : public Component {

TextLayout layout;

public:
OkayCancelDialog(Dialog* dialog, String const& title, std::function<void(bool)> const& callback, StringArray const& options)
MultiChoiceDialog(Dialog* dialog, String const& title, std::function<void(int)> const& callback, StringArray const& options)
: label("", title)
{
auto attributedTitle = AttributedString(title);
attributedTitle.setJustification(Justification::centred);
attributedTitle.setJustification(Justification::horizontallyCentred);
attributedTitle.setFont(Fonts::getBoldFont().withHeight(14));
attributedTitle.setColour(findColour(PlugDataColour::panelTextColourId));

setSize(270, 220);
layout.createLayout(attributedTitle, getWidth() - 32);

addAndMakeVisible(cancel);
addAndMakeVisible(okay);

okay.setButtonText(options[0]);
cancel.setButtonText(options[1]);

auto backgroundColour = findColour(PlugDataColour::dialogBackgroundColourId);
cancel.setColour(TextButton::buttonColourId, backgroundColour.contrasting(0.05f));
cancel.setColour(TextButton::buttonOnColourId, backgroundColour.contrasting(0.1f));
cancel.setColour(ComboBox::outlineColourId, Colours::transparentBlack);

okay.setColour(TextButton::buttonColourId, backgroundColour.contrasting(0.05f));
okay.setColour(TextButton::buttonOnColourId, backgroundColour.contrasting(0.1f));
okay.setColour(ComboBox::outlineColourId, Colours::transparentBlack);

cancel.onClick = [dialog, callback] {
callback(false);
dialog->closeDialog();
};

okay.onClick = [dialog, callback] {
callback(true);
dialog->closeDialog();
};

for(int i = 0; i < options.size(); i++)
{
auto* button = buttons.add(new TextButton(options[i]));

auto backgroundColour = findColour(PlugDataColour::dialogBackgroundColourId);
button->setColour(TextButton::buttonColourId, backgroundColour.contrasting(0.05f));
button->setColour(TextButton::buttonOnColourId, backgroundColour.contrasting(0.1f));
button->setColour(ComboBox::outlineColourId, Colours::transparentBlack);
addAndMakeVisible(button);
button->onClick = [dialog, callback, i] {
callback(i);
dialog->closeDialog();
};
}

auto width = 270;
layout.createLayout(attributedTitle, width - 32);
setSize(width, getBestHeight());

setOpaque(false);
}

int getBestHeight()
{
return buttons.size() * 34 + layout.getHeight() + 116;
}

void paint(Graphics& g) override
{
Expand All @@ -299,29 +295,31 @@ void Dialogs::showOkayCancelDialog(std::unique_ptr<Dialog>* target, Component* p
warningIcon.setJustification(Justification::centred);
warningIcon.draw(g, getLocalBounds().toFloat().removeFromTop(90));

auto contentBounds = getLocalBounds().withTrimmedTop(63).reduced(16);
auto contentBounds = getLocalBounds().withTrimmedTop(66).reduced(16);
layout.draw(g, contentBounds.removeFromTop(48).toFloat());
}

void resized() override
{
auto contentBounds = getLocalBounds().reduced(16);
contentBounds.removeFromTop(126);
contentBounds.removeFromTop(layout.getHeight() + 90);

okay.setBounds(contentBounds.removeFromTop(28));
contentBounds.removeFromTop(6);
cancel.setBounds(contentBounds.removeFromTop(28));
for(auto* button : buttons)
{
button->setBounds(contentBounds.removeFromTop(28));
contentBounds.removeFromTop(6);
}
}

private:
Label label;
TextButton cancel = TextButton("Cancel");
TextButton okay = TextButton("OK");
OwnedArray<TextButton> buttons;
};

auto* dialog = new Dialog(target, parent, 270, 220, false);
auto* dialogContent = new OkayCancelDialog(dialog, title, callback, options);
auto* dialogContent = new MultiChoiceDialog(dialog, title, callback, options);

dialog->height = dialogContent->getBestHeight();
dialog->setViewedComponent(dialogContent);
target->reset(dialog);
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Dialogs/Dialogs.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ struct Dialogs {

static void showMainMenu(PluginEditor* editor, Component* centre);

static void showOkayCancelDialog(std::unique_ptr<Dialog>* target, Component* parent, String const& title, std::function<void(bool)> const& callback, StringArray const& options = { "Okay", "Cancel " });
static void showMultiChoiceDialog(std::unique_ptr<Dialog>* target, Component* parent, String const& title, std::function<void(int)> const& callback, StringArray const& options = { "Okay", "Cancel " });

static void showHeavyExportDialog(std::unique_ptr<Dialog>* target, Component* parent);

Expand Down
4 changes: 2 additions & 2 deletions Source/Dialogs/KeyMappingSettingsPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class KeyMappingSettingsPanel : public SettingsDialogPanel
propertiesPanel.clear();

auto resetMaxDefaults = [this] {
Dialogs::showOkayCancelDialog(&confirmationDialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset all the key-mappings?",
Dialogs::showMultiChoiceDialog(&confirmationDialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset all the key-mappings?",
[this](int result) {
resetKeyMappingsToMaxCallback(result, this);
});
};
auto resetPdDefaults = [this]() {
Dialogs::showOkayCancelDialog(&confirmationDialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset all the key-mappings?",
Dialogs::showMultiChoiceDialog(&confirmationDialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset all the key-mappings?",
[this](int result) {
resetKeyMappingsToPdCallback(result, this);
});
Expand Down
2 changes: 1 addition & 1 deletion Source/Dialogs/PathsSettingsPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class SearchPathPanel : public Component

addAndMakeVisible(resetButton);
resetButton.onClick = [this]() {
Dialogs::showOkayCancelDialog(&confirmationDialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset all the search paths?",
Dialogs::showMultiChoiceDialog(&confirmationDialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset all the search paths?",
[this](int result) {
if (result == 0)
return;
Expand Down
4 changes: 2 additions & 2 deletions Source/Dialogs/ThemeSettingsPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ class ThemeSettingsPanel : public SettingsDialogPanel
};

auto* resetButton = new PropertiesPanel::ActionComponent([this]() {
Dialogs::showOkayCancelDialog(&dialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset to default theme settings?",
[this](bool result) {
Dialogs::showMultiChoiceDialog(&dialog, findParentComponentOfClass<Dialog>(), "Are you sure you want to reset to default theme settings?",
[this](int result) {
if (result) {
resetDefaults();
}
Expand Down
119 changes: 19 additions & 100 deletions Source/PluginEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,97 +44,6 @@ using namespace juce::gl;

#include <nanovg.h>

class CorruptSettingsAlert : public Component {
Label errorMessage;
Label errorSub;

TextEditor errorInfo;

TextButton dismissButton;
TextButton revealFileButton;

public:
CorruptSettingsAlert(SettingsFile* settingsFile, std::function<void()> dismissFn)
{
setVisible(false);

errorMessage.setText("Corrupt settings detected and fixed", dontSendNotification);
errorMessage.setFont(Fonts::getBoldFont().withHeight(20));
errorMessage.setJustificationType(Justification::centred);

String errorText;

switch (settingsFile->getSettingsState()) {
case SettingsFile::SettingsState::DefaultSettings:
errorText = "plugdata will use default settings.";
break;
case SettingsFile::SettingsState::BackupSettings:
errorText = "plugdata will use last good settings.";
break;
default:
break;
}

errorSub.setText(errorText + " Previous settings backed up to:", dontSendNotification);
errorSub.setFont(Fonts::getDefaultFont().withHeight(14));
errorSub.setJustificationType(Justification::centred);

auto corruptSettingsLoc = settingsFile->getCorruptBackupSettingsLocation();

errorInfo.setText(corruptSettingsLoc, dontSendNotification);
errorInfo.setMultiLine(true);
errorInfo.setReadOnly(true);
errorInfo.setJustification(Justification::centred);
errorInfo.setColour(TextEditor::outlineColourId, Colours::transparentBlack);
errorInfo.setColour(TextEditor::backgroundColourId, Colours::transparentBlack);

dismissButton.setButtonText("Dismiss");
dismissButton.onClick = dismissFn;

#if JUCE_MAC
String revealTip = "Reveal in Finder";
#elif JUCE_WINDOWS
String revealTip = "Reveal in Explorer";
#else
String revealTip = "Reveal in file browser";
#endif

revealFileButton.setButtonText(revealTip);
revealFileButton.onClick = [corruptSettingsLoc, dismissFn]() {
auto backupLoc = File(corruptSettingsLoc);
if (backupLoc.existsAsFile())
backupLoc.revealToUser();
dismissFn();
};

addAndMakeVisible(errorMessage);
addAndMakeVisible(errorSub);
addAndMakeVisible(errorInfo);
addAndMakeVisible(dismissButton);
addAndMakeVisible(revealFileButton);
};

void resized() override
{
auto w = getWidth() - 10;

errorMessage.setBounds(Rectangle<int>(5, 5, w, 22));
errorSub.setBounds(Rectangle<int>(5, errorMessage.getBottom() + 3, w, 16));

errorInfo.setBounds(Rectangle<int>(5, errorSub.getBottom() + 3, w, 40));

int const buttonHeight = 25;
int const dismissButtonWidth = 70;
int const revealButtonWidth = 130;
int const totalButtonWidth = dismissButtonWidth + revealButtonWidth + 10;
int const startX = (getWidth() - totalButtonWidth) / 2;
int const buttonY = getHeight() - 35;

dismissButton.setBounds(startX, buttonY, dismissButtonWidth, buttonHeight);
revealFileButton.setBounds(startX + dismissButtonWidth + 10, buttonY, revealButtonWidth, buttonHeight);
}
};

PluginEditor::PluginEditor(PluginProcessor& p)
: AudioProcessorEditor(&p)
, pd(&p)
Expand Down Expand Up @@ -420,19 +329,29 @@ PluginEditor::PluginEditor(PluginProcessor& p)
pd->objectLibrary->waitForInitialisationToFinish();

lookAndFeelChanged();

::Timer::callAfterDelay(100, [this, settingsFile]() {
if (settingsFile->getSettingsState() != SettingsFile::SettingsState::UserSettings) {
auto* dialog = new Dialog(&openedDialog, this, 450, 150, false);

auto dismissDialog = [this]() {
openedDialog.reset(nullptr);
};

String errorText = "Corrupt settings detected and fixed\n";

if(settingsFile->getSettingsState() == SettingsFile::SettingsState::DefaultSettings) {
errorText += "plugdata will use default settings.\n\n";
}
else {
errorText += "plugdata will use last good settings.\n\n";
}

auto* corruptAlert = new CorruptSettingsAlert(settingsFile, dismissDialog);
dialog->setViewedComponent(corruptAlert);
openedDialog.reset(dialog);
auto corruptedSettingsLocation = settingsFile->getCorruptBackupSettingsLocation();
errorText += " Previous settings backed up to:\n\n" + settingsFile->getCorruptBackupSettingsLocation();

Dialogs::showMultiChoiceDialog(&openedDialog, this, errorText, [corruptedSettingsLocation](int result){
if(result)
{
File(corruptedSettingsLocation).revealToUser();
}
}, {"Dismiss", "Reveal corrupted file"});

settingsFile->resetSettingsState();
}
});
Expand Down
2 changes: 1 addition & 1 deletion Source/Sidebar/CommandInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ class CommandInput final
int startPos = 0;

// if the lua expression is not at the start of the message, we expect a return value
auto hasReturnValue = !message.startsWith("{");
auto hasReturnValue = !message.trim().startsWith("{") || consoleTargetName != ">";

while (startPos < message.length()) {
auto openBrace = message.indexOf(startPos, "{");
Expand Down
1 change: 1 addition & 0 deletions Source/Standalone/PlugDataApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class PlugDataApp : public JUCEApplication {
{
macOSTrash.deleteRecursively();
}

// TODO: show success dialog
}
else {
Expand Down
6 changes: 4 additions & 2 deletions Source/TabComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ void TabComponent::moveToLeftSplit(TabBarButtonComponent* tab)

showTab(tabbars[1][0]->cnv, 1); // Show first tab of right split
}

sendTabUpdateToVisibleCanvases();
}

void TabComponent::moveToRightSplit(TabBarButtonComponent* tab)
Expand Down Expand Up @@ -245,6 +247,8 @@ void TabComponent::moveToRightSplit(TabBarButtonComponent* tab)
showTab(tabbars[0][0]->cnv, 0); // Show first tab of left tabbar
showTab(tab->cnv, 1); // Show the moved tab on right tabbar
}

sendTabUpdateToVisibleCanvases();
}

void TabComponent::nextTab()
Expand Down Expand Up @@ -542,8 +546,6 @@ void TabComponent::showTab(Canvas* cnv, int splitIndex)

editor->nvgSurface.invalidateAll();

// sendTabUpdateToVisibleCanvases();

editor->sidebar->hideParameters();
editor->sidebar->clearSearchOutliner();
editor->updateCommandStatus();
Expand Down
4 changes: 2 additions & 2 deletions Source/Utility/Autosave.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class Autosave : public Timer
if (lastAutoSavedPatch.isValid() && autoSavedTime > fileChangedTime) {
auto timeDescription = RelativeTime((autoSavedTime - fileChangedTime) / 1000.0f).getApproximateDescription();

Dialogs::showOkayCancelDialog(
&editor->openedDialog, editor, "Restore autosave?\n (last autosave is " + timeDescription + " newer)", [lastAutoSavedPatch, patchPath, callback](bool useAutosaved) {
Dialogs::showMultiChoiceDialog(
&editor->openedDialog, editor, "Restore autosave?\n (last autosave is " + timeDescription + " newer)", [lastAutoSavedPatch, patchPath, callback](int useAutosaved) {
if (useAutosaved) {
MemoryOutputStream ostream;
Base64::convertFromBase64(ostream, lastAutoSavedPatch.getProperty("Patch").toString());
Expand Down

0 comments on commit 89a5c90

Please sign in to comment.