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:
parent
3c18ed542c
commit
f906c3dcd2
|
@ -893,6 +893,14 @@
|
||||||
RelativePath="..\..\src\mythes.hxx"
|
RelativePath="..\..\src\mythes.hxx"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\persist_location.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\persist_location.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\spline.cpp"
|
RelativePath="..\..\src\spline.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -198,6 +198,7 @@ SRC += \
|
||||||
md5.c \
|
md5.c \
|
||||||
mkv_wrap.cpp \
|
mkv_wrap.cpp \
|
||||||
mythes.cxx \
|
mythes.cxx \
|
||||||
|
persist_location.cpp \
|
||||||
plugin_manager.cpp \
|
plugin_manager.cpp \
|
||||||
preferences.cpp \
|
preferences.cpp \
|
||||||
preferences_base.cpp \
|
preferences_base.cpp \
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "dialog_detached_video.h"
|
#include "dialog_detached_video.h"
|
||||||
#include "frame_main.h"
|
#include "frame_main.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "persist_location.h"
|
||||||
#include "video_box.h"
|
#include "video_box.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
#include "video_display.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)
|
: wxDialog(parent,-1,_T("Detached Video"),wxDefaultPosition,wxSize(400,300),wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxWANTS_CHARS)
|
||||||
, parent(parent)
|
, 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
|
// Set obscure stuff
|
||||||
SetExtraStyle((GetExtraStyle() & ~wxWS_EX_BLOCK_EVENTS) | wxWS_EX_PROCESS_UI_UPDATES);
|
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));
|
videoBox->SetMinSize(wxSize(1,1));
|
||||||
SetMinSize(wxSize(1,1));
|
SetMinSize(wxSize(1,1));
|
||||||
|
|
||||||
|
persist.reset(new PersistLocation(this, "Video/Detached"));
|
||||||
|
|
||||||
int display_index = wxDisplay::GetFromWindow(this);
|
int display_index = wxDisplay::GetFromWindow(this);
|
||||||
if (display_index == wxNOT_FOUND)
|
// Ensure that the dialog is no larger than the screen
|
||||||
{
|
if (display_index != wxNOT_FOUND) {
|
||||||
int caption_size = wxSystemSettings::GetMetric(wxSYS_CAPTION_Y, this);
|
|
||||||
Move(parent->GetPosition() + wxPoint(caption_size, caption_size));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxRect bounds_rect = GetRect();
|
wxRect bounds_rect = GetRect();
|
||||||
wxRect disp_rect = wxDisplay(display_index).GetClientArea();
|
wxRect disp_rect = wxDisplay(display_index).GetClientArea();
|
||||||
|
SetSize(std::min(bounds_rect.width, disp_rect.width), std::min(bounds_rect.height, disp_rect.height));
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
parent->SetDisplayMode(0, -1);
|
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);
|
OPT_SET("Video/Detached/Enabled")->SetBool(true);
|
||||||
|
|
||||||
// Copy the main accelerator table to this dialog
|
// Copy the main accelerator table to this dialog
|
||||||
|
@ -132,13 +105,11 @@ DialogDetachedVideo::DialogDetachedVideo(FrameMain *parent, agi::Context *contex
|
||||||
|
|
||||||
/// @brief Destructor
|
/// @brief Destructor
|
||||||
DialogDetachedVideo::~DialogDetachedVideo() {
|
DialogDetachedVideo::~DialogDetachedVideo() {
|
||||||
OPT_SET("Video/Detached/Maximized")->SetBool(IsMaximized());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event table
|
// Event table
|
||||||
BEGIN_EVENT_TABLE(DialogDetachedVideo,wxDialog)
|
BEGIN_EVENT_TABLE(DialogDetachedVideo,wxDialog)
|
||||||
EVT_CLOSE(DialogDetachedVideo::OnClose)
|
EVT_CLOSE(DialogDetachedVideo::OnClose)
|
||||||
EVT_MOVE(DialogDetachedVideo::OnMove)
|
|
||||||
EVT_ICONIZE(DialogDetachedVideo::OnMinimize)
|
EVT_ICONIZE(DialogDetachedVideo::OnMinimize)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
@ -151,14 +122,6 @@ void DialogDetachedVideo::OnClose(wxCloseEvent &WXUNUSED(event)) {
|
||||||
parent->SetDisplayMode(1,-1);
|
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
|
/// @brief Minimize event handler
|
||||||
/// @param event
|
/// @param event
|
||||||
void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) {
|
void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) {
|
||||||
|
|
|
@ -40,8 +40,11 @@
|
||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <libaegisub/scoped_ptr.h>
|
||||||
|
|
||||||
namespace agi { struct Context; }
|
namespace agi { struct Context; }
|
||||||
class FrameMain;
|
class FrameMain;
|
||||||
|
class PersistLocation;
|
||||||
class VideoBox;
|
class VideoBox;
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
|
@ -50,7 +53,7 @@ class VideoBox;
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class DialogDetachedVideo : public wxDialog {
|
class DialogDetachedVideo : public wxDialog {
|
||||||
private:
|
agi::scoped_ptr<PersistLocation> persist;
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
VideoBox *videoBox;
|
VideoBox *videoBox;
|
||||||
|
@ -59,7 +62,6 @@ private:
|
||||||
FrameMain *parent;
|
FrameMain *parent;
|
||||||
|
|
||||||
void OnClose(wxCloseEvent &event);
|
void OnClose(wxCloseEvent &event);
|
||||||
void OnMove(wxMoveEvent &event);
|
|
||||||
void OnMinimize(wxIconizeEvent &event);
|
void OnMinimize(wxIconizeEvent &event);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
88
aegisub/src/persist_location.cpp
Normal file
88
aegisub/src/persist_location.cpp
Normal 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());
|
||||||
|
}
|
46
aegisub/src/persist_location.h
Normal file
46
aegisub/src/persist_location.h
Normal 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);
|
||||||
|
};
|
Loading…
Reference in a new issue