summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2024-11-23 23:53:12 +0100
committerCarl Hetherington <cth@carlh.net>2025-09-28 19:49:26 +0200
commitf3275bba73347eef03bbe6f7982e8ca25f2aced6 (patch)
tree872667cdb63a4e3372b5cd5235d82c5b868fac3b /src
parenteda4ed548e51ab1c231205ec141dac3dd6be2ac4 (diff)
Save window metrics in the config file (#1575).
Perhaps these should be in a separate GUI file, like how it's done for Films, but I can't really see a big advantage (and there already GUI-only details in there). In this commit we also save the hints dialog size/position and start it a bit larger (#2892).
Diffstat (limited to 'src')
-rw-r--r--src/lib/config.cc36
-rw-r--r--src/lib/config.h6
-rw-r--r--src/tools/dcpomatic.cc4
-rw-r--r--src/wx/hints_dialog.cc14
-rw-r--r--src/wx/hints_dialog.h5
-rw-r--r--src/wx/text_view.cc29
-rw-r--r--src/wx/text_view.h4
-rw-r--r--src/wx/window_metrics.cc85
-rw-r--r--src/wx/window_metrics.h26
9 files changed, 170 insertions, 39 deletions
diff --git a/src/lib/config.cc b/src/lib/config.cc
index af97c7af7..a69f953bf 100644
--- a/src/lib/config.cc
+++ b/src/lib/config.cc
@@ -683,6 +683,13 @@ try
#endif
_export.read(f.optional_node_child("Export"));
+
+ for (auto metrics: f.node_children("WindowMetrics")) {
+ _window_metrics[metrics->string_attribute("name")] = {
+ { metrics->number_attribute<int>("x"), metrics->number_attribute<int>("y") },
+ { metrics->number_attribute<int>("width"), metrics->number_attribute<int>("height") }
+ };
+ }
}
catch (...) {
if (have_existing("config.xml")) {
@@ -1171,6 +1178,15 @@ Config::write_config() const
_export.write(cxml::add_child(root, "Export"));
+ for (auto metrics: _window_metrics) {
+ auto m = cxml::add_child(root, "WindowMetrics");
+ m->set_attribute("name", metrics.first);
+ m->set_attribute("x", fmt::to_string(metrics.second.first.x));
+ m->set_attribute("y", fmt::to_string(metrics.second.first.y));
+ m->set_attribute("width", fmt::to_string(metrics.second.second.width));
+ m->set_attribute("height", fmt::to_string(metrics.second.second.height));
+ }
+
auto target = config_write_file();
try {
@@ -1756,6 +1772,26 @@ Config::cinemas_file() const
}
+optional<std::pair<Position<int>, dcp::Size>>
+Config::window_metrics(string name) const
+{
+ auto iter = _window_metrics.find(name);
+ if (iter != _window_metrics.end()) {
+ return iter->second;
+ }
+
+ return {};
+}
+
+
+void
+Config::set_window_metrics(string name, Position<int> position, dcp::Size size)
+{
+ _window_metrics[name] = { position, size };
+ changed(OTHER);
+}
+
+
#ifdef DCPOMATIC_GROK
Config::Grok::Grok()
diff --git a/src/lib/config.h b/src/lib/config.h
index d8ff70db8..88f8eda1a 100644
--- a/src/lib/config.h
+++ b/src/lib/config.h
@@ -39,6 +39,7 @@
#include <dcp/language_tag.h>
#include <boost/signals2.hpp>
#include <boost/filesystem.hpp>
+#include <unordered_map>
#include <vector>
@@ -697,6 +698,8 @@ public:
return _layout_for_short_screen;
}
+ boost::optional<std::pair<Position<int>, dcp::Size>> window_metrics(std::string name) const;
+
/* SET (mostly) */
void set_master_encoding_threads(int n) {
@@ -1273,6 +1276,7 @@ public:
maybe_set(_layout_for_short_screen, layout);
}
+ void set_window_metrics(std::string name, Position<int> position, dcp::Size size);
void changed(Property p = OTHER);
boost::signals2::signal<void (Property)> Changed;
@@ -1529,6 +1533,8 @@ private:
ExportConfig _export;
+ std::unordered_map<std::string, std::pair<Position<int>, dcp::Size>> _window_metrics;
+
static int const _current_version;
/** Singleton instance, or 0 */
diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc
index 8f8cf3df0..7da0f43f7 100644
--- a/src/tools/dcpomatic.cc
+++ b/src/tools/dcpomatic.cc
@@ -839,6 +839,7 @@ private:
if (Config::instance()->show_hints_before_make_dcp()) {
HintsDialog hints(this, _film, false);
+ hints.show();
if (hints.ShowModal() == wxID_CANCEL) {
return;
}
@@ -939,6 +940,7 @@ private:
if (Config::instance()->show_hints_before_make_dcp()) {
HintsDialog hints(this, _film, false);
+ hints.show();
if (hints.ShowModal() == wxID_CANCEL) {
return;
}
@@ -1120,7 +1122,7 @@ private:
_hints_dialog = new HintsDialog (this, _film, true);
}
- _hints_dialog->Show ();
+ _hints_dialog->show();
}
void tools_encoding_servers ()
diff --git a/src/wx/hints_dialog.cc b/src/wx/hints_dialog.cc
index e02c07518..47d96a70e 100644
--- a/src/wx/hints_dialog.cc
+++ b/src/wx/hints_dialog.cc
@@ -46,10 +46,11 @@ using namespace boost::placeholders;
HintsDialog::HintsDialog(wxWindow* parent, std::weak_ptr<Film> film, bool ok)
- : wxDialog(parent, wxID_ANY, _("Hints"))
+ : wxDialog(parent, wxID_ANY, _("Hints"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, _film(film)
, _hints(0)
, _finished(false)
+ , _metrics(std::string{"hints"}, { 800, 600 }, this)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
@@ -58,7 +59,7 @@ HintsDialog::HintsDialog(wxWindow* parent, std::weak_ptr<Film> film, bool ok)
_gauge_message = new StaticText(this, {});
sizer->Add(_gauge_message, 0, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
- _text = new wxRichTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(400, 300), wxRE_READONLY);
+ _text = new wxRichTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxRE_READONLY);
sizer->Add(_text, 1, wxEXPAND | wxALL, 6);
if (!ok) {
@@ -95,6 +96,8 @@ HintsDialog::HintsDialog(wxWindow* parent, std::weak_ptr<Film> film, bool ok)
}
film_change(ChangeType::DONE);
+
+ _metrics.bind();
}
@@ -189,3 +192,10 @@ HintsDialog::progress(string m)
{
_gauge_message->SetLabel(std_to_wx(m));
}
+
+void
+HintsDialog::show()
+{
+ _metrics.show();
+}
+
diff --git a/src/wx/hints_dialog.h b/src/wx/hints_dialog.h
index 44420405a..e10e80717 100644
--- a/src/wx/hints_dialog.h
+++ b/src/wx/hints_dialog.h
@@ -19,6 +19,7 @@
*/
+#include "window_metrics.h"
#include "lib/change_signaller.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
@@ -36,6 +37,8 @@ class HintsDialog : public wxDialog
public:
HintsDialog(wxWindow* parent, std::weak_ptr<Film>, bool ok);
+ void show();
+
private:
void film_change(ChangeType);
void film_content_change(ChangeType type);
@@ -60,4 +63,6 @@ private:
boost::signals2::scoped_connection _hints_progress_connection;
boost::signals2::scoped_connection _hints_pulse_connection;
boost::signals2::scoped_connection _hints_finished_connection;
+
+ WindowMetrics _metrics;
};
diff --git a/src/wx/text_view.cc b/src/wx/text_view.cc
index bde7b09e9..fd647f050 100644
--- a/src/wx/text_view.cc
+++ b/src/wx/text_view.cc
@@ -42,17 +42,15 @@ using namespace boost::placeholders;
#endif
-WindowMetrics TextView::_metrics;
-
-
TextView::TextView (
wxWindow* parent, shared_ptr<Film> film, shared_ptr<Content> content, shared_ptr<TextContent> text, shared_ptr<Decoder> decoder, FilmViewer& viewer
)
- : wxDialog(parent, wxID_ANY, _("Captions"), _metrics.position, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
+ : wxDialog(parent, wxID_ANY, _("Captions"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, _content (content)
, _film_viewer (viewer)
+ , _metrics(std::string{"text"}, { 800, 600 }, this)
{
- _list = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, _metrics.size, wxLC_REPORT | wxLC_SINGLE_SEL);
+ _list = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
{
wxListItem ip;
@@ -108,31 +106,14 @@ TextView::TextView (
while (!decoder->pass ()) {}
SetSizerAndFit (sizer);
- _list->Bind(wxEVT_SIZE, boost::bind(&TextView::list_sized, this, _1));
- Bind(wxEVT_MOVE, boost::bind(&TextView::moved, this, _1));
-}
-
-
-void
-TextView::list_sized(wxSizeEvent& ev)
-{
- _metrics.size = ev.GetSize();
- ev.Skip();
-}
-
-
-void
-TextView::moved(wxMoveEvent& ev)
-{
- _metrics.position = ClientToScreen({0, 0});
- ev.Skip();
+ _metrics.bind();
}
void
TextView::show()
{
- _metrics.show(this);
+ _metrics.show();
}
void
diff --git a/src/wx/text_view.h b/src/wx/text_view.h
index ee7650673..dbb601fc4 100644
--- a/src/wx/text_view.h
+++ b/src/wx/text_view.h
@@ -55,8 +55,6 @@ private:
void data_start (ContentStringText cts);
void data_stop (dcpomatic::ContentTime time);
void subtitle_selected (wxListEvent &);
- void moved(wxMoveEvent& ev);
- void list_sized(wxSizeEvent& ev);
wxListCtrl* _list;
int _subs;
@@ -66,7 +64,7 @@ private:
std::weak_ptr<Content> _content;
FilmViewer& _film_viewer;
- static WindowMetrics _metrics;
+ WindowMetrics _metrics;
};
diff --git a/src/wx/window_metrics.cc b/src/wx/window_metrics.cc
index 4b0c6ce66..81ad7f2ea 100644
--- a/src/wx/window_metrics.cc
+++ b/src/wx/window_metrics.cc
@@ -20,26 +20,99 @@
#include "window_metrics.h"
+#include "lib/config.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include <wx/app.h>
#include <wx/wx.h>
LIBDCP_ENABLE_WARNINGS
+#include <boost/bind/bind.hpp>
+
+
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
+
+
+WindowMetrics::WindowMetrics(std::string name, wxSize default_size, wxWindow* window)
+ : _name(name)
+ , _window(window)
+{
+ if (auto metrics = Config::instance()->window_metrics(name)) {
+ _position = { metrics->first.x, metrics->first.y };
+ _size = { metrics->second.width, metrics->second.height };
+ } else {
+ _position = wxDefaultPosition;
+ _size = default_size;
+ }
+}
void
-WindowMetrics::show(wxWindow* window) const
+WindowMetrics::bind()
+{
+ _window->Bind(wxEVT_SIZE, boost::bind(&WindowMetrics::sized, this, _1));
+ _window->Bind(wxEVT_MOVE, boost::bind(&WindowMetrics::moved, this, _1));
+}
+
+
+void
+WindowMetrics::show() const
{
#ifdef DCPOMATIC_LINUX
- auto const position_before = position;
+ auto const position_before = _position;
+
+ _window->SetSize(_size);
+ _window->Show();
+
+ wxTheApp->CallAfter([this, position_before] {
+ _window->SetPosition(position_before);
+ });
+#else
+ _window->SetSize(_size);
+ _window->SetPosition(_position);
+ _window->Show();
#endif
+}
+
+
+void
+WindowMetrics::write_to_config() const
+{
+ Config::instance()->set_window_metrics(_name, { _position.x, _position.y }, { _size.GetWidth(), _size.GetHeight() });
+}
+
+
+void
+WindowMetrics::sized(wxSizeEvent& ev)
+{
+ auto top_level_window = dynamic_cast<wxTopLevelWindow*>(_window);
+ if (top_level_window && top_level_window->IsMaximized()) {
+ /* On Windows the maximised state looks a little different to the
+ * window just being as big as it can be; set wxDefaultSize here
+ * so that we call Maximize in show().
+ */
+ _size = wxDefaultSize;
+ } else {
+ _size = ev.GetSize();
+ }
+ write_to_config();
+ ev.Skip();
+}
- window->Show();
+void
+WindowMetrics::moved(wxMoveEvent& ev)
+{
#ifdef DCPOMATIC_LINUX
- wxTheApp->CallAfter([window, position_before] {
- window->SetPosition(position_before);
- });
+ _position = _window->ClientToScreen({0, 0});
+#else
+ int x;
+ int y;
+ _window->GetScreenPosition(&x, &y);
+ _position = { x, y };
#endif
+ write_to_config();
+ ev.Skip();
}
diff --git a/src/wx/window_metrics.h b/src/wx/window_metrics.h
index 9a1e10a66..5d99dbe0a 100644
--- a/src/wx/window_metrics.h
+++ b/src/wx/window_metrics.h
@@ -29,16 +29,36 @@ LIBDCP_DISABLE_WARNINGS
LIBDCP_ENABLE_WARNINGS
+class wxMoveEvent;
+class wxSizeEvent;
class wxWindow;
class WindowMetrics
{
public:
- void show(wxWindow* window) const;
+ WindowMetrics(std::string name, wxSize default_size, wxWindow* window);
- wxPoint position = wxDefaultPosition;
- wxSize size = wxDefaultSize;
+ wxPoint position() const {
+ return _position;
+ }
+
+ wxSize size() const {
+ return _size;
+ }
+
+ void bind();
+ void show() const;
+
+private:
+ void moved(wxMoveEvent& event);
+ void sized(wxSizeEvent& event);
+ void write_to_config() const;
+
+ std::string _name;
+ wxWindow* _window;
+ wxPoint _position;
+ wxSize _size;
};