summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-01-11 02:30:56 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-01-11 02:30:56 +0000
commite545b222b9ff9bde402da247910db424a04c1d2e (patch)
treec8e6680773d31f02fec4019710625861d2900a23
parentccebd73f6b5da1074a115d080c5ec90541fdda0c (diff)
try to rationalize zoom/scroll ops for the canvas
git-svn-id: svn://localhost/ardour2/trunk@1305 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour_ui.cc6
-rw-r--r--gtk2_ardour/editor.cc277
-rw-r--r--gtk2_ardour/editor.h34
-rw-r--r--gtk2_ardour/editor_canvas.cc2
-rw-r--r--gtk2_ardour/editor_imageframe.cc2
-rw-r--r--gtk2_ardour/editor_ops.cc4
-rw-r--r--gtk2_ardour/public_editor.h2
7 files changed, 195 insertions, 132 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index b6142bbd59..8b1bc78e68 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -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);
}
}
}
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 2e50a778df..2fdbb5c7fb 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -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;
@@ -825,65 +824,6 @@ Editor::tie_vertical_scrolling ()
}
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 ()
{
if (!constructed || !ARDOUR_UI::instance()->session_loaded) {
@@ -898,28 +838,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()
{
if (edit_cursor->current_frame != edit_cursor_clock.current_time()) {
@@ -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;
+}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 8ee9c45ed1..82f60e8d3d 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -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__ */
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 5415ffa9cf..3f70322573 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -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 */
diff --git a/gtk2_ardour/editor_imageframe.cc b/gtk2_ardour/editor_imageframe.cc
index 0e5131bb97..b65ce93178 100644
--- a/gtk2_ardour/editor_imageframe.cc
+++ b/gtk2_ardour/editor_imageframe.cc
@@ -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
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 2e78f63ee2..2e271d7671 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -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
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 1e93e17735..f672ea180d 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -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;