/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
}
/* no modifiers, propagate first */
-
+
if (!gtk_window_propagate_key_event (win, ev)) {
return gtk_window_activate_key (win, ev);
}
+
return true;
}
ignore_route_list_reorder = false;
verbose_cursor_on = true;
route_removal = false;
- track_spacing = 0;
+ track_spacing = 2;
show_automatic_regions_in_region_list = true;
have_pending_keyboard_selection = false;
_follow_playhead = true;
range_marker_drag_rect = 0;
marker_drag_line = 0;
- mouse_mode = MouseZoom; /* force change in next call */
set_mouse_mode (MouseObject, true);
frames_per_unit = 2048; /* too early to use set_frames_per_unit */
initialize_rulers ();
initialize_canvas ();
- edit_controls_vbox.set_spacing (track_spacing);
+ edit_controls_vbox.set_spacing (0);
horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::canvas_horizontally_scrolled));
vertical_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::tie_vertical_scrolling));
track_canvas.signal_map_event().connect (mem_fun (*this, &Editor::track_canvas_map_handler));
time_canvas.signal_map_event().connect (mem_fun (*this, &Editor::time_canvas_map_handler));
- // edit_controls_hbox.pack_start (edit_controls_vbox, true, true);
controls_layout.add (edit_controls_vbox);
controls_layout.set_name ("EditControlsBase");
- controls_layout.signal_size_request().connect (mem_fun(*this, &Editor::set_layout_width), false);
- controls_layout.signal_expose_event().connect (mem_fun(*this, &Editor::layout_expose), false);
+ controls_layout.add_events (Gdk::SCROLL_MASK);
+ controls_layout.signal_scroll_event().connect (mem_fun(*this, &Editor::control_layout_scroll), false);
controls_layout.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK);
controls_layout.signal_button_release_event().connect (mem_fun(*this, &Editor::edit_controls_button_release));
bottom_hbox.set_spacing (3);
route_display_model = ListStore::create(route_display_columns);
- route_list.set_model (route_display_model);
- route_list.append_column (_("Tracks"), route_display_columns.text);
- route_list.set_name ("TrackListDisplay");
- route_list.get_selection()->set_mode (Gtk::SELECTION_MULTIPLE);
- route_list.set_reorderable (true);
+ route_list_display.set_model (route_display_model);
+ route_list_display.append_column (_("Tracks"), route_display_columns.text);
+ route_list_display.set_headers_visible (false);
+ route_list_display.set_name ("TrackListDisplay");
+ route_list_display.get_selection()->set_mode (Gtk::SELECTION_MULTIPLE);
+ route_list_display.set_reorderable (true);
- route_list.set_size_request (75,-1);
- route_list.set_headers_visible (true);
- route_list.set_headers_clickable (true);
+ route_list_display.set_size_request (75,-1);
+ route_list_display.set_headers_visible (true);
+ route_list_display.set_headers_clickable (true);
// GTK2FIX
- // route_list.signal_rows_reordered().connect (mem_fun (*this, &Editor::queue_route_list_reordered));
+ // route_list_display.signal_rows_reordered().connect (mem_fun (*this, &Editor::queue_route_list_reordered));
// GTK2FIX
// route_display_model->set_sort_func (0, mem_fun (*this, &Editor::route_list_compare_func));
- // GTK2FIX
- //route_list.set_shadow_type (Gtk::SHADOW_IN);
-
- route_list_scroller.add (route_list);
+ route_list_scroller.add (route_list_display);
route_list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
- route_list.get_selection()->signal_changed().connect (mem_fun (*this, &Editor::route_display_selection_changed));
- route_list.signal_columns_changed().connect (mem_fun(*this, &Editor::route_list_column_click));
+ route_list_display.get_selection()->signal_changed().connect (mem_fun (*this, &Editor::route_display_selection_changed));
+ route_list_display.signal_columns_changed().connect (mem_fun(*this, &Editor::route_list_column_click));
edit_group_list_button_label.set_text (_("Edit Groups"));
edit_group_list_button_label.set_name ("EditGroupTitleButton");
edit_group_list_button.set_name ("EditGroupTitleButton");
group_model = ListStore::create(group_columns);
- edit_group_list.set_model (group_model);
- edit_group_list.append_column (_("active"), group_columns.is_active);
- edit_group_list.append_column (_("groupname"), group_columns.text);
- edit_group_list.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
- edit_group_list.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
+ edit_group_display.set_model (group_model);
+ edit_group_display.append_column (_("active"), group_columns.is_active);
+ edit_group_display.append_column (_("groupname"), group_columns.text);
+ edit_group_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
+ edit_group_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
+ edit_group_display.set_headers_visible (false);
/* use checkbox for the active column */
- CellRendererToggle *active_cell = dynamic_cast<CellRendererToggle*>(edit_group_list.get_column_cell_renderer (0));
+ CellRendererToggle *active_cell = dynamic_cast<CellRendererToggle*>(edit_group_display.get_column_cell_renderer (0));
active_cell->property_activatable() = true;
active_cell->property_radio() = false;
- edit_group_list.set_name ("MixerGroupList");
- //edit_group_list.set_shadow_type (Gtk::SHADOW_IN);
+ edit_group_display.set_name ("MixerGroupList");
+ //edit_group_display.set_shadow_type (Gtk::SHADOW_IN);
- edit_group_list.columns_autosize ();
- edit_group_list.get_selection()->set_mode (Gtk::SELECTION_MULTIPLE);
- edit_group_list.set_reorderable (false);
+ edit_group_display.columns_autosize ();
+ edit_group_display.get_selection()->set_mode (Gtk::SELECTION_MULTIPLE);
+ edit_group_display.set_reorderable (false);
- edit_group_list.set_size_request (75, -1);
- edit_group_list.set_headers_visible (true);
+ edit_group_display.set_size_request (75, -1);
+ edit_group_display.set_headers_visible (true);
- edit_group_list_scroller.add (edit_group_list);
+ edit_group_list_scroller.add (edit_group_display);
edit_group_list_scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
edit_group_list_button.signal_clicked().connect (mem_fun(*this, &Editor::edit_group_list_button_clicked));
- edit_group_list.signal_button_press_event().connect (mem_fun(*this, &Editor::edit_group_list_button_press_event));
- edit_group_list.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::edit_group_selection_changed));
+ edit_group_display.signal_button_press_event().connect (mem_fun(*this, &Editor::edit_group_list_button_press_event));
+ edit_group_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::edit_group_selection_changed));
TreeModel::Row row = *(group_model->append());
row[group_columns.is_active] = false;
row[group_columns.text] = (_("-all-"));
- edit_group_list.get_selection()->select (row);
-/* GTK2FIX is set_data(0) setting the is_active to false here?
- list<string> stupid_list;
-
- stupid_list.push_back ("*");
- stupid_list.push_back (_("-all-"));
+ row[group_columns.routegroup] = 0;
+ edit_group_display.get_selection()->select (row);
- edit_group_list.rows().push_back (stupid_list);
- edit_group_list.rows().back().set_data (0);
- edit_group_list.rows().back().select();
-
-*/
edit_group_vbox.pack_start (edit_group_list_button, false, false);
edit_group_vbox.pack_start (edit_group_list_scroller, true, true);
+ region_list_display.set_size_request (100, -1);
+ region_list_display.set_name ("RegionListDisplay");
+
region_list_model = TreeStore::create (region_list_columns);
region_list_sort_model = TreeModelSort::create (region_list_model);
region_list_model->set_sort_func (0, mem_fun (*this, &Editor::region_list_sorter));
region_list_display.set_model (region_list_sort_model);
- region_list_display.append_column (_("Regions"), region_list_columns.name);
+ CellRendererText* renderer = Gtk::manage( new Gtk::CellRendererText() );
+ region_list_display.append_column (_("Regions"), *renderer);
+
+ TreeViewColumn* tv_col = region_list_display.get_column(0);
+ tv_col->add_attribute(renderer->property_text(), region_list_columns.name);
+ tv_col->add_attribute(renderer->property_foreground_gdk(), region_list_columns.color_);
+
region_list_display.set_reorderable (true);
- region_list_display.set_size_request (100, -1);
- region_list_display.set_data ("editor", this);
- region_list_display.set_flags (Gtk::CAN_FOCUS);
- region_list_display.set_name ("RegionListDisplay");
- region_list_scroller.add (region_list_display);
- region_list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ region_list_display.get_selection()->set_mode (SELECTION_SINGLE);
+ region_list_display.add_object_drag (region_list_columns.region.index(), "regions");
+ /* setup DnD handling */
+
list<Gtk::TargetEntry> region_list_target_table;
region_list_target_table.push_back (TargetEntry ("STRING"));
region_list_target_table.push_back (TargetEntry ("text/plain"));
region_list_target_table.push_back (TargetEntry ("text/uri-list"));
region_list_target_table.push_back (TargetEntry ("application/x-rootwin-drop"));
+
+ region_list_display.add_drop_targets (region_list_target_table);
+ region_list_display.signal_drag_data_received().connect (mem_fun(*this, &Editor::region_list_display_drag_data_received));
- // GTK2FIX
- // region_list_display.drag_dest_set (region_list_target_table, DEST_DEFAULT_ALL, GdkDragAction (Gdk::ACTION_COPY|Gdk::ACTION_MOVE));
- // region_list_display.signal_drag_data_received().connect (mem_fun(*this, &Editor::region_list_display_drag_data_received));
+ region_list_scroller.add (region_list_display);
+ region_list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
region_list_display.signal_key_press_event().connect (mem_fun(*this, &Editor::region_list_display_key_press));
region_list_display.signal_key_release_event().connect (mem_fun(*this, &Editor::region_list_display_key_release));
- region_list_display.signal_button_press_event().connect (mem_fun(*this, &Editor::region_list_display_button_press));
+ region_list_display.signal_button_press_event().connect (mem_fun(*this, &Editor::region_list_display_button_press), false);
region_list_display.signal_button_release_event().connect (mem_fun(*this, &Editor::region_list_display_button_release));
region_list_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::region_list_selection_changed));
- // GTK2FIX
- //region_list_display.unselect_row.connect (mem_fun(*this, &Editor::region_list_display_unselected));
- //region_list_display.signal_columns_changed().connect (mem_fun(*this, &Editor::region_list_column_click));
+ // region_list_display.signal_popup_menu().connect (bind (mem_fun (*this, &Editor::show_region_list_display_context_menu), 1, 0));
named_selection_scroller.add (named_selection_display);
named_selection_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
named_selection_model = TreeStore::create (named_selection_columns);
named_selection_display.set_model (named_selection_model);
named_selection_display.append_column (_("Chunks"), named_selection_columns.text);
+ named_selection_display.set_headers_visible (false);
named_selection_display.set_size_request (100, -1);
named_selection_display.set_name ("RegionListDisplay");
the_notebook.set_scrollable (true);
the_notebook.popup_enable ();
- TearOff *notebook_tearoff = manage (new TearOff (the_notebook));
+ TearOff *notebook_tearoff = manage (new TearOff (the_notebook, true));
+ notebook_tearoff->tearoff_window().set_size_request (200, 400);
edit_pane.pack1 (edit_frame, true, true);
edit_pane.pack2 (*notebook_tearoff, true, true);
add_accel_group (ActionManager::ui_manager->get_accel_group());
vpacker.pack_end (global_hpacker, true, true);
+
+ /* register actions now so that set_state() can find them and set toggles/checks etc */
+
+ register_actions ();
XMLNode* node = ARDOUR_UI::instance()->editor_settings();
set_state (*node);
{
double y1 = vertical_adjustment.get_value();
controls_layout.get_vadjustment()->set_value (y1);
-
playhead_cursor->set_y_axis(y1);
edit_cursor->set_y_axis(y1);
}
Editor::on_realize ()
{
Window::on_realize ();
-
- /* Even though we're not using acceleration, we want the
- labels to show up.
- */
-
- track_context_menu.accelerate (*this->get_toplevel());
- track_region_context_menu.accelerate (*this->get_toplevel());
+ Realized ();
}
-
void
Editor::queue_session_control_changed (Session::ControlType t)
{
}
void
-Editor::update_title_s (stringcr_t snap_name)
+Editor::update_title_s (const string & snap_name)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::update_title_s), snap_name));
first_action_message->hide();
}
- flush_track_canvas();
-
update_title ();
session->going_away.connect (mem_fun(*this, &Editor::session_going_away));
redisplay_regions ();
redisplay_named_selections ();
- //route_list.freeze (); GTK2FIX
+ // GTK2FIX
+ // route_list_display.set_model (Glib::RefPtr<TreeModel>(0));
route_display_model->clear ();
+
session->foreach_route (this, &Editor::handle_new_route);
- // route_list.select_all ();
+ // route_list_display.select_all ();
// GTK2FIX
- //route_list.sort ();
+ //route_list_display.sort ();
+
route_list_reordered ();
- //route_list.thaw ();
+
+ // route_list_display.set_model (route_display_model);
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(static_cast<TimeAxisView*>(*i))->set_samples_per_unit (frames_per_unit);
TreeModel::Children rows = route_display_model->children();
TreeModel::Children::iterator i;
- //route_list.freeze ();
+ //route_list_display.freeze ();
for (i = rows.begin(); i != rows.end(); ++i) {
TimeAxisView *tv = (*i)[route_display_columns.tv];
if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
if (atv->route().master()) {
- route_list.get_selection()->unselect (i);
+ route_list_display.get_selection()->unselect (i);
//(*i)->unselect ();
}
}
}
- //route_list.thaw ();
+ //route_list_display.thaw ();
}
}
if (!with_selection) {
if (region_edit_menu_split_item) {
if (clicked_regionview && clicked_regionview->region.covers (edit_cursor->current_frame)) {
- // GTK2FIX find the action, change its sensitivity
- // region_edit_menu_split_item->set_sensitive (true);
+ ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, true);
} else {
- // GTK2FIX see above
- // region_edit_menu_split_item->set_sensitive (false);
+ ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, false);
}
}
if (region_edit_menu_split_multichannel_item) {
if ((prop = node.property ("follow-playhead"))) {
bool yn = (prop->value() == "yes");
- _follow_playhead = !yn;
- set_follow_playhead (yn);
+ RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleFollowPlayhead"));
+ if (act) {
+ RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
+ /* do it twice to force the change */
+ tact->set_active (!yn);
+ tact->set_active (yn);
+ }
}
if ((prop = node.property ("xfades-visible"))) {
mouse_mode_tearoff->set_name ("MouseModeBase");
mouse_mode_tearoff->Detach.connect (bind (mem_fun(*this, &Editor::detach_tearoff), static_cast<Gtk::Box*>(&toolbar_hbox),
- mouse_mode_tearoff->tearoff_window()));
+ &mouse_mode_tearoff->tearoff_window()));
mouse_mode_tearoff->Attach.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast<Gtk::Box*> (&toolbar_hbox),
- mouse_mode_tearoff->tearoff_window(), 1));
+ &mouse_mode_tearoff->tearoff_window(), 1));
mouse_move_button.set_name ("MouseModeButton");
mouse_select_button.set_name ("MouseModeButton");
tools_tearoff->set_name ("MouseModeBase");
tools_tearoff->Detach.connect (bind (mem_fun(*this, &Editor::detach_tearoff), static_cast<Gtk::Box*>(&toolbar_hbox),
- tools_tearoff->tearoff_window()));
+ &tools_tearoff->tearoff_window()));
tools_tearoff->Attach.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast<Gtk::Box*> (&toolbar_hbox),
- tools_tearoff->tearoff_window(), 0));
+ &tools_tearoff->tearoff_window(), 0));
toolbar_hbox.set_spacing (8);
int
Editor::convert_drop_to_paths (vector<string>& paths,
- GdkDragContext *context,
+ const RefPtr<Gdk::DragContext>& context,
gint x,
gint y,
- GtkSelectionData *data,
+ const SelectionData& data,
guint info,
guint time)
{
- string spath;
- char *path;
- int state;
- gchar *tname = gdk_atom_name (data->type);
-
- if (session == 0 || strcmp (tname, "text/plain") != 0) {
+ if (session == 0) {
return -1;
}
- /* Parse the "uri-list" format that Nautilus provides,
- where each pathname is delimited by \r\n
- */
+ vector<ustring> uris = data.get_uris();
- path = (char *) data->data;
- state = 0;
+ if (uris.empty()) {
+
+ /* This is seriously fucked up. Nautilus doesn't say that its URI lists
+ are actually URI lists. So do it by hand.
+ */
- for (int n = 0; n < data->length; ++n) {
+ if (data.get_target() != "text/plain") {
+ return -1;
+ }
+
+ /* Parse the "uri-list" format that Nautilus provides,
+ where each pathname is delimited by \r\n
+ */
+
+ const char* p = data.get_text().c_str();
+ const char* q;
- switch (state) {
- case 0:
- if (path[n] == '\r') {
- state = 1;
- } else {
- spath += path[n];
- }
- break;
- case 1:
- if (path[n] == '\n') {
- paths.push_back (spath);
- spath = "";
- state = 0;
- } else {
- warning << _("incorrectly formatted URI list, ignored")
- << endmsg;
- return -1;
+ while (p)
+ {
+ if (*p != '#')
+ {
+ while (g_ascii_isspace (*p))
+ p++;
+
+ q = p;
+ while (*q && (*q != '\n') && (*q != '\r'))
+ q++;
+
+ if (q > p)
+ {
+ q--;
+ while (q > p && g_ascii_isspace (*q))
+ q--;
+
+ if (q > p)
+ {
+ uris.push_back (ustring (p, q - p + 1));
+ }
+ }
}
- break;
+ p = strchr (p, '\n');
+ if (p)
+ p++;
}
- }
- /* nautilus and presumably some other file managers prefix even text/plain with file:// */
-
- for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
-
- // cerr << "dropped text was " << *p << endl;
-
- url_decode (*p);
-
- // cerr << "decoded was " << *p << endl;
-
- if ((*p).substr (0,7) == "file://") {
- (*p) = (*p).substr (7);
+ if (uris.empty()) {
+ return -1;
}
}
- return 0;
-}
-
-void
-Editor::track_canvas_drag_data_received (GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *data,
- guint info,
- guint time)
-{
- TimeAxisView* tvp;
- AudioTimeAxisView* tv;
- double cy;
- vector<string> paths;
- string spath;
- GdkEvent ev;
- jack_nframes_t frame;
-
- if (convert_drop_to_paths (paths, context, x, y, data, info, time)) {
- goto out;
- }
-
- /* D-n-D coordinates are window-relative, so convert to "world" coordinates
- */
-
- double wx;
- double wy;
-
- track_canvas.c2w( x, y, wx, wy);
-
- ev.type = GDK_BUTTON_RELEASE;
- ev.button.x = wx;
- ev.button.y = wy;
-
- frame = event_frame (&ev, 0, &cy);
-
- snap_to (frame);
-
- if ((tvp = trackview_by_y_position (cy)) == 0) {
-
- /* drop onto canvas background: create a new track */
-
- insert_paths_as_new_tracks (paths, false);
-
-
- } else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) {
-
- /* check that its an audio track, not a bus */
-
- if (tv->get_diskstream()) {
-
- for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
- insert_sndfile_into (*p, true, tv, frame);
- }
+ for (vector<ustring>::iterator i = uris.begin(); i != uris.end(); ++i) {
+ if ((*i).substr (0,7) == "file://") {
+ string p = *i;
+ url_decode (p);
+ cerr << "adding " << p << endl;
+ paths.push_back (p.substr (7));
}
-
}
- out:
- gtk_drag_finish (context, TRUE, FALSE, time);
+ return 0;
}
void
}
}
-void
-Editor::flush_track_canvas ()
-{
- /* I don't think this is necessary, and only causes more problems.
- I'm commenting it out
- and if the imageframe folks don't have any issues, we can take
- out this method entirely
- */
-
- //gnome_canvas_update_now (GNOME_CANVAS(track_canvas));
- //gtk_main_iteration ();
-}
-
void
Editor::set_selected_track_from_click (bool add, bool with_undo, bool no_remove)
{
}
void
-Editor::set_verbose_canvas_cursor (stringcr_t txt, double x, double y)
+Editor::set_verbose_canvas_cursor (const string & txt, double x, double y)
{
/* XXX get origin of canvas relative to root window,
add x and y and check compared to gdk_screen_{width,height}
}
void
-Editor::set_verbose_canvas_cursor_text (stringcr_t txt)
+Editor::set_verbose_canvas_cursor_text (const string & txt)
{
verbose_canvas_cursor->property_text() = txt.c_str();
}
}
}
+void
+Editor::toggle_follow_playhead ()
+{
+ RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleFollowPlayhead"));
+ if (act) {
+ RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
+ set_follow_playhead (tact->get_active());
+ }
+}
+
void
Editor::set_follow_playhead (bool yn)
{
}
}
-void
-Editor::set_layout_width(Gtk::Requisition *r)
-{
- edit_controls_vbox.check_resize();
- int w = edit_controls_vbox.get_width();
- cerr << "set_layout_width() called w = " << w << endl;
-
- controls_layout.set_size_request (w, -1);
-}
-
bool
-Editor::layout_expose (GdkEventExpose* ex)
+Editor::control_layout_scroll (GdkEventScroll* ev)
{
- cerr << "layout_expose() called" << endl;
- return TRUE;
+ switch (ev->direction) {
+ case GDK_SCROLL_UP:
+ scroll_tracks_up_line ();
+ return true;
+ break;
+
+ case GDK_SCROLL_DOWN:
+ scroll_tracks_down_line ();
+ return true;
+
+ default:
+ /* no left/right handling yet */
+ break;
+ }
+
+ return false;
}