From: Carl Hetherington Date: Thu, 14 Nov 2013 13:40:35 +0000 (+0000) Subject: Add ratio control to multi-select. X-Git-Tag: v2.0.48~1156 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=b1e4b53ed5b674bb3b65390eba4c04873a8b9ec7 Add ratio control to multi-select. --- diff --git a/src/wx/content_widget.h b/src/wx/content_widget.h index 07abc7cbd..30501c1a9 100644 --- a/src/wx/content_widget.h +++ b/src/wx/content_widget.h @@ -50,7 +50,8 @@ public: int property, boost::function model_getter, boost::function model_setter, - boost::function view_getter + boost::function view_to_model, + boost::function model_to_view ) : _wrapped (wrapped) , _sizer (0) @@ -58,7 +59,8 @@ public: , _property (property) , _model_getter (model_getter) , _model_setter (model_setter) - , _view_getter (view_getter) + , _view_to_model (view_to_model) + , _model_to_view (model_to_view) , _ignore_model_changes (false) { _button->SetToolTip (_("Click the button to set all selected content to the same value.")); @@ -66,12 +68,15 @@ public: _button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentWidget::button_clicked, this)); } - T* wrapped () const { + /** @return the widget that we are wrapping */ + T* wrapped () const + { return _wrapped; } typedef std::vector > List; + /** Set the content that this control is working on (i.e. the selected content) */ void set_content (List content) { for (typename std::list::iterator i = _connections.begin(); i != _connections.end(); ++i) { @@ -91,6 +96,7 @@ public: } } + /** Add this widget to a wxGridBagSizer */ void add (wxGridBagSizer* sizer, wxGBPosition position) { _sizer = sizer; @@ -98,6 +104,7 @@ public: _sizer->Add (_wrapped, _position); } + /** Update the view from the model */ void update_from_model () { if (_content.empty ()) { @@ -113,7 +120,7 @@ public: if (i == _content.end ()) { set_single (); - checked_set (_wrapped, v); + checked_set (_wrapped, _model_to_view (v)); } else { set_multiple (); } @@ -121,11 +128,11 @@ public: void view_changed () { + _ignore_model_changes = true; for (size_t i = 0; i < _content.size(); ++i) { - /* Only update our view on the last time round this loop */ - _ignore_model_changes = i < (_content.size() - 1); - boost::bind (_model_setter, _content[i].get(), static_cast (boost::bind (_view_getter, _wrapped)()))(); + boost::bind (_model_setter, _content[i].get(), _view_to_model (wx_get (_wrapped))) (); } + _ignore_model_changes = false; } private: @@ -179,29 +186,64 @@ private: int _property; boost::function _model_getter; boost::function _model_setter; - boost::function _view_getter; + boost::function _view_to_model; + boost::function _model_to_view; std::list _connections; bool _ignore_model_changes; }; +template +V caster (U x) +{ + return static_cast (x); +} + template class ContentSpinCtrl : public ContentWidget { public: - ContentSpinCtrl (wxWindow* parent, wxSpinCtrl* wrapped, int property, boost::function getter, boost::function setter) - : ContentWidget (parent, wrapped, property, getter, setter, boost::mem_fn (&wxSpinCtrl::GetValue)) + ContentSpinCtrl ( + wxWindow* parent, + wxSpinCtrl* wrapped, + int property, + boost::function getter, + boost::function setter + ) + : ContentWidget ( + parent, + wrapped, + property, + getter, setter, + &caster, + &caster + ) { wrapped->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ContentWidget::view_changed, this)); } - }; template class ContentChoice : public ContentWidget { public: - ContentChoice (wxWindow* parent, wxChoice* wrapped, int property, boost::function getter, boost::function setter) - : ContentWidget (parent, wrapped, property, getter, setter, boost::mem_fn (&wxChoice::GetSelection)) + ContentChoice ( + wxWindow* parent, + wxChoice* wrapped, + int property, + boost::function getter, + boost::function setter, + boost::function view_to_model, + boost::function model_to_view + ) + : ContentWidget ( + parent, + wrapped, + property, + getter, + setter, + view_to_model, + model_to_view + ) { wrapped->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ContentWidget::view_changed, this)); } diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index 9adc64641..5d841b0cc 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -41,6 +41,31 @@ using boost::dynamic_pointer_cast; using boost::bind; using boost::optional; +static Ratio const * +index_to_ratio (int n) +{ + assert (n >= 0); + + vector ratios = Ratio::all (); + if (n >= int (ratios.size ())) { + return 0; + } + + return ratios[n]; +} + +static int +ratio_to_index (Ratio const * r) +{ + vector ratios = Ratio::all (); + size_t i = 0; + while (i < ratios.size() && ratios[i] != r) { + ++i; + } + + return i; +} + VideoPanel::VideoPanel (FilmEditor* e) : FilmEditorPanel (e, _("Video")) { @@ -55,7 +80,9 @@ VideoPanel::VideoPanel (FilmEditor* e) new wxChoice (this, wxID_ANY), VideoContentProperty::VIDEO_FRAME_TYPE, boost::mem_fn (&VideoContent::video_frame_type), - boost::mem_fn (&VideoContent::set_video_frame_type) + boost::mem_fn (&VideoContent::set_video_frame_type), + &caster, + &caster ); _frame_type->add (grid, wxGBPosition (r, 1)); ++r; @@ -105,8 +132,16 @@ VideoPanel::VideoPanel (FilmEditor* e) ++r; add_label_to_grid_bag_sizer (grid, this, _("Scale to"), true, wxGBPosition (r, 0)); - _ratio = new wxChoice (this, wxID_ANY); - grid->Add (_ratio, wxGBPosition (r, 1)); + _ratio = new ContentChoice ( + this, + new wxChoice (this, wxID_ANY), + VideoContentProperty::VIDEO_RATIO, + boost::mem_fn (&VideoContent::ratio), + boost::mem_fn (&VideoContent::set_ratio), + &index_to_ratio, + &ratio_to_index + ); + _ratio->add (grid, wxGBPosition (r, 1)); ++r; { @@ -156,16 +191,15 @@ VideoPanel::VideoPanel (FilmEditor* e) _bottom_crop->wrapped()->SetRange (0, 1024); vector ratios = Ratio::all (); - _ratio->Clear (); + _ratio->wrapped()->Clear (); for (vector::iterator i = ratios.begin(); i != ratios.end(); ++i) { - _ratio->Append (std_to_wx ((*i)->nickname ())); + _ratio->wrapped()->Append (std_to_wx ((*i)->nickname ())); } - _ratio->Append (_("No stretch")); + _ratio->wrapped()->Append (_("No stretch")); _frame_type->wrapped()->Append (_("2D")); _frame_type->wrapped()->Append (_("3D left/right")); - _ratio->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&VideoPanel::ratio_changed, this)); _filters_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_filters_clicked, this)); _colour_conversion_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_colour_conversion_clicked, this)); } @@ -199,23 +233,6 @@ VideoPanel::film_content_changed (int property) } else if (property == VideoContentProperty::VIDEO_CROP) { setup_description (); } else if (property == VideoContentProperty::VIDEO_RATIO) { - if (vcs) { - int n = 0; - vector ratios = Ratio::all (); - vector::iterator i = ratios.begin (); - while (i != ratios.end() && *i != vcs->ratio()) { - ++i; - ++n; - } - - if (i == ratios.end()) { - checked_set (_ratio, ratios.size ()); - } else { - checked_set (_ratio, n); - } - } else { - checked_set (_ratio, -1); - } setup_description (); } else if (property == VideoContentProperty::VIDEO_FRAME_RATE) { setup_description (); @@ -327,30 +344,6 @@ VideoPanel::setup_description () _sizer->Layout (); } - -void -VideoPanel::ratio_changed () -{ - if (!_editor->film ()) { - return; - } - - VideoContentList vc = _editor->selected_video_content (); - if (vc.size() != 1) { - return; - } - - int const n = _ratio->GetSelection (); - if (n >= 0) { - vector ratios = Ratio::all (); - if (n < int (ratios.size ())) { - vc.front()->set_ratio (ratios[n]); - } else { - vc.front()->set_ratio (0); - } - } -} - void VideoPanel::edit_colour_conversion_clicked () { @@ -379,14 +372,13 @@ VideoPanel::content_selection_changed () _top_crop->set_content (sel); _bottom_crop->set_content (sel); _frame_type->set_content (sel); + _ratio->set_content (sel); /* Things that are only allowed with single selections */ - _ratio->Enable (single); _filters_button->Enable (single); _colour_conversion_button->Enable (single); film_content_changed (VideoContentProperty::VIDEO_CROP); - film_content_changed (VideoContentProperty::VIDEO_RATIO); film_content_changed (VideoContentProperty::VIDEO_FRAME_RATE); film_content_changed (VideoContentProperty::COLOUR_CONVERSION); film_content_changed (FFmpegContentProperty::FILTERS); diff --git a/src/wx/video_panel.h b/src/wx/video_panel.h index 577bbf0e7..fb1f98b29 100644 --- a/src/wx/video_panel.h +++ b/src/wx/video_panel.h @@ -37,7 +37,6 @@ public: private: void edit_filters_clicked (); - void ratio_changed (); void edit_colour_conversion_clicked (); void setup_description (); @@ -47,7 +46,7 @@ private: ContentSpinCtrl* _right_crop; ContentSpinCtrl* _top_crop; ContentSpinCtrl* _bottom_crop; - wxChoice* _ratio; + ContentChoice* _ratio; wxStaticText* _ratio_description; wxStaticText* _description; wxStaticText* _filters; diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index 515550e59..27a4554ca 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -277,3 +277,15 @@ dcpomatic_setup_i18n () dcpomatic_setup_gettext_i18n (wx_to_std (locale->GetCanonicalName ())); } } + +int +wx_get (wxSpinCtrl* w) +{ + return w->GetValue (); +} + +int +wx_get (wxChoice* w) +{ + return w->GetSelection (); +} diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index 48683492c..8ac824c50 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -84,6 +84,9 @@ extern void checked_set (wxCheckBox* widget, bool value); extern void checked_set (wxRadioButton* widget, bool value); extern void checked_set (wxStaticText* widget, std::string value); +extern int wx_get (wxChoice* widget); +extern int wx_get (wxSpinCtrl* widget); + /* GTK 2.24.17 has a buggy GtkFileChooserButton and it was put in Ubuntu 13.04. This also seems to apply to 2.24.20 in Ubuntu 13.10 Use our own dir picker as this is the least bad option I can think of.