diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index e7f47d619..de884c928 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -687,7 +687,6 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { if (dlg == GetActiveLine()) { SetActiveLine(GetDialogue(GetFirstSelRow())); } - wxGetApp().frame->UpdateToolbar(); lastRow = row; return; } @@ -697,7 +696,6 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { SetActiveLine(dlg); if (dclick) context->videoController->JumpToTime(dlg->Start.GetMS()); SelectRow(row,false); - wxGetApp().frame->UpdateToolbar(); lastRow = row; return; } @@ -725,8 +723,6 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { newsel.insert(GetDialogue(i)); } SetSelectedSet(newsel); - - wxGetApp().frame->UpdateToolbar(); } return; } diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 695c3df8c..f5eafba4c 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -85,7 +85,6 @@ #include "video_slider.h" enum { - ID_TOOLBAR_ZOOM_DROPDOWN = 11001, ID_APP_TIMER_AUTOSAVE = 12001, ID_APP_TIMER_STATUSCLEAR = 12002, ID_MENU_AUTOMATION_MACRO = 13006, @@ -250,11 +249,8 @@ void FrameMain::cmd_call(wxCommandEvent& event) { void FrameMain::InitToolbar () { wxSystemOptions::SetOption("msw.remap", 0); - Toolbar = CreateToolBar(wxTB_FLAT | wxTB_HORIZONTAL,-1,"Toolbar"); - - toolbar::toolbar->GetToolbar("main", Toolbar); - - Toolbar->Realize(); + toolbar::AttachToolbar(this, "main", context.get()); + GetToolBar()->Realize(); } void FrameMain::InitMenu() { @@ -320,30 +316,6 @@ void FrameMain::InitContents() { StartupLog("Leaving InitContents"); } -static void validate_toolbar(wxToolBar *toolbar, const char *command, const agi::Context *context) { - toolbar->FindById(cmd::id(command))->Enable(cmd::get(command)->Validate(context)); -} - -void FrameMain::UpdateToolbar() { - wxToolBar* toolbar = GetToolBar(); - const agi::Context *c = context.get(); - - validate_toolbar(toolbar, "video/jump", c); - validate_toolbar(toolbar, "video/zoom/in", c); - validate_toolbar(toolbar, "video/zoom/out", c); - - validate_toolbar(toolbar, "video/jump/start", c); - validate_toolbar(toolbar, "video/jump/end", c); - - validate_toolbar(toolbar, "time/snap/start_video", c); - validate_toolbar(toolbar, "time/snap/end_video", c); - - validate_toolbar(toolbar, "subtitle/select/visible", c); - validate_toolbar(toolbar, "time/snap/scene", c); - validate_toolbar(toolbar, "time/snap/frame", c); - toolbar->Realize(); -} - void FrameMain::LoadSubtitles(wxString filename,wxString charset) { if (context->ass->loaded) { if (TryToCloseSubs() == wxCANCEL) return; @@ -427,7 +399,6 @@ void FrameMain::SetDisplayMode(int video, int audio) { TopSizer->Show(videoBox, showVideo, true); ToolsSizer->Show(audioSash, showAudio, true); - UpdateToolbar(); MainSizer->CalcMin(); MainSizer->RecalcSizes(); MainSizer->Layout(); @@ -535,7 +506,6 @@ void FrameMain::DetachVideo(bool detach) { context->detachedVideo = 0; SetDisplayMode(1,-1); } - UpdateToolbar(); } void FrameMain::StatusTimeout(wxString text,int ms) { diff --git a/aegisub/src/frame_main.h b/aegisub/src/frame_main.h index 11834e4b9..c90e60be9 100644 --- a/aegisub/src/frame_main.h +++ b/aegisub/src/frame_main.h @@ -107,7 +107,6 @@ private: bool blockVideoLoad; wxPanel *Panel; - wxToolBar *Toolbar; ///< The main toolbar std::vector activeMacroItems; int AddMacroMenuItems(wxMenu *menu, const std::vector ¯os); @@ -160,7 +159,6 @@ public: FrameMain(wxArrayString args); ~FrameMain(); - void UpdateToolbar(); bool HasASSDraw(); DECLARE_EVENT_TABLE() diff --git a/aegisub/src/include/aegisub/toolbar.h b/aegisub/src/include/aegisub/toolbar.h index 653831ec1..74175906f 100644 --- a/aegisub/src/include/aegisub/toolbar.h +++ b/aegisub/src/include/aegisub/toolbar.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010, Amar Takhar +// Copyright (c) 2011, Thomas Goyne // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -19,42 +19,16 @@ /// @ingroup menu toolbar #ifndef AGI_PRE -#include - -#include +#include #endif -#include - -namespace json { class Array; } +namespace agi { struct Context; } +class wxFrame; namespace toolbar { -DEFINE_BASE_EXCEPTION_NOINNER(ToolbarError, agi::Exception) -DEFINE_SIMPLE_EXCEPTION_NOINNER(ToolbarJsonValueArray, ToolbarError, "toolbar/value/array") -DEFINE_SIMPLE_EXCEPTION_NOINNER(ToolbarInvalidName, ToolbarError, "toolbar/invalid") - -class Toolbar; -extern Toolbar *toolbar; - -class Toolbar { -public: - Toolbar(); - ~Toolbar(); - void GetToolbar(std::string name, wxToolBar *toolbar); - -private: - typedef std::map TbMap; - typedef std::pair TbPair; - - TbMap map; - - enum ToolbarTypes { - Standard = 1, - Spacer = 100 - }; - - void BuildToolbar(wxToolBar *toolbar, const json::Array& array); - -}; - -} // namespace toolbar + /// Add the named toolbar to a window + /// @param frame Frame to attach the toolbar to + /// @param name Name of the toolbar + /// @param context Project context + void AttachToolbar(wxFrame *frame, std::string const& name, agi::Context *context); +} diff --git a/aegisub/src/libresrc/default_config.json b/aegisub/src/libresrc/default_config.json index 83695fece..1557cc2f5 100644 --- a/aegisub/src/libresrc/default_config.json +++ b/aegisub/src/libresrc/default_config.json @@ -14,7 +14,8 @@ "Maximized" : false, "Nonstandard Milisecond Times" : false, "Save Charset" : "UTF-8", - "Tips" : false + "Tips" : false, + "Toolbar Icon Size" : 16 }, diff --git a/aegisub/src/libresrc/default_toolbar.json b/aegisub/src/libresrc/default_toolbar.json index 02300a512..2f46b6846 100644 --- a/aegisub/src/libresrc/default_toolbar.json +++ b/aegisub/src/libresrc/default_toolbar.json @@ -1,140 +1,39 @@ { - "main" : [ - { - "type" : 1, - "command" : "subtitle/new" - }, - { - "type" : 1, - "command" : "subtitle/open" - }, - { - "type" : 1, - "command" : "subtitle/save" - }, - { - "type" : 100 - }, - { - "type" : 1, - "command" : "video/jump" - }, - { - "type" : 1, - "command" : "video/zoom/in" - }, - { - "type" : 1, - "command" : "video/zoom/out" - }, - { - "type" : 1, - "command" : "video/jump/start" - }, - { - "type" : 1, - "command" : "video/jump/end" - }, - { - "type" : 100 - }, - { - "type" : 1, - "command" : "time/snap/start_video" - }, - { - "type" : 1, - "command" : "time/snap/end_video" - }, - { - "type" : 1, - "command" : "subtitle/select/visible" - }, - { - "type" : 1, - "command" : "time/snap/scene" - }, - { - "type" : 1, - "command" : "time/snap/frame" - }, - { - "type" : 100 - }, - { - "type" : 1, - "command" : "tool/style/manager" - }, - { - "type" : 1, - "command" : "subtitle/properties" - }, - { - "type" : 1, - "command" : "subtitle/attachment" - }, - { - "type" : 1, - "command" : "tool/font_collector" - }, - { - "type" : 100 - }, - { - "type" : 1, - "command" : "am/manager" - }, - { - "type" : 100 - }, - { - "type" : 1, - "command" : "tool/assdraw" - }, - { - "type" : 100 - }, - { - "type" : 1, - "command" : "time/shift" - }, - { - "type" : 1, - "command" : "tool/style/assistant" - }, - { - "type" : 1, - "command" : "tool/translation_assistant" - }, - { - "type" : 1, - "command" : "tool/resampleres" - }, - { - "type" : 1, - "command" : "tool/time/postprocess" - }, - { - "type" : 1, - "command" : "tool/time/kanji" - }, - { - "type" : 1, - "command" : "subtitle/spellcheck" - }, - { - "type" : 100 - }, - { - "type" : 1, - "command" : "app/options" - }, - { - "type" : 1, - "command" : "grid/tag/cycle_hiding" - }, - { - "type" : 100 - } - ] + "main" : [ + "subtitle/new", + "subtitle/open", + "subtitle/save", + "", + "video/jump", + "video/zoom/in", + "video/zoom/out", + "video/jump/start", + "video/jump/end", + "", + "time/snap/start_video", + "time/snap/end_video", + "subtitle/select/visible", + "time/snap/scene", + "time/snap/frame", + "", + "tool/style/manager", + "subtitle/properties", + "subtitle/attachment", + "tool/font_collector", + "", + "am/manager", + "", + "tool/assdraw", + "", + "time/shift", + "tool/style/assistant", + "tool/translation_assistant", + "tool/resampleres", + "tool/time/postprocess", + "tool/time/kanji", + "subtitle/spellcheck", + "", + "app/options", + "grid/tag/cycle_hiding" + ] } diff --git a/aegisub/src/main.cpp b/aegisub/src/main.cpp index ba7c278cb..ad5508016 100644 --- a/aegisub/src/main.cpp +++ b/aegisub/src/main.cpp @@ -198,9 +198,6 @@ bool AegisubApp::OnInit() { // Generate menus. menu::menu = new menu::Menu(); - // Generate toolbars. - toolbar::toolbar = new toolbar::Toolbar(); - // Install assertion handler // wxSetAssertHandler(wxAssertHandler); diff --git a/aegisub/src/preferences.cpp b/aegisub/src/preferences.cpp index b96ad4d3b..cc6e3aa9d 100644 --- a/aegisub/src/preferences.cpp +++ b/aegisub/src/preferences.cpp @@ -44,9 +44,6 @@ #include "include/aegisub/subtitles_provider.h" #include "video_provider_manager.h" -/// Define make all platform-specific options visible in a single view. -#define SHOW_ALL 1 - #include "preferences_base.h" /// General preferences page @@ -63,6 +60,9 @@ General::General(wxTreebook *book, Preferences *parent): OptionPage(book, parent wxFlexGridSizer *undo = PageSizer(_("Undo / Redo Settings")); OptionAdd(undo, _("Undo Levels"), "Limits/MRU"); + wxFlexGridSizer *toolbar = PageSizer(_("Toolbar Settings")); + OptionAdd(toolbar, _("Toolbar Icon Size"), "App/Toolbar Icon Size"); + SetSizerAndFit(sizer); } @@ -335,7 +335,7 @@ Advanced_Audio::Advanced_Audio(wxTreebook *book, Preferences *parent): OptionPag OptionAdd(spectrum, _("Cache memory max (MB)"), "Audio/Renderer/Spectrum/Memory Max", 2, 1024); -#if defined(WIN32) || defined(SHOW_ALL) +#if defined(WIN32) || defined(_DEBUG) wxFlexGridSizer *windows = PageSizer(_("Windows Specific")); const wxString adm_arr[3] = { _T("ConvertToMono"), _T("GetLeftChannel"), _T("GetRightChannel") }; wxArrayString adm_choice(3, adm_arr); @@ -357,7 +357,7 @@ Advanced_Video::Advanced_Video(wxTreebook *book, Preferences *parent): OptionPag OptionChoice(expert, _("Subtitle provider"), sp_choice, "Subtitle/Provider"); -#if defined(WIN32) || defined(SHOW_ALL) +#if defined(WIN32) || defined(_DEBUG) wxFlexGridSizer *windows = PageSizer(_("Windows Specific")); OptionAdd(windows, _("Allow pre-2.56a Avisynth"), "Provider/Avisynth/Allow Ancient"); CellSkip(windows); diff --git a/aegisub/src/toolbar.cpp b/aegisub/src/toolbar.cpp index 73f298d0d..2224ddb51 100644 --- a/aegisub/src/toolbar.cpp +++ b/aegisub/src/toolbar.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2010, Amar Takhar +// Copyright (c) 2011, Thomas Goyne // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -20,81 +20,132 @@ #include "config.h" -#ifndef AGI_PRE -#include - -#include -#endif - -#include -#include -#include - +#include "command/command.h" +#include "include/aegisub/context.h" #include "include/aegisub/toolbar.h" #include "libresrc/libresrc.h" -#include "command/command.h" +#include "main.h" +#ifndef AGI_PRE +#include + +#include +#endif + +#include +#include + +namespace { + json::Object const& get_root() { + static json::Object root; + if (root.Empty()) { + root = agi::json_util::parse(new std::istringstream(GET_DEFAULT_CONFIG(default_toolbar))); + } + return root; + } + + class Toolbar : public wxToolBar { + /// Window ID of first toolbar control + static const int TOOL_ID_BASE = 5000; + + /// Toolbar name in config file + std::string name; + /// Project context + agi::Context *context; + /// Commands for each of the buttons + std::vector commands; + + /// Listener for icon size change signal + agi::signal::Connection icon_size_slot; + + /// Enable/disable the toolbar buttons + void OnIdle(wxIdleEvent &) { + for (size_t i = 0; i < commands.size(); ++i) { + if (commands[i]->Type() & cmd::COMMAND_VALIDATE) { + EnableTool(TOOL_ID_BASE + i, commands[i]->Validate(context)); + } + if (commands[i]->Type() & cmd::COMMAND_TOGGLE) { + ToggleTool(TOOL_ID_BASE + i, commands[i]->IsActive(context)); + } + } + } + + /// Toolbar button click handler + void OnClick(wxCommandEvent &evt) { + (*commands[evt.GetId() - TOOL_ID_BASE])(context); + } + + /// Clear the toolbar and recreate it with the new icon size + void OnIconSizeChanged() { + Unbind(wxEVT_IDLE, &Toolbar::OnIdle, this); + ClearTools(); + commands.clear(); + Populate(); + } + + /// Populate the toolbar with buttons + void Populate() { + json::Object const& root = get_root(); + json::Object::const_iterator it = root.Find(name); + if (it == root.End()) { + // Toolbar names are all hardcoded so this should never happen + throw agi::InternalError("Toolbar named " + name + " not found.", 0); + } + + int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt(); + + json::Array arr = it->element; + commands.reserve(arr.Size()); + bool needs_onidle = false; + + for (json::Array::const_iterator it = arr.Begin(); it != arr.End(); ++it) { + json::String const& command_name = *it; + + if (command_name.Value().empty()) { + AddSeparator(); + } + else { + cmd::Command *command = cmd::get(command_name.Value()); + + wxBitmap *bitmap = command->Icon(icon_size); + // this hack is needed because ??? + wxBitmap icon = bitmap->GetSubBitmap(wxRect(0, 0, bitmap->GetWidth(), bitmap->GetHeight())); + + int flags = command->Type(); + wxItemKind kind = + flags & cmd::COMMAND_RADIO ? wxITEM_RADIO : + flags & cmd::COMMAND_TOGGLE ? wxITEM_CHECK : + wxITEM_NORMAL; + + AddTool(TOOL_ID_BASE + commands.size(), command->StrMenu(), icon, command->StrHelp(), kind); + + commands.push_back(command); + needs_onidle = needs_onidle || flags != cmd::COMMAND_NORMAL; + } + } + + // Only bind the update function if there are actually any dynamic tools + if (needs_onidle) { + Bind(wxEVT_IDLE, &Toolbar::OnIdle, this); + } + + Realize(); + } + public: + Toolbar(wxWindow *parent, std::string const& name, agi::Context *c) + : wxToolBar(parent, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_HORIZONTAL) + , name(name) + , context(c) + , icon_size_slot(OPT_SUB("App/Toolbar Icon Size", &Toolbar::OnIconSizeChanged, this)) + { + Populate(); + Bind(wxEVT_COMMAND_TOOL_CLICKED, &Toolbar::OnClick, this); + } + }; +} namespace toolbar { - -Toolbar *toolbar; - -Toolbar::Toolbar() {} - -Toolbar::~Toolbar() {} - - -void Toolbar::GetToolbar(std::string name, wxToolBar *toolbar) { - -// TbMap::iterator index; - -// if ((index = map.find(name)) != map.end()) { -// return index->second; -// } - -// throw ToolbarInvalidName("Unknown index"); - - LOG_D("toolbar/init") << "Generating " << name << " toolbar."; - - std::istringstream *stream = new std::istringstream(GET_DEFAULT_CONFIG(default_toolbar)); - json::UnknownElement toolbar_root = agi::json_util::parse(stream); - - const json::Array& arr = toolbar_root[name]; - - BuildToolbar(toolbar, arr); -// map.insert(TbPair(name, toolbar)); + void AttachToolbar(wxFrame *frame, std::string const& name, agi::Context *c) { + frame->SetToolBar(new Toolbar(frame, name, c)); + } } - - -void Toolbar::BuildToolbar(wxToolBar *toolbar, const json::Array& array) { - - for (json::Array::const_iterator index(array.Begin()); index != array.End(); index++) { - - const json::Object& obj = *index; - int type = static_cast(obj["type"]).Value(); - if (type == Toolbar::Spacer) { - toolbar->AddSeparator(); - continue; - } - - const json::String& command = obj["command"]; - cmd::Command *cmd = cmd::get(command.Value()); - - // this is dumb. - wxBitmap *bitmap = cmd->Icon(24); - wxBitmap icon = bitmap->GetSubBitmap(wxRect(0, 0, bitmap->GetWidth(), bitmap->GetHeight())); - - switch (type) { - case Toolbar::Standard: { - toolbar->AddTool(cmd::id(command.Value()), cmd->StrMenu(), icon, cmd->StrHelp(), wxITEM_NORMAL); - } - break; - } - - } // for index - -} - -} // namespace toolbar - - diff --git a/aegisub/src/video_display.cpp b/aegisub/src/video_display.cpp index 4b054df25..05e0e6a62 100644 --- a/aegisub/src/video_display.cpp +++ b/aegisub/src/video_display.cpp @@ -143,10 +143,8 @@ VideoDisplay::VideoDisplay( { assert(box); - if (zoomBox) { - zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.)); - zoomBox->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &VideoDisplay::SetZoomFromBox, this); - } + zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.)); + zoomBox->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &VideoDisplay::SetZoomFromBox, this); box->Bind(wxEVT_COMMAND_TOOL_CLICKED, &VideoDisplay::OnMode, this, Video_Mode_Standard, Video_Mode_Vector_Clip); con->videoController->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); @@ -170,9 +168,6 @@ VideoDisplay::VideoDisplay( VideoDisplay::~VideoDisplay () { con->videoController->Unbind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); - if (zoomBox) { - zoomBox->Unbind(wxEVT_COMMAND_COMBOBOX_SELECTED, &VideoDisplay::SetZoomFromBox, this); - } } bool VideoDisplay::InitContext() { @@ -477,11 +472,10 @@ void VideoDisplay::OnKeyDown(wxKeyEvent &event) { void VideoDisplay::SetZoom(double value) { zoomValue = std::max(value, .125); - if (zoomBox) zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.)); + zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.)); UpdateSize(); } void VideoDisplay::SetZoomFromBox(wxCommandEvent &) { - if (!zoomBox) return; wxString strValue = zoomBox->GetValue(); strValue.EndsWith(L"%", &strValue); double value;