try to rationalize zoom/scroll ops for the canvas
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 11 Jan 2007 02:30:56 +0000 (02:30 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 11 Jan 2007 02:30:56 +0000 (02:30 +0000)
git-svn-id: svn://localhost/ardour2/trunk@1305 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/ardour_ui.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_imageframe.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/public_editor.h

index b6142bbd5951fa553a0b4d5e4ff0082440b82f16..8b1bc78e68f0759b3a08865c7b2b9ff6b5b4233a 100644 (file)
@@ -956,7 +956,7 @@ ARDOUR_UI::transport_goto_start ()
                */
                
                if (editor) {
-                       editor->reposition_x_origin (session->current_start_frame());
+                       editor->reset_x_origin (session->current_start_frame());
                }
        }
 }
@@ -973,7 +973,7 @@ ARDOUR_UI::transport_goto_zero ()
                */
                
                if (editor) {
-                       editor->reposition_x_origin (0);
+                       editor->reset_x_origin (0);
                }
        }
 }
@@ -990,7 +990,7 @@ ARDOUR_UI::transport_goto_end ()
                */
                
                if (editor) {
-                       editor->reposition_x_origin (frame);
+                       editor->reset_x_origin (frame);
                }
        }
 }
index 2e50a778df2acb0091ddf2b42ae36eb86e05ad00..2fdbb5c7fb0b2ba15bc193a02f0315145204ada3 100644 (file)
@@ -291,7 +291,6 @@ Editor::Editor (AudioEngine& eng)
        new_transport_marker_menu = 0;
        editor_mixer_strip_width = Wide;
        show_editor_mixer_when_tracks_arrive = false;
-       repos_zoom_queued = false;
        region_edit_menu_split_item = 0;
        temp_location = 0;
        region_edit_menu_split_multichannel_item = 0;
@@ -322,7 +321,7 @@ Editor::Editor (AudioEngine& eng)
        
        set_mouse_mode (MouseObject, true);
 
-       frames_per_unit = 2048; /* too early to use set_frames_per_unit */
+       frames_per_unit = 2048; /* too early to use reset_zoom () */
        reset_hscrollbar_stepping ();
        
        zoom_focus = ZoomFocusLeft;
@@ -824,65 +823,6 @@ Editor::tie_vertical_scrolling ()
        edit_cursor->set_y_axis(y1);
 }
 
-void
-Editor::set_frames_per_unit (double fpu)
-{
-       nframes_t frames;
-
-       if (fpu == frames_per_unit) {
-               return;
-       }
-
-       if (fpu < 2.0) {
-               fpu = 2.0;
-       }
-
-       // convert fpu to frame count
-
-       frames = (nframes_t) floor (fpu * canvas_width);
-       
-       /* don't allow zooms that fit more than the maximum number
-          of frames into an 800 pixel wide space.
-       */
-
-       if (max_frames / fpu < 800.0) {
-               return;
-       }
-
-       if (fpu == frames_per_unit) {
-               return;
-       }
-
-       frames_per_unit = fpu;
-
-       if (frames != zoom_range_clock.current_duration()) {
-               zoom_range_clock.set (frames);
-       }
-
-       if (mouse_mode == MouseRange && selection->time.start () != selection->time.end_frame ()) {
-               if (!selection->tracks.empty()) {
-                       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-                               (*i)->reshow_selection (selection->time);
-                       }
-               } else {
-                       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-                               (*i)->reshow_selection (selection->time);
-                       }
-               }
-       }
-
-       ZoomChanged (); /* EMIT_SIGNAL */
-
-       reset_hscrollbar_stepping ();
-       reset_scrolling_region ();
-       
-       if (edit_cursor) edit_cursor->set_position (edit_cursor->current_frame);
-       if (playhead_cursor) playhead_cursor->set_position (playhead_cursor->current_frame);
-
-       instant_save ();
-
-}
-
 void
 Editor::instant_save ()
 {
@@ -897,28 +837,6 @@ Editor::instant_save ()
        }
 }
 
-void
-Editor::reposition_x_origin (nframes_t frame)
-{
-       cerr << "repsosition to " << frame << endl;
-
-       if (frame != leftmost_frame) {
-               leftmost_frame = frame;
-               
-               nframes_t rightmost_frame = leftmost_frame + current_page_frames ();
-
-               if (rightmost_frame > last_canvas_frame) {
-                       last_canvas_frame = rightmost_frame;
-                       reset_scrolling_region ();
-               }
-
-               horizontal_adjustment.set_value (frame/frames_per_unit);
-       } else {
-               update_fixed_rulers();
-               tempo_map_changed (Change (0));
-       }
-}
-
 void
 Editor::edit_cursor_clock_changed()
 {
@@ -974,9 +892,9 @@ Editor::control_scroll (float fraction)
 
        if (target > (current_page_frames() / 2)) {
                /* try to center PH in window */
-               reposition_x_origin (target - (current_page_frames()/2));
+               reset_x_origin (target - (current_page_frames()/2));
        } else {
-               reposition_x_origin (0);
+               reset_x_origin (0);
        }
 
        /* cancel the existing */
@@ -995,36 +913,6 @@ Editor::deferred_control_scroll (nframes_t target)
        return false;
 }
 
