++r;
add_label_to_grid_bag_sizer (grid, this, _("Audio Gain"), true, wxGBPosition (r, 0));
- _gain = new ContentWidget<AudioContent, wxSpinCtrl> (
+ _gain = new ContentSpinCtrl<AudioContent> (
this,
new wxSpinCtrl (this),
AudioContentProperty::AUDIO_GAIN,
boost::mem_fn (&AudioContent::audio_gain),
boost::mem_fn (&AudioContent::set_audio_gain)
);
+
_gain->add (grid, wxGBPosition (r, 1));
add_label_to_grid_bag_sizer (grid, this, _("dB"), false, wxGBPosition (r, 2));
_gain_calculate_button = new wxButton (this, wxID_ANY, _("Calculate..."));
++r;
add_label_to_grid_bag_sizer (grid, this, _("Audio Delay"), false, wxGBPosition (r, 0));
- _delay = new ContentWidget<AudioContent, wxSpinCtrl> (
+ _delay = new ContentSpinCtrl<AudioContent> (
this,
new wxSpinCtrl (this),
AudioContentProperty::AUDIO_DELAY,
boost::mem_fn (&AudioContent::audio_delay),
boost::mem_fn (&AudioContent::set_audio_delay)
);
+
_delay->add (grid, wxGBPosition (r,1 ));
/// TRANSLATORS: this is an abbreviation for milliseconds, the unit of time
add_label_to_grid_bag_sizer (grid, this, _("ms"), false, wxGBPosition (r, 2));
void mapping_changed (AudioMapping);
void setup_stream_description ();
- ContentWidget<AudioContent, wxSpinCtrl>* _gain;
+ ContentSpinCtrl<AudioContent>* _gain;
wxButton* _gain_calculate_button;
wxButton* _show;
- ContentWidget<AudioContent, wxSpinCtrl>* _delay;
+ ContentSpinCtrl<AudioContent>* _delay;
wxChoice* _stream;
wxStaticText* _description;
AudioMappingView* _mapping;
*
* @param S Type containing the content being represented (e.g. VideoContent)
* @param T Type of the widget (e.g. wxSpinCtrl)
+ * @param U Data type of state as used by the model.
+ * @param V Data type of state as used by the view.
*/
-template <class S, class T>
+template <class S, class T, typename U, typename V>
class ContentWidget
{
public:
/** @param parent Parent window.
* @param wrapped Control widget that we are wrapping.
* @param property ContentProperty that the widget is handling.
- * @param getter Function on the Content to get the value.
- * @param setter Function on the Content to set the value.
+ * @param model_getter Function on the Content to get the value.
+ * @param model_setter Function on the Content to set the value.
*/
- ContentWidget (wxWindow* parent, T* wrapped, int property, boost::function<int (S*)> getter, boost::function<void (S*, int)> setter)
+ ContentWidget (
+ wxWindow* parent,
+ T* wrapped,
+ int property,
+ boost::function<U (S*)> model_getter,
+ boost::function<void (S*, U)> model_setter,
+ boost::function<V (T*)> view_getter
+ )
: _wrapped (wrapped)
, _sizer (0)
, _button (new wxButton (parent, wxID_ANY, _("Multiple values")))
, _property (property)
- , _getter (getter)
- , _setter (setter)
+ , _model_getter (model_getter)
+ , _model_setter (model_setter)
+ , _view_getter (view_getter)
, _ignore_model_changes (false)
{
_button->SetToolTip (_("Click the button to set all selected content to the same value."));
_button->Hide ();
_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentWidget::button_clicked, this));
- _wrapped->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ContentWidget::view_changed, this));
}
T* wrapped () const {
for (typename std::list<boost::signals2::connection>::iterator i = _connections.begin(); i != _connections.end(); ++i) {
i->disconnect ();
}
+
+ _connections.clear ();
_content = content;
_sizer->Add (_wrapped, _position);
}
-
void update_from_model ()
{
if (_content.empty ()) {
}
typename List::iterator i = _content.begin ();
- int const v = boost::bind (_getter, _content.front().get())();
- while (i != _content.end() && boost::bind (_getter, i->get())() == v) {
+ U const v = boost::bind (_model_getter, _content.front().get())();
+ while (i != _content.end() && boost::bind (_model_getter, i->get())() == v) {
++i;
}
}
}
+ void view_changed ()
+ {
+ 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<U> (boost::bind (_view_getter, _wrapped)()))();
+ }
+ }
+
private:
void set_single ()
void button_clicked ()
{
- int const v = boost::bind (_getter, _content.front().get())();
+ U const v = boost::bind (_model_getter, _content.front().get())();
for (typename List::iterator i = _content.begin (); i != _content.end(); ++i) {
- boost::bind (_setter, i->get(), v) ();
- }
- }
-
- void view_changed ()
- {
- 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 (_setter, _content[i].get(), _wrapped->GetValue ()) ();
+ boost::bind (_model_setter, i->get(), v) ();
}
}
wxButton* _button;
List _content;
int _property;
- boost::function<int (S*)> _getter;
- boost::function<void (S*, int)> _setter;
+ boost::function<U (S*)> _model_getter;
+ boost::function<void (S*, U)> _model_setter;
+ boost::function<V (T*)> _view_getter;
std::list<boost::signals2::connection> _connections;
bool _ignore_model_changes;
};
+template <class S>
+class ContentSpinCtrl : public ContentWidget<S, wxSpinCtrl, int, int>
+{
+public:
+ ContentSpinCtrl (wxWindow* parent, wxSpinCtrl* wrapped, int property, boost::function<int (S*)> getter, boost::function<void (S*, int)> setter)
+ : ContentWidget<S, wxSpinCtrl, int, int> (parent, wrapped, property, getter, setter, boost::mem_fn (&wxSpinCtrl::GetValue))
+ {
+ wrapped->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ContentWidget<S, wxSpinCtrl, int, int>::view_changed, this));
+ }
+
+};
+
+template <class S, class U>
+class ContentChoice : public ContentWidget<S, wxChoice, U, int>
+{
+public:
+ ContentChoice (wxWindow* parent, wxChoice* wrapped, int property, boost::function<U (S*)> getter, boost::function<void (S*, U)> setter)
+ : ContentWidget<S, wxChoice, U, int> (parent, wrapped, property, getter, setter, boost::mem_fn (&wxChoice::GetSelection))
+ {
+ wrapped->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ContentWidget<S, wxChoice, U, int>::view_changed, this));
+ }
+
+};
+
#endif
int r = 0;
add_label_to_grid_bag_sizer (grid, this, _("Type"), true, wxGBPosition (r, 0));
- _frame_type = new wxChoice (this, wxID_ANY);
- grid->Add (_frame_type, wxGBPosition (r, 1));
+ _frame_type = new ContentChoice<VideoContent, VideoFrameType> (
+ this,
+ new wxChoice (this, wxID_ANY),
+ VideoContentProperty::VIDEO_FRAME_TYPE,
+ boost::mem_fn (&VideoContent::video_frame_type),
+ boost::mem_fn (&VideoContent::set_video_frame_type)
+ );
+ _frame_type->add (grid, wxGBPosition (r, 1));
++r;
add_label_to_grid_bag_sizer (grid, this, _("Left crop"), true, wxGBPosition (r, 0));
- _left_crop = new ContentWidget<VideoContent, wxSpinCtrl> (
+ _left_crop = new ContentSpinCtrl<VideoContent> (
this,
new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
VideoContentProperty::VIDEO_CROP,
++r;
add_label_to_grid_bag_sizer (grid, this, _("Right crop"), true, wxGBPosition (r, 0));
- _right_crop = new ContentWidget<VideoContent, wxSpinCtrl> (
+ _right_crop = new ContentSpinCtrl<VideoContent> (
this,
new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
VideoContentProperty::VIDEO_CROP,
++r;
add_label_to_grid_bag_sizer (grid, this, _("Top crop"), true, wxGBPosition (r, 0));
- _top_crop = new ContentWidget<VideoContent, wxSpinCtrl> (
+ _top_crop = new ContentSpinCtrl<VideoContent> (
this,
new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
VideoContentProperty::VIDEO_CROP,
++r;
add_label_to_grid_bag_sizer (grid, this, _("Bottom crop"), true, wxGBPosition (r, 0));
- _bottom_crop = new ContentWidget<VideoContent, wxSpinCtrl> (
+ _bottom_crop = new ContentSpinCtrl<VideoContent> (
this,
new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
VideoContentProperty::VIDEO_CROP,
}
_ratio->Append (_("No stretch"));
- _frame_type->Append (_("2D"));
- _frame_type->Append (_("3D left/right"));
+ _frame_type->wrapped()->Append (_("2D"));
+ _frame_type->wrapped()->Append (_("3D left/right"));
- _frame_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&VideoPanel::frame_type_changed, this));
_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));
}
if (property == VideoContentProperty::VIDEO_FRAME_TYPE) {
- checked_set (_frame_type, vcs ? vcs->video_frame_type () : VIDEO_FRAME_TYPE_2D);
setup_description ();
} else if (property == VideoContentProperty::VIDEO_CROP) {
setup_description ();
}
}
-void
-VideoPanel::frame_type_changed ()
-{
- VideoContentList vc = _editor->selected_video_content ();
- if (vc.size() == 1) {
- vc.front()->set_video_frame_type (static_cast<VideoFrameType> (_frame_type->GetSelection ()));
- }
-}
-
void
VideoPanel::edit_colour_conversion_clicked ()
{
_right_crop->set_content (sel);
_top_crop->set_content (sel);
_bottom_crop->set_content (sel);
+ _frame_type->set_content (sel);
/* Things that are only allowed with single selections */
- _frame_type->Enable (single);
_ratio->Enable (single);
_filters_button->Enable (single);
_colour_conversion_button->Enable (single);
- film_content_changed (VideoContentProperty::VIDEO_FRAME_TYPE);
film_content_changed (VideoContentProperty::VIDEO_CROP);
film_content_changed (VideoContentProperty::VIDEO_RATIO);
film_content_changed (VideoContentProperty::VIDEO_FRAME_RATE);
private:
void edit_filters_clicked ();
void ratio_changed ();
- void frame_type_changed ();
void edit_colour_conversion_clicked ();
void setup_description ();
- wxChoice* _frame_type;
- ContentWidget<VideoContent, wxSpinCtrl>* _left_crop;
- ContentWidget<VideoContent, wxSpinCtrl>* _right_crop;
- ContentWidget<VideoContent, wxSpinCtrl>* _top_crop;
- ContentWidget<VideoContent, wxSpinCtrl>* _bottom_crop;
+ ContentChoice<VideoContent, VideoFrameType>* _frame_type;
+ ContentSpinCtrl<VideoContent>* _left_crop;
+ ContentSpinCtrl<VideoContent>* _right_crop;
+ ContentSpinCtrl<VideoContent>* _top_crop;
+ ContentSpinCtrl<VideoContent>* _bottom_crop;
wxChoice* _ratio;
wxStaticText* _ratio_description;
wxStaticText* _description;