Add a dialog manager for modeless dialogs so that they don't have to all be stuffed into the context

Originally committed to SVN as r6553.
This commit is contained in:
Thomas Goyne 2012-03-09 00:23:41 +00:00
parent 41f2f67042
commit 36548b93b1
15 changed files with 169 additions and 90 deletions

View file

@ -733,6 +733,10 @@
RelativePath="..\..\src\colorspace.h"
>
</File>
<File
RelativePath="..\..\src\dialog_manager.h"
>
</File>
<File
RelativePath="..\..\src\factory_manager.h"
>

View file

@ -51,6 +51,8 @@
#include "../audio_controller.h"
#include "../dialog_about.h"
#include "../dialog_detached_video.h"
#include "../dialog_manager.h"
#include "../dialog_log.h"
#include "../dialog_version_check.h"
#include "../frame_main.h"
@ -112,7 +114,7 @@ struct app_display_full : public Command {
}
bool Validate(const agi::Context *c) {
return c->audioController->IsAudioOpen() && c->videoController->IsLoaded() && !c->detachedVideo;
return c->audioController->IsAudioOpen() && c->videoController->IsLoaded() && !c->dialog->Get<DialogDetachedVideo>();
}
bool IsActive(const agi::Context *) {
@ -152,7 +154,7 @@ struct app_display_video_subs : public Command {
}
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded() && !c->detachedVideo;
return c->videoController->IsLoaded() && !c->dialog->Get<DialogDetachedVideo>();
}
bool IsActive(const agi::Context *) {
@ -210,7 +212,7 @@ struct app_log : public Command {
STR_HELP("View the event log")
void operator()(agi::Context *c) {
(new LogWindow(c->parent))->Show(1);
c->dialog->Show<LogWindow>(c);
}
};

View file

@ -46,6 +46,7 @@
#include "../main.h"
#include "../include/aegisub/context.h"
#include "../dialog_automation.h"
#include "../dialog_manager.h"
#include "../auto4_base.h"
#include "../video_context.h"
#include "../frame_main.h"
@ -87,14 +88,7 @@ struct open_manager : public Command {
STR_HELP("Open automation manager")
void operator()(agi::Context *c) {
if (c->automationManager) {
c->automationManager->Show();
c->automationManager->SetFocus();
}
else {
c->automationManager = new DialogAutomation(c);
c->automationManager->Show();
}
c->dialog->Show<DialogAutomation>(c);
}
};

View file

@ -48,6 +48,7 @@
#include "../ass_file.h"
#include "../audio_controller.h"
#include "../audio_timing.h"
#include "../dialog_manager.h"
#include "../dialog_shift_times.h"
#include "../include/aegisub/context.h"
#include "../main.h"
@ -155,8 +156,7 @@ struct time_shift : public Command {
STR_HELP("Shift subtitles by time or frames")
void operator()(agi::Context *c) {
c->videoController->Stop();
(new DialogShiftTimes(c))->Show();
c->dialog->Show<DialogShiftTimes>(c);
}
};

View file

@ -51,6 +51,7 @@
#include "../video_context.h" // tool_font_collector
#include "../compat.h"
#include "../dialog_export.h"
#include "../dialog_manager.h"
#include "../dialog_resample.h"
#include "../dialog_selection.h"
#include "../dialog_styling_assistant.h"
@ -114,7 +115,7 @@ struct tool_line_select : public Command {
STR_HELP("Selects lines based on defined criteria")
void operator()(agi::Context *c) {
(new DialogSelection(c))->Show();
c->dialog->Show<DialogSelection>(c);
}
};
@ -141,9 +142,7 @@ struct tool_style_assistant : public Command {
STR_HELP("Open styling assistant")
void operator()(agi::Context *c) {
c->videoController->Stop();
if (!c->stylingAssistant) c->stylingAssistant = new DialogStyling(c);
c->stylingAssistant->Show(true);
c->dialog->Show<DialogStyling>(c);
}
};
@ -151,7 +150,7 @@ struct tool_styling_assistant_validator : public Command {
CMD_TYPE(COMMAND_VALIDATE)
bool Validate(const agi::Context *c) {
return !!c->stylingAssistant;
return !!c->dialog->Get<DialogStyling>();
}
};
@ -163,7 +162,7 @@ struct tool_styling_assistant_commit : public tool_styling_assistant_validator {
STR_HELP("Commit changes and move to the next line")
void operator()(agi::Context *c) {
c->stylingAssistant->Commit(true);
c->dialog->Get<DialogStyling>()->Commit(true);
}
};
@ -175,7 +174,7 @@ struct tool_styling_assistant_preview : public tool_styling_assistant_validator
STR_HELP("Commit changes and stay on the current line")
void operator()(agi::Context *c) {
c->stylingAssistant->Commit(false);
c->dialog->Get<DialogStyling>()->Commit(false);
}
};
@ -187,14 +186,7 @@ struct tool_style_manager : public Command {
STR_HELP("Open styles manager")
void operator()(agi::Context *c) {
if (c->stylesManager) {
c->stylesManager->Show();
c->stylesManager->SetFocus();
}
else {
c->stylesManager = new DialogStyleManager(c);
c->stylesManager->Show();
}
c->dialog->Show<DialogStyleManager>(c);
}
};
@ -235,13 +227,9 @@ struct tool_translation_assistant : public Command {
void operator()(agi::Context *c) {
c->videoController->Stop();
try {
DialogTranslation d(c);
c->translationAssistant = &d;
d.ShowModal();
c->translationAssistant = 0;
c->dialog->ShowModal<DialogTranslation>(c);
}
catch (agi::Exception const& e) {
c->translationAssistant = 0;
wxMessageBox(lagi_wxString(e.GetChainedMessage()));
}
}
@ -251,7 +239,7 @@ struct tool_translation_assistant_validator : public Command {
CMD_TYPE(COMMAND_VALIDATE)
bool Validate(const agi::Context *c) {
return !!c->translationAssistant;
return !!c->dialog->Get<DialogTranslation>();
}
};
@ -263,7 +251,7 @@ struct tool_translation_assistant_commit : public tool_translation_assistant_val
STR_HELP("Commit changes and move to the next line")
void operator()(agi::Context *c) {
c->translationAssistant->Commit(true);
c->dialog->Get<DialogTranslation>()->Commit(true);
}
};
@ -275,7 +263,7 @@ struct tool_translation_assistant_preview : public tool_translation_assistant_va
STR_HELP("Commit changes and stay on the current line")
void operator()(agi::Context *c) {
c->translationAssistant->Commit(false);
c->dialog->Get<DialogTranslation>()->Commit(false);
}
};
@ -287,7 +275,7 @@ struct tool_translation_assistant_next : public tool_translation_assistant_valid
STR_HELP("Move to the next line without committing changes")
void operator()(agi::Context *c) {
c->translationAssistant->NextBlock();
c->dialog->Get<DialogTranslation>()->NextBlock();
}
};
@ -299,7 +287,7 @@ struct tool_translation_assistant_prev : public tool_translation_assistant_valid
STR_HELP("Move to the previous line without committing changes")
void operator()(agi::Context *c) {
c->translationAssistant->PrevBlock();
c->dialog->Get<DialogTranslation>()->PrevBlock();
}
};
}
@ -312,7 +300,7 @@ struct tool_translation_assistant_insert : public tool_translation_assistant_val
STR_HELP("Insert the untranslated text")
void operator()(agi::Context *c) {
c->translationAssistant->InsertOriginal();
c->dialog->Get<DialogTranslation>()->InsertOriginal();
}
};
/// @}