-void 
-Editor::canvas_horizontally_scrolled ()
-{
-
-       leftmost_frame = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
-       update_fixed_rulers ();
-       tempo_map_changed (Change (0));
-
-}
-
-void
-Editor::reposition_and_zoom (nframes_t frame, double nfpu)
-{
-       if (!repos_zoom_queued) {
-               repos_zoom_queued = true;
-               Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::deferred_reposition_and_zoom), frame, nfpu));
-       }
-}
-
-gint
-Editor::deferred_reposition_and_zoom (nframes_t frame, double nfpu)
-{
-
-       set_frames_per_unit (nfpu);
-       reposition_x_origin  (frame);
-       repos_zoom_queued = false;
-       
-       return FALSE;
-}
-
 void
 Editor::on_realize ()
 {
@@ -1082,7 +970,7 @@ Editor::center_screen_internal (nframes_t frame, float page)
                frame = 0;
        }
 
-    reposition_x_origin (frame);
+       reset_x_origin (frame);
 }
 
 void
@@ -2114,7 +2002,7 @@ Editor::set_state (const XMLNode& node)
        } else {
                playhead_cursor->set_position (0);
 
-               /* ::reposition_x_origin() doesn't work right here, since the old
+               /* reset_x_origin() doesn't work right here, since the old
                   position may be zero already, and it does nothing in such
                   circumstances.
                */
@@ -2135,7 +2023,7 @@ Editor::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property ("zoom"))) {
-               set_frames_per_unit (PBD::atof (prop->value()));
+               reset_zoom (PBD::atof (prop->value()));
        }
 
        if ((prop = node.property ("snap-to"))) {
@@ -4250,3 +4138,156 @@ Editor::on_key_press_event (GdkEventKey* ev)
        return key_press_focus_accelerator_handler (*this, ev);
 }
 
+void
+Editor::reset_x_origin (nframes_t frame)
+{
+       queue_visual_change (frame);
+}
+
+void
+Editor::reset_zoom (double fpu)
+{
+       queue_visual_change (fpu);
+}
+
+void
+Editor::reposition_and_zoom (nframes_t frame, double fpu)
+{
+       reset_x_origin (frame);
+       reset_zoom (fpu);
+}
+
+void
+Editor::set_frames_per_unit (double fpu)
+{
+       nframes_t frames;
+
+       /* this is the core function that controls the zoom level of the canvas. it is called
+          whenever one or more calls are made to reset_zoom(). it executes in an idle handler.
+       */
+
+       if (fpu == frames_per_unit) {
+               return;
+       }
+
+       if (fpu < 2.0) {
+               fpu = 2.0;
+       }
+
+       // convert fpu to frame count
+
+       frames = (nframes_t) floor (fpu * canvas_width);
+       
+       /* don't allow zooms that fit more than the maximum number
+          of frames into an 800 pixel wide space.
+       */
+
+       if (max_frames / fpu < 800.0) {
+               return;
+       }
+
+       if (fpu == frames_per_unit) {
+               return;
+       }
+
+       frames_per_unit = fpu;
+
+       if (frames != zoom_range_clock.current_duration()) {
+               zoom_range_clock.set (frames);
+       }
+
+       if (mouse_mode == MouseRange && selection->time.start () != selection->time.end_frame ()) {
+               if (!selection->tracks.empty()) {
+                       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+                               (*i)->reshow_selection (selection->time);
+                       }
+               } else {
+                       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                               (*i)->reshow_selection (selection->time);
+                       }
+               }
+       }
+
+       ZoomChanged (); /* EMIT_SIGNAL */
+
+       reset_hscrollbar_stepping ();
+       reset_scrolling_region ();
+       
+       if (edit_cursor) edit_cursor->set_position (edit_cursor->current_frame);
+       if (playhead_cursor) playhead_cursor->set_position (playhead_cursor->current_frame);
+
+       instant_save ();
+}
+
+void 
+Editor::canvas_horizontally_scrolled ()
+{
+       /* this is the core function that controls horizontal scrolling of the canvas. it is called
+          whenever the horizontal_adjustment emits its "value_changed" signal. it executes in an
+          idle handler.
+       */
+
+       leftmost_frame = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+       nframes_t rightmost_frame = leftmost_frame + current_page_frames ();
+       
+       if (rightmost_frame > last_canvas_frame) {
+               last_canvas_frame = rightmost_frame;
+               reset_scrolling_region ();
+       }
+       
+       update_fixed_rulers ();
+       tempo_map_changed (Change (0));
+}
+
+void
+Editor::queue_visual_change (nframes_t where)
+{
+       pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
+       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);
+       }
+}
+
+void
+Editor::queue_visual_change (double fpu)
+{
+       pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::ZoomLevel);
+       pending_visual_change.frames_per_unit = fpu;
+
+       if (pending_visual_change.idle_handler_id < 0) {
+               pending_visual_change.idle_handler_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, _idle_visual_changer, this, 0);
+       }
+}
+
+int
+Editor::_idle_visual_changer (void* arg)
+{
+       return static_cast<Editor*>(arg)->idle_visual_changer ();
+}
+
+int
+Editor::idle_visual_changer ()
+{
+       VisualChange::Type p = pending_visual_change.pending;
+
+       pending_visual_change.pending = (VisualChange::Type) 0;
+       pending_visual_change.idle_handler_id = -1;
+       
+       if (p & VisualChange::ZoomLevel) {
+               set_frames_per_unit (pending_visual_change.frames_per_unit);
+       }
+
+       if (p & VisualChange::TimeOrigin) {
+               if (pending_visual_change.time_origin != leftmost_frame) {
+                       horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit);
+                       /* the signal handler will do the rest */
+               } else {
+                       update_fixed_rulers();
+                       tempo_map_changed (Change (0));
+               }
+       }
+
+       return 0;
+}
index 8ee9c45ed111426b21b5aba7cae65d9075ba0877..82f60e8d3d74e42a2dd6a5931e0daaac684a0baa 100644 (file)
@@ -332,11 +332,13 @@ class Editor : public PublicEditor
        bool new_regionviews_display_gain () { return _new_regionviews_show_envelope; }
        void prepare_for_cleanup ();
 
