diff --git a/aegisub/src/colour_button.cpp b/aegisub/src/colour_button.cpp index b217a62cc..6638d1854 100644 --- a/aegisub/src/colour_button.cpp +++ b/aegisub/src/colour_button.cpp @@ -47,8 +47,15 @@ ColourButton::ColourButton(wxWindow* parent, wxWindowID id, const wxSize& size, wxColour col) : wxBitmapButton(parent, id, wxBitmap(size)) , bmp(GetBitmapLabel()) +, colour(col) { - SetColour(col); + { + wxMemoryDC dc; + dc.SelectObject(bmp); + dc.SetBrush(wxBrush(colour)); + dc.DrawRectangle(0,0,bmp.GetWidth(),bmp.GetHeight()); + } + SetBitmapLabel(bmp); Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ColourButton::OnClick, this); } diff --git a/aegisub/src/dialog_colorpicker.cpp b/aegisub/src/dialog_colorpicker.cpp index a49c83306..6f23f2a7d 100644 --- a/aegisub/src/dialog_colorpicker.cpp +++ b/aegisub/src/dialog_colorpicker.cpp @@ -891,6 +891,7 @@ wxColour GetColorFromUser(wxWindow *parent, wxColour original, ColorCallback cal { DialogColorPicker dialog(parent, original, callback, userdata); if (dialog.ShowModal() == wxID_OK) { + if (callback) callback(userdata, dialog.GetColor()); return dialog.GetColor(); } else { if (callback) callback(userdata, original); diff --git a/aegisub/src/preferences.cpp b/aegisub/src/preferences.cpp index f257c7996..e1eb6f324 100644 --- a/aegisub/src/preferences.cpp +++ b/aegisub/src/preferences.cpp @@ -50,7 +50,7 @@ #include "preferences_base.h" /// General preferences page -General::General(wxTreebook *book): OptionPage(book, _("General")) { +General::General(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("General")) { wxFlexGridSizer *startup = PageSizer(_("Startup")); OptionAdd(startup, _("Check for updates"), "App/Auto/Check For Updates"); @@ -69,7 +69,7 @@ General::General(wxTreebook *book): OptionPage(book, _("General")) { /// Subtitles preferences page -Subtitles::Subtitles(wxTreebook *book): OptionPage(book, _("Subtitles")) { +Subtitles::Subtitles(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Subtitles")) { wxFlexGridSizer *general = PageSizer(_("Options")); OptionAdd(general, _("Enable call tips"), "App/Call Tips"); @@ -86,7 +86,7 @@ Subtitles::Subtitles(wxTreebook *book): OptionPage(book, _("Subtitles")) { /// Audio preferences page -Audio::Audio(wxTreebook *book): OptionPage(book, _("Audio")) { +Audio::Audio(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Audio")) { wxFlexGridSizer *general = PageSizer(_("Options")); OptionAdd(general, _("Grab times from line upon selection"), "Audio/Grab Times on Select"); @@ -119,7 +119,7 @@ Audio::Audio(wxTreebook *book): OptionPage(book, _("Audio")) { /// Video preferences page -Video::Video(wxTreebook *book): OptionPage(book, _("Video")) { +Video::Video(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Video")) { wxFlexGridSizer *general = PageSizer(_("Options")); OptionAdd(general, _("Show keyframes in slider"), "Video/Slider/Show Keyframes"); @@ -144,7 +144,7 @@ Video::Video(wxTreebook *book): OptionPage(book, _("Video")) { /// Interface preferences page -Interface::Interface(wxTreebook *book): OptionPage(book, _("Interface")) { +Interface::Interface(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Interface")) { wxFlexGridSizer *grid = PageSizer(_("Subtitle Grid")); OptionBrowse(grid, _("Font face"), BROWSE_FONT, "Subtitle/Grid/Font Face"); @@ -157,7 +157,7 @@ Interface::Interface(wxTreebook *book): OptionPage(book, _("Interface")) { /// Interface Colours preferences subpage -Interface_Colours::Interface_Colours(wxTreebook *book): OptionPage(book, _("Colours"), PAGE_SCROLL|PAGE_SUB) { +Interface_Colours::Interface_Colours(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Colours"), PAGE_SCROLL|PAGE_SUB) { delete sizer; wxSizer *main_sizer = new wxBoxSizer(wxHORIZONTAL); sizer = new wxBoxSizer(wxVERTICAL); @@ -214,7 +214,7 @@ Interface_Colours::Interface_Colours(wxTreebook *book): OptionPage(book, _("Colo /// Interface Hotkeys preferences subpage -Interface_Hotkeys::Interface_Hotkeys(wxTreebook *book): OptionPage(book, _("Hotkeys"), PAGE_SUB) { +Interface_Hotkeys::Interface_Hotkeys(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Hotkeys"), PAGE_SUB) { wxFlexGridSizer *hotkeys = PageSizer(_("Hotkeys")); hotkeys->Add(new wxStaticText(this, wxID_ANY, _T("To be added after hotkey rewrite.")), 0, wxALL, 5); @@ -223,7 +223,7 @@ Interface_Hotkeys::Interface_Hotkeys(wxTreebook *book): OptionPage(book, _("Hotk /// Paths preferences page class Paths: public OptionPage { public: -Paths::Paths(wxTreebook *book): OptionPage(book, _("Paths")) { +Paths::Paths(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Paths")) { wxFlexGridSizer *general = PageSizer(_("General")); general->Add(new wxStaticText(this, wxID_ANY, _T("TBD..")), 0, wxALL, 5); @@ -233,7 +233,7 @@ Paths::Paths(wxTreebook *book): OptionPage(book, _("Paths")) { /// File Associations preferences page -File_Associations::File_Associations(wxTreebook *book): OptionPage(book, _("File Associations")) { +File_Associations::File_Associations(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("File Associations")) { wxFlexGridSizer *assoc = PageSizer(_("General")); assoc->Add(new wxStaticText(this, wxID_ANY, _T("TBD..")), 0, wxALL, 5); @@ -243,7 +243,7 @@ File_Associations::File_Associations(wxTreebook *book): OptionPage(book, _("File /// Backup preferences page -Backup::Backup(wxTreebook *book): OptionPage(book, _("Backup")) { +Backup::Backup(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Backup")) { wxFlexGridSizer *save = PageSizer(_("Automatic Save")); OptionAdd(save, _("Enable"), "App/Auto/Backup"); CellSkip(save); @@ -261,7 +261,7 @@ Backup::Backup(wxTreebook *book): OptionPage(book, _("Backup")) { /// Automation preferences page -Automation::Automation(wxTreebook *book): OptionPage(book, _("Automation")) { +Automation::Automation(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Automation")) { wxFlexGridSizer *general = PageSizer(_("General")); OptionAdd(general, _("Base path"), "Path/Automation/Base"); @@ -285,7 +285,7 @@ Automation::Automation(wxTreebook *book): OptionPage(book, _("Automation")) { /// Advanced preferences page -Advanced::Advanced(wxTreebook *book): OptionPage(book, _("Advanced")) { +Advanced::Advanced(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Advanced")) { wxFlexGridSizer *general = PageSizer(_("General")); wxStaticText *warning = new wxStaticText(this, wxID_ANY ,_("Changing these settings might result in bugs and/or crashes. Do not touch these unless you know what you're doing.")); @@ -299,7 +299,7 @@ Advanced::Advanced(wxTreebook *book): OptionPage(book, _("Advanced")) { /// Advanced Interface preferences subpage -Advanced_Interface::Advanced_Interface(wxTreebook *book): OptionPage(book, _("Backup"), PAGE_SUB) { +Advanced_Interface::Advanced_Interface(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Backup"), PAGE_SUB) { wxFlexGridSizer *interface_ = PageSizer(_("Interface")); interface_->Add(new wxStaticText(this, wxID_ANY, _T("TBD..")), 0, wxALL, 5); @@ -314,7 +314,7 @@ static wxArrayString vec_to_arrstr(std::vector const& vec) { } /// Advanced Audio preferences subpage -Advanced_Audio::Advanced_Audio(wxTreebook *book): OptionPage(book, _("Audio"), PAGE_SUB) { +Advanced_Audio::Advanced_Audio(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Audio"), PAGE_SUB) { wxFlexGridSizer *expert = PageSizer(_("Expert")); wxArrayString ap_choice = vec_to_arrstr(AudioProviderFactory::GetClasses()); @@ -353,7 +353,7 @@ Advanced_Audio::Advanced_Audio(wxTreebook *book): OptionPage(book, _("Audio"), P /// Advanced Video preferences subpage -Advanced_Video::Advanced_Video(wxTreebook *book): OptionPage(book, _("Video"), PAGE_SUB) { +Advanced_Video::Advanced_Video(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _("Video"), PAGE_SUB) { wxFlexGridSizer *expert = PageSizer(_("Expert")); wxArrayString vp_choice = vec_to_arrstr(VideoProviderFactory::GetClasses()); diff --git a/aegisub/src/preferences.h b/aegisub/src/preferences.h index 11ef602c3..01cdcb601 100644 --- a/aegisub/src/preferences.h +++ b/aegisub/src/preferences.h @@ -20,57 +20,30 @@ /// @ingroup configuration_ui #ifndef AGI_PRE +#include + +#include #include #include #include #include #endif -#include "browse_button.h" - -class General; -class Subtitles; -class Audio; -class Video; -class Interface; -class Interface_Colours; -class Interface_Hotkeys; -class Paths; -class File_Associations; -class Backup; -class Automation; -class Advanced; -class Advanced_Interface; -class Advanced_Audio; -class Advanced_Video; - class Preferences: public wxDialog { wxTreebook *book; + wxButton *applyButton; + + std::map pending_changes; void OnOK(wxCommandEvent &event); void OnCancel(wxCommandEvent &event); void OnApply(wxCommandEvent &event); - General *general; - Subtitles *subtitles; - Audio *audio; - Video *video; - Interface *interface_; - Interface_Colours *interface_colours; - Interface_Hotkeys *interface_hotkeys; - Paths *paths; - File_Associations *file_associations; - Backup *backup; - Automation *automation; - Advanced *advanced; - Advanced_Interface *advanced_interface; - Advanced_Audio *advanced_audio; - Advanced_Video *advanced_video; - public: Preferences(wxWindow *parent); ~Preferences(); + void SetOption(const char *name, wxAny value); + DECLARE_EVENT_TABLE() }; - diff --git a/aegisub/src/preferences_base.cpp b/aegisub/src/preferences_base.cpp index 503c7ffbf..d377b717b 100644 --- a/aegisub/src/preferences_base.cpp +++ b/aegisub/src/preferences_base.cpp @@ -50,10 +50,40 @@ DEFINE_BASE_EXCEPTION_NOINNER(PreferencesError, agi::Exception) DEFINE_SIMPLE_EXCEPTION_NOINNER(PreferenceIncorrectType, PreferencesError, "preferences/incorrect_type") DEFINE_SIMPLE_EXCEPTION_NOINNER(PreferenceNotSupported, PreferencesError, "preferences/not_supported") +#define OPTION_UPDATER(type, evttype, body) \ + class type { \ + const char *name; \ + Preferences *parent; \ + public: \ + type(const char *n="",Preferences *p=NULL) : name(n),parent(p) {} \ + void operator()(evttype& evt) { parent->SetOption(name, body); } \ + } +OPTION_UPDATER(StringUpdater, wxCommandEvent, STD_STR(evt.GetString())); +OPTION_UPDATER(IntUpdater, wxSpinEvent, evt.GetInt()); +OPTION_UPDATER(IntCBUpdater, wxCommandEvent, evt.GetInt()); +OPTION_UPDATER(DoubleUpdater, wxSpinEvent, evt.GetInt()); +OPTION_UPDATER(BoolUpdater, wxCommandEvent, !!evt.GetInt()); +class ColourUpdater { + const char *name; + Preferences *parent; +public: + ColourUpdater(const char *n = "", Preferences *p = NULL) : name(n), parent(p) { } + void operator()(wxCommandEvent& evt) { + ColourButton *btn = static_cast(evt.GetClientData()); + if (btn) { + parent->SetOption(name, STD_STR(btn->GetColour().GetAsString(wxC2S_CSS_SYNTAX))); + } + else { + evt.Skip(); + } + } +}; -OptionPage::OptionPage(wxTreebook *book, wxString name, int style): - wxScrolled(book, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL) { +OptionPage::OptionPage(wxTreebook *book, Preferences *parent, wxString name, int style) +: wxScrolled(book, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL) +, parent(parent) +{ if (style & PAGE_SUB) { book->AddSubPage(this, name, true); @@ -88,13 +118,22 @@ void OptionPage::OptionAdd(wxFlexGridSizer *&flex, const wxString &name, const c wxCheckBox *cb = new wxCheckBox(this, wxID_ANY, name); flex->Add(cb, 1, wxEXPAND, 0); cb->SetValue(opt->GetBool()); + cb->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, BoolUpdater(opt_name, parent)); break; } - case agi::OptionValue::Type_Int: + case agi::OptionValue::Type_Int: { + flex->Add(new wxStaticText(this, wxID_ANY, name), 1, wxALIGN_CENTRE_VERTICAL); + wxSpinCtrl *sc = new wxSpinCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetInt()); + sc->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, IntUpdater(opt_name, parent)); + flex->Add(sc); + + break; + } case agi::OptionValue::Type_Double: { flex->Add(new wxStaticText(this, wxID_ANY, name), 1, wxALIGN_CENTRE_VERTICAL); - wxSpinCtrlDouble *scd = new wxSpinCtrlDouble(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetInt(), inc); + wxSpinCtrlDouble *scd = new wxSpinCtrlDouble(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetDouble(), inc); + scd->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, DoubleUpdater(opt_name, parent)); flex->Add(scd); break; @@ -104,12 +143,15 @@ void OptionPage::OptionAdd(wxFlexGridSizer *&flex, const wxString &name, const c flex->Add(new wxStaticText(this, wxID_ANY, name), 1, wxALIGN_CENTRE_VERTICAL); wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY , lagi_wxString(opt->GetString()), wxDefaultPosition, wxDefaultSize); flex->Add(text, 1, wxEXPAND); + text->Bind(wxEVT_COMMAND_TEXT_UPDATED, StringUpdater(opt_name, parent)); break; } case agi::OptionValue::Type_Colour: { flex->Add(new wxStaticText(this, wxID_ANY, name), 1, wxALIGN_CENTRE_VERTICAL); - flex->Add(new ColourButton(this, wxID_ANY, wxSize(40,10), lagi_wxColour(opt->GetColour()))); + ColourButton *cb = new ColourButton(this, wxID_ANY, wxSize(40,10), lagi_wxColour(opt->GetColour())); + flex->Add(cb); + cb->Bind(wxEVT_COMMAND_BUTTON_CLICKED, ColourUpdater(opt_name, parent)); break; } @@ -122,26 +164,24 @@ void OptionPage::OptionAdd(wxFlexGridSizer *&flex, const wxString &name, const c void OptionPage::OptionChoice(wxFlexGridSizer *&flex, const wxString &name, const wxArrayString &choices, const char *opt_name) { agi::OptionValue *opt = OPT_GET(opt_name); - int type = opt->GetType(); - wxString selection; + flex->Add(new wxStaticText(this, wxID_ANY, name), 1, wxALIGN_CENTRE_VERTICAL); + wxComboBox *cb = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, choices, wxCB_READONLY | wxCB_DROPDOWN); + flex->Add(cb, 1, wxEXPAND, 0); - switch (type) { + switch (opt->GetType()) { case agi::OptionValue::Type_Int: { - selection = choices.Item(opt->GetInt()); + cb->SetValue(choices[opt->GetInt()]); + cb->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, IntCBUpdater(opt_name, parent)); break; } case agi::OptionValue::Type_String: { - selection.assign(opt->GetString()); + cb->SetValue(lagi_wxString(opt->GetString())); + cb->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, StringUpdater(opt_name, parent)); break; } default: throw PreferenceNotSupported("Unsupported type"); } - - flex->Add(new wxStaticText(this, wxID_ANY, name), 1, wxALIGN_CENTRE_VERTICAL); - wxComboBox *cb = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, choices, wxCB_READONLY | wxCB_DROPDOWN); - cb->SetValue(selection); - flex->Add(cb, 1, wxEXPAND, 0); } @@ -157,7 +197,6 @@ wxFlexGridSizer* OptionPage::PageSizer(wxString name) { void OptionPage::OptionBrowse(wxFlexGridSizer *&flex, const wxString &name, BrowseType browse_type, const char *opt_name) { - agi::OptionValue *opt = OPT_GET(opt_name); if (opt->GetType() != agi::OptionValue::Type_String) @@ -174,15 +213,46 @@ void OptionPage::OptionBrowse(wxFlexGridSizer *&flex, const wxString &name, Brow BrowseButton *browse = new BrowseButton(this, wxID_ANY, wxEmptyString, browse_type); browse->Bind(text); button_flex->Add(browse, 1, wxEXPAND); + text->Bind(wxEVT_COMMAND_TEXT_UPDATED, StringUpdater(opt_name, parent)); } +void Preferences::SetOption(const char *name, wxAny value) { + pending_changes[name] = value; + if (IsEnabled()) applyButton->Enable(true); +} void Preferences::OnOK(wxCommandEvent &event) { + OnApply(event); EndModal(0); } void Preferences::OnApply(wxCommandEvent &event) { + for (std::map::iterator cur = pending_changes.begin(); cur != pending_changes.end(); ++cur) { + agi::OptionValue *opt = OPT_SET(cur->first); + switch (opt->GetType()) { + case agi::OptionValue::Type_Bool: + opt->SetBool(cur->second.As()); + break; + case agi::OptionValue::Type_Colour: + opt->SetColour(cur->second.As()); + break; + case agi::OptionValue::Type_Double: + opt->SetDouble(cur->second.As()); + break; + case agi::OptionValue::Type_Int: + opt->SetInt(cur->second.As()); + break; + case agi::OptionValue::Type_String: + opt->SetString(cur->second.As()); + break; + default: + throw PreferenceNotSupported("Unsupported type"); + } + } + pending_changes.clear(); + applyButton->Enable(false); + config::opt->Flush(); } @@ -194,21 +264,21 @@ Preferences::Preferences(wxWindow *parent): wxDialog(parent, -1, _("Preferences" // SetIcon(BitmapToIcon(GETIMAGE(options_button_24))); book = new wxTreebook(this, -1, wxDefaultPosition, wxDefaultSize); - general = new General(book); - subtitles = new Subtitles(book); - audio = new Audio(book); - video = new Video(book); - interface_ = new Interface(book); - interface_colours = new Interface_Colours(book); - interface_hotkeys = new Interface_Hotkeys(book); - paths = new Paths(book); - file_associations = new File_Associations(book); - backup = new Backup(book); - automation = new Automation(book); - advanced = new Advanced(book); - advanced_interface = new Advanced_Interface(book); - advanced_audio = new Advanced_Audio(book); - advanced_video = new Advanced_Video(book); + new General(book, this); + new Subtitles(book, this); + new Audio(book, this); + new Video(book, this); + new Interface(book, this); + new Interface_Colours(book, this); + new Interface_Hotkeys(book, this); + new Paths(book, this); + new File_Associations(book, this); + new Backup(book, this); + new Automation(book, this); + new Advanced(book, this); + new Advanced_Interface(book, this); + new Advanced_Audio(book, this); + new Advanced_Video(book, this); book->Fit(); @@ -219,7 +289,7 @@ Preferences::Preferences(wxWindow *parent): wxDialog(parent, -1, _("Preferences" wxStdDialogButtonSizer *stdButtonSizer = new wxStdDialogButtonSizer(); stdButtonSizer->AddButton(new wxButton(this,wxID_OK)); stdButtonSizer->AddButton(new wxButton(this,wxID_CANCEL)); - stdButtonSizer->AddButton(new wxButton(this,wxID_APPLY)); + stdButtonSizer->AddButton(applyButton = new wxButton(this,wxID_APPLY)); stdButtonSizer->Realize(); wxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL); wxButton *defaultButton = new wxButton(this,2342,_("Restore Defaults")); @@ -237,16 +307,14 @@ Preferences::Preferences(wxWindow *parent): wxDialog(parent, -1, _("Preferences" this->SetMaxSize(wxSize(-1, 500)); CenterOnParent(); - - + applyButton->Enable(false); } Preferences::~Preferences() { } - BEGIN_EVENT_TABLE(Preferences, wxDialog) - EVT_BUTTON(wxID_OK, Preferences::OnOK) - EVT_BUTTON(wxID_CANCEL, Preferences::OnCancel) - EVT_BUTTON(wxID_APPLY, Preferences::OnApply) + EVT_BUTTON(wxID_OK, Preferences::OnOK) + EVT_BUTTON(wxID_CANCEL, Preferences::OnCancel) + EVT_BUTTON(wxID_APPLY, Preferences::OnApply) END_EVENT_TABLE() diff --git a/aegisub/src/preferences_base.h b/aegisub/src/preferences_base.h index 98a89a3a6..b985394f2 100644 --- a/aegisub/src/preferences_base.h +++ b/aegisub/src/preferences_base.h @@ -19,6 +19,10 @@ /// @see preferences_base.cpp /// @ingroup configuration_ui +#include "browse_button.h" + +class Preferences; + class OptionPage: public wxScrolled { public: enum Style { @@ -28,8 +32,9 @@ public: }; wxSizer *sizer; + Preferences *parent; - OptionPage(wxTreebook *book, wxString name, int style = PAGE_DEFAULT); + OptionPage(wxTreebook *book, Preferences *parent, wxString name, int style = PAGE_DEFAULT); ~OptionPage(); wxFlexGridSizer* PageSizer(wxString name); @@ -39,10 +44,10 @@ public: void OptionBrowse(wxFlexGridSizer *&flex, const wxString &name, BrowseType browse_type, const char *opt_name); }; -#define CLASS_PAGE(name) \ - class name: public OptionPage { \ - public: \ - name(wxTreebook *book); \ +#define CLASS_PAGE(name) \ + class name: public OptionPage { \ + public: \ + name(wxTreebook *book, Preferences *parent); \ }; CLASS_PAGE(General)