View file

@ -53,6 +53,7 @@
#include "../include/aegisub/context.h"
#include "../dialog_detached_video.h"
#include "../dialog_dummy_video.h"
#include "../dialog_manager.h"
#include "../dialog_jumpto.h"
#include "../dialog_video_details.h"
#include "../selection_controller.h"
@ -80,7 +81,7 @@ struct validator_video_loaded : public Command {
struct validator_video_attached : public Command {
CMD_TYPE(COMMAND_VALIDATE)
bool Validate(const agi::Context *c) {
return c->videoController->IsLoaded() && !c->detachedVideo;
return c->videoController->IsLoaded() && !c->dialog->Get<DialogDetachedVideo>();
}
};
@ -256,16 +257,14 @@ struct video_detach : public validator_video_loaded {
CMD_TYPE(COMMAND_VALIDATE | COMMAND_TOGGLE)
bool IsActive(const agi::Context *c) {
return !!c->detachedVideo;
return !!c->dialog->Get<DialogDetachedVideo>();
}
void operator()(agi::Context *c) {
if (!c->detachedVideo) {
c->detachedVideo = new DialogDetachedVideo(c, c->videoDisplay->GetClientSize());
}
else {
c->detachedVideo->Close();
}
if (DialogDetachedVideo *d = c->dialog->Get<DialogDetachedVideo>())
d->Close();
else
c->dialog->Show<DialogDetachedVideo>(c);
}
};

View file

@ -53,7 +53,7 @@
#include "video_context.h"
#include "video_display.h"
DialogDetachedVideo::DialogDetachedVideo(agi::Context *context, const wxSize &initialDisplaySize)
DialogDetachedVideo::DialogDetachedVideo(agi::Context *context)
: wxDialog(context->parent, -1, "Detached Video", wxDefaultPosition, wxSize(400,300), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxWANTS_CHARS)
, context(context)
, old_display(context->videoDisplay)
@ -67,7 +67,7 @@ DialogDetachedVideo::DialogDetachedVideo(agi::Context *context, const wxSize &in
// Video area;
VideoBox *videoBox = new VideoBox(this, true, context);
context->videoDisplay->SetMinClientSize(initialDisplaySize);
context->videoDisplay->SetMinClientSize(old_display->GetClientSize());
videoBox->Layout();
// Set sizer
@ -95,19 +95,16 @@ DialogDetachedVideo::DialogDetachedVideo(agi::Context *context, const wxSize &in
Bind(wxEVT_CLOSE_WINDOW, &DialogDetachedVideo::OnClose, this);
Bind(wxEVT_ICONIZE, &DialogDetachedVideo::OnMinimize, this);
Bind(wxEVT_KEY_DOWN, &DialogDetachedVideo::OnKeyDown, this);
Show();
}
DialogDetachedVideo::~DialogDetachedVideo() { }
void DialogDetachedVideo::OnClose(wxCloseEvent&) {
context->detachedVideo = 0;
void DialogDetachedVideo::OnClose(wxCloseEvent &evt) {
evt.Skip();
context->videoDisplay = old_display;
context->videoSlider = old_slider;
OPT_SET("Video/Detached/Enabled")->SetBool(false);
context->videoController->Reload();
Destroy();
}
void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) {
@ -126,10 +123,7 @@ void DialogDetachedVideo::OnKeyDown(wxKeyEvent &evt) {
void DialogDetachedVideo::OnVideoOpen() {
if (!context->videoController->IsLoaded()) {
context->detachedVideo = 0;
context->videoDisplay = old_display;
context->videoSlider = old_slider;
context->videoController->Reload();
Destroy();
Close();
OPT_SET("Video/Detached/Enabled")->SetBool(true);
}
}

View file

@ -67,8 +67,7 @@ class DialogDetachedVideo : public wxDialog {
public:
/// @brief Constructor
/// @param context Project context
/// @param initialDisplaySize Initial size of the window
DialogDetachedVideo(agi::Context *context, const wxSize &initialDisplaySize);
DialogDetachedVideo(agi::Context *context);
/// Destructor
~DialogDetachedVideo();
};

View file

@ -52,6 +52,8 @@
#include <libaegisub/log.h>
#include "include/aegisub/context.h"
class EmitLog : public agi::log::Emitter {
wxTextCtrl *text_ctrl;
public:
@ -91,8 +93,8 @@ public:
}
};
LogWindow::LogWindow(wxWindow *parent)
: wxDialog (parent, -1, _("Log window"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER)
LogWindow::LogWindow(agi::Context *c)
: wxDialog(c->parent, -1, _("Log window"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER)
{
wxTextCtrl *text_ctrl = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxSize(700,300), wxTE_MULTILINE|wxTE_READONLY);
text_ctrl->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, wxFont(8, wxMODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)));
@ -103,8 +105,6 @@ LogWindow::LogWindow(wxWindow *parent)
SetSizerAndFit(sizer);
agi::log::log->Subscribe(emit_log = new EmitLog(text_ctrl));
Bind(wxEVT_CLOSE_WINDOW, std::tr1::bind(&wxDialog::Destroy, this));
}
LogWindow::~LogWindow() {

View file

@ -38,14 +38,17 @@
#include <wx/dialog.h>
#endif
namespace agi { namespace log { class Emitter; } }
namespace agi {
namespace log { class Emitter; }
struct Context;
}
class LogWindow: public wxDialog {
agi::log::Emitter *emit_log;
public:
/// @brief Constructor
/// @param parent Parent frame.
LogWindow(wxWindow *parent);
/// @param c Project context
LogWindow(agi::Context *c);
~LogWindow();
};

View file

@ -0,0 +1,109 @@
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @file dialog_manager.h
/// @brief Manager for dialogs
/// @ingroup utility
#ifndef AGI_PRE
#include <map>
#include <typeinfo>
#endif
/// @brief A manager for dialogs
///
/// DialogManager keeps track of modal and modeless dialogs which have been
/// created, so that commands can be send to the appropriate places and so that
/// the same dialog can't be opened twice at once.
class DialogManager {
/// Comparer for pointers to std::type_info
struct type_info_lt {
bool operator()(const std::type_info *lft, const std::type_info *rgt) const {
return !!lft->before(*rgt);
}
};
typedef std::map<const std::type_info *, wxDialog *, type_info_lt> DialogMap;
/// Dialogs which currently exist
DialogMap created_dialogs;
/// Close handler which deletes and unregisters closed modeless dialogs
void OnClose(wxCloseEvent &evt) {
evt.Skip();
wxDialog *dialog = static_cast<wxDialog*>(evt.GetEventObject());
dialog->Destroy();
for (DialogMap::iterator it = created_dialogs.begin(); it != created_dialogs.end(); ++it) {
if (it->second == dialog) {
created_dialogs.erase(it);
return;
}
}
}
public:
/// Show a modeless dialog of the given type, creating it if needed
/// @tparam DialogType Type of dialog to show
template<class DialogType>
void Show(agi::Context *c) {
DialogMap::iterator it = created_dialogs.find(&typeid(DialogType));
if (it != created_dialogs.end()) {
it->second->Show();
it->second->SetFocus();
}
else {
wxDialog *d = new DialogType(c);
created_dialogs[&typeid(DialogType)] = d;
d->Bind(wxEVT_CLOSE_WINDOW, &DialogManager::OnClose, this);
d->Show();
}
}
/// Show a modal dialog of the given type, creating it if needed
/// @tparam DialogType Type of dialog to show
template<class DialogType>
void ShowModal(agi::Context *c) {
DialogType diag(c);
created_dialogs[&typeid(DialogType)] = &diag;
try {
diag.ShowModal();
}
catch (...) {
created_dialogs.erase(&typeid(DialogType));
throw;
}
created_dialogs.erase(&typeid(DialogType));
}
/// Get the dialog of the given type
/// @tparam DialogType Type of dialog to get
/// @return A pointer to a DialogType or NULL if no dialog of the given type has been created
template<class DialogType>
DialogType *Get() const {
DialogMap::const_iterator it = created_dialogs.find(&typeid(DialogType));
return it != created_dialogs.end() ? static_cast<DialogType*>(it->second) : 0;
}
~DialogManager() {
for (DialogMap::iterator it = created_dialogs.begin(); it != created_dialogs.end(); ++it) {
it->second->Unbind(wxEVT_CLOSE_WINDOW, &DialogManager::OnClose, this);
it->second->Destroy();
}
created_dialogs.clear();
}
};

View file

@ -145,7 +145,6 @@ DialogStyling::DialogStyling(agi::Context *context)
c->selectionController->AddSelectionListener(this);
Bind(wxEVT_ACTIVATE, &DialogStyling::OnActivate, this);
Bind(wxEVT_KEY_DOWN, &DialogStyling::OnKeyDown, this);
Bind(wxEVT_SHOW, &DialogStyling::OnShow, this);
style_name->Bind(wxEVT_KEY_DOWN, &DialogStyling::OnKeyDown, this);
play_video->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayVideoButton, this);
play_audio->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayAudioButton, this);
@ -157,17 +156,9 @@ DialogStyling::DialogStyling(agi::Context *context)
}
DialogStyling::~DialogStyling () {
c->stylingAssistant = 0;
c->selectionController->RemoveSelectionListener(this);
}
void DialogStyling::OnShow(wxShowEvent &evt) {
if (evt.IsShown())
evt.Skip();
else
Destroy();
}
void DialogStyling::OnActiveLineChanged(AssDialogue *new_line) {
if (!new_line) return;
active_line = new_line;

View file

@ -59,7 +59,6 @@ class DialogStyling : public wxDialog, public SelectionListener<AssDialogue> {
void OnListDoubleClicked(wxCommandEvent &evt);
void OnPlayAudioButton(wxCommandEvent &evt);
void OnPlayVideoButton(wxCommandEvent &evt);
void OnShow(wxShowEvent &evt);
void OnStyleBoxModified(wxCommandEvent &evt);
void OnActiveLineChanged(AssDialogue *);

View file

@ -60,6 +60,8 @@
#include "auto4_base.h"
#include "compat.h"
#include "command/command.h"
#include "dialog_detached_video.h"
#include "dialog_manager.h"
#include "dialog_search_replace.h"
#include "dialog_version_check.h"
#include "help_button.h"
@ -181,6 +183,7 @@ FrameMain::FrameMain (wxArrayString args)
#endif
StartupLog("Create views and inner main window controls");
context->dialog = new DialogManager;
InitContents();
OPT_SUB("Video/Detached/Enabled", &FrameMain::OnVideoDetach, this, agi::signal::_1);
@ -220,6 +223,8 @@ FrameMain::FrameMain (wxArrayString args)
}
FrameMain::~FrameMain () {
delete context->dialog;
// Because the subs grid is the selection controller, it needs to stay
// alive significantly longer than the other child controls
SubsGrid->Reparent(0);
@ -363,7 +368,7 @@ void FrameMain::SetDisplayMode(int video, int audio) {
bool sv = false, sa = false;
if (video == -1) sv = showVideo;
else if (video) sv = context->videoController->IsLoaded() && !context->detachedVideo;
else if (video) sv = context->videoController->IsLoaded() && !context->dialog->Get<DialogDetachedVideo>();
if (audio == -1) sa = showAudio;
else if (audio) sa = context->audioController->IsAudioOpen();
@ -427,7 +432,7 @@ void FrameMain::OnVideoOpen() {
SetDisplayMode(1,-1);
if (OPT_GET("Video/Detached/Enabled")->GetBool() && !context->detachedVideo)
if (OPT_GET("Video/Detached/Enabled")->GetBool() && !context->dialog->Get<DialogDetachedVideo>())
cmd::call("video/detach", context.get());
Thaw();
}

View file

@ -3,11 +3,7 @@ class AudioBox;
class AudioController;
class AssDialogue;
class AudioKaraoke;
class DialogAutomation;
class DialogDetachedVideo;
class DialogStyling;
class DialogStyleManager;
class DialogTranslation;
class DialogManager;
template<class T> class SelectionController;
class SubsTextEditCtrl;
class SubtitlesGrid;
@ -36,11 +32,7 @@ struct Context {
// Views (i.e. things that should eventually not be here at all)
AudioBox *audioBox;
AudioKaraoke *karaoke;
DialogAutomation *automationManager;
DialogDetachedVideo *detachedVideo;
DialogStyling *stylingAssistant;
DialogStyleManager *stylesManager;
DialogTranslation *translationAssistant;
DialogManager *dialog;
SubsTextEditCtrl *editBox;
SubtitlesGrid *subsGrid;
VideoDisplay *videoDisplay;