From 20157d04f8a5f8f7e24bd450f3a2961b4e251570 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 2 May 2008 20:02:48 +0000 Subject: [PATCH] many changes related to region zooming; proto-visual state undo/redo stack; fill-tracks command steals "f" (follow-playhead now on shift-f git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3306 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour.menus | 1 + gtk2_ardour/audio_region_view.cc | 10 +-- gtk2_ardour/audio_streamview.cc | 2 +- gtk2_ardour/audio_time_axis.cc | 11 ++- gtk2_ardour/audio_time_axis.h | 2 +- gtk2_ardour/automation_time_axis.cc | 4 +- gtk2_ardour/automation_time_axis.h | 2 +- gtk2_ardour/axis_view.h | 5 +- gtk2_ardour/crossfade_view.cc | 12 +-- gtk2_ardour/editor.cc | 98 +++++++++++++++++++----- gtk2_ardour/editor.h | 31 ++++---- gtk2_ardour/editor_actions.cc | 2 + gtk2_ardour/editor_mouse.cc | 6 +- gtk2_ardour/editor_ops.cc | 67 ++++++++++++---- gtk2_ardour/editor_route_list.cc | 29 +++---- gtk2_ardour/ghostregion.cc | 6 +- gtk2_ardour/imageframe_time_axis_view.cc | 2 +- gtk2_ardour/imageframe_view.cc | 4 +- gtk2_ardour/mnemonic-us.bindings.in | 5 +- gtk2_ardour/region_view.cc | 2 +- gtk2_ardour/streamview.cc | 2 +- gtk2_ardour/time_axis_view.cc | 33 +++++++- gtk2_ardour/time_axis_view.h | 12 +-- gtk2_ardour/time_axis_view_item.cc | 12 +-- 24 files changed, 242 insertions(+), 118 deletions(-) diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index f9c20a434a..17f11abd00 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -234,6 +234,7 @@ + diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 415adca90f..f622f16c8a 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -215,7 +215,7 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd) gain_line->reset (); } - set_height (trackview.height); + set_height (trackview.current_height()); region_muted (); region_sync_changed (); @@ -840,10 +840,10 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct) uint32_t nwaves = std::min (nchans, audio_region()->n_channels()); gdouble ht; - if (trackview.height < NAME_HIGHLIGHT_SIZE) { - ht = ((trackview.height) / (double) nchans); + if (trackview.current_height() < NAME_HIGHLIGHT_SIZE) { + ht = ((trackview.current_height()) / (double) nchans); } else { - ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans); + ht = ((trackview.current_height() - NAME_HIGHLIGHT_SIZE) / (double) nchans); } gdouble yoff = which * ht; @@ -954,7 +954,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) /* compute vertical fractional position */ - y = 1.0 - (y / (trackview.height - NAME_HIGHLIGHT_SIZE)); + y = 1.0 - (y / (trackview.current_height() - NAME_HIGHLIGHT_SIZE)); /* map using gain line */ diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index ab3a9f5303..344b8f4734 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -545,7 +545,7 @@ AudioStreamView::setup_rec_box () rec_rect->property_x1() = xstart; rec_rect->property_y1() = 1.0; rec_rect->property_x2() = xend; - rec_rect->property_y2() = (double) _trackview.height - 1; + rec_rect->property_y2() = (double) _trackview.current_height() - 1; rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get(); rec_rect->property_outline_what() = 0x1 | 0x2 | 0x4 | 0x8; rec_rect->property_fill_color_rgba() = fill_color; diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index a5b5c3e3a9..f47e0ec33f 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -160,12 +160,15 @@ AudioTimeAxisView::hide () TimeAxisView::hide (); } -void +int AudioTimeAxisView::set_state (const XMLNode& node) { const XMLProperty *prop; - - TimeAxisView::set_state (node); + int ret; + + if ((ret = TimeAxisView::set_state (node)) != 0) { + return ret; + } if ((prop = node.property ("shown_editor")) != 0) { if (prop->value() == "no") { @@ -210,6 +213,8 @@ AudioTimeAxisView::set_state (const XMLNode& node) continue; } } + + return 0; } void diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h index 30507b8ef6..d0fe2b9868 100644 --- a/gtk2_ardour/audio_time_axis.h +++ b/gtk2_ardour/audio_time_axis.h @@ -82,7 +82,7 @@ class AudioTimeAxisView : public RouteTimeAxisView guint32 show_at (double y, int& nth, Gtk::VBox *parent); void hide (); - void set_state (const XMLNode&); + int set_state (const XMLNode&); XMLNode* get_child_xml_node (const string & childname); void first_idle (); diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index f825868bb0..96a20f98d2 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -795,10 +795,10 @@ AutomationTimeAxisView::color_handler () -void +int AutomationTimeAxisView::set_state (const XMLNode& node) { - TimeAxisView::set_state (node); + return TimeAxisView::set_state (node); } XMLNode* diff --git a/gtk2_ardour/automation_time_axis.h b/gtk2_ardour/automation_time_axis.h index 921d41125b..698d627ef1 100644 --- a/gtk2_ardour/automation_time_axis.h +++ b/gtk2_ardour/automation_time_axis.h @@ -93,7 +93,7 @@ class AutomationTimeAxisView : public TimeAxisView { void show_all_control_points (); void hide_all_but_selected_control_points (); - void set_state (const XMLNode&); + int set_state (const XMLNode&); XMLNode* get_state_node (); protected: diff --git a/gtk2_ardour/axis_view.h b/gtk2_ardour/axis_view.h index 11ee9c9377..ddc5d57171 100644 --- a/gtk2_ardour/axis_view.h +++ b/gtk2_ardour/axis_view.h @@ -52,11 +52,8 @@ class AxisView : public virtual Selectable virtual string name() const = 0; virtual bool marked_for_display() const { return _marked_for_display; } - virtual void set_marked_for_display (bool yn) { - if (yn != _marked_for_display) { - _marked_for_display = yn; - } + _marked_for_display = yn; } sigc::signal Hiding; diff --git a/gtk2_ardour/crossfade_view.cc b/gtk2_ardour/crossfade_view.cc index 4787837617..0d1d9427d6 100644 --- a/gtk2_ardour/crossfade_view.cc +++ b/gtk2_ardour/crossfade_view.cc @@ -69,7 +69,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent, fade_out->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeLine.get(); fade_out->property_width_pixels() = 1; - set_height (get_time_axis_view().height); + set_height (get_time_axis_view().current_height()); /* no frame around the xfade or overlap rects */ @@ -109,11 +109,11 @@ CrossfadeView::reset_width_dependent_items (double pixel_width) void CrossfadeView::set_height (double height) { - if (height == TimeAxisView::hSmaller || - height == TimeAxisView::hSmall) - TimeAxisViewItem::set_height (height - 3 ); - else + if (height <= TimeAxisView::hSmaller) { + TimeAxisViewItem::set_height (height - 3); + } else { TimeAxisViewItem::set_height (height - NAME_HIGHLIGHT_SIZE - 3 ); + } redraw_curves (); } @@ -160,7 +160,7 @@ CrossfadeView::redraw_curves () At "height - 3.0" the bottom of the crossfade touches the name highlight or the bottom of the track (if the track is either Small or Smaller. */ - double tav_height = get_time_axis_view().height; + double tav_height = get_time_axis_view().current_height(); if (tav_height == TimeAxisView::hSmaller || tav_height == TimeAxisView::hSmall) { h = tav_height - 3.0; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 548b65d424..6d26394038 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -338,6 +338,7 @@ Editor::Editor () zoomed_to_region = false; rhythm_ferret = 0; allow_vertical_scroll = false; + no_save_visual = false; _scrubbing = false; scrubbing_direction = 0; @@ -356,8 +357,6 @@ Editor::Editor () set_mouse_mode (MouseObject, true); - last_visual_state.frames_per_unit = 0; - frames_per_unit = 2048; /* too early to use reset_zoom () */ reset_hscrollbar_stepping (); @@ -4117,33 +4116,98 @@ Editor::reposition_and_zoom (nframes_t frame, double fpu) { reset_x_origin (frame); reset_zoom (fpu); + + if (!no_save_visual) { + undo_visual_stack.push_back (current_visual_state(false)); + } +} + +Editor::VisualState* +Editor::current_visual_state (bool with_tracks) +{ + VisualState* vs = new VisualState; + vs->y_position = vertical_adjustment.get_value(); + vs->frames_per_unit = frames_per_unit; + vs->leftmost_frame = leftmost_frame; + vs->zoom_focus = zoom_focus; + vs->zoomed_to_region = zoomed_to_region; + + if (with_tracks) { + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + vs->track_states.push_back (TAVState ((*i), &(*i)->get_state())); + } + } + + return vs; } void -Editor::swap_visual_state () +Editor::undo_visual_state () { - if (last_visual_state.frames_per_unit == 0) { - // never set + if (undo_visual_stack.empty()) { return; } - /* note: the correct functionality here is very dependent on the ordering of - setting zoom focus, horizontal position and finally zoom. this is because - it is set_frames_per_unit() that overwrites last_visual_state. - */ + VisualState* vs = undo_visual_stack.back(); + undo_visual_stack.pop_back(); + use_visual_state (*vs); + redo_visual_stack.push_back (vs); +} + +void +Editor::redo_visual_state () +{ + if (redo_visual_stack.empty()) { + return; + } + + VisualState* vs = redo_visual_stack.back(); + redo_visual_stack.pop_back(); + use_visual_state (*vs); + undo_visual_stack.push_back (vs); +} - set_zoom_focus (last_visual_state.zoom_focus); - reposition_and_zoom (last_visual_state.leftmost_frame, last_visual_state.frames_per_unit); +void +Editor::swap_visual_state () +{ + if (undo_visual_stack.empty()) { + redo_visual_state (); + } else { + undo_visual_state (); + } +} + +void +Editor::use_visual_state (VisualState& vs) +{ + no_save_visual = true; + + vertical_adjustment.set_value (vs.y_position); + + set_zoom_focus (vs.zoom_focus); + reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit); - if (zoomed_to_region) { + if (vs.zoomed_to_region) { for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (*i)->set_height_scaling_factor (1.0); } } - toggle_temporarily_hidden_tracks (zoomed_to_region); + for (list::iterator i = vs.track_states.begin(); i != vs.track_states.end(); ++i) { + TrackViewList::iterator t; - zoomed_to_region = false; + /* check if the track still exists - it could have been deleted */ + + if ((t = find (track_views.begin(), track_views.end(), i->first)) != track_views.end()) { + (*t)->set_state (*(i->second)); + } + } + + if (!vs.track_states.empty()) { + update_route_visibility (); + } + + no_save_visual = false; } void @@ -4173,11 +4237,7 @@ Editor::set_frames_per_unit (double fpu) if (fpu == frames_per_unit) { return; } - - last_visual_state.frames_per_unit = frames_per_unit; - last_visual_state.leftmost_frame = leftmost_frame; - last_visual_state.zoom_focus = zoom_focus; - + frames_per_unit = fpu; post_zoom (); } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 232866c28c..fef19140e1 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -388,21 +388,31 @@ class Editor : public PublicEditor PlaylistSelector* _playlist_selector; + typedef std::pair TAVState; + struct VisualState { - double frames_per_unit; - nframes_t leftmost_frame; - Editing::ZoomFocus zoom_focus; + double y_position; + double frames_per_unit; + nframes_t leftmost_frame; + Editing::ZoomFocus zoom_focus; + bool zoomed_to_region; + std::list track_states; }; - VisualState last_visual_state; + std::list undo_visual_stack; + std::list redo_visual_stack; + VisualState* current_visual_state (bool with_tracks = true); + void undo_visual_state (); + void redo_visual_state (); + void use_visual_state (VisualState&); + bool no_save_visual; + void swap_visual_state (); nframes_t leftmost_frame; double frames_per_unit; Editing::ZoomFocus zoom_focus; - void use_visual_state (const VisualState&); void set_frames_per_unit (double); - void swap_visual_state (); void post_zoom (); Editing::MouseMode mouse_mode; @@ -1656,7 +1666,7 @@ public: Gtk::ScrolledWindow route_list_scroller; Gtk::Menu* route_list_menu; - void toggle_temporarily_hidden_tracks (bool yn); + void update_route_visibility (); void sync_order_keys (); bool ignore_route_order_sync; @@ -1848,12 +1858,6 @@ public: void begin_reversible_command (string cmd_name); void commit_reversible_command (); - /* visual history */ - - UndoHistory visual_history; - UndoTransaction current_visual_command; - - void update_title (); void update_title_s (const string & snapshot_name); @@ -2121,6 +2125,7 @@ public: RhythmFerret* rhythm_ferret; + void fit_tracks (); void set_track_height (uint32_t h); void set_track_height_largest (); void set_track_height_large (); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 3e676e073b..1b4fa9eaa9 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -515,6 +515,8 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "fit-tracks", _("Fit Selected Tracks"), (mem_fun(*this, &Editor::fit_tracks))); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "track-height-largest", _("Largest"), (mem_fun(*this, &Editor::set_track_height_largest))); ActionManager::session_sensitive_actions.push_back (act); ActionManager::track_selection_sensitive_actions.push_back (act); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 6586c1ebca..7aaccc62a8 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -3293,12 +3293,12 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) tracks = tracks |= (0x01 << atv2->order); } - height_list[atv2->order] = (*i)->height; + height_list[atv2->order] = (*i)->current_height(); children = 1; if ((children_list = atv2->get_child_list()).size() > 0) { for (list::iterator j = children_list.begin(); j != children_list.end(); ++j) { tracks = tracks |= (0x01 << (atv2->order + children)); - height_list[atv2->order + children] = (*j)->height; + height_list[atv2->order + children] = (*j)->current_height(); numtracks++; children++; } @@ -3615,7 +3615,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) tvp2 = trackview_by_y_position (iy1 + y_delta); temp_atv = dynamic_cast(tvp2); - rv->set_height (temp_atv->height); + rv->set_height (temp_atv->current_height()); /* if you un-comment the following, the region colours will follow the track colours whilst dragging, personally, i think this can confuse things, but never mind. diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 2f346ebb98..3c9a81b843 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -1729,8 +1729,15 @@ Editor::temporal_zoom_region (bool both_axes) gint mmwidth = gdk_screen_get_width_mm (screen); double pix_per_mm = (double) pixwidth/ (double) mmwidth; double one_centimeter_in_pixels = pix_per_mm * 10.0; - nframes_t extra_samples = unit_to_frame (one_centimeter_in_pixels); - + + if ((start == 0 && end == 0) || end < start) { + return; + } + + nframes_t range = end - start; + double new_fpu = (double)range / (double)canvas_width; + nframes_t extra_samples = one_centimeter_in_pixels * new_fpu; + if (start > extra_samples) { start -= extra_samples; } else { @@ -1743,6 +1750,14 @@ Editor::temporal_zoom_region (bool both_axes) end = max_frames; } + if (both_axes) { + /* save visual state with track states included, and prevent + set_frames_per_unit() from doing it again. + */ + undo_visual_stack.push_back (current_visual_state(true)); + no_save_visual = true; + } + temporal_zoom_by_frame (start, end, "zoom to region"); if (both_axes) { @@ -1751,7 +1766,7 @@ Editor::temporal_zoom_region (bool both_axes) /* set visible track heights appropriately */ for (set::iterator t = tracks.begin(); t != tracks.end(); ++t) { - (*t)->set_height_scaling_factor (per_track_height/(*t)->height); + (*t)->set_height_scaling_factor (per_track_height/(*t)->current_height()); } /* hide irrelevant tracks */ @@ -1768,9 +1783,11 @@ Editor::temporal_zoom_region (bool both_axes) redisplay_route_list (); vertical_adjustment.set_value (std::max (top_y_position - 5.0, 0.0)); + no_save_visual = false; } zoomed_to_region = true; + redo_visual_stack.push_back (current_visual_state()); } void @@ -1820,23 +1837,14 @@ Editor::temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & o nframes_t range = end - start; double new_fpu = (double)range / (double)canvas_width; -// double p2 = 1.0; - -// while (p2 < new_fpu) { -// p2 *= 2.0; -// } -// new_fpu = p2; nframes_t new_page = (nframes_t) floor (canvas_width * new_fpu); nframes_t middle = (nframes_t) floor( (double)start + ((double)range / 2.0f )); nframes_t new_leftmost = (nframes_t) floor( (double)middle - ((double)new_page/2.0f)); - if (new_leftmost > middle) new_leftmost = 0; - -// begin_reversible_command (op); -// session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit)); -// session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu)); -// commit_reversible_command (); + if (new_leftmost > middle) { + new_leftmost = 0; + } reposition_and_zoom (new_leftmost, new_fpu); } @@ -5865,3 +5873,32 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, commit_reversible_command (); } } + +void +Editor::fit_tracks () +{ + if (selection->tracks.empty()) { + return; + } + + uint32_t child_heights = 0; + + for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) { + child_heights += ((*t)->effective_height - (*t)->current_height()); + } + + uint32_t h = (uint32_t) floor ((canvas_height - child_heights)/selection->tracks.size()); + double first_y_pos = DBL_MAX; + + undo_visual_stack.push_back (current_visual_state()); + + for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) { + (*t)->set_height (h); + first_y_pos = std::min ((*t)->y_position, first_y_pos); + } + + + vertical_adjustment.set_value (first_y_pos); + + redo_visual_stack.push_back (current_visual_state()); +} diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index e6ef9e40a8..dae674a4f5 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -68,7 +68,6 @@ Editor::handle_new_route (Session::RouteList& routes) row[route_display_columns.route] = route; row[route_display_columns.text] = route->name(); row[route_display_columns.visible] = tv->marked_for_display(); - row[route_display_columns.temporary_visible] = tv->marked_for_display(); row[route_display_columns.tv] = tv; track_views.push_back (tv); @@ -173,19 +172,20 @@ Editor::route_name_changed (TimeAxisView *tv) break; } } - } void -Editor::toggle_temporarily_hidden_tracks (bool yn) +Editor::update_route_visibility () { TreeModel::Children rows = route_display_model->children(); TreeModel::Children::iterator i; no_route_list_redisplay = true; - + for (i = rows.begin(); i != rows.end(); ++i) { - (*i)[route_display_columns.temporary_visible] = yn; + TimeAxisView *tv = (*i)[route_display_columns.tv]; + bool v = (*i)[route_display_columns.visible]; + (*i)[route_display_columns.visible] = tv->marked_for_display (); } no_route_list_redisplay = false; @@ -200,10 +200,10 @@ Editor::hide_track_in_display (TimeAxisView& tv, bool temponly) for (i = rows.begin(); i != rows.end(); ++i) { if ((*i)[route_display_columns.tv] == &tv) { - if (!temponly) { - (*i)[route_display_columns.visible] = false; + (*i)[route_display_columns.visible] = false; + if (temponly) { + tv.set_marked_for_display (false); } - (*i)[route_display_columns.temporary_visible] = false; break; } } @@ -225,7 +225,6 @@ Editor::show_track_in_display (TimeAxisView& tv) for (i = rows.begin(); i != rows.end(); ++i) { if ((*i)[route_display_columns.tv] == &tv) { (*i)[route_display_columns.visible] = true; - (*i)[route_display_columns.temporary_visible] = true; tv.set_marked_for_display (true); break; } @@ -300,11 +299,7 @@ Editor::redisplay_route_list () if (visible) { tv->set_marked_for_display (true); - if ((*i)[route_display_columns.temporary_visible]) { - position += tv->show_at (position, n, &edit_controls_vbox); - } else { - tv->hide (); - } + position += tv->show_at (position, n, &edit_controls_vbox); } else { tv->hide (); } @@ -346,7 +341,6 @@ Editor::hide_all_tracks (bool with_select) } row[route_display_columns.visible] = false; - row[route_display_columns.temporary_visible] = false; } no_route_list_redisplay = false; @@ -397,7 +391,6 @@ Editor::set_all_tracks_visibility (bool yn) } (*i)[route_display_columns.visible] = yn; - (*i)[route_display_columns.temporary_visible] = yn; } no_route_list_redisplay = false; @@ -425,20 +418,17 @@ Editor::set_all_audio_visibility (int tracks, bool yn) switch (tracks) { case 0: (*i)[route_display_columns.visible] = yn; - (*i)[route_display_columns.temporary_visible] = yn; break; case 1: if (atv->is_audio_track()) { (*i)[route_display_columns.visible] = yn; - (*i)[route_display_columns.temporary_visible] = yn; } break; case 2: if (!atv->is_audio_track()) { (*i)[route_display_columns.visible] = yn; - (*i)[route_display_columns.temporary_visible] = yn; } break; } @@ -508,7 +498,6 @@ Editor::route_list_display_button_press (GdkEventButton* ev) if (tv) { bool visible = (*iter)[route_display_columns.visible]; (*iter)[route_display_columns.visible] = !visible; - (*iter)[route_display_columns.temporary_visible] = !visible; } } return true; diff --git a/gtk2_ardour/ghostregion.cc b/gtk2_ardour/ghostregion.cc index 915c487c1e..41911f27d3 100644 --- a/gtk2_ardour/ghostregion.cc +++ b/gtk2_ardour/ghostregion.cc @@ -42,7 +42,7 @@ GhostRegion::GhostRegion (AutomationTimeAxisView& atv, double initial_pos) base_rect = new ArdourCanvas::SimpleRect (*group); base_rect->property_x1() = (double) 0.0; base_rect->property_y1() = (double) 0.0; - base_rect->property_y2() = (double) trackview.height; + base_rect->property_y2() = (double) trackview.current_height(); base_rect->property_outline_what() = (guint32) 0; base_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_GhostTrackBase.get(); base_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_GhostTrackBase.get(); @@ -79,8 +79,8 @@ GhostRegion::set_height () vector::iterator i; uint32_t n; - base_rect->property_y2() = (double) trackview.height; - ht = ((trackview.height) / (double) waves.size()); + base_rect->property_y2() = (double) trackview.current_height(); + ht = ((trackview.current_height()) / (double) waves.size()); for (n = 0, i = waves.begin(); i != waves.end(); ++i, ++n) { gdouble yoff = n * ht; diff --git a/gtk2_ardour/imageframe_time_axis_view.cc b/gtk2_ardour/imageframe_time_axis_view.cc index 69205cd511..a57db60a38 100644 --- a/gtk2_ardour/imageframe_time_axis_view.cc +++ b/gtk2_ardour/imageframe_time_axis_view.cc @@ -50,7 +50,7 @@ using namespace Editing; ImageFrameTimeAxisView::ImageFrameTimeAxisView (ImageFrameTimeAxis& tv) : _trackview (tv), canvas_group (*_trackview.canvas_display), - canvas_rect (canvas_group, 0.0, 0.0, 1000000.0, tv.height) + canvas_rect (canvas_group, 0.0, 0.0, 1000000.0, tv.current_height()) { region_color = _trackview.color() ; stream_base_color = ARDOUR_UI::config()->canvasvar_ImageTrack.get() ; diff --git a/gtk2_ardour/imageframe_view.cc b/gtk2_ardour/imageframe_view.cc index f8bba3aa84..f35381301e 100644 --- a/gtk2_ardour/imageframe_view.cc +++ b/gtk2_ardour/imageframe_view.cc @@ -91,9 +91,9 @@ ImageFrameView::ImageFrameView(const string & item_id, //calculate our image width based on the track height double im_ratio = (double)width/(double)height ; - double im_width = ((double)(trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE) * im_ratio) ; + double im_width = ((double)(trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE) * im_ratio) ; - imageframe = new ImageFrame (*group, pbuf, 1.0, 1.0, ANCHOR_NW, im_width, (trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE)); + imageframe = new ImageFrame (*group, pbuf, 1.0, 1.0, ANCHOR_NW, im_width, (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE)); frame_handle_start->signal_event().connect (bind (mem_fun (trackview.editor, &PublicEditor::canvas_imageframe_start_handle_event), frame_handle_start, this)); frame_handle_end->signal_event().connect (bind (mem_fun (trackview.editor, &PublicEditor::canvas_imageframe_end_handle_event), frame_handle_end, this)); diff --git a/gtk2_ardour/mnemonic-us.bindings.in b/gtk2_ardour/mnemonic-us.bindings.in index a1cb481f51..c882923837 100644 --- a/gtk2_ardour/mnemonic-us.bindings.in +++ b/gtk2_ardour/mnemonic-us.bindings.in @@ -79,7 +79,8 @@ (gtk_accel_path "/Common/Save" "<%PRIMARY%>s") (gtk_accel_path "/Editor/duplicate-region" "d") (gtk_accel_path "/Editor/select-all-in-punch-range" "<%PRIMARY%>d") -(gtk_accel_path "/Editor/toggle-follow-playhead" "f") +(gtk_accel_path "/Editor/fit-tracks" "f") +(gtk_accel_path "/Editor/toggle-follow-playhead" "<%PRIMARY%>f") (gtk_accel_path "/Editor/toggle-rhythm-ferret" "<%WINDOW%>f") (gtk_accel_path "/MouseMode/set-mouse-mode-gain" "g") (gtk_accel_path "/Editor/play-selected-regions" "h") @@ -92,7 +93,7 @@ ;; HOME ROW -(gtk_accel_path "/Editor/zoom-to-region" "z") +(gtk_accel_path "/Editor/zoom-to-region" "<%PRIMARY%><%SECONDARY%>z") (gtk_accel_path "/Editor/zoom-to-region-both-axes" "<%SECONDARY%>z") (gtk_accel_path "/Editor/undo" "<%PRIMARY%>z") (gtk_accel_path "/Editor/toggle-zoom" "<%TERTIARY%>z") diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 71370e163c..a88f821693 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -155,7 +155,7 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) reset_width_dependent_items ((double) _region->length() / samples_per_unit); - set_height (trackview.height); + set_height (trackview.current_height()); _region->StateChanged.connect (mem_fun(*this, &RegionView::region_changed)); diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index d8afa18fba..07c84a87e0 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -62,7 +62,7 @@ StreamView::StreamView (RouteTimeAxisView& tv) canvas_rect->property_x1() = 0.0; canvas_rect->property_y1() = 0.0; canvas_rect->property_x2() = _trackview.editor.frame_to_pixel (max_frames); - canvas_rect->property_y2() = (double) tv.height; + canvas_rect->property_y2() = (double) tv.current_height(); canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8); // outline ends and bottom // (Fill/Outline colours set in derived classes) diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index 7723e122f4..d90698db0e 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -921,11 +921,34 @@ TimeAxisView::get_parent_with_state () return parent->get_parent_with_state (); } -void + +XMLNode& +TimeAxisView::get_state () +{ + XMLNode* node = new XMLNode ("TAV-" + name()); + char buf[32]; + + snprintf (buf, sizeof(buf), "%u", height); + node->add_property ("height", buf); + snprintf (buf, sizeof(buf), "%f", height_scaling_factor); + node->add_property ("height_scaling_factor", buf); + node->add_property ("marked_for_display", (_marked_for_display ? "1" : "0")); + return *node; +} + +int TimeAxisView::set_state (const XMLNode& node) { const XMLProperty *prop; + if ((prop = node.property ("marked_for_display")) != 0) { + _marked_for_display = (prop->value() == "1"); + } + + if ((prop = node.property ("height_scaling_factor")) != 0) { + height_scaling_factor = atof (prop->value()); + } + if ((prop = node.property ("track_height")) != 0) { if (prop->value() == "largest") { @@ -947,12 +970,14 @@ TimeAxisView::set_state (const XMLNode& node) } else if ((prop = node.property ("height")) != 0) { - uint32_t h = atoi (prop->value()); - set_height (h); - + set_height (atoi (prop->value())); + } else { + set_height (hNormal); } + + return 0; } void diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index 7fa138dc39..ec11f6dfdb 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -32,6 +32,8 @@ #include +#include + #include #include @@ -68,7 +70,7 @@ class Selectable; * extended to create functional time-axis based views. * */ -class TimeAxisView : public virtual AxisView +class TimeAxisView : public virtual AxisView, public Stateful { private: enum NamePackingBits { @@ -87,11 +89,13 @@ class TimeAxisView : public virtual AxisView TimeAxisView(ARDOUR::Session& sess, PublicEditor& ed, TimeAxisView* parent, ArdourCanvas::Canvas& canvas); virtual ~TimeAxisView (); + XMLNode& get_state (void); + int set_state (const XMLNode&); + /* public data: XXX create accessor/mutators for these ?? */ PublicEditor& editor; - uint32_t height; /* in canvas units */ uint32_t effective_height; /* in canvas units */ double height_scaling_factor; /* used to zoom the track height without changing it */ double y_position; @@ -221,14 +225,12 @@ class TimeAxisView : public virtual AxisView void set_parent (TimeAxisView& p); bool has_state () const; - virtual void set_state (const XMLNode&); - virtual XMLNode* get_state_node () { return 0; } - /* call this on the parent */ virtual XMLNode* get_child_xml_node (const string & childname) { return 0; } protected: + uint32_t height; /* in canvas units */ string controls_base_unselected_name; string controls_base_selected_name; diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index a659eba79c..df48fe9c24 100644 --- a/gtk2_ardour/time_axis_view_item.cc +++ b/gtk2_ardour/time_axis_view_item.cc @@ -150,7 +150,7 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo vestigial_frame->property_x1() = (double) 0.0; vestigial_frame->property_y1() = (double) 1.0; vestigial_frame->property_x2() = 2.0; - vestigial_frame->property_y2() = (double) trackview.height; + vestigial_frame->property_y2() = (double) trackview.current_height(); vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get(); vestigial_frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get(); vestigial_frame->hide (); @@ -160,7 +160,7 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo frame->property_x1() = (double) 0.0; frame->property_y1() = (double) 1.0; frame->property_x2() = (double) trackview.editor.frame_to_pixel(duration); - frame->property_y2() = (double) trackview.height; + frame->property_y2() = (double) trackview.current_height(); frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get(); frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get(); @@ -195,8 +195,8 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo name_highlight->property_x1() = (double) 1.0; name_highlight->property_x2() = (double) (trackview.editor.frame_to_pixel(item_duration)) - 1; } - name_highlight->property_y1() = (double) (trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE); - name_highlight->property_y2() = (double) (trackview.height - 1); + name_highlight->property_y1() = (double) (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE); + name_highlight->property_y2() = (double) (trackview.current_height() - 1); name_highlight->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightFill.get(); name_highlight->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightOutline.get(); @@ -209,10 +209,10 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo if (visibility & ShowNameText) { name_text = new ArdourCanvas::Text (*group); name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET; - /* trackview.height is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight, + /* trackview.current_height() is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight, then NAME_Y_OFFSET to position the text in the vertical center of the highlight */ - name_text->property_y() = (double) trackview.height - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET; + name_text->property_y() = (double) trackview.current_height() - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET; name_text->property_font_desc() = *NAME_FONT; name_text->property_anchor() = Gtk::ANCHOR_NW; -- 2.30.2