X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor.cc;h=c9c309c6c545a51fd682b322aa288563ea713ac3;hb=9649a94053eda177086ac2930c7d172db3a2af11;hp=a984f6129ef8c7937e156af09f179db469021fe0;hpb=6532d139ec2dc569e6e46cfc9a933f7111c44b03;p=ardour.git diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index a984f6129e..c9c309c6c5 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2007 Paul Davis + Copyright (C) 2000-2009 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 @@ -19,11 +19,14 @@ /* Note: public Editor methods are documented in public_editor.h */ +#define __STDC_LIMIT_MACROS 1 +#include #include #include #include #include #include +#include #include @@ -33,6 +36,7 @@ #include "pbd/error.h" #include "pbd/enumwriter.h" #include "pbd/memento_command.h" +#include "pbd/unknown_type.h" #include #include @@ -45,6 +49,7 @@ #include #include #include +#include #include "ardour/audio_diskstream.h" #include "ardour/audio_track.h" @@ -91,6 +96,14 @@ #include "bundle_manager.h" #include "global_port_matrix.h" #include "editor_drag.h" +#include "editor_group_tabs.h" +#include "automation_time_axis.h" +#include "editor_routes.h" +#include "midi_time_axis.h" +#include "mixer_strip.h" +#include "editor_route_groups.h" +#include "editor_regions.h" +#include "editor_snapshots.h" #include "i18n.h" @@ -198,50 +211,47 @@ show_me_the_size (Requisition* r, const char* what) } Editor::Editor () - : /* time display buttons */ - - minsec_label (_("Mins:Secs")), - bbt_label (_("Bars:Beats")), - smpte_label (_("Timecode")), - frame_label (_("Samples")), - tempo_label (_("Tempo")), - meter_label (_("Meter")), - mark_label (_("Location Markers")), - range_mark_label (_("Range Markers")), - transport_mark_label (_("Loop/Punch Ranges")), - cd_mark_label (_("CD Markers")), - edit_packer (3, 4, true), + : minsec_label (_("Mins:Secs")) + , bbt_label (_("Bars:Beats")) + , smpte_label (_("Timecode")) + , frame_label (_("Samples")) + , tempo_label (_("Tempo")) + , meter_label (_("Meter")) + , mark_label (_("Location Markers")) + , range_mark_label (_("Range Markers")) + , transport_mark_label (_("Loop/Punch Ranges")) + , cd_mark_label (_("CD Markers")) + , edit_packer (4, 4, true) /* the values here don't matter: layout widgets reset them as needed. */ - - vertical_adjustment (0.0, 0.0, 10.0, 400.0), - horizontal_adjustment (0.0, 0.0, 20.0, 1200.0), - + + , vertical_adjustment (0.0, 0.0, 10.0, 400.0) + , horizontal_adjustment (0.0, 0.0, 20.0, 1200.0) + /* tool bar related */ - edit_point_clock (X_("editpoint"), false, X_("EditPointClock"), true), - zoom_range_clock (X_("zoomrange"), false, X_("ZoomRangeClock"), true, true), + , edit_point_clock (X_("editpoint"), false, X_("EditPointClock"), true) + , zoom_range_clock (X_("zoomrange"), false, X_("ZoomRangeClock"), true, true) - toolbar_selection_clock_table (2,3), + , toolbar_selection_clock_table (2,3) + + , automation_mode_button (_("mode")) + , global_automation_button (_("automation")) + + , midi_panic_button (_("Panic")) - automation_mode_button (_("mode")), - global_automation_button (_("automation")), - - midi_panic_button (_("Panic")), - midi_tools_tearoff (0), - #ifdef WITH_CMT - image_socket_listener(0), + , image_socket_listener(0) #endif - + /* nudge */ - - nudge_clock (X_("nudge"), false, X_("NudgeClock"), true, true), - meters_running(false), - _pending_locate_request (false) + + , nudge_clock (X_("nudge"), false, X_("NudgeClock"), true, true) + , meters_running(false) + , _pending_locate_request (false) { constructed = false; @@ -277,8 +287,8 @@ Editor::Editor () snap_threshold = 5.0; bbt_beat_subdivision = 4; - canvas_width = 0; - canvas_height = 0; + _canvas_width = 0; + _canvas_height = 0; last_autoscroll_x = 0; last_autoscroll_y = 0; autoscroll_active = false; @@ -290,27 +300,18 @@ Editor::Editor () current_interthread_info = 0; _show_measures = true; - _show_waveforms = true; _show_waveforms_recording = true; show_gain_after_trim = false; - route_redisplay_does_not_sync_order_keys = false; - route_redisplay_does_not_reset_order_keys = false; - no_route_list_redisplay = false; verbose_cursor_on = true; route_removal = false; - show_automatic_regions_in_region_list = true; last_item_entered = 0; last_item_entered_n = 0; - region_list_sort_type = (Editing::RegionListSortType) 0; have_pending_keyboard_selection = false; _follow_playhead = true; _xfade_visibility = true; editor_ruler_menu = 0; no_ruler_shown_update = false; - edit_group_list_menu = 0; - route_list_menu = 0; - region_list_menu = 0; marker_menu = 0; start_end_marker_menu = 0; range_marker_menu = 0; @@ -324,8 +325,6 @@ Editor::Editor () region_edit_menu_split_item = 0; temp_location = 0; leftmost_frame = 0; - ignore_mouse_mode_toggle = false; - ignore_midi_edit_mode_toggle = false; current_stepping_trackview = 0; entered_track = 0; entered_regionview = 0; @@ -333,7 +332,6 @@ Editor::Editor () clear_entered_track = false; _new_regionviews_show_envelope = false; current_timefx = 0; - in_edit_group_row_change = false; playhead_cursor = 0; button_release_can_deselect = true; _dragging_playhead = false; @@ -348,10 +346,6 @@ Editor::Editor () } allow_vertical_scroll = false; no_save_visual = false; - need_resize_line = false; - resize_line_y = 0; - old_resize_line_y = -1; - no_region_list_redisplay = false; resize_idle_id = -1; scrubbing_direction = 0; @@ -364,9 +358,9 @@ Editor::Editor () location_loop_color = ARDOUR_UI::config()->canvasvar_LocationLoop.get(); location_punch_color = ARDOUR_UI::config()->canvasvar_LocationPunch.get(); - set_midi_edit_mode (MidiEditPencil, true); _edit_point = EditAtMouse; - set_mouse_mode (MouseObject, true); + _internal_editing = false; + current_canvas_cursor = 0; frames_per_unit = 2048; /* too early to use reset_zoom () */ reset_hscrollbar_stepping (); @@ -438,6 +432,7 @@ Editor::Editor () transport_mark_label.set_no_show_all(); initialize_rulers (); + _summary = new EditorSummary (this); initialize_canvas (); selection->TimeChanged.connect (mem_fun(*this, &Editor::time_selection_changed)); @@ -451,7 +446,12 @@ Editor::Editor () vertical_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::tie_vertical_scrolling), true); track_canvas->signal_map_event().connect (mem_fun (*this, &Editor::track_canvas_map_handler)); - controls_layout.add (edit_controls_vbox); + HBox* h = manage (new HBox); + _group_tabs = new EditorGroupTabs (this); + h->pack_start (*_group_tabs, PACK_SHRINK); + h->pack_start (edit_controls_vbox); + controls_layout.add (*h); + controls_layout.set_name ("EditControlsBase"); controls_layout.add_events (Gdk::SCROLL_MASK); controls_layout.signal_scroll_event().connect (mem_fun(*this, &Editor::control_layout_scroll), false); @@ -482,16 +482,14 @@ Editor::Editor () pad_line_1->show(); time_pad->show(); - //time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2); - //time_canvas_vbox.set_size_request (-1, -1); + time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2); + time_canvas_vbox.set_size_request (-1, -1); ruler_label_event_box.add (ruler_label_vbox); ruler_label_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - ruler_label_event_box.set_name ("TimebarLabelBase"); ruler_label_event_box.signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_label_button_release)); time_button_event_box.add (time_button_vbox); - time_button_event_box.set_name ("TimebarLabelBase"); time_button_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); time_button_event_box.signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_label_button_release)); @@ -503,208 +501,33 @@ Editor::Editor () time_canvas_event_box.add (time_canvas_vbox); time_canvas_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK); - + edit_packer.set_col_spacings (0); edit_packer.set_row_spacings (0); edit_packer.set_homogeneous (false); edit_packer.set_border_width (0); edit_packer.set_name ("EditorWindow"); -#ifndef THE_OLD_WAY - - edit_packer.attach (ruler_label_event_box, 0, 1, 0, 1, FILL, SHRINK, 0, 0); - - edit_packer.attach (time_button_event_box, 0, 1, 1, 2, FILL, SHRINK, 0, 0); - edit_packer.attach (time_canvas_event_box, 1, 2, 0, 1, FILL|EXPAND, FILL, 0, 0); - - edit_packer.attach (controls_layout, 0, 1, 2, 3, FILL, FILL|EXPAND, 0, 0); - edit_packer.attach (track_canvas_event_box, 1, 2, 1, 3, FILL|EXPAND, FILL|EXPAND, 0, 0); - - edit_packer.attach (zoom_box, 0, 1, 3, 4, FILL, FILL, 0, 0); - edit_packer.attach (edit_hscrollbar, 1, 2, 3, 4, FILL|EXPAND, FILL, 0, 0); - - edit_packer.attach (edit_vscrollbar, 3, 4, 2, 3, FILL, FILL|EXPAND, 0, 0); - -#else - - edit_packer.attach (edit_vscrollbar, 0, 1, 0, 4, FILL, FILL|EXPAND, 0, 0); - + edit_packer.attach (zoom_vbox, 0, 1, 0, 2, SHRINK, FILL, 0, 0); + /* labels for the rulers */ edit_packer.attach (ruler_label_event_box, 1, 2, 0, 1, FILL, SHRINK, 0, 0); + /* labels for the marker "tracks" */ edit_packer.attach (time_button_event_box, 1, 2, 1, 2, FILL, SHRINK, 0, 0); + /* the rulers */ edit_packer.attach (time_canvas_event_box, 2, 3, 0, 1, FILL|EXPAND, FILL, 0, 0); - - edit_packer.attach (controls_layout, 1, 2, 2, 3, FILL, FILL|EXPAND, 0, 0); + /* track controls */ + edit_packer.attach (controls_layout, 0, 2, 2, 3, FILL, FILL|EXPAND, 0, 0); + /* main canvas */ edit_packer.attach (track_canvas_event_box, 2, 3, 1, 3, FILL|EXPAND, FILL|EXPAND, 0, 0); - edit_packer.attach (zoom_box, 1, 2, 3, 4, FILL, FILL, 0, 0); - edit_packer.attach (edit_hscrollbar, 2, 3, 3, 4, FILL|EXPAND, FILL, 0, 0); -#endif - bottom_hbox.set_border_width (2); bottom_hbox.set_spacing (3); - route_display_model = ListStore::create(route_display_columns); - route_list_display.set_model (route_display_model); - route_list_display.append_column (_("Show"), route_display_columns.visible); - route_list_display.append_column (_("Name"), route_display_columns.text); - route_list_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0)); - route_list_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1)); - route_list_display.set_headers_visible (true); - route_list_display.set_name ("TrackListDisplay"); - route_list_display.get_selection()->set_mode (SELECTION_SINGLE); - route_list_display.set_reorderable (true); - route_list_display.set_size_request (100,-1); - route_list_display.add_object_drag (route_display_columns.route.index(), "routes"); - - CellRendererToggle* route_list_visible_cell = dynamic_cast(route_list_display.get_column_cell_renderer (0)); - route_list_visible_cell->property_activatable() = true; - route_list_visible_cell->property_radio() = false; - - route_display_model->signal_row_deleted().connect (mem_fun (*this, &Editor::route_list_delete)); - route_display_model->signal_row_changed().connect (mem_fun (*this, &Editor::route_list_change)); - route_display_model->signal_rows_reordered().connect (mem_fun (*this, &Editor::route_list_reordered)); - - route_list_display.signal_button_press_event().connect (mem_fun (*this, &Editor::route_list_display_button_press), false); - - route_list_scroller.add (route_list_display); - route_list_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); - - group_model = ListStore::create(group_columns); - edit_group_display.set_model (group_model); - edit_group_display.append_column (_("Name"), group_columns.text); - edit_group_display.append_column (_("Active"), group_columns.is_active); - edit_group_display.append_column (_("Show"), group_columns.is_visible); - edit_group_display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0)); - edit_group_display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1)); - edit_group_display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2)); - edit_group_display.get_column (0)->set_expand (true); - edit_group_display.get_column (1)->set_expand (false); - edit_group_display.get_column (2)->set_expand (false); - edit_group_display.set_headers_visible (true); - - /* name is directly editable */ - - CellRendererText* name_cell = dynamic_cast(edit_group_display.get_column_cell_renderer (0)); - name_cell->property_editable() = true; - name_cell->signal_edited().connect (mem_fun (*this, &Editor::edit_group_name_edit)); - - /* use checkbox for the active + visible columns */ - - CellRendererToggle* active_cell = dynamic_cast(edit_group_display.get_column_cell_renderer (1)); - active_cell->property_activatable() = true; - active_cell->property_radio() = false; - - active_cell = dynamic_cast(edit_group_display.get_column_cell_renderer (1)); - active_cell->property_activatable() = true; - active_cell->property_radio() = false; - - group_model->signal_row_changed().connect (mem_fun (*this, &Editor::edit_group_row_change)); - - edit_group_display.set_name ("EditGroupList"); - edit_group_display.get_selection()->set_mode (SELECTION_SINGLE); - edit_group_display.set_headers_visible (true); - edit_group_display.set_reorderable (false); - edit_group_display.set_rules_hint (true); - edit_group_display.set_size_request (75, -1); - - edit_group_display_scroller.add (edit_group_display); - edit_group_display_scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC); - - edit_group_display.signal_button_press_event().connect (mem_fun(*this, &Editor::edit_group_list_button_press_event), false); - - VBox* edit_group_display_packer = manage (new VBox()); - HBox* edit_group_display_button_box = manage (new HBox()); - edit_group_display_button_box->set_homogeneous (true); - - Button* edit_group_add_button = manage (new Button ()); - Button* edit_group_remove_button = manage (new Button ()); - - Widget* w; - - w = manage (new Image (Stock::ADD, ICON_SIZE_BUTTON)); - w->show(); - edit_group_add_button->add (*w); - - w = manage (new Image (Stock::REMOVE, ICON_SIZE_BUTTON)); - w->show(); - edit_group_remove_button->add (*w); - - edit_group_add_button->signal_clicked().connect (mem_fun (*this, &Editor::new_edit_group)); - edit_group_remove_button->signal_clicked().connect (mem_fun (*this, &Editor::remove_selected_edit_group)); - - edit_group_display_button_box->pack_start (*edit_group_add_button); - edit_group_display_button_box->pack_start (*edit_group_remove_button); - - edit_group_display_packer->pack_start (edit_group_display_scroller, true, true); - edit_group_display_packer->pack_start (*edit_group_display_button_box, false, false); - - region_list_display.set_size_request (100, -1); - region_list_display.set_name ("RegionListDisplay"); - /* Try to prevent single mouse presses from initiating edits. - This relies on a hack in gtktreeview.c:gtk_treeview_button_press() - */ - region_list_display.set_data ("mouse-edits-require-mod1", (gpointer) 0x1); - - region_list_model = TreeStore::create (region_list_columns); - region_list_model->set_sort_func (0, mem_fun (*this, &Editor::region_list_sorter)); - region_list_model->set_sort_column (0, SORT_ASCENDING); - - region_list_display.set_model (region_list_model); - region_list_display.append_column (_("Regions"), region_list_columns.name); - region_list_display.append_column (_("Start"), region_list_columns.start); - region_list_display.append_column (_("End"), region_list_columns.end); - region_list_display.append_column (_("Length"), region_list_columns.length); - region_list_display.append_column (_("Sync"), region_list_columns.sync); - region_list_display.append_column (_("Fade In"), region_list_columns.fadein); - region_list_display.append_column (_("Fade Out"), region_list_columns.fadeout); - region_list_display.append_column (_("L"), region_list_columns.locked); - region_list_display.append_column (_("G"), region_list_columns.glued); - region_list_display.append_column (_("M"), region_list_columns.muted); - region_list_display.append_column (_("O"), region_list_columns.opaque); - region_list_display.append_column (_("Used"), region_list_columns.used); - region_list_display.append_column (_("Path"), region_list_columns.path); - region_list_display.set_headers_visible (true); - //region_list_display.set_grid_lines (TREE_VIEW_GRID_LINES_BOTH); - - CellRendererText* region_name_cell = dynamic_cast(region_list_display.get_column_cell_renderer (0)); - region_name_cell->property_editable() = true; - region_name_cell->signal_edited().connect (mem_fun (*this, &Editor::region_name_edit)); - - region_list_display.get_selection()->set_select_function (mem_fun (*this, &Editor::region_list_selection_filter)); - - TreeViewColumn* tv_col = region_list_display.get_column(0); - CellRendererText* renderer = dynamic_cast(region_list_display.get_column_cell_renderer (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.get_selection()->set_mode (SELECTION_MULTIPLE); - region_list_display.add_object_drag (region_list_columns.region.index(), "regions"); - - /* setup DnD handling */ - - list region_list_target_table; - - 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)); + _route_groups = new EditorRouteGroups (this); + _routes = new EditorRoutes (this); + _regions = new EditorRegions (this); + _snapshots = new EditorSnapshots (this); - region_list_scroller.add (region_list_display); - region_list_scroller.set_policy (POLICY_AUTOMATIC, 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), false); - region_list_display.signal_button_release_event().connect (mem_fun(*this, &Editor::region_list_display_button_release)); - region_list_change_connection = region_list_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::region_list_selection_changed)); - // region_list_display.signal_popup_menu().connect (bind (mem_fun (*this, &Editor::show_region_list_display_context_menu), 1, 0)); - - //ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (mem_fun(*this, &Editor::redisplay_regions)); - ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (mem_fun(*this, &Editor::update_all_region_rows)); - ARDOUR::Region::RegionPropertyChanged.connect (mem_fun(*this, &Editor::update_region_row)); - named_selection_scroller.add (named_selection_display); named_selection_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); @@ -721,35 +544,20 @@ Editor::Editor () named_selection_display.signal_key_release_event().connect (mem_fun(*this, &Editor::named_selection_display_key_release), false); named_selection_display.get_selection()->signal_changed().connect (mem_fun (*this, &Editor::named_selection_display_selection_changed)); - /* SNAPSHOTS */ - - snapshot_display_model = ListStore::create (snapshot_display_columns); - snapshot_display.set_model (snapshot_display_model); - snapshot_display.append_column (X_("snapshot"), snapshot_display_columns.visible_name); - snapshot_display.set_name ("SnapshotDisplay"); - snapshot_display.set_size_request (75, -1); - snapshot_display.set_headers_visible (false); - snapshot_display.set_reorderable (false); - snapshot_display_scroller.add (snapshot_display); - snapshot_display_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); - - snapshot_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::snapshot_display_selection_changed)); - snapshot_display.signal_button_press_event().connect (mem_fun (*this, &Editor::snapshot_display_button_press), false); - Gtk::Label* nlabel; nlabel = manage (new Label (_("Regions"))); nlabel->set_angle (-90); - the_notebook.append_page (region_list_scroller, *nlabel); + the_notebook.append_page (_regions->widget (), *nlabel); nlabel = manage (new Label (_("Tracks/Busses"))); nlabel->set_angle (-90); - the_notebook.append_page (route_list_scroller, *nlabel); + the_notebook.append_page (_routes->widget (), *nlabel); nlabel = manage (new Label (_("Snapshots"))); nlabel->set_angle (-90); - the_notebook.append_page (snapshot_display_scroller, *nlabel); - nlabel = manage (new Label (_("Edit Groups"))); + the_notebook.append_page (_snapshots->widget (), *nlabel); + nlabel = manage (new Label (_("Route Groups"))); nlabel->set_angle (-90); - the_notebook.append_page (*edit_group_display_packer, *nlabel); + the_notebook.append_page (_route_groups->widget (), *nlabel); if (!Profile->get_sae()) { nlabel = manage (new Label (_("Chunks"))); @@ -765,13 +573,17 @@ Editor::Editor () post_maximal_editor_width = 0; post_maximal_pane_position = 0; - edit_pane.pack1 (edit_packer, true, true); + + VPaned *editor_summary_pane = manage(new VPaned()); + editor_summary_pane->pack1(edit_packer); + editor_summary_pane->pack2(*_summary); + + edit_pane.pack1 (*editor_summary_pane, true, true); edit_pane.pack2 (the_notebook, false, true); edit_pane.signal_size_allocate().connect (bind (mem_fun(*this, &Editor::pane_allocation_handler), static_cast (&edit_pane))); top_hbox.pack_start (toolbar_frame, false, true); - top_hbox.pack_start (midi_toolbar_frame, false, true); HBox *hbox = manage (new HBox); hbox->pack_start (edit_pane, true, true); @@ -797,6 +609,7 @@ Editor::Editor () set_snap_to (snap_type); snap_mode = SnapOff; set_snap_mode (snap_mode); + set_mouse_mode (MouseObject, true); set_edit_point_preference (EditAtMouse, true); XMLNode* node = ARDOUR_UI::instance()->editor_settings(); @@ -862,7 +675,8 @@ Editor::Editor () BasicUI::AccessAction.connect (mem_fun (*this, &Editor::access_action)); Config->ParameterChanged.connect (mem_fun (*this, &Editor::parameter_changed)); - Route::SyncOrderKeys.connect (mem_fun (*this, &Editor::sync_order_keys)); + + _last_normalization_value = 0; constructed = true; instant_save (); @@ -882,6 +696,8 @@ Editor::~Editor() } #endif + delete _routes; + delete _route_groups; delete track_canvas; delete _drag; } @@ -949,8 +765,13 @@ Editor::show_window () if (! is_visible ()) { show_all (); - /* re-hide editor list if necessary */ - editor_list_button_toggled (); + /* re-hide editor list if necessary */ + editor_list_button_toggled (); + + /* re-hide summary widget if necessary */ + parameter_changed ("show-summary"); + + parameter_changed ("show-edit-group-tabs"); /* now reset all audio_time_axis heights, because widgets might need to be re-hidden @@ -1009,14 +830,14 @@ Editor::zoom_adjustment_changed () return; } - double fpu = zoom_range_clock.current_duration() / canvas_width; + double fpu = zoom_range_clock.current_duration() / _canvas_width; if (fpu < 1.0) { fpu = 1.0; - zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width)); - } else if (fpu > session->current_end_frame() / canvas_width) { - fpu = session->current_end_frame() / canvas_width; - zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width)); + zoom_range_clock.set ((nframes64_t) floor (fpu * _canvas_width)); + } else if (fpu > session->current_end_frame() / _canvas_width) { + fpu = session->current_end_frame() / _canvas_width; + zoom_range_clock.set ((nframes64_t) floor (fpu * _canvas_width)); } temporal_zoom (fpu); @@ -1085,7 +906,7 @@ Editor::control_scroll (float fraction) } bool -Editor::deferred_control_scroll (nframes64_t target) +Editor::deferred_control_scroll (nframes64_t /*target*/) { session->request_locate (*_control_scroll_target, session->transport_rolling()); // reset for next stream @@ -1150,7 +971,7 @@ Editor::map_position_change (nframes64_t frame) void Editor::center_screen (nframes64_t frame) { - double page = canvas_width * frames_per_unit; + double page = _canvas_width * frames_per_unit; /* if we're off the page, then scroll. */ @@ -1187,8 +1008,8 @@ Editor::handle_new_duration () horizontal_adjustment.set_upper (new_end / frames_per_unit); horizontal_adjustment.set_page_size (current_page_frames()/frames_per_unit); - if (horizontal_adjustment.get_value() + canvas_width > horizontal_adjustment.get_upper()) { - horizontal_adjustment.set_value (horizontal_adjustment.get_upper() - canvas_width); + if (horizontal_adjustment.get_value() + _canvas_width > horizontal_adjustment.get_upper()) { + horizontal_adjustment.set_value (horizontal_adjustment.get_upper() - _canvas_width); } //cerr << "Editor::handle_new_duration () called ha v:l:u:ps:lcf = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << endl;//DEBUG } @@ -1258,17 +1079,12 @@ Editor::connect_to_session (Session *t) session_connections.push_back (session->TransportStateChange.connect (mem_fun(*this, &Editor::map_transport_state))); session_connections.push_back (session->PositionChanged.connect (mem_fun(*this, &Editor::map_position_change))); session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route))); - session_connections.push_back (session->RegionsAdded.connect (mem_fun(*this, &Editor::handle_new_regions))); - session_connections.push_back (session->RegionRemoved.connect (mem_fun(*this, &Editor::handle_region_removed))); session_connections.push_back (session->DurationChanged.connect (mem_fun(*this, &Editor::handle_new_duration))); - session_connections.push_back (session->edit_group_added.connect (mem_fun(*this, &Editor::add_edit_group))); - session_connections.push_back (session->edit_group_removed.connect (mem_fun(*this, &Editor::edit_groups_changed))); session_connections.push_back (session->NamedSelectionAdded.connect (mem_fun(*this, &Editor::handle_new_named_selection))); session_connections.push_back (session->NamedSelectionRemoved.connect (mem_fun(*this, &Editor::handle_new_named_selection))); session_connections.push_back (session->DirtyChanged.connect (mem_fun(*this, &Editor::update_title))); session_connections.push_back (session->StateSaved.connect (mem_fun(*this, &Editor::update_title_s))); session_connections.push_back (session->AskAboutPlaylistDeletion.connect (mem_fun(*this, &Editor::playlist_deletion_dialog))); - session_connections.push_back (session->RegionHiddenChange.connect (mem_fun(*this, &Editor::region_hidden))); session_connections.push_back (session->SMPTEOffsetChanged.connect (mem_fun(*this, &Editor::update_just_smpte))); @@ -1277,8 +1093,6 @@ Editor::connect_to_session (Session *t) session_connections.push_back (session->Located.connect (mem_fun (*this, &Editor::located))); session_connections.push_back (session->config.ParameterChanged.connect (mem_fun (*this, &Editor::parameter_changed))); - edit_groups_changed (); - edit_point_clock.set_mode(AudioClock::BBT); edit_point_clock.set_session (session); zoom_range_clock.set_session (session); @@ -1333,6 +1147,7 @@ Editor::connect_to_session (Session *t) } Config->map_parameters (mem_fun (*this, &Editor::parameter_changed)); + session->config.map_parameters (mem_fun (*this, &Editor::parameter_changed)); session->StateSaved.connect (mem_fun(*this, &Editor::session_state_saved)); @@ -1349,46 +1164,18 @@ Editor::connect_to_session (Session *t) handle_new_duration (); - redisplay_regions (); redisplay_named_selections (); - redisplay_snapshots (); restore_ruler_visibility (); //tempo_map_changed (Change (0)); session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); - initial_route_list_display (); - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (static_cast(*i))->set_samples_per_unit (frames_per_unit); } start_scrolling (); - /* don't show master bus in a new session */ - - if (ARDOUR_UI::instance()->session_is_new ()) { - - TreeModel::Children rows = route_display_model->children(); - TreeModel::Children::iterator i; - - no_route_list_redisplay = true; - - for (i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; - RouteTimeAxisView *rtv; - - if ((rtv = dynamic_cast(tv)) != 0) { - if (rtv->route()->is_master()) { - route_list_display.get_selection()->unselect (i); - } - } - } - - no_route_list_redisplay = false; - redisplay_route_list (); - } - switch (snap_type) { case SnapToRegionStart: case SnapToRegionEnd: @@ -1404,6 +1191,13 @@ Editor::connect_to_session (Session *t) /* register for undo history */ session->register_with_memento_command_factory(_id, this); + _summary->connect_to_session (session); + _group_tabs->connect_to_session (session); + _route_groups->connect_to_session (session); + _regions->connect_to_session (session); + _snapshots->connect_to_session (session); + _routes->connect_to_session (session); + start_updating (); } @@ -1669,7 +1463,7 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, } Menu* -Editor::build_track_context_menu (nframes64_t ignored) +Editor::build_track_context_menu (nframes64_t) { using namespace Menu_Helpers; @@ -1681,7 +1475,7 @@ Editor::build_track_context_menu (nframes64_t ignored) } Menu* -Editor::build_track_bus_context_menu (nframes64_t ignored) +Editor::build_track_bus_context_menu (nframes64_t) { using namespace Menu_Helpers; @@ -1813,7 +1607,7 @@ Editor::analyze_range_selection() } Menu* -Editor::build_track_selection_context_menu (nframes64_t ignored) +Editor::build_track_selection_context_menu (nframes64_t) { using namespace Menu_Helpers; MenuList& edit_items = track_selection_context_menu.items(); @@ -1830,7 +1624,7 @@ Editor::build_track_selection_context_menu (nframes64_t ignored) * @param edit_items List to add the items to. */ void -Editor::add_crossfade_context_items (AudioStreamView* view, boost::shared_ptr xfade, Menu_Helpers::MenuList& edit_items, bool many) +Editor::add_crossfade_context_items (AudioStreamView* /*view*/, boost::shared_ptr xfade, Menu_Helpers::MenuList& edit_items, bool many) { using namespace Menu_Helpers; Menu *xfade_menu = manage (new Menu); @@ -1886,20 +1680,6 @@ Editor::xfade_edit_right_region () } } -/** Add an element to a menu, settings its sensitivity. - * @param m Menu to add to. - * @param e Element to add. - * @param s true to make sensitive, false to make insensitive - */ -void -Editor::add_item_with_sensitivity (Menu_Helpers::MenuList& m, Menu_Helpers::MenuElem e, bool s) const -{ - m.push_back (e); - if (!s) { - m.back().set_sensitive (false); - } -} - void Editor::add_region_context_items (StreamView* sv, boost::shared_ptr region, Menu_Helpers::MenuList& edit_items) { @@ -2135,40 +1915,44 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items) { using namespace Menu_Helpers; - edit_items.push_back (MenuElem (_("Play range"), mem_fun(*this, &Editor::play_selection))); - edit_items.push_back (MenuElem (_("Loop range"), bind (mem_fun(*this, &Editor::set_loop_from_selection), true))); + edit_items.push_back (MenuElem (_("Play Range"), mem_fun(*this, &Editor::play_selection))); + edit_items.push_back (MenuElem (_("Loop Range"), bind (mem_fun(*this, &Editor::set_loop_from_selection), true))); edit_items.push_back (SeparatorElem()); edit_items.push_back (MenuElem (_("Spectral Analysis"), mem_fun(*this, &Editor::analyze_range_selection))); - - edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Extend Range to End of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_end_of_region), false))); - edit_items.push_back (MenuElem (_("Extend Range to Start of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_start_of_region), false))); + + if (!selection->regions.empty()) { + edit_items.push_back (SeparatorElem()); + edit_items.push_back (MenuElem (_("Extend Range to End of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_end_of_region), false))); + edit_items.push_back (MenuElem (_("Extend Range to Start of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_start_of_region), false))); + } edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Convert to region in-place"), mem_fun(*this, &Editor::separate_region_from_selection))); - edit_items.push_back (MenuElem (_("Convert to region in region list"), mem_fun(*this, &Editor::new_region_from_selection))); + edit_items.push_back (MenuElem (_("Silence Range"), mem_fun(*this, &Editor::separate_region_from_selection))); + edit_items.push_back (MenuElem (_("Convert to Region in Region List"), mem_fun(*this, &Editor::new_region_from_selection))); edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Select all in range"), mem_fun(*this, &Editor::select_all_selectables_using_time_selection))); + edit_items.push_back (MenuElem (_("Select All in Range"), mem_fun(*this, &Editor::select_all_selectables_using_time_selection))); edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Set loop from selection"), bind (mem_fun(*this, &Editor::set_loop_from_selection), false))); - edit_items.push_back (MenuElem (_("Set punch from selection"), mem_fun(*this, &Editor::set_punch_from_selection))); + edit_items.push_back (MenuElem (_("Set Loop from Range"), bind (mem_fun(*this, &Editor::set_loop_from_selection), false))); + edit_items.push_back (MenuElem (_("Set Punch from Range"), mem_fun(*this, &Editor::set_punch_from_selection))); edit_items.push_back (SeparatorElem()); edit_items.push_back (MenuElem (_("Add Range Markers"), mem_fun (*this, &Editor::add_location_from_selection))); + edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Crop region to range"), mem_fun(*this, &Editor::crop_region_to_selection))); - edit_items.push_back (MenuElem (_("Fill range with region"), mem_fun(*this, &Editor::region_fill_selection))); - edit_items.push_back (MenuElem (_("Duplicate range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false))); - edit_items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::create_named_selection))); + edit_items.push_back (MenuElem (_("Crop Region to Range"), mem_fun(*this, &Editor::crop_region_to_selection))); + edit_items.push_back (MenuElem (_("Fill Range with Region"), mem_fun(*this, &Editor::region_fill_selection))); + edit_items.push_back (MenuElem (_("Duplicate Range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false))); + edit_items.push_back (MenuElem (_("Create Chunk from Range"), mem_fun(*this, &Editor::create_named_selection))); + edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Consolidate range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, false))); - edit_items.push_back (MenuElem (_("Consolidate range with processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, true))); - edit_items.push_back (MenuElem (_("Bounce range to region list"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, false))); - edit_items.push_back (MenuElem (_("Bounce range to region list with processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, true))); - edit_items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_range))); + edit_items.push_back (MenuElem (_("Consolidate Range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, false))); + edit_items.push_back (MenuElem (_("Consolidate Range With Processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, true))); + edit_items.push_back (MenuElem (_("Bounce Range to Region List"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, false))); + edit_items.push_back (MenuElem (_("Bounce Range to Region List With Processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, true))); + edit_items.push_back (MenuElem (_("Export Range"), mem_fun(*this, &Editor::export_range))); } @@ -2541,10 +2325,6 @@ Editor::set_state (const XMLNode& node) set_snap_mode ((SnapMode) atoi (prop->value())); } - if ((prop = node.property ("edit-point"))) { - set_edit_point_preference ((EditPoint) string_2_enum (prop->value(), _edit_point), true); - } - if ((prop = node.property ("mouse-mode"))) { MouseMode m = str2mousemode(prop->value()); mouse_mode = MouseMode ((int) m + 1); /* lie, force mode switch */ @@ -2554,16 +2334,8 @@ Editor::set_state (const XMLNode& node) set_mouse_mode (MouseObject, true); } - if ((prop = node.property ("show-waveforms"))) { - bool yn = (prop->value() == "yes"); - _show_waveforms = !yn; - RefPtr act = ActionManager::get_action (X_("Editor"), X_("toggle-waveform-visible")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); - /* do it twice to force the change */ - tact->set_active (!yn); - tact->set_active (yn); - } + if ((prop = node.property ("edit-point"))) { + set_edit_point_preference ((EditPoint) string_2_enum (prop->value(), _edit_point), true); } if ((prop = node.property ("show-waveforms-recording"))) { @@ -2603,8 +2375,7 @@ Editor::set_state (const XMLNode& node) } if ((prop = node.property ("region-list-sort-type"))) { - region_list_sort_type = (Editing::RegionListSortType) -1; // force change - reset_region_list_sort_type(str2regionlistsorttype(prop->value())); + _regions->reset_sort_type (str2regionlistsorttype(prop->value()), true); } if ((prop = node.property ("xfades-visible"))) { @@ -2701,12 +2472,11 @@ Editor::get_state () snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame); node->add_property ("playhead", buf); - node->add_property ("show-waveforms", _show_waveforms ? "yes" : "no"); node->add_property ("show-waveforms-recording", _show_waveforms_recording ? "yes" : "no"); node->add_property ("show-measures", _show_measures ? "yes" : "no"); node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no"); node->add_property ("xfades-visible", _xfade_visibility ? "yes" : "no"); - node->add_property ("region-list-sort-type", enum2str(region_list_sort_type)); + node->add_property ("region-list-sort-type", enum2str (_regions->sort_type ())); node->add_property ("mouse-mode", enum2str(mouse_mode)); Glib::RefPtr act = ActionManager::get_action (X_("Editor"), X_("show-editor-mixer")); @@ -3010,36 +2780,13 @@ Editor::setup_toolbar () /* Mode Buttons (tool selection) */ - vector mouse_mode_buttons; - - mouse_move_button.add (*(manage (new Image (::get_icon("tool_object"))))); mouse_move_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_move_button); - - if (!Profile->get_sae()) { - mouse_select_button.add (*(manage (new Image (get_xpm("tool_range.xpm"))))); - mouse_select_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_select_button); - - mouse_gain_button.add (*(manage (new Image (::get_icon("tool_gain"))))); - mouse_gain_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_gain_button); - } - - mouse_zoom_button.add (*(manage (new Image (::get_icon("tool_zoom"))))); + mouse_select_button.set_relief(Gtk::RELIEF_NONE); + mouse_gain_button.set_relief(Gtk::RELIEF_NONE); mouse_zoom_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_zoom_button); - mouse_timefx_button.add (*(manage (new Image (::get_icon("tool_stretch"))))); mouse_timefx_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_timefx_button); - mouse_audition_button.add (*(manage (new Image (::get_icon("tool_audition"))))); mouse_audition_button.set_relief(Gtk::RELIEF_NONE); - mouse_note_button.add (*(manage (new Image (::get_icon("tool_note"))))); - mouse_note_button.set_relief(Gtk::RELIEF_NONE); - mouse_mode_buttons.push_back (&mouse_note_button); - mouse_mode_buttons.push_back (&mouse_audition_button); - - mouse_mode_button_set = new GroupedButtons (mouse_mode_buttons); + // internal_edit_button.set_relief(Gtk::RELIEF_NONE); HBox* mode_box = manage(new HBox); mode_box->set_border_width (2); @@ -3055,7 +2802,7 @@ Editor::setup_toolbar () } mouse_mode_button_box.pack_start(mouse_timefx_button, true, true); mouse_mode_button_box.pack_start(mouse_audition_button, true, true); - mouse_mode_button_box.pack_start(mouse_note_button, true, true); + mouse_mode_button_box.pack_start(internal_edit_button, true, true); mouse_mode_button_box.set_homogeneous(true); vector edit_mode_strings; @@ -3088,21 +2835,21 @@ Editor::setup_toolbar () mouse_mode_tearoff->Visible.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), &mouse_mode_tearoff->tearoff_window(), 1)); + mouse_move_button.set_mode (false); + mouse_select_button.set_mode (false); + mouse_gain_button.set_mode (false); + mouse_zoom_button.set_mode (false); + mouse_timefx_button.set_mode (false); + mouse_audition_button.set_mode (false); + mouse_move_button.set_name ("MouseModeButton"); mouse_select_button.set_name ("MouseModeButton"); mouse_gain_button.set_name ("MouseModeButton"); mouse_zoom_button.set_name ("MouseModeButton"); mouse_timefx_button.set_name ("MouseModeButton"); mouse_audition_button.set_name ("MouseModeButton"); - mouse_note_button.set_name ("MouseModeButton"); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("Select/Move Objects")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("Select/Move Ranges")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_gain_button, _("Draw Gain Automation")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("Select Zoom Range")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("Stretch/Shrink Regions")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("Listen to Specific Regions")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_note_button, _("Edit MIDI Notes")); + internal_edit_button.set_name ("MouseModeButton"); mouse_move_button.unset_flags (CAN_FOCUS); mouse_select_button.unset_flags (CAN_FOCUS); @@ -3110,20 +2857,7 @@ Editor::setup_toolbar () mouse_zoom_button.unset_flags (CAN_FOCUS); mouse_timefx_button.unset_flags (CAN_FOCUS); mouse_audition_button.unset_flags (CAN_FOCUS); - mouse_note_button.unset_flags (CAN_FOCUS); - - mouse_select_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseRange)); - mouse_select_button.signal_button_release_event().connect (mem_fun(*this, &Editor::mouse_select_button_release)); - - mouse_move_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseObject)); - mouse_gain_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseGain)); - mouse_zoom_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseZoom)); - mouse_timefx_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseTimeFX)); - mouse_audition_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseAudition)); - mouse_note_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseNote)); - - // mouse_move_button.set_active (true); - + internal_edit_button.unset_flags (CAN_FOCUS); /* Zoom */ @@ -3153,11 +2887,15 @@ Editor::setup_toolbar () zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done)); ARDOUR_UI::instance()->tooltips().set_tip (zoom_focus_selector, _("Zoom focus")); - zoom_box.pack_start (zoom_focus_selector, true, true); zoom_box.pack_start (zoom_out_button, false, false); zoom_box.pack_start (zoom_in_button, false, false); zoom_box.pack_start (zoom_out_full_button, false, false); + HBox* zbc = manage (new HBox); + zbc->pack_start (zoom_focus_selector, PACK_SHRINK); + zoom_vbox.pack_start (*zbc, PACK_SHRINK); + zoom_vbox.pack_start (zoom_box, PACK_SHRINK); + snap_box.set_spacing (1); snap_box.set_border_width (2); @@ -3221,11 +2959,10 @@ Editor::setup_toolbar () toolbar_hbox.pack_start (*mouse_mode_tearoff, false, false); toolbar_hbox.pack_start (*tools_tearoff, false, false); - hbox->pack_start (snap_box, false, false); - // hbox->pack_start (zoom_box, false, false); hbox->pack_start (*nudge_box, false, false); + hbox->pack_start (panic_box, false, false); hbox->show_all (); @@ -3248,12 +2985,7 @@ Editor::midi_panic_button_pressed () void Editor::setup_midi_toolbar () { - string pixmap_path; - - /* Mode Buttons (tool selection) */ - - vector midi_tool_buttons; - +#if 0 midi_tool_pencil_button.add (*(manage (new Image (::get_icon("midi_tool_pencil"))))); midi_tool_pencil_button.set_relief(Gtk::RELIEF_NONE); midi_tool_buttons.push_back (&midi_tool_pencil_button); @@ -3267,42 +2999,11 @@ Editor::setup_midi_toolbar () midi_tool_erase_button.set_relief(Gtk::RELIEF_NONE); midi_tool_buttons.push_back (&midi_tool_erase_button); - midi_tool_pencil_button.set_active(true); - - midi_tool_button_set = new GroupedButtons (midi_tool_buttons); - - midi_tool_button_box.set_border_width (2); - midi_tool_button_box.set_spacing(1); - midi_tool_button_box.pack_start(midi_tool_pencil_button, true, true); - midi_tool_button_box.pack_start(midi_tool_select_button, true, true); - midi_tool_button_box.pack_start(midi_tool_resize_button, true, true); - midi_tool_button_box.pack_start(midi_tool_erase_button , true, true); - midi_tool_button_box.set_homogeneous(true); - - midi_tool_pencil_button.set_name ("MouseModeButton"); - midi_tool_select_button.set_name ("MouseModeButton"); - midi_tool_resize_button.set_name ("MouseModeButton"); - midi_tool_erase_button .set_name ("MouseModeButton"); - ARDOUR_UI::instance()->tooltips().set_tip (midi_tool_pencil_button, _("Add/Move/Stretch Notes")); ARDOUR_UI::instance()->tooltips().set_tip (midi_tool_select_button, _("Select/Move Notes")); ARDOUR_UI::instance()->tooltips().set_tip (midi_tool_resize_button, _("Resize Notes")); ARDOUR_UI::instance()->tooltips().set_tip (midi_tool_erase_button, _("Erase Notes")); - - midi_tool_pencil_button.unset_flags (CAN_FOCUS); - midi_tool_select_button.unset_flags (CAN_FOCUS); - midi_tool_resize_button.unset_flags (CAN_FOCUS); - midi_tool_erase_button.unset_flags (CAN_FOCUS); - - midi_tool_pencil_button.signal_toggled().connect (bind (mem_fun(*this, - &Editor::midi_edit_mode_toggled), Editing::MidiEditPencil)); - midi_tool_select_button.signal_toggled().connect (bind (mem_fun(*this, - &Editor::midi_edit_mode_toggled), Editing::MidiEditSelect)); - midi_tool_resize_button.signal_toggled().connect (bind (mem_fun(*this, - &Editor::midi_edit_mode_toggled), Editing::MidiEditResize)); - midi_tool_erase_button.signal_toggled().connect (bind (mem_fun(*this, - &Editor::midi_edit_mode_toggled), Editing::MidiEditErase)); - +#endif /* Midi sound notes */ midi_sound_notes.add (*(manage (new Image (::get_icon("midi_sound_notes"))))); @@ -3312,57 +3013,22 @@ Editor::setup_midi_toolbar () /* Panic */ - HBox* panic_box = manage (new HBox); midi_panic_button.set_name("MidiPanicButton"); - midi_panic_button.signal_pressed().connect ( - mem_fun(this, &Editor::midi_panic_button_pressed)); - panic_box->pack_start (midi_sound_notes , true, true); - panic_box->pack_start (midi_panic_button, true, true); - - /* Pack everything in... */ - - midi_tools_tearoff = manage (new TearOff (midi_tool_button_box)); - midi_tools_tearoff->set_name ("MouseModeBase"); - - /* - midi_tools_tearoff->Detach.connect (bind (mem_fun(*this, &Editor::detach_tearoff), static_cast(&midi_toolbar_hbox), - &midi_tools_tearoff->tearoff_window())); - midi_tools_tearoff->Attach.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast (&midi_toolbar_hbox), - &midi_tools_tearoff->tearoff_window(), 0)); - midi_tools_tearoff->Hidden.connect (bind (mem_fun(*this, &Editor::detach_tearoff), static_cast(&midi_toolbar_hbox), - &midi_tools_tearoff->tearoff_window())); - midi_tools_tearoff->Visible.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast (&midi_toolbar_hbox), - &midi_tools_tearoff->tearoff_window(), 0)); - */ - - midi_toolbar_hbox.set_spacing (10); - midi_toolbar_hbox.set_border_width (1); - - midi_toolbar_hbox.pack_start (*midi_tools_tearoff, false, true); - - midi_toolbar_hbox.pack_start(*panic_box, false, true, 4); - - midi_tool_button_box.show_all (); - midi_toolbar_hbox.show_all(); - midi_tools_tearoff->show_all(); - - midi_toolbar_base.set_name ("ToolBarBase"); - midi_toolbar_base.add (midi_toolbar_hbox); + midi_panic_button.signal_pressed().connect (mem_fun(this, &Editor::midi_panic_button_pressed)); - midi_toolbar_frame.set_shadow_type (SHADOW_OUT); - midi_toolbar_frame.set_name ("BaseFrame"); - midi_toolbar_frame.add (midi_toolbar_base); + panic_box.pack_start (midi_sound_notes , true, true); + panic_box.pack_start (midi_panic_button, true, true); } int Editor::convert_drop_to_paths ( vector& paths, - const RefPtr& context, - gint x, - gint y, + const RefPtr& /*context*/, + gint /*x*/, + gint /*y*/, const SelectionData& data, - guint info, - guint time) + guint /*info*/, + guint /*time*/) { if (session == 0) { return -1; @@ -3533,24 +3199,24 @@ Editor::commit_reversible_command () } void -Editor::set_edit_group_solo (Route& route, bool yn) +Editor::set_route_group_solo (Route& route, bool yn) { - RouteGroup *edit_group; + RouteGroup *route_group; - if ((edit_group = route.edit_group()) != 0) { - edit_group->apply (&Route::set_solo, yn, this); + if ((route_group = route.route_group()) != 0) { + route_group->apply (&Route::set_solo, yn, this); } else { route.set_solo (yn, this); } } void -Editor::set_edit_group_mute (Route& route, bool yn) +Editor::set_route_group_mute (Route& route, bool yn) { - RouteGroup *edit_group = 0; + RouteGroup *route_group = 0; - if ((edit_group == route.edit_group()) != 0) { - edit_group->apply (&Route::set_mute, yn, this); + if ((route_group == route.route_group()) != 0) { + route_group->apply (&Route::set_mute, yn, this); } else { route.set_mute (yn, this); } @@ -3672,7 +3338,7 @@ Editor::clamp_verbose_cursor_x (double x) if (x < 0) { x = 0; } else { - x = min (canvas_width - 200.0, x); + x = min (_canvas_width - 200.0, x); } return x; } @@ -3683,7 +3349,7 @@ Editor::clamp_verbose_cursor_y (double y) if (y < canvas_timebars_vsize) { y = canvas_timebars_vsize; } else { - y = min (canvas_height - 50, y); + y = min (_canvas_height - 50, y); } return y; } @@ -3917,10 +3583,9 @@ Editor::mouse_select_button_release (GdkEventButton* ev) Editor::TrackViewList * Editor::get_valid_views (TimeAxisView* track, RouteGroup* group) { - TrackViewList *v; TrackViewList::iterator i; - v = new TrackViewList; + TrackViewList* v = new TrackViewList; if (track == 0 && group == 0) { @@ -3930,7 +3595,7 @@ Editor::get_valid_views (TimeAxisView* track, RouteGroup* group) v->push_back (*i); } - } else if ((track != 0 && group == 0) || (track != 0 && group != 0 && !group->is_active())) { + } else if ((track != 0 && group == 0) || (track != 0 && group != 0 && !group->active_property (RouteGroup::Select))) { /* just the view for this track */ @@ -3939,11 +3604,11 @@ Editor::get_valid_views (TimeAxisView* track, RouteGroup* group) } else { - /* views for all tracks in the edit group */ + /* views for all tracks in the route group */ - for (i = track_views.begin(); i != track_views.end (); ++i) { + for (i = track_views.begin(); i != track_views.end (); ++i) { - if (group == 0 || (*i)->edit_group() == group) { + if (group == 0 || ((*i)->route_group() == group && group->active_property (RouteGroup::Select))) { v->push_back (*i); } } @@ -4032,8 +3697,10 @@ Editor::pane_allocation_handler (Allocation &alloc, Paned* which) } void -Editor::detach_tearoff (Box* b, Window* w) +Editor::detach_tearoff (Box* /*b*/, Window* /*w*/) { + cerr << "remove tearoff\n"; + if (tools_tearoff->torn_off() && mouse_mode_tearoff->torn_off()) { top_hbox.remove (toolbar_frame); @@ -4041,8 +3708,9 @@ Editor::detach_tearoff (Box* b, Window* w) } void -Editor::reattach_tearoff (Box* b, Window* w, int32_t n) +Editor::reattach_tearoff (Box* /*b*/, Window* /*w*/, int32_t /*n*/) { + cerr << "reattach tearoff\n"; if (toolbar_frame.get_parent() == 0) { top_hbox.pack_end (toolbar_frame); } @@ -4210,14 +3878,13 @@ Editor::prepare_for_cleanup () selection->clear_regions (); selection->clear_playlists (); - no_region_list_redisplay = true; + _regions->suspend_redisplay (); } void Editor::finish_cleanup () { - no_region_list_redisplay = false; - redisplay_regions (); + _regions->resume_redisplay (); } Location* @@ -4261,161 +3928,12 @@ Editor::control_layout_scroll (GdkEventScroll* ev) return false; } - -/** A new snapshot has been selected. - */ -void -Editor::snapshot_display_selection_changed () -{ - if (snapshot_display.get_selection()->count_selected_rows() > 0) { - - TreeModel::iterator i = snapshot_display.get_selection()->get_selected(); - - Glib::ustring snap_name = (*i)[snapshot_display_columns.real_name]; - - if (snap_name.length() == 0) { - return; - } - - if (session->snap_name() == snap_name) { - return; - } - - ARDOUR_UI::instance()->load_session(session->path(), string (snap_name)); - } -} - -bool -Editor::snapshot_display_button_press (GdkEventButton* ev) -{ - if (ev->button == 3) { - /* Right-click on the snapshot list. Work out which snapshot it - was over. */ - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col; - int cx; - int cy; - snapshot_display.get_path_at_pos ((int) ev->x, (int) ev->y, path, col, cx, cy); - Gtk::TreeModel::iterator iter = snapshot_display_model->get_iter (path); - if (iter) { - Gtk::TreeModel::Row row = *iter; - popup_snapshot_context_menu (ev->button, ev->time, row[snapshot_display_columns.real_name]); - } - return true; - } - - return false; -} - - -/** Pop up the snapshot display context menu. - * @param button Button used to open the menu. - * @param time Menu open time. - * @snapshot_name Name of the snapshot that the menu click was over. - */ - -void -Editor::popup_snapshot_context_menu (int button, int32_t time, Glib::ustring snapshot_name) -{ - using namespace Menu_Helpers; - - MenuList& items (snapshot_context_menu.items()); - items.clear (); - - const bool modification_allowed = (session->snap_name() != snapshot_name && session->name() != snapshot_name); - - add_item_with_sensitivity (items, MenuElem (_("Remove"), bind (mem_fun (*this, &Editor::remove_snapshot), snapshot_name)), modification_allowed); - - add_item_with_sensitivity (items, MenuElem (_("Rename"), bind (mem_fun (*this, &Editor::rename_snapshot), snapshot_name)), modification_allowed); - - snapshot_context_menu.popup (button, time); -} - -void -Editor::rename_snapshot (Glib::ustring old_name) -{ - ArdourPrompter prompter(true); - - string new_name; - - prompter.set_name ("Prompter"); - prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); - prompter.set_prompt (_("New name of snapshot")); - prompter.set_initial_text (old_name); - - if (prompter.run() == RESPONSE_ACCEPT) { - prompter.get_result (new_name); - if (new_name.length()) { - session->rename_state (old_name, new_name); - redisplay_snapshots (); - } - } -} - - -void -Editor::remove_snapshot (Glib::ustring name) -{ - vector choices; - - std::string prompt = string_compose (_("Do you really want to remove snapshot \"%1\" ?\n(cannot be undone)"), name); - - choices.push_back (_("No, do nothing.")); - choices.push_back (_("Yes, remove it.")); - - Gtkmm2ext::Choice prompter (prompt, choices); - - if (prompter.run () == 1) { - session->remove_state (name); - redisplay_snapshots (); - } -} - -void -Editor::redisplay_snapshots () -{ - if (session == 0) { - return; - } - - vector state_file_paths; - - get_state_files_in_directory (session->session_directory().root_path(), - state_file_paths); - - if (state_file_paths.empty()) return; - - vector state_file_names(get_file_names_no_extension(state_file_paths)); - - snapshot_display_model->clear (); - - for (vector::iterator i = state_file_names.begin(); - i != state_file_names.end(); ++i) - { - string statename = (*i); - TreeModel::Row row = *(snapshot_display_model->append()); - - /* this lingers on in case we ever want to change the visible - name of the snapshot. - */ - - string display_name; - display_name = statename; - - if (statename == session->snap_name()) { - snapshot_display.get_selection()->select(row); - } - - row[snapshot_display_columns.visible_name] = display_name; - row[snapshot_display_columns.real_name] = statename; - } -} - void Editor::session_state_saved (string snap_name) { ENSURE_GUI_THREAD (bind (mem_fun(*this, &Editor::session_state_saved), snap_name)); - redisplay_snapshots (); + + _snapshots->redisplay (); } void @@ -4461,7 +3979,7 @@ Editor::restore_editing_space () /** * Make new playlists for a given track and also any others that belong - * to the same active edit group. + * to the same active route group with the `edit' property. * @param v Track. */ @@ -4471,13 +3989,13 @@ Editor::new_playlists (TimeAxisView* v) begin_reversible_command (_("new playlists")); vector > playlists; session->get_playlists(playlists); - mapover_tracks ( bind(mem_fun (*this, &Editor::mapped_use_new_playlist), playlists), v ); + mapover_tracks (bind (mem_fun (*this, &Editor::mapped_use_new_playlist), playlists), v, RouteGroup::Edit); commit_reversible_command (); } /** * Use a copy of the current playlist for a given track and also any others that belong - * to the same active edit group. + * to the same active route group with the `edit' property. * @param v Track. */ @@ -4487,13 +4005,12 @@ Editor::copy_playlists (TimeAxisView* v) begin_reversible_command (_("copy playlists")); vector > playlists; session->get_playlists(playlists); - mapover_tracks ( bind(mem_fun (*this, &Editor::mapped_use_copy_playlist), playlists), v ); + mapover_tracks (bind (mem_fun (*this, &Editor::mapped_use_copy_playlist), playlists), v, RouteGroup::Edit); commit_reversible_command (); } -/** - * Clear the current playlist for a given track and also any others that belong - * to the same active edit group. +/** Clear the current playlist for a given track and also any others that belong + * to the same active route group with the `edit' property. * @param v Track. */ @@ -4503,7 +4020,7 @@ Editor::clear_playlists (TimeAxisView* v) begin_reversible_command (_("clear playlists")); vector > playlists; session->get_playlists(playlists); - mapover_tracks ( mem_fun (*this, &Editor::mapped_clear_playlist), v ); + mapover_tracks (mem_fun (*this, &Editor::mapped_clear_playlist), v, RouteGroup::Edit); commit_reversible_command (); } @@ -4520,7 +4037,7 @@ Editor::mapped_use_copy_playlist (RouteTimeAxisView& atv, uint32_t sz, vectorsuspend_redisplay (); vertical_adjustment.set_value (vs.y_position); @@ -4642,11 +4166,10 @@ Editor::use_visual_state (VisualState& vs) if (!vs.track_states.empty()) { - update_route_visibility (); + _routes->update_visibility (); } - no_route_list_redisplay = false; - redisplay_route_list (); + _routes->resume_redisplay (); no_save_visual = false; } @@ -4689,7 +4212,7 @@ Editor::post_zoom () // convert fpu to frame count - nframes64_t frames = (nframes64_t) floor (frames_per_unit * canvas_width); + nframes64_t frames = (nframes64_t) floor (frames_per_unit * _canvas_width); if (frames_per_unit != zoom_range_clock.current_duration()) { zoom_range_clock.set (frames); @@ -4724,13 +4247,16 @@ Editor::post_zoom () playhead_cursor->set_position (playhead_cursor->current_frame); } + refresh_location_display(); + _summary->set_overlays_dirty (); + instant_save (); } void Editor::queue_visual_change (nframes64_t where) { - pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin); + pending_visual_change.add (VisualChange::TimeOrigin); /* if we're moving beyond the end, make sure the upper limit of the horizontal adjustment can reach. @@ -4742,21 +4268,34 @@ Editor::queue_visual_change (nframes64_t where) pending_visual_change.time_origin = where; - if (pending_visual_change.idle_handler_id < 0) { - pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this); - } + ensure_visual_change_idle_handler (); } void Editor::queue_visual_change (double fpu) { - pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::ZoomLevel); + pending_visual_change.add (VisualChange::ZoomLevel); pending_visual_change.frames_per_unit = fpu; + ensure_visual_change_idle_handler (); + +} + +void +Editor::queue_visual_change_y (double y) +{ + pending_visual_change.add (VisualChange::YOrigin); + pending_visual_change.y_origin = y; + + ensure_visual_change_idle_handler (); +} + +void +Editor::ensure_visual_change_idle_handler () +{ if (pending_visual_change.idle_handler_id < 0) { - pending_visual_change.idle_handler_id = g_idle_add ( _idle_visual_changer, this); + pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this); } - } int @@ -4786,7 +4325,10 @@ Editor::idle_visual_changer () if (p & VisualChange::TimeOrigin) { horizontal_adjustment.set_value (pending_visual_change.time_origin / frames_per_unit); } - + if (p & VisualChange::YOrigin) { + vertical_adjustment.set_value (pending_visual_change.y_origin); + } + nframes64_t csf=0, cef=0; nframes64_t current_time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit); @@ -4813,6 +4355,9 @@ Editor::idle_visual_changer () update_fixed_rulers(); redisplay_tempo (true); } + + _summary->set_overlays_dirty (); + //cerr << "Editor::idle_visual_changer () called ha v:l:u:ps:fpu = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << frames_per_unit << endl;//DEBUG pending_visual_change.idle_handler_id = -1; return 0; /* this is always a one-shot call */ @@ -4939,6 +4484,11 @@ Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd) commit_reversible_command (); } +/** Find regions which exist at a given time, and optionally on a given list of tracks. + * @param rs List to which found regions are added. + * @param where Time to look at. + * @param ts Tracks to look on; if this is empty, all tracks are examined. + */ void Editor::get_regions_at (RegionSelection& rs, nframes64_t where, const TrackSelection& ts) const { @@ -5011,68 +4561,50 @@ Editor::get_regions_after (RegionSelection& rs, nframes64_t where, const TrackSe } } +/** Find all regions which are either: + * - selected or + * - the entered_regionview (if allow_entered == true) or + * - under the preferred edit position AND on a selected track, or on a track + * which is in the same active edit-enable route group as a selected region. + * @param rs Returned region list. + * @param allow_entered true to include the entered_regionview in the list. + */ void Editor::get_regions_for_action (RegionSelection& rs, bool allow_entered) { - if (selection->regions.empty()) { - - if (selection->tracks.empty()) { - - /* no regions or tracks selected - */ - - if (entered_regionview && mouse_mode == Editing::MouseObject) { - - /* entered regionview is valid and we're in object mode - - just use entered regionview - */ - - rs.add (entered_regionview); - } - - return; + /* Start with selected regions */ + rs = selection->regions; - } else { - - /* no regions selected, so get all regions at the edit point across - all selected tracks. - */ - - nframes64_t where = get_preferred_edit_position(); - get_regions_at (rs, where, selection->tracks); - - /* if the entered regionview wasn't selected and neither was its track - then add it. - */ - - if (entered_regionview != 0 && - !selection->selected (entered_regionview) && - !selection->selected (&entered_regionview->get_time_axis_view())) { - rs.add (entered_regionview); - } - } + /* Add the entered_regionview, if requested */ + if (allow_entered && entered_regionview) { + rs.add (entered_regionview); + } - } else { - - /* just use the selected regions */ + TrackSelection tracks = selection->tracks; - rs = selection->regions; + RegionSelection to_map = rs; - /* if the entered regionview wasn't selected and we allow this sort of thing, - then add it. - */ + /* tracks is currently the set of selected tracks; add any other tracks that + * have regions that are in the same edit-activated route group as one of + * our regions */ + for (RegionSelection::iterator i = to_map.begin (); i != to_map.end(); ++i) { - if (allow_entered && entered_regionview && !selection->selected (entered_regionview)) { - rs.add (entered_regionview); + RouteGroup* g = (*i)->get_time_axis_view().route_group (); + if (g && g->active_property (RouteGroup::Edit)) { + tracks.add (axis_views_from_routes (g->route_list())); } + } + /* now find regions that are at the edit position on those tracks */ + for (RegionSelection::iterator i = to_map.begin (); i != to_map.end(); ++i) { + nframes64_t const where = get_preferred_edit_position (); + get_regions_at (rs, where, tracks); } } void Editor::get_regions_corresponding_to (boost::shared_ptr region, vector& regions) { - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { RouteTimeAxisView* tatv; @@ -5155,187 +4687,313 @@ Editor::first_idle () } // first idle adds route children (automation tracks), so we need to redisplay here - redisplay_route_list(); + _routes->redisplay (); delete dialog; _have_idled = true; } -void -Editor::start_resize_line_ops () +static gboolean +_idle_resizer (gpointer arg) { -#if 0 - old_resize_line_y = -1; - resize_line_y = -1; - need_resize_line = true; -#endif + return ((Editor*)arg)->idle_resize (); } void -Editor::end_resize_line_ops () +Editor::add_to_idle_resize (TimeAxisView* view, int32_t h) { -#if 0 - need_resize_line = false; - - if (old_resize_line_y >= 0) { - Gdk::Rectangle r (0, old_resize_line_y, (int) canvas_width, 3); - Glib::RefPtr win = get_window(); - cerr << "Final invalidation at " << old_resize_line_y << endl; - win->invalidate_rect (r, false); + if (resize_idle_id < 0) { + resize_idle_id = g_idle_add (_idle_resizer, this); + _pending_resize_amount = 0; } -#endif -} -void -Editor::queue_draw_resize_line (int at) -{ -#if 0 - Glib::RefPtr win = get_window(); + /* make a note of the smallest resulting height, so that we can clamp the + lower limit at TimeAxisView::hSmall */ - resize_line_y = at; + int32_t min_resulting = INT32_MAX; - if (win && canvas_width) { + _pending_resize_amount += h; + _pending_resize_view = view; - int controls_width = controls_layout.get_width(); - int xroot, discard; - - controls_layout.get_window()->get_origin (xroot, discard); + min_resulting = min (min_resulting, int32_t (_pending_resize_view->current_height()) + _pending_resize_amount); - if (old_resize_line_y >= 0) { - - /* redraw where it used to be */ - - - Gdk::Rectangle r (0, old_resize_line_y - 1, controls_width + (int) canvas_width, 3); - win->invalidate_rect (r, true); - cerr << "invalidate " << xroot << "," << old_resize_line_y - 1 << ' ' - << controls_width + canvas_width << " x 3\n"; + if (selection->tracks.contains (_pending_resize_view)) { + for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { + min_resulting = min (min_resulting, int32_t ((*i)->current_height()) + _pending_resize_amount); } + } - /* draw where it is */ + if (min_resulting < 0) { + min_resulting = 0; + } - Gdk::Rectangle r (0, at - 1, controls_width + (int) canvas_width, 3); - win->invalidate_rect (r, true); + /* clamp */ + if (uint32_t (min_resulting) < TimeAxisView::hSmall) { + _pending_resize_amount += TimeAxisView::hSmall - min_resulting; } -#endif } +/** Handle pending resizing of tracks */ bool -Editor::on_expose_event (GdkEventExpose* ev) -{ - /* cerr << "+++ editor expose " - << ev->area.x << ',' << ev->area.y - << ' ' - << ev->area.width << " x " << ev->area.height - << " need reize ? " << need_resize_line - << endl; - */ - bool ret = Window::on_expose_event (ev); +Editor::idle_resize () +{ + _pending_resize_view->idle_resize (_pending_resize_view->current_height() + _pending_resize_amount); -#if 0 - if (need_resize_line) { + if (dynamic_cast (_pending_resize_view) == 0 && + selection->tracks.contains (_pending_resize_view)) { - int xroot, yroot, discard; - int controls_width; + for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { + if (*i != _pending_resize_view) { + (*i)->idle_resize ((*i)->current_height() + _pending_resize_amount); + } + } + } + + flush_canvas (); + _group_tabs->set_dirty (); + resize_idle_id = -1; + + return false; +} - /* Our root coordinates for drawing the line will be the left edge - of the track controls, and the upper left edge of our own window. - */ +void +Editor::located () +{ + ENSURE_GUI_THREAD (mem_fun (*this, &Editor::located)); - get_window()->get_origin (discard, yroot); - controls_layout.get_window()->get_origin (xroot, discard); - controls_width = controls_layout.get_width(); - - GdkRectangle lr; - GdkRectangle intersection; + _pending_locate_request = false; +} - lr.x = 0; - lr.y = resize_line_y; - lr.width = controls_width + (int) canvas_width; - lr.height = 3; +void +Editor::region_view_added (RegionView *) +{ + _summary->set_dirty (); +} - if (gdk_rectangle_intersect (&lr, &ev->area, &intersection)) { - - Glib::RefPtr style (get_style()); - Glib::RefPtr black_gc (style->get_black_gc ()); - Glib::RefPtr gc = wrap (black_gc->gobj_copy(), false); +void +Editor::streamview_height_changed () +{ + _summary->set_dirty (); +} - /* draw on root window */ +TimeAxisView* +Editor::axis_view_from_route (Route* r) const +{ + TrackViewList::const_iterator j = track_views.begin (); + while (j != track_views.end()) { + RouteTimeAxisView* rtv = dynamic_cast (*j); + if (rtv && rtv->route().get() == r) { + return rtv; + } + ++j; + } - GdkWindow* win = gdk_get_default_root_window(); - - gc->set_subwindow (Gdk::INCLUDE_INFERIORS); - gc->set_line_attributes (3, Gdk::LINE_SOLID, - Gdk::CAP_NOT_LAST, - Gdk::JOIN_MITER); - - gdk_draw_line (win, gc->gobj(), - 0, - resize_line_y, - (int) canvas_width + controls_width, - resize_line_y); -#if 0 - cerr << "drew line @ " << xroot << ", " << yroot + resize_line_y - << " to " << xroot + (int) canvas_width + controls_width - << ", " << yroot + resize_line_y - << endl; -#endif - old_resize_line_y = resize_line_y; - cerr << "NEXT EXPOSE SHOULD BE AT " << old_resize_line_y << endl; + return 0; +} + + +TrackSelection +Editor::axis_views_from_routes (list r) const +{ + TrackSelection t; + + for (list::const_iterator i = r.begin(); i != r.end(); ++i) { + TimeAxisView* tv = axis_view_from_route (*i); + if (tv) { + t.push_back (tv); + } + } + + return t; +} + + +void +Editor::handle_new_route (RouteList& routes) +{ + ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_route), routes)); + + RouteTimeAxisView *rtv; + list new_views; + + for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) { + boost::shared_ptr route = (*x); + + if (route->is_hidden()) { + continue; + } + + DataType dt = route->input()->default_type(); + + if (dt == ARDOUR::DataType::AUDIO) { + rtv = new AudioTimeAxisView (*this, *session, route, *track_canvas); + } else if (dt == ARDOUR::DataType::MIDI) { + rtv = new MidiTimeAxisView (*this, *session, route, *track_canvas); } else { - cerr << "no intersect with " - << lr.x << ',' << lr.y - << ' ' - << lr.width << " x " << lr.height - << endl; + throw unknown_type(); } + + new_views.push_back (rtv); + track_views.push_back (rtv); + + rtv->effective_gain_display (); + + rtv->view()->RegionViewAdded.connect (mem_fun (*this, &Editor::region_view_added)); + rtv->view()->HeightChanged.connect (mem_fun (*this, &Editor::streamview_height_changed)); + + rtv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), rtv)); } - //cerr << "--- editor expose\n"; -#endif + _routes->routes_added (new_views); - return ret; + if (show_editor_mixer_when_tracks_arrive) { + show_editor_mixer (true); + } + + editor_list_button.set_sensitive (true); + + _summary->set_dirty (); } -static gboolean -_idle_resizer (gpointer arg) +void +Editor::remove_route (TimeAxisView *tv) { - return ((Editor*)arg)->idle_resize (); + ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::remove_route), tv)); + + TrackViewList::iterator i; + boost::shared_ptr route; + TimeAxisView* next_tv; + + if (tv == entered_track) { + entered_track = 0; + } + + if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) { + + i = track_views.erase (i); + + if (track_views.empty()) { + next_tv = 0; + } else if (i == track_views.end()) { + next_tv = track_views.front(); + } else { + next_tv = (*i); + } + } + + if (current_mixer_strip && current_mixer_strip->route() == route) { + + if (next_tv) { + set_selected_mixer_strip (*next_tv); + } else { + /* make the editor mixer strip go away setting the + * button to inactive (which also unticks the menu option) + */ + + ActionManager::uncheck_toggleaction ("/Editor/show-editor-mixer"); + } + } } void -Editor::add_to_idle_resize (TimeAxisView* view, uint32_t h) +Editor::hide_track_in_display (TimeAxisView& tv, bool /*temponly*/) { - if (resize_idle_id < 0) { - resize_idle_id = g_idle_add (_idle_resizer, this); - } + RouteTimeAxisView* rtv = dynamic_cast (&tv); - resize_idle_target = h; + if (rtv && current_mixer_strip && (rtv->route() == current_mixer_strip->route())) { + // this will hide the mixer strip + set_selected_mixer_strip (tv); + } + + _routes->hide_track_in_display (tv); +} - pending_resizes.push_back (view); +bool +Editor::sync_track_view_list_and_routes () +{ + track_views = TrackSelection (_routes->views ()); + + _summary->set_dirty (); + _group_tabs->set_dirty (); + + return false; // do not call again (until needed) +} - if (selection->selected (view) && !selection->tracks.empty()) { - pending_resizes.insert (pending_resizes.end(), selection->tracks.begin(), selection->tracks.end()); +void +Editor::foreach_time_axis_view (sigc::slot theslot) +{ + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + theslot (**i); } } -bool -Editor::idle_resize () +RouteTimeAxisView* +Editor::get_route_view_by_id (PBD::ID& id) { - for (vector::iterator i = pending_resizes.begin(); i != pending_resizes.end(); ++i) { - (*i)->idle_resize (resize_idle_target); + RouteTimeAxisView* v; + + for(TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + if((v = dynamic_cast(*i)) != 0) { + if(v->route()->id() == id) { + return v; + } + } } - pending_resizes.clear(); - flush_canvas (); - resize_idle_id = -1; - return false; + + return 0; } void -Editor::located () +Editor::fit_route_group (RouteGroup *g) { - ENSURE_GUI_THREAD (mem_fun (*this, &Editor::located)); + TrackSelection ts = axis_views_from_routes (g->route_list ()); + fit_tracks (ts); +} - _pending_locate_request = false; +void +Editor::consider_auditioning (boost::shared_ptr region) +{ + boost::shared_ptr r = boost::dynamic_pointer_cast (region); + + if (r == 0) { + session->cancel_audition (); + return; + } + + if (session->is_auditioning()) { + session->cancel_audition (); + if (r == last_audition_region) { + return; + } + } + + session->audition_region (r); + last_audition_region = r; +} + + +void +Editor::hide_a_region (boost::shared_ptr r) +{ + r->set_hidden (true); } + +void +Editor::remove_a_region (boost::shared_ptr r) +{ + session->remove_region_from_region_list (r); +} + +void +Editor::audition_region_from_region_list () +{ + _regions->selection_mapover (mem_fun (*this, &Editor::consider_auditioning)); +} + +void +Editor::hide_region_from_region_list () +{ + _regions->selection_mapover (mem_fun (*this, &Editor::hide_a_region)); +} +