diff options
| author | Carl Hetherington <cth@carlh.net> | 2024-11-23 23:53:12 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-09-28 19:49:26 +0200 |
| commit | f3275bba73347eef03bbe6f7982e8ca25f2aced6 (patch) | |
| tree | 872667cdb63a4e3372b5cd5235d82c5b868fac3b /src | |
| parent | eda4ed548e51ab1c231205ec141dac3dd6be2ac4 (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.cc | 36 | ||||
| -rw-r--r-- | src/lib/config.h | 6 | ||||
| -rw-r--r-- | src/tools/dcpomatic.cc | 4 | ||||
| -rw-r--r-- | src/wx/hints_dialog.cc | 14 | ||||
| -rw-r--r-- | src/wx/hints_dialog.h | 5 | ||||
| -rw-r--r-- | src/wx/text_view.cc | 29 | ||||
| -rw-r--r-- | src/wx/text_view.h | 4 | ||||
| -rw-r--r-- | src/wx/window_metrics.cc | 85 | ||||
| -rw-r--r-- | src/wx/window_metrics.h | 26 |
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; }; |
