1 #include <gtkmm/table.h>
2 #include <gtkmm/stock.h>
3 #include <gtkmm/alignment.h>
4 #include <ardour/region.h>
8 #include "public_editor.h"
9 #include "region_layering_order_editor.h"
13 using namespace ARDOUR
;
15 RegionLayeringOrderEditor::RegionLayeringOrderEditor (PublicEditor
& pe
)
16 : ArdourDialog (pe
, _("RegionLayeringOrderEditor"), false, false)
19 , in_row_change (false)
20 , regions_at_position (0)
21 , layering_order_columns ()
22 , layering_order_model (Gtk::ListStore::create (layering_order_columns
))
23 , layering_order_display ()
24 , clock ("layer dialog", true, "RegionLayeringOrderEditorClock", false, false, false)
28 set_name ("RegionLayeringOrderEditorWindow");
30 layering_order_display
.set_model (layering_order_model
);
32 layering_order_display
.append_column (_("Region Name"), layering_order_columns
.name
);
33 layering_order_display
.set_headers_visible (true);
34 layering_order_display
.set_reorderable (false);
35 layering_order_display
.set_rules_hint (true);
37 scroller
.set_border_width (10);
38 scroller
.set_policy (Gtk::POLICY_AUTOMATIC
, Gtk::POLICY_AUTOMATIC
);
39 scroller
.add (layering_order_display
);
41 clock
.set_mode (AudioClock::BBT
);
44 Gtk::Table
* scroller_table
= manage (new Gtk::Table
);
45 scroller_table
->set_size_request (300, 250);
46 scroller_table
->attach (scroller
, 0, 1, 0, 1);
47 scroller_table
->set_col_spacings (5);
48 scroller_table
->set_row_spacings (5);
49 scroller_table
->set_border_width (5);
51 track_label
.set_name ("RegionLayeringOrderEditorLabel");
52 track_label
.set_text (_("Track:"));
53 clock_label
.set_name ("RegionLayeringOrderEditorLabel");
54 clock_label
.set_text (_("Position:"));
55 track_name_label
.set_name ("RegionLayeringOrderEditorNameLabel");
56 clock
.set_mode (AudioClock::BBT
);
58 Gtk::Alignment
* track_alignment
= manage (new Gtk::Alignment
);
59 track_alignment
->set (1.0, 0.5);
60 track_alignment
->add (track_label
);
62 Gtk::Alignment
* clock_alignment
= manage (new Gtk::Alignment
);
63 clock_alignment
->set (1.0, 0.5);
64 clock_alignment
->add (clock_label
);
66 Gtk::Table
* info_table
= manage (new Gtk::Table (2, 2));
67 info_table
->set_col_spacings (5);
68 info_table
->set_row_spacings (5);
69 info_table
->set_border_width (5);
70 info_table
->attach (*track_alignment
, 0, 1, 0, 1, FILL
, FILL
);
71 info_table
->attach (track_name_label
, 1, 2, 0, 1, FILL
, FILL
);
72 info_table
->attach (*clock_alignment
, 0, 1, 1, 2, FILL
, FILL
);
73 info_table
->attach (clock
, 1, 2, 1, 2, FILL
, FILL
);
75 HBox
* info_hbox
= manage (new HBox
);
77 info_hbox
->pack_start (*info_table
, true, false);
79 get_vbox()->set_spacing (5);
80 get_vbox()->pack_start (*info_hbox
, false, false);
81 get_vbox()->pack_start (*scroller_table
, true, true);
83 info_table
->set_name ("RegionLayeringOrderTable");
84 scroller_table
->set_name ("RegionLayeringOrderTable");
86 layering_order_display
.set_name ("RegionLayeringOrderDisplay");
88 layering_order_display
.signal_row_activated ().connect (mem_fun (*this, &RegionLayeringOrderEditor::row_activated
));
90 layering_order_display
.grab_focus ();
92 set_title (_("Choose Top Region"));
96 RegionLayeringOrderEditor::~RegionLayeringOrderEditor ()
101 RegionLayeringOrderEditor::row_activated (const TreeModel::Path
& path
, TreeViewColumn
* column
)
107 TreeModel::iterator iter
= layering_order_model
->get_iter (path
);
110 TreeModel::Row row
= *iter
;
111 boost::shared_ptr
<Region
> region
= row
[layering_order_columns
.region
];
113 region
->raise_to_top ();
117 typedef boost::shared_ptr
<Region
> RegionPtr
;
119 struct RegionCompareByLayer
{
120 bool operator() (RegionPtr a
, RegionPtr b
) const {
121 return a
->layer() > b
->layer();
126 RegionLayeringOrderEditor::refill ()
128 regions_at_position
= 0;
134 typedef Playlist::RegionList RegionList
;
136 in_row_change
= true;
138 layering_order_model
->clear ();
140 boost::shared_ptr
<RegionList
> region_list(playlist
->regions_at (position
));
142 regions_at_position
= region_list
->size();
144 if (regions_at_position
< 2) {
145 playlist_modified_connection
.disconnect ();
147 in_row_change
= false;
151 RegionCompareByLayer cmp
;
152 region_list
->sort (cmp
);
154 for (RegionList::const_iterator i
= region_list
->begin(); i
!= region_list
->end(); ++i
) {
155 TreeModel::Row newrow
= *(layering_order_model
->append());
156 newrow
[layering_order_columns
.name
] = (*i
)->name();
157 newrow
[layering_order_columns
.region
] = *i
;
159 if (i
== region_list
->begin()) {
160 layering_order_display
.get_selection()->select(newrow
);
164 in_row_change
= false;
168 RegionLayeringOrderEditor::set_context (const string
& a_name
, Session
* s
, const boost::shared_ptr
<Playlist
> & pl
, nframes64_t pos
)
170 track_name_label
.set_text (a_name
);
172 clock
.set_session (s
);
173 clock
.set (pos
, true, 0, 0);
175 playlist_modified_connection
.disconnect ();
177 playlist_modified_connection
= playlist
->Modified
.connect (mem_fun (*this, &RegionLayeringOrderEditor::playlist_modified
));
184 RegionLayeringOrderEditor::on_key_press_event (GdkEventKey
* ev
)
186 bool handled
= false;
188 /* in general, we want shortcuts working while in this
189 dialog. However, we'd like to treat "return" specially
190 since it is used for row activation. So ..
192 for return: try normal handling first
193 then try the editor (to get accelerators/shortcuts)
194 then try normal handling (for keys other than return)
197 if (ev
->keyval
== GDK_Return
) {
198 handled
= ArdourDialog::on_key_press_event (ev
);
202 handled
= key_press_focus_accelerator_handler (editor
, ev
);
206 handled
= ArdourDialog::on_key_press_event (ev
);
213 RegionLayeringOrderEditor::maybe_present ()
215 if (regions_at_position
< 2) {
223 RegionLayeringOrderEditor::playlist_modified ()