1 // Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
2 //
3 // Permission to use, copy, modify, and distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 //
15 // Aegisub Project http://www.aegisub.org/
16
17 /// @file persist_location.cpp
18 /// @see persist_location.h
19 /// @ingroup utility
20
21 #include "persist_location.h"
22
23 #include "options.h"
24
25 #include <wx/dialog.h>
26 #include <wx/display.h>
27
PersistLocation(wxDialog * dialog,std::string options_prefix,bool size_too)28 PersistLocation::PersistLocation(wxDialog *dialog, std::string options_prefix, bool size_too)
29 : x_opt(OPT_SET(options_prefix + "/Last/X"))
30 , y_opt(OPT_SET(options_prefix + "/Last/Y"))
31 , w_opt(size_too ? OPT_SET(options_prefix + "/Last/Width") : nullptr)
32 , h_opt(size_too ? OPT_SET(options_prefix + "/Last/Height") : nullptr)
33 , maximize_opt(OPT_SET(options_prefix + "/Maximized"))
34 , dialog(dialog)
35 {
36 int x = x_opt->GetInt();
37 int y = y_opt->GetInt();
38 if (x == -1 && y == -1)
39 dialog->CenterOnParent();
40 else {
41 // First move to the saved place so that it ends up on the right monitor
42 dialog->Move(x, y);
43
44 if (size_too && w_opt->GetInt() > 0 && h_opt->GetInt() > 0)
45 dialog->SetSize(w_opt->GetInt(), h_opt->GetInt());
46
47 int display_index = wxDisplay::GetFromWindow(dialog);
48
49 // If it's moved offscreen center on the parent and try again
50 if (display_index == wxNOT_FOUND) {
51 dialog->CenterOnParent();
52 display_index = wxDisplay::GetFromWindow(dialog);
53 }
54
55 // If it's still offscreen just give up
56 if (display_index == wxNOT_FOUND) return;
57
58 wxRect display_area = wxDisplay(display_index).GetClientArea();
59 wxSize dialog_size = dialog->GetSize();
60
61 // Ensure that the top-left corner is onscreen
62 if (x < display_area.x) x = display_area.x;
63 if (y < display_area.y) y = display_area.y;
64
65 // Ensure that the bottom-right corner is onscreen as long as doing so
66 // wouldn't force the top-left corner offscreen
67 if (x + dialog_size.x > display_area.GetRight())
68 x = std::max(display_area.x, display_area.GetRight() - dialog_size.x);
69 if (y + dialog_size.y > display_area.GetBottom())
70 y = std::max(display_area.y, display_area.GetBottom() - dialog_size.y);
71
72 dialog->Move(x, y);
73 }
74
75 dialog->Bind(wxEVT_MOVE, &PersistLocation::OnMove, this);
76
77 dialog->Bind(wxEVT_SIZE, &PersistLocation::OnSize, this);
78 if ((dialog->GetWindowStyle() & wxMAXIMIZE_BOX) && maximize_opt->GetBool())
79 dialog->Maximize();
80 }
81
OnMove(wxMoveEvent & e)82 void PersistLocation::OnMove(wxMoveEvent &e) {
83 wxPoint pos = dialog->GetPosition();
84 x_opt->SetInt(pos.x);
85 y_opt->SetInt(pos.y);
86 e.Skip();
87 }
88
OnSize(wxSizeEvent & e)89 void PersistLocation::OnSize(wxSizeEvent &e) {
90 maximize_opt->SetBool(dialog->IsMaximized());
91 if (w_opt) {
92 w_opt->SetInt(dialog->GetSize().GetWidth());
93 h_opt->SetInt(dialog->GetSize().GetHeight());
94 }
95 e.Skip();
96 }
97