-       void reposition_x_origin (nframes_t sample);
-
        void maximise_editing_space();
        void restore_editing_space();
 
+       void reset_x_origin (nframes_t);
+       void reset_zoom (double);
+       void reposition_and_zoom (nframes_t, double);
+
   protected:
        void map_transport_state ();
        void map_position_change (nframes_t);
@@ -678,10 +680,31 @@ class Editor : public PublicEditor
        void tie_vertical_scrolling ();
        void canvas_horizontally_scrolled ();
 
-       void reposition_and_zoom (nframes_t sample, double fpu);
-       gint deferred_reposition_and_zoom (nframes_t sample, double fpu);
+       struct VisualChange {
+           enum Type { 
+                   TimeOrigin = 0x1,
+                   ZoomLevel = 0x2
+           };
+
+           Type pending;
+           nframes_t time_origin;
+           double frames_per_unit;
+
+           int idle_handler_id;
+
+           VisualChange() : pending ((VisualChange::Type) 0), time_origin (0), frames_per_unit (0), idle_handler_id (-1) {}
+       };
+
+
+       VisualChange pending_visual_change;
+
+       static int _idle_visual_changer (void *arg);
+       int idle_visual_changer ();
+
+       void queue_visual_change (nframes_t);
+       void queue_visual_change (double);
+
        void end_location_changed (ARDOUR::Location*);
-       bool repos_zoom_queued;
 
        struct RegionListDisplayModelColumns : public Gtk::TreeModel::ColumnRecord {
            RegionListDisplayModelColumns() {
@@ -1798,7 +1821,6 @@ class Editor : public PublicEditor
        Glib::RefPtr<Gtk::Action>              redo_action;
 
        void history_changed ();
-
 };
 
 #endif /* __ardour_editor_h__ */
index 5415ffa9cfbb93de6bff8e0abe0dde1edfa32f91..3f70322573daf214551732632db739dcce5acd27 100644 (file)
@@ -638,7 +638,7 @@ Editor::autoscroll_canvas ()
        } 
 
        if (new_frame != leftmost_frame) {
-               reposition_x_origin (new_frame);
+               reset_x_origin (new_frame);
        }
 
        if (autoscroll_cnt == 50) { /* 0.5 seconds */
index 0e5131bb97d18be7d4cbcab496107e0bafec54a5..b65ce93178b58ec0abc0fd83aee1d3cc9974818f 100644 (file)
@@ -107,7 +107,7 @@ Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
                x_pos = item->get_position() - offset + (item->get_duration() / 2);
        }
        
-       reposition_x_origin (x_pos);
+       reset_x_origin (x_pos);
 }
 
 void
index 2e78f63ee272a0765986c0112526d1f1cba585fd..2e271d7671faa31ac4892314bf244c12aca354c0 100644 (file)
@@ -926,7 +926,7 @@ Editor::scroll_backward (float pages)
                frame = leftmost_frame - cnt;
        }
 
-       reposition_x_origin (frame);
+       reset_x_origin (frame);
 }
 
 void
@@ -954,7 +954,7 @@ Editor::scroll_forward (float pages)
                frame = leftmost_frame + cnt;
        }
 
-       reposition_x_origin (frame);
+       reset_x_origin (frame);
 }
 
 void
index 1e93e177358d810ba798569052379b4e0cb8a994..f672ea180d01c2c0ee66174902e50b571939e458 100644 (file)
@@ -129,7 +129,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void scroll_tracks_up_line () = 0;
        virtual bool new_regionviews_display_gain () = 0;
        virtual void prepare_for_cleanup () = 0;
-       virtual void reposition_x_origin (nframes_t frame) = 0;
+       virtual void reset_x_origin (nframes_t frame) = 0;
        virtual void remove_last_capture () = 0;
        virtual void maximise_editing_space() = 0;
        virtual void restore_editing_space() = 0;