1 #include <gtkmm/table.h>
2 #include <gtkmm/stock.h>
3 #include <gtkmm/alignment.h>
4 #include "ardour/region.h"
6 #include "gui_thread.h"
8 #include "public_editor.h"
9 #include "region_layering_order_editor.h"
15 using namespace ARDOUR
;
17 RegionLayeringOrderEditor::RegionLayeringOrderEditor (PublicEditor
& pe
)
18 : ArdourDialog (pe
, _("RegionLayeringOrderEditor"), false, false)
21 , in_row_change (false)
22 , regions_at_position (0)
23 , layering_order_columns ()
24 , layering_order_model (Gtk::ListStore::create (layering_order_columns
))
25 , layering_order_display ()
26 , clock ("layer dialog", true, "RegionLayeringOrderEditorClock", false, false, false)
30 set_name ("RegionLayeringOrderEditorWindow");
32 layering_order_display
.set_model (layering_order_model
);
34 layering_order_display
.append_column (_("Region Name"), layering_order_columns
.name
);
35 layering_order_display
.set_headers_visible (true);
36 layering_order_display
.set_reorderable (false);
37 layering_order_display
.set_rules_hint (true);
39 scroller
.set_policy (Gtk::POLICY_AUTOMATIC
, Gtk::POLICY_AUTOMATIC
);
40 scroller
.add (layering_order_display
);
42 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);
50 track_label
.set_name ("RegionLayeringOrderEditorLabel");
51 track_label
.set_text (_("Track:"));
52 track_label
.set_alignment (0, 0.5);
53 clock_label
.set_name ("RegionLayeringOrderEditorLabel");
54 clock_label
.set_text (_("Position:"));
55 clock_label
.set_alignment (0, 0.5);
56 track_name_label
.set_name ("RegionLayeringOrderEditorNameLabel");
57 track_name_label
.set_alignment (0, 0.5);
58 clock
.set_mode (AudioClock::BBT
);
60 Gtk::Table
* info_table
= manage (new Gtk::Table (2, 2));
61 info_table
->set_col_spacings (5);
62 info_table
->set_row_spacings (5);
63 info_table
->attach (track_label
, 0, 1, 0, 1, FILL
, FILL
);
64 info_table
->attach (track_name_label
, 1, 2, 0, 1, FILL
, FILL
);
65 info_table
->attach (clock_label
, 0, 1, 1, 2, FILL
, FILL
);
66 info_table
->attach (clock
, 1, 2, 1, 2, FILL
, FILL
);
68 get_vbox()->set_spacing (12);
69 get_vbox()->pack_start (*info_table
, false, false);
70 get_vbox()->pack_start (*scroller_table
, true, true);
72 info_table
->set_name ("RegionLayeringOrderTable");
73 scroller_table
->set_name ("RegionLayeringOrderTable");
75 layering_order_display
.set_name ("RegionLayeringOrderDisplay");
77 layering_order_display
.signal_row_activated ().connect (mem_fun (*this, &RegionLayeringOrderEditor::row_activated
));
79 layering_order_display
.grab_focus ();
81 set_title (_("Choose Top Region"));
85 RegionLayeringOrderEditor::~RegionLayeringOrderEditor ()
90 RegionLayeringOrderEditor::row_activated (const TreeModel::Path
& path
, TreeViewColumn
*)
96 TreeModel::iterator iter
= layering_order_model
->get_iter (path
);
99 TreeModel::Row row
= *iter
;
100 boost::shared_ptr
<Region
> region
= row
[layering_order_columns
.region
];
102 region
->raise_to_top ();
106 typedef boost::shared_ptr
<Region
> RegionPtr
;
108 struct RegionCompareByLayer
{
109 bool operator() (RegionPtr a
, RegionPtr b
) const {
110 return a
->layer() > b
->layer();
115 RegionLayeringOrderEditor::refill ()
117 regions_at_position
= 0;
123 typedef Playlist::RegionList RegionList
;
125 in_row_change
= true;
127 layering_order_model
->clear ();
129 boost::shared_ptr
<RegionList
> region_list(playlist
->regions_at (position
));
131 regions_at_position
= region_list
->size();
133 if (regions_at_position
< 2) {
134 playlist_modified_connection
.disconnect ();
136 in_row_change
= false;
140 RegionCompareByLayer cmp
;
141 region_list
->sort (cmp
);
143 for (RegionList::const_iterator i
= region_list
->begin(); i
!= region_list
->end(); ++i
) {
144 TreeModel::Row newrow
= *(layering_order_model
->append());
145 newrow
[layering_order_columns
.name
] = (*i
)->name();
146 newrow
[layering_order_columns
.region
] = *i
;
148 if (i
== region_list
->begin()) {
149 layering_order_display
.get_selection()->select(newrow
);
153 in_row_change
= false;
157 RegionLayeringOrderEditor::set_context (const string
& a_name
, Session
* s
, const boost::shared_ptr
<Playlist
> & pl
, framepos_t pos
)
159 track_name_label
.set_text (a_name
);
161 clock
.set_session (s
);
162 clock
.set (pos
, true, 0, 0);
164 playlist_modified_connection
.disconnect ();
166 playlist
->ContentsChanged
.connect (playlist_modified_connection
, invalidator (*this), boost::bind
167 (&RegionLayeringOrderEditor::playlist_modified
, this), gui_context());
174 RegionLayeringOrderEditor::on_key_press_event (GdkEventKey
* ev
)
176 bool handled
= false;
178 /* in general, we want shortcuts working while in this
179 dialog. However, we'd like to treat "return" specially
180 since it is used for row activation. So ..
182 for return: try normal handling first
183 then try the editor (to get accelerators/shortcuts)
184 then try normal handling (for keys other than return)
187 if (ev
->keyval
== GDK_Return
) {
188 handled
= ArdourDialog::on_key_press_event (ev
);
192 handled
= key_press_focus_accelerator_handler (editor
, ev
);
196 handled
= ArdourDialog::on_key_press_event (ev
);
203 RegionLayeringOrderEditor::maybe_present ()
205 if (regions_at_position
< 2) {
214 RegionLayeringOrderEditor::playlist_modified ()