Factor DialogDetachedVideo's position persistance logic into a seperate class so that it can be used for other dialogs.

Originally committed to SVN as r5517.
This commit is contained in:
Thomas Goyne 2011-07-27 05:36:02 +00:00
parent 3c18ed542c
commit f906c3dcd2
6 changed files with 153 additions and 45 deletions

View File

@ -893,6 +893,14 @@
RelativePath="..\..\src\mythes.hxx"
>
</File>
<File
RelativePath="..\..\src\persist_location.cpp"
>
</File>
<File
RelativePath="..\..\src\persist_location.h"
>
</File>
<File
RelativePath="..\..\src\spline.cpp"
>

View File

@ -198,6 +198,7 @@ SRC += \
md5.c \
mkv_wrap.cpp \
mythes.cxx \
persist_location.cpp \
plugin_manager.cpp \
preferences.cpp \
preferences_base.cpp \

View File

@ -46,6 +46,7 @@
#include "dialog_detached_video.h"
#include "frame_main.h"
#include "main.h"
#include "persist_location.h"
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
@ -58,12 +59,6 @@ DialogDetachedVideo::DialogDetachedVideo(FrameMain *parent, agi::Context *contex
: wxDialog(parent,-1,_T("Detached Video"),wxDefaultPosition,wxSize(400,300),wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxWANTS_CHARS)
, parent(parent)
{
// Set up window
int x = OPT_GET("Video/Detached/Last/X")->GetInt();
int y = OPT_GET("Video/Detached/Last/Y")->GetInt();
if (x != -1 && y != -1) SetPosition(wxPoint(x,y));
if (OPT_GET("Video/Detached/Maximized")->GetBool()) Maximize();
// Set obscure stuff
SetExtraStyle((GetExtraStyle() & ~wxWS_EX_BLOCK_EVENTS) | wxWS_EX_PROCESS_UI_UPDATES);
@ -89,40 +84,18 @@ DialogDetachedVideo::DialogDetachedVideo(FrameMain *parent, agi::Context *contex
videoBox->SetMinSize(wxSize(1,1));
SetMinSize(wxSize(1,1));
persist.reset(new PersistLocation(this, "Video/Detached"));
int display_index = wxDisplay::GetFromWindow(this);
if (display_index == wxNOT_FOUND)
{
int caption_size = wxSystemSettings::GetMetric(wxSYS_CAPTION_Y, this);
Move(parent->GetPosition() + wxPoint(caption_size, caption_size));
}
else
{
// Ensure that the dialog is no larger than the screen
if (display_index != wxNOT_FOUND) {
wxRect bounds_rect = GetRect();
wxRect disp_rect = wxDisplay(display_index).GetClientArea();
// Ensure our x/y position is past the top left of the display
int new_x = std::max(bounds_rect.x, disp_rect.x);
int new_y = std::max(bounds_rect.y, disp_rect.y);
// Pick the smallest size of display and window.
// By doing this, we're guaranteed to get a width/height that fits on the display
// and won't have to adjust width/height any further.
int new_w = std::min(bounds_rect.width, disp_rect.width);
int new_h = std::min(bounds_rect.height, disp_rect.height);
// Check if bottom right corner is outside display and move inside then
if (new_x + new_w > disp_rect.x + disp_rect.width)
new_x = disp_rect.x + disp_rect.width - new_w;
if (new_y + new_h > disp_rect.y + disp_rect.height)
new_y = disp_rect.y + disp_rect.height - new_h;
SetSize(new_x, new_y, new_w, new_h, wxSIZE_ALLOW_MINUS_ONE);
SetSize(std::min(bounds_rect.width, disp_rect.width), std::min(bounds_rect.height, disp_rect.height));
}
// Update
parent->SetDisplayMode(0, -1);
GetPosition(&x, &y);
OPT_SET("Video/Detached/Last/X")->SetInt(x);
OPT_SET("Video/Detached/Last/Y")->SetInt(y);
OPT_SET("Video/Detached/Enabled")->SetBool(true);
// Copy the main accelerator table to this dialog
@ -132,13 +105,11 @@ DialogDetachedVideo::DialogDetachedVideo(FrameMain *parent, agi::Context *contex
/// @brief Destructor
DialogDetachedVideo::~DialogDetachedVideo() {
OPT_SET("Video/Detached/Maximized")->SetBool(IsMaximized());
}
// Event table
BEGIN_EVENT_TABLE(DialogDetachedVideo,wxDialog)
EVT_CLOSE(DialogDetachedVideo::OnClose)
EVT_MOVE(DialogDetachedVideo::OnMove)
EVT_ICONIZE(DialogDetachedVideo::OnMinimize)
END_EVENT_TABLE()
@ -151,14 +122,6 @@ void DialogDetachedVideo::OnClose(wxCloseEvent &WXUNUSED(event)) {
parent->SetDisplayMode(1,-1);
}
/// @brief Move window
/// @param event
void DialogDetachedVideo::OnMove(wxMoveEvent &event) {
wxPoint pos = event.GetPosition();
OPT_SET("Video/Detached/Last/X")->SetInt(pos.x);
OPT_SET("Video/Detached/Last/Y")->SetInt(pos.y);
}
/// @brief Minimize event handler
/// @param event
void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) {

View File

@ -40,8 +40,11 @@
#include <wx/dialog.h>
#endif
#include <libaegisub/scoped_ptr.h>
namespace agi { struct Context; }
class FrameMain;
class PersistLocation;
class VideoBox;
/// DOCME
@ -50,7 +53,7 @@ class VideoBox;
///
/// DOCME
class DialogDetachedVideo : public wxDialog {
private:
agi::scoped_ptr<PersistLocation> persist;
/// DOCME
VideoBox *videoBox;
@ -59,7 +62,6 @@ private:
FrameMain *parent;
void OnClose(wxCloseEvent &event);
void OnMove(wxMoveEvent &event);
void OnMinimize(wxIconizeEvent &event);
public:

View File

@ -0,0 +1,88 @@
// Copyright (c) 2011, 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.
//
// Aegisub Project http://www.aegisub.org/
//
// $Id$
/// @file persist_location.cpp
/// @see persist_location.h
/// @ingroup utility
#include "config.h"
#include "persist_location.h"
#include "main.h"
#ifndef AGI_PRE
#include <wx/dialog.h>
#endif
PersistLocation::PersistLocation(wxDialog *dialog, std::string options_prefix)
: x_opt(OPT_SET(options_prefix + "/Last/X"))
, y_opt(OPT_SET(options_prefix + "/Last/Y"))
, maximize_opt(OPT_SET(options_prefix + "/Maximized"))
{
dialog->Bind(wxEVT_MOVE, &PersistLocation::OnMove, this);
dialog->Bind(wxEVT_ICONIZE, &PersistLocation::OnMinimize, this);
if (maximize_opt->GetBool()) dialog->Maximize();
int x = x_opt->GetInt();
int y = y_opt->GetInt();
if (x == -1 && y == -1)
dialog->CenterOnParent();
else {
// First move to the saved place so that it ends up on the right monitor
dialog->Move(x, y);
int display_index = wxDisplay::GetFromWindow(dialog);
// If it's moved offscreen center on the parent and try again
if (display_index == wxNOT_FOUND) {
dialog->CenterOnParent();
display_index = wxDisplay::GetFromWindow(dialog);
}
// If it's still offscreen just give up
if (display_index == wxNOT_FOUND) return;
wxRect display_area = wxDisplay(display_index).GetClientArea();
wxSize dialog_size = dialog->GetSize();
// Ensure that the top-left corner is onscreen
if (x < display_area.x) x = display_area.x;
if (y < display_area.y) y = display_area.y;
// Ensure that the bottom-right corner is onscreen as long as doing so
// wouldn't force the top-left corner offscreen
if (x + dialog_size.x > display_area.GetRight())
x = std::max(display_area.x, display_area.GetRight() - dialog_size.x);
if (y + dialog_size.y > display_area.GetBottom())
y = std::max(display_area.y, display_area.GetBottom() - dialog_size.y);
dialog->Move(x, y);
}
}
void PersistLocation::OnMove(wxMoveEvent &evt) {
wxPoint pos = evt.GetPosition();
x_opt->SetInt(pos.x);
y_opt->SetInt(pos.y);
}
void PersistLocation::OnMinimize(wxIconizeEvent &evt) {
maximize_opt->SetBool(!evt.IsIconized());
}

View File

@ -0,0 +1,46 @@
// Copyright (c) 2011, 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.
//
// Aegisub Project http://www.aegisub.org/
//
// $Id$
/// @file persist_location.h
/// @see persist_location.cpp
/// @ingroup utility
namespace agi { class OptionValue; }
class wxDialog;
/// @class PersistLocation
/// @brief Automatically save and restore the location of a dialog
///
/// This class saves the location of the supplied dialog to the preferences
/// file with the given prefix, then restores the saved position when it is
/// recreated in the future. This class should always have lifetime equal to
/// the associated dialog, as it does not unbind its events.
class PersistLocation {
agi::OptionValue *x_opt;
agi::OptionValue *y_opt;
agi::OptionValue *maximize_opt;
void OnMove(wxMoveEvent &evt);
void OnMinimize(wxIconizeEvent &evt);
public:
/// Persist the location of a dialog
/// @param dialog The dialog to save and restore the position of
/// @param options_prefix Prefix for the options names to store the location
PersistLocation(wxDialog *dialog, std::string options_prefix);
};