diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-09-10 21:27:39 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-09-10 21:27:39 +0000 |
commit | c86210a9d5bdb7b36ad58552a1f99f53d48781b3 (patch) | |
tree | 6ab06935a1e2bc4ef6a4448dd01b09f5b2628c66 /gtk2_ardour | |
parent | 68e943265edf04e63a8e8b8f62bab20f99d9c637 (diff) |
merge 2.0-ongoing into 3.0 @ 3581 - 3710
git-svn-id: svn://localhost/ardour2/branches/3.0@3712 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
33 files changed, 1017 insertions, 594 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 836755c064..136fe6a3db 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -286,8 +286,11 @@ if env['VST']: extra_sources += vst_files gtkardour.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst") +lv2_files = [ 'lv2_plugin_ui.cc' ] + if env['LV2']: - gtkardour.Append (CCFLAGS="-DHAVE_SLV2") + extra_sources += lv2_files + gtkardour.Append (CCFLAGS="-DHAVE_LV2") gtkardour.Merge ([libraries['slv2']]) @@ -432,7 +435,7 @@ else: keybindings_dict['%LEVEL4%'] = env['WINDOWS_KEY'] keybindings_dict['%WINDOW%'] = 'Alt' -for b in [ 'SAE-de', 'mnemonic-us', 'ergonomic-us' ]: +for b in [ 'SAE-de', 'SAE-us', 'mnemonic-us', 'ergonomic-us' ]: target_file = b + '.bindings' src_file = target_file + '.in' Default (env.SubstInFile (target_file, src_file, SUBST_DICT = keybindings_dict)) diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 1e55d2be1f..9ed6d0e599 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1344,7 +1344,7 @@ ARDOUR_UI::do_transport_locate (nframes_t new_position) } void -ARDOUR_UI::transport_goto_start () +ARDOUR_UI::transport_goto_start () { if (session) { session->goto_start(); diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index a3dbc1d3d0..23b9787408 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -104,6 +104,9 @@ AudioClock::AudioClock (std::string clock_name, bool transient, std::string widg Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0); Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0); + Gtkmm2ext::set_size_request_to_display_given_text(*bbt_upper_info_label, "88|88",0,0); + Gtkmm2ext::set_size_request_to_display_given_text(*bbt_lower_info_label, "888.88",0,0); + frames_info_box.pack_start (*frames_upper_info_label, true, true); frames_info_box.pack_start (*frames_lower_info_label, true, true); smpte_info_box.pack_start (*smpte_upper_info_label, true, true); @@ -644,11 +647,17 @@ AudioClock::set_bbt (nframes_t when, bool force) } sprintf (buf, "%03" PRIu32, bbt.bars); - bars_label.set_text (buf); + if (force || bars_label.get_text () != buf) { + bars_label.set_text (buf); + } sprintf (buf, "%02" PRIu32, bbt.beats); - beats_label.set_text (buf); + if (force || beats_label.get_text () != buf) { + beats_label.set_text (buf); + } sprintf (buf, "%04" PRIu32, bbt.ticks); - ticks_label.set_text (buf); + if (force || ticks_label.get_text () != buf) { + ticks_label.set_text (buf); + } if (bbt_upper_info_label) { nframes64_t pos; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index ab8940874c..6c276f3b0c 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -209,8 +209,7 @@ Editor::Editor () range_mark_label (_("Range Markers")), transport_mark_label (_("Loop/Punch Ranges")), cd_mark_label (_("CD Markers")), - - edit_packer (3, 3, true), + edit_packer (3, 4, true), /* the values here don't matter: layout widgets reset them as needed. @@ -219,9 +218,6 @@ Editor::Editor () vertical_adjustment (0.0, 0.0, 10.0, 400.0), horizontal_adjustment (0.0, 0.0, 20.0, 1200.0), - tempo_lines(0), - marker_tempo_lines(0), - /* tool bar related */ edit_point_clock (X_("editpoint"), false, X_("EditPointClock"), true), @@ -375,7 +371,6 @@ Editor::Editor () range_marker_drag_rect = 0; marker_drag_line = 0; tempo_map_change_idle_handler_id = -1; - canvas_hroizontally_scrolled_handler_id = -1; set_midi_edit_mode (MidiEditPencil, true); set_mouse_mode (MouseObject, true); @@ -390,16 +385,10 @@ Editor::Editor () initialize_canvas (); edit_controls_vbox.set_spacing (0); - horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::canvas_horizontally_scrolled), false); + horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::scroll_canvas_horizontally), false); vertical_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::tie_vertical_scrolling), true); - - track_canvas->set_hadjustment (horizontal_adjustment); - track_canvas->set_vadjustment (vertical_adjustment); - time_canvas->set_hadjustment (horizontal_adjustment); - track_canvas->signal_map_event().connect (mem_fun (*this, &Editor::track_canvas_map_handler)); - time_canvas->signal_map_event().connect (mem_fun (*this, &Editor::time_canvas_map_handler)); - + controls_layout.add (edit_controls_vbox); controls_layout.set_name ("EditControlsBase"); controls_layout.add_events (Gdk::SCROLL_MASK); @@ -436,9 +425,8 @@ Editor::Editor () time_canvas_vbox.pack_start (*smpte_ruler, false, false); time_canvas_vbox.pack_start (*frames_ruler, false, false); time_canvas_vbox.pack_start (*bbt_ruler, false, false); - time_canvas_vbox.pack_start (*time_canvas, true, true); - time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 5); - + //time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2); + time_canvas_vbox.set_size_request (-1, -1); bbt_label.set_name ("EditorTimeButton"); bbt_label.set_size_request (-1, (int)timebar_height); bbt_label.set_alignment (1.0, 0.5); @@ -455,6 +443,7 @@ Editor::Editor () frame_label.set_size_request (-1, (int)timebar_height); frame_label.set_alignment (1.0, 0.5); frame_label.set_padding (5,0); + tempo_label.set_name ("EditorTimeButton"); tempo_label.set_size_request (-1, (int)timebar_height); tempo_label.set_alignment (1.0, 0.5); @@ -479,26 +468,26 @@ Editor::Editor () transport_mark_label.set_size_request (-1, (int)timebar_height); transport_mark_label.set_alignment (1.0, 0.5); transport_mark_label.set_padding (5,0); + + ruler_label_vbox.pack_start (minsec_label, false, false); + ruler_label_vbox.pack_start (smpte_label, false, false); + ruler_label_vbox.pack_start (frame_label, false, false); + ruler_label_vbox.pack_start (bbt_label, false, false); - time_button_vbox.pack_start (minsec_label, false, false); - time_button_vbox.pack_start (smpte_label, false, false); - time_button_vbox.pack_start (frame_label, false, false); - time_button_vbox.pack_start (bbt_label, false, false); + 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_vbox.pack_start (meter_label, false, false); time_button_vbox.pack_start (tempo_label, false, false); time_button_vbox.pack_start (mark_label, false, false); time_button_event_box.add (time_button_vbox); time_button_event_box.set_name ("TimebarLabelBase"); - time_button_frame.set_shadow_type (Gtk::SHADOW_NONE); - 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)); - time_button_frame.add (time_button_event_box); - time_button_frame.set_name ("TimebarLabelBase"); - time_button_frame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT); - /* these enable us to have a dedicated window (for cursor setting, etc.) for the canvas areas. */ @@ -514,16 +503,16 @@ Editor::Editor () edit_packer.set_border_width (0); edit_packer.set_name ("EditorWindow"); - edit_packer.attach (edit_vscrollbar, 3, 4, 1, 2, FILL, FILL|EXPAND, 0, 0); - - edit_packer.attach (time_button_frame, 0, 2, 0, 1, FILL, SHRINK, 0, 0); - edit_packer.attach (time_canvas_event_box, 2, 4, 0, 1, FILL|EXPAND, FILL, 0, 0); + edit_packer.attach (edit_vscrollbar, 0, 1, 0, 4, FILL, FILL|EXPAND, 0, 0); + edit_packer.attach (ruler_label_event_box, 1, 2, 0, 1, FILL, SHRINK, 0, 0); + edit_packer.attach (time_button_event_box, 1, 2, 1, 2, FILL, SHRINK, 0, 0); + edit_packer.attach (time_canvas_event_box, 2, 3, 0, 1, FILL|EXPAND, FILL, 0, 0); - edit_packer.attach (controls_layout, 1, 2, 1, 2, FILL, FILL|EXPAND, 0, 0); - edit_packer.attach (track_canvas_event_box, 2, 3, 1, 2, FILL|EXPAND, FILL|EXPAND, 0, 0); + edit_packer.attach (controls_layout, 1, 2, 2, 3, FILL, FILL|EXPAND, 0, 0); + edit_packer.attach (track_canvas_event_box, 2, 3, 1, 3, FILL|EXPAND, FILL|EXPAND, 0, 0); - edit_packer.attach (zoom_box, 1, 2, 2, 3, FILL, FILL, 0, 0); - edit_packer.attach (edit_hscrollbar, 2, 3, 2, 3, FILL|EXPAND, FILL, 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); bottom_hbox.set_border_width (2); bottom_hbox.set_spacing (3); @@ -854,20 +843,10 @@ Editor::~Editor() track_canvas = 0; } - if (time_canvas) { - delete time_canvas; - time_canvas = 0; - } - if (track_canvas) { delete track_canvas; track_canvas = 0; } - - if (time_canvas) { - delete time_canvas; - time_canvas = 0; - } } void @@ -1103,6 +1082,7 @@ Editor::start_scrolling () { scroll_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun(*this, &Editor::update_current_screen)); + } void @@ -1161,7 +1141,7 @@ Editor::handle_new_duration () if (new_end > last_canvas_frame) { last_canvas_frame = new_end; horizontal_adjustment.set_upper (last_canvas_frame / frames_per_unit); - reset_scrolling_region (); + //reset_scrolling_region (); } horizontal_adjustment.set_value (leftmost_frame/frames_per_unit); @@ -3562,13 +3542,23 @@ Editor::hide_verbose_canvas_cursor () double Editor::clamp_verbose_cursor_x (double x) { - return min (horizontal_adjustment.get_value() + canvas_width - 75.0, x); + if (x < 0) { + x = 0; + } else { + x = min (canvas_width - 200.0, x); + } + return x; } double Editor::clamp_verbose_cursor_y (double y) { - return min (vertical_adjustment.get_value() + canvas_height - 50.0, y); + if (y < canvas_timebars_vsize) { + y = canvas_timebars_vsize; + } else { + y = min (canvas_height - 50, y); + } + return y; } void @@ -3577,7 +3567,7 @@ Editor::set_verbose_canvas_cursor (const string & txt, double x, double y) verbose_canvas_cursor->property_text() = txt.c_str(); /* don't get too close to the edge */ verbose_canvas_cursor->property_x() = clamp_verbose_cursor_x (x); - verbose_canvas_cursor->property_y() = clamp_verbose_cursor_x (y); + verbose_canvas_cursor->property_y() = clamp_verbose_cursor_y (y); } void @@ -4014,7 +4004,8 @@ void Editor::end_location_changed (Location* location) { ENSURE_GUI_THREAD (bind (mem_fun(*this, &Editor::end_location_changed), location)); - reset_scrolling_region (); + //reset_scrolling_region (); + horizontal_adjustment.set_upper ( location->start()); } int @@ -4405,6 +4396,7 @@ Editor::on_key_release_event (GdkEventKey* ev) void Editor::reset_x_origin (nframes64_t frame) { + //cerr << "resetting x origin" << endl; queue_visual_change (frame); } @@ -4532,10 +4524,6 @@ Editor::set_frames_per_unit (double fpu) return; } - if (fpu == frames_per_unit) { - return; - } - frames_per_unit = fpu; post_zoom (); } @@ -4566,9 +4554,11 @@ Editor::post_zoom () ZoomChanged (); /* EMIT_SIGNAL */ reset_hscrollbar_stepping (); - reset_scrolling_region (); + //reset_scrolling_region (); - if (playhead_cursor) playhead_cursor->set_position (playhead_cursor->current_frame); + if (playhead_cursor) { + playhead_cursor->set_position (playhead_cursor->current_frame); + } instant_save (); } @@ -4576,10 +4566,12 @@ Editor::post_zoom () void Editor::queue_visual_change (nframes64_t where) { - pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin); - pending_visual_change.time_origin = 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.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin); + pending_visual_change.time_origin = where; pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this); } } @@ -4606,13 +4598,6 @@ int Editor::idle_visual_changer () { VisualChange::Type p = pending_visual_change.pending; - nframes64_t csf, cef; - - if (session) { - csf = session->current_start_frame(); - cef = session->current_end_frame() + (current_page_frames() / 24);// Add a little extra so we can see the end marker - } - pending_visual_change.pending = (VisualChange::Type) 0; if (p & VisualChange::ZoomLevel) { @@ -4624,26 +4609,29 @@ Editor::idle_visual_changer () update_tempo_based_rulers (); } if (p & VisualChange::TimeOrigin) { - - nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit); + + nframes64_t csf, cef; + nframes64_t current_time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit); + + if (session) { + csf = session->current_start_frame(); + cef = session->current_end_frame() + (current_page_frames() / 24);// Add a little extra so we can see the end marker + } /* if we seek beyond the current end of the canvas, move the end */ - if (time_origin != pending_visual_change.time_origin) { - - if (horizontal_adjustment.get_upper() < pending_visual_change.time_origin) { - last_canvas_frame = (cef > (pending_visual_change.time_origin + current_page_frames())) ? cef : pending_visual_change.time_origin + current_page_frames(); - horizontal_adjustment.set_upper ((cef - csf) / frames_per_unit); - reset_scrolling_region (); - } - - horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit); + if (current_time_origin != pending_visual_change.time_origin) { + //if (horizontal_adjustment.get_upper() < pending_visual_change.time_origin) { + last_canvas_frame = (cef > (pending_visual_change.time_origin + current_page_frames())) ? cef : pending_visual_change.time_origin + current_page_frames(); + horizontal_adjustment.set_upper ((cef - csf) / frames_per_unit); + //} + horizontal_adjustment.set_value (pending_visual_change.time_origin / frames_per_unit); } else { update_fixed_rulers(); redisplay_tempo (true); } } - + //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 */ } @@ -5020,7 +5008,7 @@ Editor::queue_draw_resize_line (int at) /* redraw where it used to be */ - Gdk::Rectangle r (xroot, old_resize_line_y - 1, controls_width + (int) canvas_width, 3); + 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"; @@ -5028,7 +5016,7 @@ Editor::queue_draw_resize_line (int at) /* draw where it is */ - Gdk::Rectangle r (xroot, at - 1, controls_width + (int) canvas_width, 3); + Gdk::Rectangle r (0, at - 1, controls_width + (int) canvas_width, 3); win->invalidate_rect (r, true); } #endif @@ -5063,7 +5051,7 @@ Editor::on_expose_event (GdkEventExpose* ev) GdkRectangle lr; GdkRectangle intersection; - lr.x = xroot; + lr.x = 0; lr.y = resize_line_y; lr.width = controls_width + (int) canvas_width; lr.height = 3; @@ -5084,15 +5072,17 @@ Editor::on_expose_event (GdkEventExpose* ev) Gdk::JOIN_MITER); gdk_draw_line (win, gc->gobj(), - xroot, - yroot + resize_line_y, - xroot + (int) canvas_width + controls_width, - yroot + resize_line_y); + 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; - old_resize_line_y = yroot + resize_line_y; +#endif + old_resize_line_y = resize_line_y; cerr << "NEXT EXPOSE SHOULD BE AT " << old_resize_line_y << endl; } else { cerr << "no intersect with " diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index e8af889ad1..eb03922eaf 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -600,7 +600,6 @@ class Editor : public PublicEditor Gdk::Cursor* which_grabber_cursor (); ArdourCanvas::Canvas* track_canvas; - ArdourCanvas::Canvas* time_canvas; ArdourCanvas::Text* first_action_message; ArdourCanvas::Text* verbose_canvas_cursor; @@ -620,7 +619,7 @@ class Editor : public PublicEditor Gtk::EventBox time_canvas_event_box; Gtk::EventBox track_canvas_event_box; Gtk::EventBox time_button_event_box; - Gtk::Frame time_button_frame; + Gtk::EventBox ruler_label_event_box; ArdourCanvas::Group *minsec_group; ArdourCanvas::Pixbuf *logo_item; @@ -633,6 +632,34 @@ class Editor : public PublicEditor ArdourCanvas::Group *range_marker_group; ArdourCanvas::Group *transport_marker_group; ArdourCanvas::Group* cd_marker_group; + + ArdourCanvas::Group* timebar_group; + + /* These bars never need to be scrolled */ + ArdourCanvas::Group* meter_bar_group; + ArdourCanvas::Group* tempo_bar_group; + ArdourCanvas::Group* marker_bar_group; + ArdourCanvas::Group* range_marker_bar_group; + ArdourCanvas::Group* transport_marker_bar_group; + ArdourCanvas::Group* cd_marker_bar_group; + + /* + The _master_group is the group containing all items + that require horizontal scrolling.. + It is primarily used to separate canvas items + that require horizontal scrolling from those that do not. + */ + ArdourCanvas::Group* _master_group; + /* + The _trackview_group is the group containing all trackviews. + It is only scrolled vertically. + */ + ArdourCanvas::Group* _trackview_group; + /* + This canvas group is used for region motion. + It sits on top of the _trackview_group + */ + ArdourCanvas::Group* _region_motion_group; enum RulerType { ruler_metric_smpte = 0, @@ -755,6 +782,7 @@ class Editor : public PublicEditor static const double timebar_height; guint32 visible_timebars; + gdouble canvas_timebars_vsize; Gtk::Menu *editor_ruler_menu; ArdourCanvas::SimpleRect* tempo_bar; @@ -858,12 +886,12 @@ class Editor : public PublicEditor nframes64_t last_canvas_frame; bool track_canvas_map_handler (GdkEventAny*); - bool time_canvas_map_handler (GdkEventAny*); gint edit_controls_button_release (GdkEventButton*); Gtk::Menu *edit_controls_left_menu; Gtk::Menu *edit_controls_right_menu; + Gtk::VBox ruler_label_vbox; Gtk::VBox track_canvas_vbox; Gtk::VBox time_canvas_vbox; Gtk::VBox edit_controls_vbox; @@ -874,7 +902,11 @@ class Editor : public PublicEditor bool deferred_control_scroll (nframes64_t); sigc::connection control_scroll_connection; + gdouble get_trackview_group_vertical_offset () const { return vertical_adjustment.get_value () - canvas_timebars_vsize;} + ArdourCanvas::Group* get_trackview_group () const { return _trackview_group; } void tie_vertical_scrolling (); + void scroll_canvas_horizontally (); + void scroll_canvas_vertically (); void canvas_horizontally_scrolled (); void canvas_scroll_to (nframes64_t); @@ -1464,15 +1496,12 @@ public: bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*); bool track_canvas_scroll (GdkEventScroll* event); - bool time_canvas_scroll (GdkEventScroll* event); bool track_canvas_scroll_event (GdkEventScroll* event); bool track_canvas_button_press_event (GdkEventButton* event); bool track_canvas_button_release_event (GdkEventButton* event); bool track_canvas_motion_notify_event (GdkEventMotion* event); - bool time_canvas_scroll_event (GdkEventScroll* event); - Gtk::Allocation canvas_allocation; bool canvas_idle_queued; void track_canvas_allocate (Gtk::Allocation alloc); @@ -1489,9 +1518,6 @@ public: void handle_new_duration (); void initialize_canvas (); - int canvas_hroizontally_scrolled_handler_id; - void reset_horizontally_scrolling_region (Gtk::Allocation* alloc = 0); - void reset_scrolling_region (Gtk::Allocation* alloc = 0); /* display control */ @@ -1505,11 +1531,12 @@ public: ARDOUR::TempoMap::BBTPointList *current_bbt_points; + typedef vector<ArdourCanvas::SimpleLine*> TimeLineList; + TimeLineList free_measure_lines; + TimeLineList used_measure_lines; + ArdourCanvas::Group* time_line_group; - ArdourCanvas::Group* marker_time_line_group; - - TempoLines* tempo_lines; - TempoLines* marker_tempo_lines; + ArdourCanvas::SimpleLine* get_time_line (); void hide_measures (); void draw_measures (); @@ -1887,12 +1914,13 @@ public: uint32_t autoscroll_cnt; nframes64_t autoscroll_x_distance; double autoscroll_y_distance; - + static gint _autoscroll_canvas (void *); bool autoscroll_canvas (); void start_canvas_autoscroll (int x, int y); void stop_canvas_autoscroll (); void maybe_autoscroll (GdkEventMotion*); + void maybe_autoscroll_horizontally (GdkEventMotion*); bool allow_vertical_scroll; /* trimming */ diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 0be64cc80f..9e0ecca93c 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -100,10 +100,8 @@ Editor::initialize_canvas () { if (getenv ("ARDOUR_NON_AA_CANVAS")) { track_canvas = new ArdourCanvas::Canvas (); - time_canvas = new ArdourCanvas::Canvas (); } else { track_canvas = new ArdourCanvas::CanvasAA (); - time_canvas = new ArdourCanvas::CanvasAA (); } ArdourCanvas::init (); @@ -112,7 +110,7 @@ Editor::initialize_canvas () /* don't try to center the canvas */ track_canvas->set_center_scroll_region (false); - track_canvas->set_dither (Gdk::RGB_DITHER_NONE); + track_canvas->set_dither (Gdk::RGB_DITHER_NONE); /* need to handle 4 specific types of events as catch-alls */ @@ -121,9 +119,6 @@ Editor::initialize_canvas () track_canvas->signal_button_press_event().connect (mem_fun (*this, &Editor::track_canvas_button_press_event)); track_canvas->signal_button_release_event().connect (mem_fun (*this, &Editor::track_canvas_button_release_event)); - /* just scroll stuff for the timecanvas */ - time_canvas->signal_scroll_event().connect (mem_fun (*this, &Editor::time_canvas_scroll_event)); - track_canvas->set_name ("EditorMainCanvas"); track_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK); track_canvas->signal_leave_notify_event().connect (mem_fun(*this, &Editor::left_track_canvas)); @@ -166,97 +161,100 @@ Editor::initialize_canvas () // logo_item->property_width_set() = true; logo_item->show (); } - - /* a group to hold time (measure) lines */ - - time_line_group = new ArdourCanvas::Group (*track_canvas->root(), 0.0, 0.0); - tempo_lines = new TempoLines(*track_canvas, time_line_group); - cursor_group = new ArdourCanvas::Group (*track_canvas->root(), 0.0, 0.0); - time_canvas->set_name ("EditorTimeCanvas"); - time_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK); - time_canvas->set_flags (CAN_FOCUS); - time_canvas->set_center_scroll_region (false); - time_canvas->set_dither (Gdk::RGB_DITHER_NONE); - - marker_time_line_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0); - marker_tempo_lines = new TempoLines(*time_canvas, marker_time_line_group); - meter_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0); - tempo_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height); - range_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 2.0); - transport_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 3.0); - marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 4.0); - cd_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 5.0); - - tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + _master_group = new ArdourCanvas::Group (*track_canvas->root()); - tempo_bar->property_outline_what() = (0x1 | 0x8); - tempo_bar->property_outline_pixels() = 1; + _trackview_group = new ArdourCanvas::Group (*_master_group); + _region_motion_group = new ArdourCanvas::Group (*_master_group); - meter_bar = new ArdourCanvas::SimpleRect (*meter_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + meter_bar_group = new ArdourCanvas::Group (*track_canvas->root()); + meter_bar = new ArdourCanvas::SimpleRect (*meter_bar_group, 0.0, 0.0, 100, timebar_height); meter_bar->property_outline_what() = (0x1 | 0x8); meter_bar->property_outline_pixels() = 1; - - marker_bar = new ArdourCanvas::SimpleRect (*marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); - - marker_bar->property_outline_what() = (0x1 | 0x8); - marker_bar->property_outline_pixels() = 1; - cd_marker_bar = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + tempo_bar_group = new ArdourCanvas::Group (*track_canvas->root()); + tempo_bar = new ArdourCanvas::SimpleRect (*tempo_bar_group, 0.0, 0.0, 100, (timebar_height)); + tempo_bar->property_outline_what() = (0x1 | 0x8); + tempo_bar->property_outline_pixels() = 0; - cd_marker_bar->property_outline_what() = (0x1 | 0x8); - cd_marker_bar->property_outline_pixels() = 1; - - range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + range_marker_bar_group = new ArdourCanvas::Group (*track_canvas->root()); + range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_bar_group, 0.0, 0.0, 100, (timebar_height)); range_marker_bar->property_outline_what() = (0x1 | 0x8); range_marker_bar->property_outline_pixels() = 1; - transport_marker_bar = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + transport_marker_bar_group = new ArdourCanvas::Group (*track_canvas->root()); + transport_marker_bar = new ArdourCanvas::SimpleRect (*transport_marker_bar_group, 0.0, 0.0, 100, (timebar_height)); transport_marker_bar->property_outline_what() = (0x1 | 0x8); transport_marker_bar->property_outline_pixels() = 1; + + marker_bar_group = new ArdourCanvas::Group (*track_canvas->root()); + marker_bar = new ArdourCanvas::SimpleRect (*marker_bar_group, 0.0, 0.0, 100, (timebar_height)); + marker_bar->property_outline_what() = (0x1 | 0x8); + marker_bar->property_outline_pixels() = 0; - cd_marker_bar_drag_rect = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); - cd_marker_bar_drag_rect->property_outline_pixels() = 0; - cd_marker_bar_drag_rect->hide (); + cd_marker_bar_group = new ArdourCanvas::Group (*track_canvas->root()); + cd_marker_bar = new ArdourCanvas::SimpleRect (*cd_marker_bar_group, 0.0, 0.0, 100, (timebar_height)); + cd_marker_bar->property_outline_what() = (0x1 | 0x8); + cd_marker_bar->property_outline_pixels() = 0; - range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); - range_bar_drag_rect->property_outline_pixels() = 0; - transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); - transport_bar_drag_rect->property_outline_pixels() = 0; - transport_bar_drag_rect->hide (); + /* a group to hold time (measure) lines */ + time_line_group = new ArdourCanvas::Group (*_master_group, 0.0, 0.0); + + range_marker_drag_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0); + //range_marker_drag_rect = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0); + range_marker_drag_rect->hide (); + + timebar_group = new ArdourCanvas::Group (*track_canvas->root()); + cursor_group = new ArdourCanvas::Group (*track_canvas->root(), 0.0, 0.0); + + meter_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 5.0); + tempo_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 4.0); + range_marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 3.0); + transport_marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 2.0); + marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height); + cd_marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, 0.0); + marker_drag_line_points.push_back(Gnome::Art::Point(0.0, 0.0)); - marker_drag_line_points.push_back(Gnome::Art::Point(0.0, 0.0)); + marker_drag_line_points.push_back(Gnome::Art::Point(0.0, 1.0)); - marker_drag_line = new ArdourCanvas::Line (*track_canvas->root()); + marker_drag_line = new ArdourCanvas::Line (*timebar_group); marker_drag_line->property_width_pixels() = 1; marker_drag_line->property_points() = marker_drag_line_points; marker_drag_line->hide(); - range_marker_drag_rect = new ArdourCanvas::SimpleRect (*track_canvas->root(), 0.0, 0.0, 0.0, 0.0); - range_marker_drag_rect->hide (); - - transport_loop_range_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0); + cd_marker_bar_drag_rect = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, 100, timebar_height); + cd_marker_bar_drag_rect->property_outline_pixels() = 0; + cd_marker_bar_drag_rect->hide (); + + range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, 100, timebar_height); + range_bar_drag_rect->property_outline_pixels() = 0; + + transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, 100, timebar_height); + transport_bar_drag_rect->property_outline_pixels() = 0; + transport_bar_drag_rect->hide (); + + transport_loop_range_rect = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0); transport_loop_range_rect->property_outline_pixels() = 1; transport_loop_range_rect->hide(); - transport_punch_range_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0); + transport_punch_range_rect = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0); transport_punch_range_rect->property_outline_pixels() = 0; transport_punch_range_rect->hide(); transport_loop_range_rect->lower_to_bottom (); // loop on the bottom - transport_punchin_line = new ArdourCanvas::SimpleLine (*time_line_group); + transport_punchin_line = new ArdourCanvas::SimpleLine (*_master_group); transport_punchin_line->property_x1() = 0.0; transport_punchin_line->property_y1() = 0.0; transport_punchin_line->property_x2() = 0.0; transport_punchin_line->property_y2() = 0.0; transport_punchin_line->hide (); - transport_punchout_line = new ArdourCanvas::SimpleLine (*time_line_group); + transport_punchout_line = new ArdourCanvas::SimpleLine (*_master_group); transport_punchout_line->property_x1() = 0.0; transport_punchout_line->property_y1() = 0.0; transport_punchout_line->property_x2() = 0.0; @@ -264,14 +262,15 @@ Editor::initialize_canvas () transport_punchout_line->hide(); // used to show zoom mode active zooming - zoom_rect = new ArdourCanvas::SimpleRect (*track_canvas->root(), 0.0, 0.0, 0.0, 0.0); + zoom_rect = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0); zoom_rect->property_outline_pixels() = 1; zoom_rect->hide(); zoom_rect->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_zoom_rect_event), (ArdourCanvas::Item*) 0)); // used as rubberband rect - rubberband_rect = new ArdourCanvas::SimpleRect (*track_canvas->root(), 0.0, 0.0, 0.0, 0.0); + rubberband_rect = new ArdourCanvas::SimpleRect (*_trackview_group, 0.0, 0.0, 0.0, 0.0); + rubberband_rect->property_outline_pixels() = 1; rubberband_rect->hide(); @@ -284,10 +283,6 @@ Editor::initialize_canvas () ZoomChanged.connect (bind (mem_fun(*this, &Editor::update_loop_range_view), false)); ZoomChanged.connect (bind (mem_fun(*this, &Editor::update_punch_range_view), false)); - - double time_height = timebar_height * 5; - double time_width = FLT_MAX/frames_per_unit; - time_canvas->set_scroll_region(0.0, 0.0, time_width, time_height); playhead_cursor = new Cursor (*this, &Editor::canvas_playhead_cursor_event); @@ -343,72 +338,47 @@ Editor::track_canvas_size_allocated () } } - full_canvas_height = height; + full_canvas_height = height + canvas_timebars_vsize; } zoom_range_clock.set ((nframes64_t) floor ((canvas_width * frames_per_unit))); playhead_cursor->set_position (playhead_cursor->current_frame); + horizontal_adjustment.set_upper (session->current_end_frame()/frames_per_unit); + horizontal_adjustment.set_page_size (current_page_frames()/frames_per_unit); + reset_hscrollbar_stepping (); - reset_scrolling_region (); - if (playhead_cursor) playhead_cursor->set_length (canvas_height); + if (playhead_cursor) { + playhead_cursor->set_length (canvas_height); + } - double y1 = vertical_adjustment.get_value (); + vertical_adjustment.set_page_size (canvas_height); for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { - (*x)->set_line_vpos (y1, canvas_height); - } - - range_marker_drag_rect->property_y1() = y1; - range_marker_drag_rect->property_y2() = full_canvas_height; - transport_loop_range_rect->property_y1() = y1; - transport_loop_range_rect->property_y2() = full_canvas_height; - transport_punch_range_rect->property_y1() = y1; - transport_punch_range_rect->property_y2() = full_canvas_height; - transport_punchin_line->property_y1() = y1; - transport_punchin_line->property_y2() = full_canvas_height; - transport_punchout_line->property_y1() = y1; - transport_punchout_line->property_y2() = full_canvas_height; - - update_fixed_rulers(); - redisplay_tempo (true); - - Resized (); /* EMIT_SIGNAL */ - - return false; -} - -void -Editor::reset_scrolling_region (Gtk::Allocation* alloc) -{ - TreeModel::Children rows = route_display_model->children(); - TreeModel::Children::iterator i; - double pos; - - for (pos = 0, i = rows.begin(); i != rows.end(); ++i) { - TimeAxisView *tv = (*i)[route_display_columns.tv]; - if (tv != 0 && !tv->hidden()) { - pos += tv->effective_height; - } + (*x)->set_line_vpos (0, canvas_height); } - double last_canvas_unit = max ((last_canvas_frame / frames_per_unit), canvas_width); - //cerr << "Editor::reset_scrolling_region () lcf:fpu:cw:lcu " << last_canvas_frame << ":" << frames_per_unit << ":" << canvas_width << ":" << last_canvas_unit << endl;//DEBUG - track_canvas->set_scroll_region (0.0, 0.0, last_canvas_unit, pos); - - // XXX what is the correct height value for the time canvas ? this overstates it - time_canvas->set_scroll_region ( 0.0, 0.0, last_canvas_unit, canvas_height); - + marker_drag_line_points.back().set_y(canvas_height); range_marker_drag_rect->property_y2() = canvas_height; transport_loop_range_rect->property_y2() = canvas_height; transport_punch_range_rect->property_y2() = canvas_height; transport_punchin_line->property_y2() = canvas_height; transport_punchout_line->property_y2() = canvas_height; - update_punch_range_view (true); + tempo_bar->property_x2() = canvas_width; + meter_bar->property_x2() = canvas_width; + marker_bar->property_x2() = canvas_width; + cd_marker_bar->property_x2() = canvas_width; + range_marker_bar->property_x2() = canvas_width; + transport_marker_bar->property_x2() = canvas_width; + + update_fixed_rulers(); + redisplay_tempo (true); + + Resized (); /* EMIT_SIGNAL */ - controls_layout.queue_resize(); + return false; } void @@ -446,7 +416,18 @@ Editor::controls_layout_size_request (Requisition* req) controls_layout.set_size (edit_controls_vbox.get_width(), (gint) pos); controls_layout.set_size_request(edit_controls_vbox.get_width(), -1); zoom_box.set_size_request(edit_controls_vbox.get_width(), -1); - time_button_frame.set_size_request(edit_controls_vbox.get_width(), -1); + time_button_event_box.set_size_request(edit_controls_vbox.get_width(), -1); + + if ((vertical_adjustment.get_value() + canvas_height) >= vertical_adjustment.get_upper()) { + /* + We're increasing the size of the canvas while the bottom is visible. + We scroll down to keep in step with the controls layout. + */ + vertical_adjustment.set_upper (pos + canvas_timebars_vsize); + vertical_adjustment.set_value (pos + canvas_timebars_vsize - canvas_height); + } else { + vertical_adjustment.set_upper (pos + canvas_timebars_vsize); + } //cerr << "sizes = " << req->width << " " << edit_controls_vbox.get_width() << " " << controls_layout.get_width() << " " << zoom_box.get_width() << " " << time_button_frame.get_width() << endl;//DEBUG } @@ -458,13 +439,6 @@ Editor::track_canvas_map_handler (GdkEventAny* ev) return false; } -bool -Editor::time_canvas_map_handler (GdkEventAny* ev) -{ - time_canvas->get_window()->set_cursor (*timebar_cursor); - return false; -} - void Editor::track_canvas_drag_data_received (const RefPtr<Gdk::DragContext>& context, int x, int y, @@ -509,8 +483,8 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, double wy; track_canvas->window_to_world (x, y, wx, wy); - wx += horizontal_adjustment.get_value(); - wy += vertical_adjustment.get_value(); + //wx += horizontal_adjustment.get_value(); + //wy += vertical_adjustment.get_value(); ev.type = GDK_BUTTON_RELEASE; ev.button.x = wx; @@ -596,16 +570,25 @@ Editor::maybe_autoscroll (GdkEventMotion* event) nframes64_t frame = drag_info.current_pointer_frame; bool startit = false; double vertical_pos = vertical_adjustment.get_value(); + double upper = vertical_adjustment.get_upper(); + + /* + adjust the event.y to take account of the bounds + of the _trackview_group + */ + + double vsx1, vsx2, vsy1, vsy2; + _trackview_group->get_bounds (vsx1, vsy1, vsx2, vsy2); autoscroll_y = 0; autoscroll_x = 0; - if (event->y < vertical_pos) { + if ((event->y - vsy1) < vertical_pos) { autoscroll_y = -1; startit = true; } - if (event->y > vertical_pos + canvas_height) { + if ((event->y - vsy1) > (vertical_pos + canvas_height - canvas_timebars_vsize) && vertical_pos <= upper) { autoscroll_y = 1; startit = true; } @@ -618,7 +601,6 @@ Editor::maybe_autoscroll (GdkEventMotion* event) } } else if (frame < leftmost_frame) { - if (leftmost_frame > 0) { autoscroll_x = -1; startit = true; @@ -642,6 +624,43 @@ Editor::maybe_autoscroll (GdkEventMotion* event) last_autoscroll_y = autoscroll_y; } +void +Editor::maybe_autoscroll_horizontally (GdkEventMotion* event) +{ + nframes64_t rightmost_frame = leftmost_frame + current_page_frames(); + nframes64_t frame = drag_info.current_pointer_frame; + bool startit = false; + + autoscroll_y = 0; + autoscroll_x = 0; + + if (frame > rightmost_frame) { + + if (rightmost_frame < max_frames) { + autoscroll_x = 1; + startit = true; + } + + } else if (frame < leftmost_frame) { + if (leftmost_frame > 0) { + autoscroll_x = -1; + startit = true; + } + + } + + if ((autoscroll_x != last_autoscroll_x) || (autoscroll_y != last_autoscroll_y) || (autoscroll_x == 0 && autoscroll_y == 0)) { + stop_canvas_autoscroll (); + } + + if (startit && autoscroll_timeout_tag < 0) { + start_canvas_autoscroll (autoscroll_x, autoscroll_y); + } + + last_autoscroll_x = autoscroll_x; + last_autoscroll_y = autoscroll_y; +} + gint Editor::_autoscroll_canvas (void *arg) { @@ -654,26 +673,63 @@ Editor::autoscroll_canvas () nframes64_t new_frame; nframes64_t limit = max_frames - current_page_frames(); GdkEventMotion ev; - nframes64_t target_frame; double new_pixel; double target_pixel; + if (autoscroll_x_distance != 0) { + + if (autoscroll_cnt == 50) { /* 0.5 seconds */ + + /* after about a while, speed up a bit by changing the timeout interval */ + + autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/30.0f); + + } else if (autoscroll_cnt == 150) { /* 1.0 seconds */ + + autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/20.0f); + + } else if (autoscroll_cnt == 300) { /* 1.5 seconds */ + + /* after about another while, speed up by increasing the shift per callback */ + + autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/10.0f); + + } + } + + if (autoscroll_y_distance != 0) { + + if (autoscroll_cnt == 50) { /* 0.5 seconds */ + + /* after about a while, speed up a bit by changing the timeout interval */ + + autoscroll_y_distance = 10; + + } else if (autoscroll_cnt == 150) { /* 1.0 seconds */ + + autoscroll_y_distance = 20; + + } else if (autoscroll_cnt == 300) { /* 1.5 seconds */ + + /* after about another while, speed up by increasing the shift per callback */ + + autoscroll_y_distance = 40; + } + } + if (autoscroll_x < 0) { if (leftmost_frame < autoscroll_x_distance) { new_frame = 0; } else { new_frame = leftmost_frame - autoscroll_x_distance; } - target_frame = drag_info.current_pointer_frame - autoscroll_x_distance; } else if (autoscroll_x > 0) { if (leftmost_frame > limit - autoscroll_x_distance) { new_frame = limit; } else { new_frame = leftmost_frame + autoscroll_x_distance; } - target_frame = drag_info.current_pointer_frame + autoscroll_x_distance; } else { - target_frame = drag_info.current_pointer_frame; new_frame = leftmost_frame; } @@ -711,23 +767,36 @@ Editor::autoscroll_canvas () target_pixel = min (target_pixel, full_canvas_height - 10); } else { - target_pixel = drag_info.current_pointer_y; + target_pixel = drag_info.current_pointer_y; new_pixel = vertical_pos; } - /* now fake a motion event to get the object that is being dragged to move too */ - ev.type = GDK_MOTION_NOTIFY; - ev.state &= Gdk::BUTTON1_MASK; - ev.x = frame_to_unit (target_frame); - ev.y = target_pixel; - motion_handler (drag_info.item, (GdkEvent*) &ev, drag_info.item_type, true); if ((new_frame == 0 || new_frame == limit) && (new_pixel == 0 || new_pixel == DBL_MAX)) { /* we are done */ return false; } + if (new_frame != leftmost_frame) { + reset_x_origin (new_frame); + } + + vertical_adjustment.set_value (new_pixel); + + /* fake an event. */ + + Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas->get_window(); + gint x, y; + Gdk::ModifierType mask; + canvas_window->get_pointer (x, y, mask); + ev.type = GDK_MOTION_NOTIFY; + ev.state &= Gdk::BUTTON1_MASK; + ev.x = x; + ev.y = y; + + motion_handler (drag_info.item, (GdkEvent*) &ev, drag_info.item_type, true); + autoscroll_cnt++; if (autoscroll_cnt == 1) { @@ -739,53 +808,6 @@ Editor::autoscroll_canvas () } - if (new_frame != leftmost_frame) { - reset_x_origin (new_frame); - } - - vertical_adjustment.set_value (new_pixel); - - if (autoscroll_x_distance != 0) { - - if (autoscroll_cnt == 50) { /* 0.5 seconds */ - - /* after about a while, speed up a bit by changing the timeout interval */ - - autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/30.0f); - - } else if (autoscroll_cnt == 150) { /* 1.0 seconds */ - - autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/20.0f); - - } else if (autoscroll_cnt == 300) { /* 1.5 seconds */ - - /* after about another while, speed up by increasing the shift per callback */ - - autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/10.0f); - - } - } - - if (autoscroll_y_distance != 0) { - - if (autoscroll_cnt == 50) { /* 0.5 seconds */ - - /* after about a while, speed up a bit by changing the timeout interval */ - - autoscroll_y_distance = 10; - - } else if (autoscroll_cnt == 150) { /* 1.0 seconds */ - - autoscroll_y_distance = 20; - - } else if (autoscroll_cnt == 300) { /* 1.5 seconds */ - - /* after about another while, speed up by increasing the shift per callback */ - - autoscroll_y_distance = 40; - } - } - return true; } @@ -813,6 +835,7 @@ Editor::start_canvas_autoscroll (int dx, int dy) void Editor::stop_canvas_autoscroll () { + if (autoscroll_timeout_tag >= 0) { g_source_remove (autoscroll_timeout_tag); autoscroll_timeout_tag = -1; @@ -840,34 +863,49 @@ Editor::entered_track_canvas (GdkEventCrossing *ev) void Editor::tie_vertical_scrolling () { - double y1 = vertical_adjustment.get_value(); - - playhead_cursor->set_y_axis (y1); - - range_marker_drag_rect->property_y1() = y1; - range_marker_drag_rect->property_y2() = full_canvas_height; - transport_loop_range_rect->property_y1() = y1; - transport_loop_range_rect->property_y2() = full_canvas_height; - transport_punch_range_rect->property_y1() = y1; - transport_punch_range_rect->property_y2() = full_canvas_height; - transport_punchin_line->property_y1() = y1; - transport_punchin_line->property_y2() = full_canvas_height; - transport_punchout_line->property_y1() = y1; - transport_punchout_line->property_y2() = full_canvas_height; - - if (!selection->markers.empty()) { - for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { - (*x)->set_line_vpos (y1, canvas_height); - } - } + scroll_canvas_vertically (); - if (logo_item) { - logo_item->property_y() = y1; + /* this will do an immediate redraw */ + + controls_layout.get_vadjustment()->set_value (vertical_adjustment.get_value()); +} + +void +Editor::scroll_canvas_horizontally () +{ + nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit); + + if (time_origin != leftmost_frame) { + canvas_scroll_to (time_origin); } - /* this will do an immediate redraw */ + /* horizontal scrolling only */ + double x1, x2, y1, y2, x_delta; - controls_layout.get_vadjustment()->set_value (y1); + _master_group->get_bounds(x1, y1, x2, y2); + x_delta = x1 + horizontal_adjustment.get_value(); + + _master_group->move (-x_delta, 0); + timebar_group->move (-x_delta, 0); + cursor_group->move (-x_delta, 0); +} + +void +Editor::scroll_canvas_vertically () +{ + /* vertical scrolling only */ + double x1, x2, y1, y2, y_delta; + + _trackview_group->get_bounds(x1, y1, x2, y2); + y_delta = y1 + vertical_adjustment.get_value() - canvas_timebars_vsize; + + _trackview_group->move (0, -y_delta); + _region_motion_group->move (0, -y_delta); + +#ifndef GTKOSX + /* required to keep the controls_layout in lock step with the canvas group */ + track_canvas->update_now (); +#endif } void @@ -884,18 +922,13 @@ void Editor::canvas_scroll_to (nframes64_t time_origin) { leftmost_frame = time_origin; - nframes64_t rightmost_frame = leftmost_frame + current_page_frames (); if (rightmost_frame > last_canvas_frame) { last_canvas_frame = rightmost_frame; - reset_scrolling_region (); + //reset_scrolling_region (); } - if (logo_item) { - logo_item->property_x() = horizontal_adjustment.get_value (); - } - update_fixed_rulers (); redisplay_tempo (!_dragging_hscrollbar); diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index dd107d8d02..e55ab9bed0 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -72,9 +72,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) */ track_canvas->get_pointer (x, y); track_canvas->window_to_world (x, y, wx, wy); - wx += horizontal_adjustment.get_value(); - wy += vertical_adjustment.get_value(); - + GdkEvent event; event.type = GDK_BUTTON_RELEASE; event.button.x = wx; @@ -89,7 +87,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); - if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) { + if (!(current_stepping_trackview = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize))) { return false; } } @@ -110,9 +108,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) //if (ev->state == GDK_CONTROL_MASK) { track_canvas->get_pointer (x, y); track_canvas->window_to_world (x, y, wx, wy); - wx += horizontal_adjustment.get_value(); - wy += vertical_adjustment.get_value(); - + GdkEvent event; event.type = GDK_BUTTON_RELEASE; event.button.x = wx; @@ -127,7 +123,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); - if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) { + if (!(current_stepping_trackview = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize))) { return false; } } @@ -178,55 +174,6 @@ Editor::track_canvas_scroll_event (GdkEventScroll *event) } bool -Editor::time_canvas_scroll (GdkEventScroll* ev) -{ - nframes64_t xdelta; - int direction = ev->direction; - - switch (direction) { - case GDK_SCROLL_UP: - temporal_zoom_step (true); - break; - - case GDK_SCROLL_DOWN: - temporal_zoom_step (false); - break; - - case GDK_SCROLL_LEFT: - xdelta = (current_page_frames() / 2); - if (leftmost_frame > xdelta) { - reset_x_origin (leftmost_frame - xdelta); - } else { - reset_x_origin (0); - } - break; - - case GDK_SCROLL_RIGHT: - xdelta = (current_page_frames() / 2); - if (max_frames - xdelta > leftmost_frame) { - reset_x_origin (leftmost_frame + xdelta); - } else { - reset_x_origin (max_frames - current_page_frames()); - } - break; - - default: - /* what? */ - break; - } - - return false; -} - -bool -Editor::time_canvas_scroll_event (GdkEventScroll *event) -{ - time_canvas->grab_focus(); - time_canvas_scroll (event); - return false; -} - -bool Editor::track_canvas_button_press_event (GdkEventButton *event) { selection->clear (); @@ -260,10 +207,6 @@ Editor::track_canvas_motion (GdkEvent *ev) verbose_canvas_cursor->property_y() = clamp_verbose_cursor_y (ev->motion.y + 20); } -#ifdef GTKOSX - flush_canvas (); -#endif - return false; } diff --git a/gtk2_ardour/editor_cursors.cc b/gtk2_ardour/editor_cursors.cc index 54786bcebf..ca00ec61d2 100644 --- a/gtk2_ardour/editor_cursors.cc +++ b/gtk2_ardour/editor_cursors.cc @@ -38,8 +38,8 @@ Editor::Cursor::Cursor (Editor& ed, bool (Editor::*callbck)(GdkEvent*,ArdourCanv /* "randomly" initialize coords */ - points.push_back(Gnome::Art::Point(-9383839.0, 0.0)); points.push_back(Gnome::Art::Point(1.0, 0.0)); + points.push_back(Gnome::Art::Point(1.0, 1.0)); canvas_item.property_points() = points; canvas_item.property_width_pixels() = 1; @@ -51,7 +51,6 @@ Editor::Cursor::Cursor (Editor& ed, bool (Editor::*callbck)(GdkEvent*,ArdourCanv canvas_item.set_data ("cursor", this); canvas_item.signal_event().connect (bind (mem_fun (ed, callbck), &canvas_item)); - current_frame = 1; /* force redraw at 0 */ } @@ -67,23 +66,15 @@ Editor::Cursor::set_position (nframes64_t frame) if (editor.session == 0) { canvas_item.hide(); - } else { - canvas_item.show(); } - current_frame = frame; - if (new_pos != points.front().get_x()) { points.front().set_x (new_pos); points.back().set_x (new_pos); canvas_item.property_points() = points; - - ArdourCanvas::Points p = canvas_item.property_points(); } - - canvas_item.raise_to_top(); } void @@ -92,6 +83,9 @@ Editor::Cursor::set_length (double units) length = units; points.back().set_y (points.front().get_y() + length); canvas_item.property_points() = points; + if (editor.session != 0) { + canvas_item.show(); + } } void diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 059855ccf5..8d86a0fbb2 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -1243,7 +1243,7 @@ Editor::marker_selection_changed () } for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { - (*x)->add_line (cursor_group, vertical_adjustment.get_value(), canvas_height); + (*x)->add_line (cursor_group, 0, canvas_height); (*x)->show_line (); } diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index 5c9208fcfb..e770e09960 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -203,7 +203,7 @@ Editor::update_current_screen () if (_follow_playhead && session->requested_return_frame() < 0) { - playhead_cursor->canvas_item.show(); + //playhead_cursor->canvas_item.show(); if (frame != last_update_frame) { @@ -259,7 +259,10 @@ Editor::update_current_screen () almost_done: last_update_frame = frame; - +#ifdef GTKOSX + /*XXX in a perfect world we would not have to do this. */ + track_canvas->update_now(); +#endif if (current_mixer_strip) { current_mixer_strip->fast_update (); } diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 384f40fdf6..7a05fcdc56 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -1,3 +1,4 @@ + /* Copyright (C) 2000-2001 Paul Davis @@ -92,23 +93,15 @@ Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas) const pointer_window = canvas_window->get_pointer (x, y, mask); if (pointer_window == track_canvas->get_bin_window()) { - - track_canvas->window_to_world (x, y, wx, wy); + wx = x; + wy = y; in_track_canvas = true; } else { in_track_canvas = false; - - if (pointer_window == time_canvas->get_bin_window()) { - time_canvas->window_to_world (x, y, wx, wy); - } else { return false; - } } - wx += horizontal_adjustment.get_value(); - wy += vertical_adjustment.get_value(); - GdkEvent event; event.type = GDK_BUTTON_RELEASE; event.button.x = wx; @@ -138,10 +131,16 @@ Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) const case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: - track_canvas->w2c(event->button.x, event->button.y, *pcx, *pcy); + + *pcx = event->button.x; + *pcy = event->button.y; + _trackview_group->w2i(*pcx, *pcy); break; case GDK_MOTION_NOTIFY: - track_canvas->w2c(event->motion.x, event->motion.y, *pcx, *pcy); + + *pcx = event->motion.x; + *pcy = event->motion.y; + _trackview_group->w2i(*pcx, *pcy); break; case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: @@ -227,9 +226,9 @@ Editor::which_grabber_cursor () return grabber_edit_point_cursor; break; default: - return grabber_cursor; break; } + return grabber_cursor; } void @@ -609,7 +608,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp pointer_window = canvas_window->get_pointer (x, y, mask); if (pointer_window == track_canvas->get_bin_window()) { - track_canvas->window_to_world (x, y, wx, wy); allow_vertical_scroll = true; } else { @@ -770,8 +768,8 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp case RegionViewName: /* rename happens on edit clicks */ - start_trim (clicked_regionview->get_name_highlight(), event); - return true; + start_trim (clicked_regionview->get_name_highlight(), event); + return true; break; case ControlPointItem: @@ -1442,7 +1440,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case MeterBarItem: case TempoBarItem: if (is_drawable()) { - time_canvas->get_window()->set_cursor (*timebar_cursor); + track_canvas->get_window()->set_cursor (*timebar_cursor); } break; @@ -1456,7 +1454,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case MeterMarkerItem: case TempoMarkerItem: if (is_drawable()) { - time_canvas->get_window()->set_cursor (*timebar_cursor); + track_canvas->get_window()->set_cursor (*timebar_cursor); } break; case FadeInHandleItem: @@ -1569,7 +1567,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case TempoBarItem: case MarkerBarItem: if (is_drawable()) { - time_canvas->get_window()->set_cursor (*timebar_cursor); + track_canvas->get_window()->set_cursor (*timebar_cursor); } break; @@ -1586,7 +1584,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case TempoMarkerItem: if (is_drawable()) { - time_canvas->get_window()->set_cursor (*timebar_cursor); + track_canvas->get_window()->set_cursor (*timebar_cursor); } break; @@ -1721,7 +1719,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item where DISPLAY = :0.0, and given the cost of what the motion event might do, its a good tradeoff. */ - + track_canvas->get_pointer (x, y); } @@ -1781,6 +1779,9 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item case PlayheadCursorItem: case MarkerItem: case ControlPointItem: + case RangeMarkerBarItem: + case TransportMarkerBarItem: + case CdMarkerBarItem: case TempoMarkerItem: case MeterMarkerItem: case RegionViewNameHighlight: @@ -1802,13 +1803,13 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item if (drag_info.item && (event->motion.state & Gdk::BUTTON1_MASK || (event->motion.state & Gdk::BUTTON2_MASK))) { if (!from_autoscroll) { - maybe_autoscroll (&event->motion); + maybe_autoscroll_horizontally (&event->motion); } (this->*(drag_info.motion_callback)) (item, event); goto handled; } goto not_handled; - + break; default: break; } @@ -2352,7 +2353,7 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event) // marker_drag_line->raise_to_top(); } else { range_marker_drag_rect->show(); - range_marker_drag_rect->raise_to_top(); + //range_marker_drag_rect->raise_to_top(); } if (is_start) { @@ -3087,6 +3088,18 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) show_verbose_time_cursor (drag_info.last_frame_position, 10); begin_reversible_command (_("move region(s)")); + /* + the group containing moved regions may have been + offset during autoscroll. reset its y offset + (we should really handle this in the same way + we do with the x axis, but a simple way of achieving that + eludes me right now). + */ + + _region_motion_group->property_y() = 0; + + /* sync the canvas to what we think is its current state */ + track_canvas->update_now(); } void @@ -3133,6 +3146,8 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) drag_info.motion_callback = &Editor::region_drag_motion_callback; drag_info.finished_callback = &Editor::region_drag_finished_callback; show_verbose_time_cursor (drag_info.last_frame_position, 10); + + _region_motion_group->property_y() = 0; } void @@ -3181,7 +3196,6 @@ Editor::possibly_copy_regions_during_grab (GdkEvent* event) vector<RegionView*> new_regionviews; for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { - RegionView* rv; RegionView* nrv; @@ -3197,7 +3211,7 @@ Editor::possibly_copy_regions_during_grab (GdkEvent* event) } else { continue; } - + const boost::shared_ptr<const Region> original = arv->region(); boost::shared_ptr<Region> region_copy = RegionFactory::create (original); boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (region_copy); @@ -3225,6 +3239,14 @@ Editor::possibly_copy_regions_during_grab (GdkEvent* event) drag_info.data = new_regionviews.front(); swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time); + /* + sync the canvas to what we think is its current state + without it, the canvas seems to + "forget" to update properly after the upcoming reparent() + ..only if the mouse is in rapid motion at the time of the grab. + something to do with regionview creation raking so long? + */ + track_canvas->update_now(); } } @@ -3344,7 +3366,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } original_pointer_order = drag_info.dest_trackview->order; - + /************************************************************ Y-Delta Computation ************************************************************/ @@ -3427,6 +3449,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv2->get_canvas_group()->i2w (ix1, iy1); + iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize; + TimeAxisView* tvp2 = trackview_by_y_position (iy1); RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(tvp2); @@ -3512,10 +3536,9 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /* compute the amount of pointer motion in frames, and where the region would be if we moved it by that much. */ - if ( drag_info.move_threshold_passed ) { - if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame >= drag_info.pointer_frame_offset) { nframes64_t sync_frame; nframes64_t sync_offset; @@ -3550,7 +3573,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) if (pending_region_position > max_frames - rv->region()->length()) { pending_region_position = drag_info.last_frame_position; } - + // printf ("3: pending_region_position= %lu %lu\n", pending_region_position, drag_info.last_frame_position ); bool x_move_allowed; @@ -3566,7 +3589,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) x_move_allowed = !drag_info.x_constrained; } - if ( pending_region_position != drag_info.last_frame_position && x_move_allowed ) { + if (( pending_region_position != drag_info.last_frame_position) && x_move_allowed ) { /* now compute the canvas unit distance we need to move the regionview to make it appear at the new location. @@ -3576,10 +3599,29 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) x_delta = ((double) (pending_region_position - drag_info.last_frame_position) / frames_per_unit); } else { x_delta = -((double) (drag_info.last_frame_position - pending_region_position) / frames_per_unit); - } + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { + + RegionView* rv2 = (*i); + + // If any regionview is at zero, we need to know so we can stop further leftward motion. + + double ix1, ix2, iy1, iy2; + rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); + rv2->get_canvas_group()->i2w (ix1, iy1); + + if (-x_delta > ix1 + horizontal_adjustment.get_value()) { + // do_move = false; + cerr << "illegal move" << endl; + x_delta = 0; + pending_region_position = drag_info.last_frame_position; + break; + } + } + } + drag_info.last_frame_position = pending_region_position; - + } else { x_delta = 0; } @@ -3599,41 +3641,16 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) trackviews. nothing to do. */ return; - } - - - if (x_delta < 0) { - for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { - - RegionView* rv2 = (*i); - - // If any regionview is at zero, we need to know so we can stop further leftward motion. - - double ix1, ix2, iy1, iy2; - rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); - rv2->get_canvas_group()->i2w (ix1, iy1); - - if (ix1 <= 1) { - x_delta = 0; - break; - } - } } /************************************************************* MOTION ************************************************************/ - - bool do_move; - + bool do_move = true; if (drag_info.first_move) { - if (drag_info.move_threshold_passed) { - do_move = true; - } else { + if (!drag_info.move_threshold_passed) { do_move = false; } - } else { - do_move = true; } if (do_move) { @@ -3658,6 +3675,30 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv->get_canvas_group()->i2w (ix1, iy1); + + if (drag_info.first_move) { + + // hide any dependent views + + rv->get_time_axis_view().hide_dependent_views (*rv); + + /* + reparent to a non scrolling group so that we can keep the + region selection above all time axis views. + reparenting means we have to move the rv as the two + parent groups have different coordinates. + */ + + rv->get_canvas_group()->property_y() = iy1 - 1; + rv->get_canvas_group()->reparent(*_region_motion_group); + + rv->fake_set_opaque (true); + } + /* for evaluation of the track position of iy1, we have to adjust + to allow for the vertical scrolling adjustment and the height of the timebars. + */ + iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize; + TimeAxisView* tvp2 = trackview_by_y_position (iy1); RouteTimeAxisView* canvas_rtv = dynamic_cast<RouteTimeAxisView*>(tvp2); RouteTimeAxisView* temp_rtv; @@ -3720,7 +3761,6 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } } - /* prevent the regionview from being moved to before the zero position on the canvas. */ @@ -3734,30 +3774,10 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) x_delta = max_frames - rv->region()->last_frame(); } - - if (drag_info.first_move) { - - /* hide any dependent views */ - - rv->get_time_axis_view().hide_dependent_views (*rv); - - /* this is subtle. raising the regionview itself won't help, - because raise_to_top() just puts the item on the top of - its parent's stack. so, we need to put the trackview canvas_display group - on the top, since its parent is the whole canvas. - */ - - rv->get_canvas_group()->raise_to_top(); - rv->get_time_axis_view().canvas_display->raise_to_top(); - cursor_group->raise_to_top(); - - rv->fake_set_opaque (true); - } - if (drag_info.brushing) { mouse_brush_insert_region (rv, pending_region_position); } else { - rv->move (x_delta, y_delta); + rv->move (x_delta, y_delta); } } /* foreach region */ @@ -3785,7 +3805,9 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event vector<RegionView*> new_selection; typedef set<boost::shared_ptr<Playlist> > PlaylistSet; PlaylistSet modified_playlists; - pair<PlaylistSet::iterator,bool> insert_result; + PlaylistSet frozen_playlists; + list <sigc::connection> modified_playlist_connections; + pair<PlaylistSet::iterator,bool> insert_result, frozen_insert_result; /* first_move is set to false if the regionview has been moved in the motion handler. @@ -3798,11 +3820,12 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event nocommit = false; - /* The regionview has been moved at some stage during the grab so we need + /* XXX is this true??? i can''t tell the difference. + The regionview has been moved at some stage during the grab so we need to account for any mouse movement between this event and the last one. */ - region_drag_motion_callback (item, event); + //region_drag_motion_callback (item, event); if (Config->get_edit_mode() == Splice && !pre_drag_region_selection.empty()) { selection->set (pre_drag_region_selection); @@ -3853,11 +3876,12 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event double ix1, ix2, iy1, iy2; rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv->get_canvas_group()->i2w (ix1, iy1); + iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize; + TimeAxisView* dest_tv = trackview_by_y_position (iy1); RouteTimeAxisView* dest_rtv = dynamic_cast<RouteTimeAxisView*>(dest_tv); double speed; - bool changed_tracks; - bool changed_position; + bool changed_tracks, changed_position; nframes64_t where; if (rv->region()->locked()) { @@ -3877,24 +3901,26 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event changed_tracks = (dest_tv != &rv->get_time_axis_view()); if (changed_position && !drag_info.x_constrained) { + _master_group->w2i(ix1, iy1); where = (nframes64_t) (unit_to_frame (ix1) * speed); } else { where = rv->region()->position(); } - /* undo the previous hide_dependent_views so that xfades don't - disappear on copying regions - */ - - rv->get_time_axis_view().reveal_dependent_views (*rv); - boost::shared_ptr<Region> new_region; if (drag_info.copy) { /* we already made a copy */ new_region = rv->region(); - } else { + + /* undo the previous hide_dependent_views so that xfades don't + disappear on copying regions + */ + + //rv->get_time_axis_view().reveal_dependent_views (*rv); + + } else if (changed_tracks) { new_region = RegionFactory::create (rv->region()); } @@ -3908,7 +3934,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event insert_result = modified_playlists.insert (to_playlist); if (insert_result.second) { - session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0)); + session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0)); } to_playlist->add_region (new_region, where); @@ -3917,19 +3943,33 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event if (!latest_regionviews.empty()) { // XXX why just the first one ? we only expect one - dest_rtv->reveal_dependent_views (*latest_regionviews.front()); + // commented out in nick_m's canvas reworking. is that intended? + //dest_atv->reveal_dependent_views (*latest_regionviews.front()); new_selection.push_back (latest_regionviews.front()); } } else { - + /* + motion on the same track. plonk the previously reparented region + back to its original canvas group (its streamview). + No need to do anything for copies as they are fake regions which will be deleted. + */ + + rv->get_canvas_group()->reparent (*dest_rtv->view()->canvas_item()); + rv->get_canvas_group()->property_y() = 0; + /* just change the model */ boost::shared_ptr<Playlist> playlist = dest_rtv->playlist(); insert_result = modified_playlists.insert (playlist); if (insert_result.second) { - session->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0)); + session->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0)); + } + /* freeze to avoid lots of relayering in the case of a multi-region drag */ + frozen_insert_result = frozen_playlists.insert(playlist); + if (frozen_insert_result.second) { + playlist->freeze(); } rv->region()->set_position (where, (void*) this); @@ -3960,7 +4000,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event insert_result = modified_playlists.insert (from_playlist); if (insert_result.second) { - session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0)); + session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0)); } from_playlist->remove_region ((rv->region())); @@ -3996,7 +4036,6 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event copies.push_back (rv); } } - if (new_selection.empty()) { if (drag_info.copy) { @@ -4012,6 +4051,10 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event */ selection->set (new_selection); } + + for (set<boost::shared_ptr<Playlist> >::iterator p = frozen_playlists.begin(); p != frozen_playlists.end(); ++p) { + (*p)->thaw(); + } out: if (!nocommit) { @@ -4024,6 +4067,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event for (vector<RegionView*>::iterator x = copies.begin(); x != copies.end(); ++x) { delete *x; } + } void @@ -4167,7 +4211,7 @@ Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos, set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset); } else { - set_verbose_canvas_cursor (buf, drag_info.current_pointer_x + offset, drag_info.current_pointer_y + offset); + set_verbose_canvas_cursor (buf, drag_info.current_pointer_x + offset - horizontal_adjustment.get_value(), drag_info.current_pointer_y + offset - vertical_adjustment.get_value() + canvas_timebars_vsize); } show_verbose_canvas_cursor (); } @@ -5088,7 +5132,7 @@ Editor::drag_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) update_marker_drag_item (temp_location); range_marker_drag_rect->show(); - range_marker_drag_rect->raise_to_top(); + //range_marker_drag_rect->raise_to_top(); } break; @@ -5369,8 +5413,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) if (drag_info.current_pointer_y < drag_info.grab_y) { y1 = drag_info.current_pointer_y; y2 = drag_info.grab_y; - } - else { + } else { y2 = drag_info.current_pointer_y; y1 = drag_info.grab_y; } @@ -5478,18 +5521,18 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event) nframes64_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position(); float percentage = (double) newlen / (double) clicked_regionview->region()->length(); - + #ifndef USE_RUBBERBAND // Soundtouch uses percentage / 100 instead of normal (/ 1) if (clicked_regionview->region()->data_type() == DataType::AUDIO) { percentage = (float) ((double) newlen - (double) clicked_regionview->region()->length()) / ((double) newlen) * 100.0f; -#endif } - +#endif + begin_reversible_command (_("timestretch")); - + // XXX how do timeFX on multiple regions ? - + RegionSelection rs; rs.add (clicked_regionview); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index fd482a9dd6..d52f4da231 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -1549,7 +1549,7 @@ Editor::scroll_tracks_down_line () { Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment(); - double vert_value = adj->get_value() + 20; + double vert_value = adj->get_value() + 60; if (vert_value>adj->get_upper() - canvas_height) { vert_value = adj->get_upper() - canvas_height; @@ -1561,7 +1561,7 @@ void Editor::scroll_tracks_up_line () { Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment(); - adj->set_value (adj->get_value() - 20); + adj->set_value (adj->get_value() - 60); } /* ZOOM */ @@ -1875,8 +1875,9 @@ Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string void Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame) { - if (!session) return; - + if (!session) { + return; + } double range_before = frame - leftmost_frame; double new_fpu; @@ -1890,12 +1891,15 @@ Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame) range_before /= 1.61803399; } - if (new_fpu == frames_per_unit) return; + if (new_fpu == frames_per_unit) { + return; + } nframes64_t new_leftmost = frame - (nframes64_t)range_before; - if (new_leftmost > frame) new_leftmost = 0; - + if (new_leftmost > frame) { + new_leftmost = 0; + } // begin_reversible_command (_("zoom to frame")); // 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)); @@ -2213,8 +2217,8 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y) boost::shared_ptr<Playlist> playlist; track_canvas->window_to_world (x, y, wx, wy); - wx += horizontal_adjustment.get_value(); - wy += vertical_adjustment.get_value(); + //wx += horizontal_adjustment.get_value(); + //wy += vertical_adjustment.get_value(); GdkEvent event; event.type = GDK_BUTTON_RELEASE; @@ -6038,7 +6042,6 @@ Editor::fit_tracks () 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_region_list.cc b/gtk2_ardour/editor_region_list.cc index 54bc71e074..121550f86f 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -140,8 +140,8 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region) for (i = rows.begin(); i != rows.end(); ++i) { boost::shared_ptr<Region> rr = (*i)[region_list_columns.region]; - - if (region->region_list_equivalent (rr)) { + + if (rr && region->region_list_equivalent (rr)) { return; } } diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index c12a30ca73..6213bf9d1e 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -364,7 +364,7 @@ Editor::redisplay_route_list () cursor_group->raise_to_top (); - reset_scrolling_region (); + //reset_scrolling_region (); if (Config->get_sync_all_route_ordering() && !ignore_route_list_reorder) { ignore_route_order_sync = true; @@ -401,7 +401,7 @@ Editor::hide_all_tracks (bool with_select) otherwise. */ - reset_scrolling_region (); + //reset_scrolling_region (); } void @@ -625,7 +625,9 @@ void Editor::route_list_delete (const Gtk::TreeModel::Path& path) { session->set_remote_control_ids(); + ignore_route_list_reorder = true; redisplay_route_list (); + ignore_route_list_reorder = false; } void diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index dc62f669f8..47ea8d01a0 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -88,7 +88,7 @@ Editor::initialize_rulers () minsec_ruler->set_size_request (-1, (int)timebar_height); gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_minsec_ruler), &ruler_metrics[ruler_metric_minsec]); - visible_timebars = 7; /* 4 here, 3 in time_canvas */ + visible_timebars = 1; /*this will be changed below */ ruler_pressed_button = 0; } @@ -559,7 +559,9 @@ Editor::update_ruler_visibility () { using namespace Box_Helpers; BoxList & lab_children = time_button_vbox.children(); + BoxList & ruler_lab_children = ruler_label_vbox.children(); BoxList & ruler_children = time_canvas_vbox.children(); + int visible_rulers = 0; if (no_ruler_shown_update) { return; @@ -568,9 +570,10 @@ Editor::update_ruler_visibility () visible_timebars = 0; lab_children.clear(); + ruler_lab_children.clear(); // leave the last one (the time_canvas) intact - while (ruler_children.size() > 1) { + while (ruler_children.size() > 0) { ruler_children.pop_front(); } @@ -628,31 +631,32 @@ Editor::update_ruler_visibility () ruler_children.insert (canvaspos, Element(*_ruler_separator, PACK_SHRINK, PACK_START)); if (ruler_minsec_action->get_active()) { - lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START)); + ruler_lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*minsec_ruler, PACK_SHRINK, PACK_START)); - visible_timebars++; + visible_rulers++; } if (ruler_timecode_action->get_active()) { - lab_children.push_back (Element(smpte_label, PACK_SHRINK, PACK_START)); + ruler_lab_children.push_back (Element(smpte_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*smpte_ruler, PACK_SHRINK, PACK_START)); - visible_timebars++; + visible_rulers++; } if (ruler_samples_action->get_active()) { - lab_children.push_back (Element(frame_label, PACK_SHRINK, PACK_START)); + ruler_lab_children.push_back (Element(frame_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*frames_ruler, PACK_SHRINK, PACK_START)); - visible_timebars++; + visible_rulers++; } if (ruler_bbt_action->get_active()) { - lab_children.push_back (Element(bbt_label, PACK_SHRINK, PACK_START)); + ruler_lab_children.push_back (Element(bbt_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*bbt_ruler, PACK_SHRINK, PACK_START)); - visible_timebars++; + visible_rulers++; } - double tbpos = 1.0; - double old_unit_pos ; + double tbpos = 0.0; + double tbgpos = 0.0; + double old_unit_pos; if (ruler_meter_action->get_active()) { lab_children.push_back (Element(meter_label, PACK_SHRINK, PACK_START)); @@ -661,11 +665,17 @@ Editor::update_ruler_visibility () if (tbpos != old_unit_pos) { meter_group->move ( 0.0, tbpos - old_unit_pos); } + old_unit_pos = meter_bar_group->property_y(); + if (tbgpos != old_unit_pos) { + meter_bar_group->move ( 0.0, tbgpos - old_unit_pos); + } + meter_bar_group->show(); meter_group->show(); tbpos += timebar_height; + tbgpos += timebar_height; visible_timebars++; - } - else { + } else { + meter_bar_group->hide(); meter_group->hide(); } @@ -675,11 +685,17 @@ Editor::update_ruler_visibility () if (tbpos != old_unit_pos) { tempo_group->move(0.0, tbpos - old_unit_pos); } + old_unit_pos = tempo_bar_group->property_y(); + if (tbgpos != old_unit_pos) { + tempo_bar_group->move ( 0.0, tbgpos - old_unit_pos); + } + tempo_bar_group->show(); tempo_group->show(); tbpos += timebar_height; + tbgpos += timebar_height; visible_timebars++; - } - else { + } else { + tempo_bar_group->hide(); tempo_group->hide(); } @@ -689,10 +705,17 @@ Editor::update_ruler_visibility () if (tbpos != old_unit_pos) { range_marker_group->move (0.0, tbpos - old_unit_pos); } + old_unit_pos = range_marker_bar_group->property_y(); + if (tbgpos != old_unit_pos) { + range_marker_bar_group->move (0.0, tbgpos - old_unit_pos); + } + range_marker_bar_group->show(); range_marker_group->show(); tbpos += timebar_height; + tbgpos += timebar_height; visible_timebars++; } else { + range_marker_bar_group->hide(); range_marker_group->hide(); } @@ -702,11 +725,17 @@ Editor::update_ruler_visibility () if (tbpos != old_unit_pos) { transport_marker_group->move ( 0.0, tbpos - old_unit_pos); } + old_unit_pos = transport_marker_bar_group->property_y(); + if (tbgpos != old_unit_pos) { + transport_marker_bar_group->move ( 0.0, tbgpos - old_unit_pos); + } + transport_marker_bar_group->show(); transport_marker_group->show(); tbpos += timebar_height; + tbgpos += timebar_height; visible_timebars++; - } - else { + } else { + transport_marker_bar_group->hide(); transport_marker_group->hide(); } @@ -716,13 +745,19 @@ Editor::update_ruler_visibility () if (tbpos != old_unit_pos) { cd_marker_group->move (0.0, tbpos - old_unit_pos); } + old_unit_pos = cd_marker_bar_group->property_y(); + if (tbgpos != old_unit_pos) { + cd_marker_bar_group->move (0.0, tbgpos - old_unit_pos); + } + cd_marker_bar_group->show(); cd_marker_group->show(); tbpos += timebar_height; + tbgpos += timebar_height; visible_timebars++; // make sure all cd markers show up in their respective places update_cd_marker_display(); - } - else { + } else { + cd_marker_bar_group->hide(); cd_marker_group->hide(); // make sure all cd markers show up in their respective places update_cd_marker_display(); @@ -734,21 +769,42 @@ Editor::update_ruler_visibility () if (tbpos != old_unit_pos) { marker_group->move ( 0.0, tbpos - old_unit_pos); } + old_unit_pos = marker_bar_group->property_y(); + if (tbgpos != old_unit_pos) { + marker_bar_group->move ( 0.0, tbgpos - old_unit_pos); + } + marker_bar_group->show(); marker_group->show(); tbpos += timebar_height; + tbgpos += timebar_height; visible_timebars++; - } - else { + } else { + marker_bar_group->hide(); marker_group->hide(); } - time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars)); + gdouble old_canvas_timebars_vsize = canvas_timebars_vsize; + canvas_timebars_vsize = timebar_height * visible_timebars; + gdouble vertical_pos_delta = canvas_timebars_vsize - old_canvas_timebars_vsize; + + if (vertical_pos_delta < 0 && (vertical_adjustment.get_value() + canvas_height) >= vertical_adjustment.get_upper()) { + /*if we're at the bottom of the canvas, don't move the _trackview_grooup*/ + vertical_adjustment.set_upper(vertical_adjustment.get_upper() + vertical_pos_delta); + } else { + vertical_adjustment.set_upper(vertical_adjustment.get_upper() + vertical_pos_delta); + _trackview_group->move (0, vertical_pos_delta); + } + ruler_label_vbox.set_size_request (-1, (int)(timebar_height * visible_rulers)); + + time_canvas_vbox.set_size_request (-1,-1); time_canvas_event_box.queue_resize(); compute_fixed_ruler_scale(); update_fixed_rulers(); + redisplay_tempo (false); time_canvas_event_box.show_all(); - time_button_frame.show_all(); + ruler_label_event_box.show_all(); + time_button_event_box.show_all(); compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit)); compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit)); @@ -1704,7 +1760,7 @@ Editor::metric_get_frames (GtkCustomRulerMark **marks, gdouble lower, gdouble up nmarks = 5; *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks); for (n = 0, pos = ilower; n < nmarks; pos += mark_interval, ++n) { - snprintf (buf, sizeof(buf), "%u", pos); + snprintf (buf, sizeof(buf), "%" PRIi64, pos); (*marks)[n].label = g_strdup (buf); (*marks)[n].position = pos; (*marks)[n].style = GtkCustomRulerMarkMajor; diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 1e5c02f5d8..49cee3e239 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -171,11 +171,36 @@ Editor::compute_current_bbt_points (nframes_t leftmost, nframes_t rightmost) current_bbt_points = session->tempo_map().get_points (session->tempo_map().frame_time (previous_beat), session->tempo_map().frame_time (next_beat) + 1); } +ArdourCanvas::SimpleLine * +Editor::get_time_line () +{ + ArdourCanvas::SimpleLine *line; + + if (free_measure_lines.empty()) { + line = new ArdourCanvas::SimpleLine (*time_line_group); + used_measure_lines.push_back (line); + } else { + line = free_measure_lines.front(); + free_measure_lines.erase (free_measure_lines.begin()); + used_measure_lines.push_back (line); + } + + return line; +} + void Editor::hide_measures () { - tempo_lines->hide(); - marker_tempo_lines->hide(); + // from old pre-merge 3.0 + // tempo_lines->hide(); + // marker_tempo_lines->hide(); + + for (TimeLineList::iterator i = used_measure_lines.begin(); i != used_measure_lines.end(); ++i) { + (*i)->hide(); + free_measure_lines.push_back (*i); + } + + used_measure_lines.clear (); } bool @@ -195,16 +220,68 @@ Editor::draw_measures () return; } - tempo_lines->draw(*current_bbt_points, frames_per_unit); - marker_tempo_lines->draw(*current_bbt_points, frames_per_unit); + TempoMap::BBTPointList::iterator i; + ArdourCanvas::SimpleLine *line; + gdouble xpos; + double beat_density; + + uint32_t beats = 0; + uint32_t bars = 0; + uint32_t color; + + if (current_bbt_points == 0 || current_bbt_points->empty()) { + return; + } + + /* get the first bar spacing */ + + i = current_bbt_points->end(); + i--; + bars = (*i).bar - (*current_bbt_points->begin()).bar; + beats = current_bbt_points->size() - bars; + + beat_density = (beats * 10.0f) / track_canvas->get_width (); + + if (beat_density > 4.0f) { + /* if the lines are too close together, they become useless + */ + return; + } + + for (i = current_bbt_points->begin(); i != current_bbt_points->end(); ++i) { + + switch ((*i).type) { + case TempoMap::Bar: + break; + + case TempoMap::Beat: + + if ((*i).beat == 1) { + color = ARDOUR_UI::config()->canvasvar_MeasureLineBar.get(); + } else { + color = ARDOUR_UI::config()->canvasvar_MeasureLineBeat.get(); + + if (beat_density > 2.0) { + /* only draw beat lines if the gaps between beats are large. + */ + break; + } + } + + xpos = frame_to_unit ((nframes64_t) (*i).frame); + line = get_time_line (); + line->property_x1() = xpos; + line->property_x2() = xpos; + line->property_y2() = canvas_height; + line->property_color_rgba() = color; + //line->raise_to_top(); + line->show(); + break; + } + } - /*time_line_group->raise_to_top(); - time_line_group->lower(1);*/ - marker_time_line_group->raise_to_top(); - //marker_time_line_group->lower(1); - /* the cursors are always on top of everything */ - cursor_group->raise_to_top(); + //cursor_group->raise_to_top(); return; } diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc new file mode 100644 index 0000000000..2ca9166dea --- /dev/null +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -0,0 +1,113 @@ +/* + Copyright (C) 2008 Paul Davis + Author: Dave Robillard + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <ardour/insert.h> +#include <ardour/lv2_plugin.h> + +#include "lv2_plugin_ui.h" + +using namespace Gtk; +using namespace ARDOUR; +using namespace PBD; + +void +LV2PluginUI::lv2_ui_write(LV2UI_Controller controller, + uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer) +{ + LV2PluginUI* me = (LV2PluginUI*)controller; + if (*(float*)buffer != me->_values[port_index]) + me->_lv2->set_parameter(port_index, *(float*)buffer); +} + +void +LV2PluginUI::parameter_changed (uint32_t port_index, float val) +{ + if (val != _values[port_index]) { + const LV2UI_Descriptor* ui_desc = slv2_ui_instance_get_descriptor(_inst); + LV2UI_Handle ui_handle = slv2_ui_instance_get_handle(_inst); + if (ui_desc->port_event) + ui_desc->port_event(ui_handle, port_index, 4, 0, &val); + _values[port_index] = val; + } +} + +LV2PluginUI::LV2PluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<LV2Plugin> lv2p) + : PlugUIBase (pi) + , _lv2(lv2p) +{ + _inst = slv2_ui_instantiate( + _lv2->slv2_plugin(), _lv2->slv2_ui(), LV2PluginUI::lv2_ui_write, this, + _lv2->features()); + + GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_inst); + _gui_widget = Glib::wrap(c_widget); + _gui_widget->show_all(); + pack_start(*_gui_widget, true, true); + + uint32_t num_ports = slv2_plugin_get_num_ports(lv2p->slv2_plugin()); + _values = new float[num_ports]; + for (uint32_t i = 0; i < num_ports; ++i) { + bool ok; + _values[i] = lv2p->nth_parameter(i, ok); + if (ok) + lv2_ui_write(this, i, 4, /* FIXME: format */0, &_values[i]); + } + + _lv2->ParameterChanged.connect(mem_fun(*this, &LV2PluginUI::parameter_changed)); +} + +LV2PluginUI::~LV2PluginUI () +{ + delete[] _values; + // plugin destructor destroys the GUI +} + +int +LV2PluginUI::get_preferred_height () +{ + Gtk::Requisition r = size_request(); + return r.height; +} + +int +LV2PluginUI::get_preferred_width () +{ + Gtk::Requisition r = size_request(); + return r.width; +} + +int +LV2PluginUI::package (Gtk::Window& win) +{ + /* forward configure events to plugin window */ + win.signal_configure_event().connect (mem_fun (*this, &LV2PluginUI::configure_handler)); + return 0; +} + +bool +LV2PluginUI::configure_handler (GdkEventConfigure* ev) +{ + cout << "CONFIGURE" << endl; + return false; +} + diff --git a/gtk2_ardour/lv2_plugin_ui.h b/gtk2_ardour/lv2_plugin_ui.h new file mode 100644 index 0000000000..5946d8bd77 --- /dev/null +++ b/gtk2_ardour/lv2_plugin_ui.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2008 Paul Davis + Author: Dave Robillard + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __ardour_lv2_plugin_ui_h__ +#define __ardour_lv2_plugin_ui_h__ + +#include <vector> +#include <map> +#include <list> + +#include <sigc++/signal.h> +#include <gtkmm/widget.h> + +#include <ardour_dialog.h> +#include <ardour/types.h> +#include "plugin_ui.h" + +#ifdef HAVE_LV2 + +namespace ARDOUR { + class PluginInsert; + class LV2Plugin; +} + +class LV2PluginUI : public PlugUIBase, public Gtk::VBox +{ + public: + LV2PluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::LV2Plugin>); + ~LV2PluginUI (); + + gint get_preferred_height (); + gint get_preferred_width (); + bool start_updating(GdkEventAny*) {return false;} + bool stop_updating(GdkEventAny*) {return false;} + + int package (Gtk::Window&); + + private: + boost::shared_ptr<ARDOUR::LV2Plugin> _lv2; + + Gtk::Widget* _gui_widget; + SLV2UIInstance _inst; + float* _values; + + static void lv2_ui_write( + LV2UI_Controller controller, + uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer); + + void parameter_changed(uint32_t, float); + bool configure_handler (GdkEventConfigure*); + void save_plugin_setting (); +}; +#endif // HAVE_LV2 + +#endif /* __ardour_lv2_plugin_ui_h__ */ + diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index abbf216eea..0edf450cd1 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -18,6 +18,7 @@ */ #include <cstdlib> +#include <signal.h> #include <sigc++/bind.h> #include <gtkmm/settings.h> @@ -252,6 +253,7 @@ fixup_bundle_environment () path += "/../Resources/gdk-pixbuf.loaders"; setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1); + cerr << "Set GDK_PIXBUF_MODULE_FILE to " << path << endl; if (getenv ("ARDOUR_WITH_JACK")) { // JACK driver dir @@ -265,6 +267,12 @@ fixup_bundle_environment () #endif +static void +sigpipe_handler (int sig) +{ + cerr << _("SIGPIPE received - JACK has probably died") << endl; +} + #ifdef VST_SUPPORT /* this is called from the entry point of a wine-compiled executable that is linked against gtk2_ardour built @@ -278,9 +286,12 @@ int main (int argc, char *argv[]) { vector<Glib::ustring> null_file_list; + cerr << "here we go\n"; + #ifdef __APPLE__ fixup_bundle_environment (); #endif + cerr << "just did it\n"; Glib::thread_init(); gtk_set_locale (); @@ -339,6 +350,10 @@ int main (int argc, char *argv[]) PBD::ID::init (); + if (::signal (SIGPIPE, sigpipe_handler)) { + cerr << _("Cannot install SIGPIPE error handler") << endl; + } + try { ui = new ARDOUR_UI (&argc, &argv); } catch (failed_constructor& err) { diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index edfec8a600..9e77d0c9e7 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -245,7 +245,7 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con mark->property_outline_color_rgba() = rgba; mark->property_width_pixels() = 1; Pango::FontDescription* font = get_font_for_style (N_("MarkerText")); - + //cerr << " font->get_size() = " << font->get_size() << " is_absolute = " << pango_font_description_get_size_is_absolute(font->gobj()) << " to_string = " << font->to_string() << endl; text = new Text (*group); text->property_font_desc() = *font; text->property_text() = annotation.c_str(); diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index b2f8ece64e..64e8ea0909 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -665,7 +665,9 @@ void Mixer_UI::track_list_delete (const Gtk::TreeModel::Path& path) { session->set_remote_control_ids(); + ignore_route_reorder = true; redisplay_track_list (); + ignore_route_reorder = false; } void diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index 87d5532d34..b49d6a0b77 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -314,7 +314,7 @@ PluginSelector::ladspa_refiller (const std::string& filterstr) void PluginSelector::lv2_refiller (const std::string& filterstr) { -#ifdef HAVE_SLV2 +#ifdef HAVE_LV2 refiller (manager->lv2_plugin_info(), filterstr, "LV2"); #endif } @@ -520,7 +520,7 @@ PluginSelector::plugin_menu() #ifdef HAVE_AUDIOUNITS all_plugs.insert (all_plugs.end(), manager->au_plugin_info().begin(), manager->au_plugin_info().end()); #endif -#ifdef HAVE_SLV2 +#ifdef HAVE_LV2 all_plugs.insert (all_plugs.end(), manager->lv2_plugin_info().begin(), manager->lv2_plugin_info().end()); #endif diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index d3c9effaa2..a91a5bf9d1 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -42,6 +42,10 @@ #ifdef VST_SUPPORT #include <ardour/vst_plugin.h> #endif +#ifdef HAVE_LV2 +#include <ardour/lv2_plugin.h> +#include "lv2_plugin_ui.h" +#endif #include <lrdf.h> @@ -86,6 +90,10 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert error << _("Eh? LADSPA plugins don't have editors!") << endmsg; break; + case ARDOUR::LV2: + have_gui = create_lv2_editor (insert); + break; + default: #ifndef VST_SUPPORT error << _("unknown type of editor-supplying plugin (note: no VST support in this version of ardour)") @@ -251,6 +259,30 @@ PluginUIWindow::app_activated (bool yn) } bool +PluginUIWindow::create_lv2_editor(boost::shared_ptr<PluginInsert> insert) +{ +#ifndef HAVE_LV2 + return false; +#else + + boost::shared_ptr<LV2Plugin> vp; + + if ((vp = boost::dynamic_pointer_cast<LV2Plugin> (insert->plugin())) == 0) { + error << _("create_lv2_editor called on non-LV2 plugin") << endmsg; + throw failed_constructor (); + } else { + LV2PluginUI* lpu = new LV2PluginUI (insert, vp); + _pluginui = lpu; + add (*lpu); + lpu->package (*this); + } + + non_gtk_gui = false; + return true; +#endif +} + +bool PluginUIWindow::on_key_press_event (GdkEventKey* event) { if (non_gtk_gui) { diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index acc1e4d53a..19c2774be0 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -234,6 +234,7 @@ class PluginUIWindow : public Gtk::Window bool create_vst_editor (boost::shared_ptr<ARDOUR::PluginInsert>); bool create_audiounit_editor (boost::shared_ptr<ARDOUR::PluginInsert>); + bool create_lv2_editor (boost::shared_ptr<ARDOUR::PluginInsert>); }; #ifdef VST_SUPPORT diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 9994f422d4..937399e94f 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -336,7 +336,12 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway static const int vertical_spacing; static const int horizontal_spacing; + + virtual gdouble get_trackview_group_vertical_offset () const = 0; + virtual ArdourCanvas::Group* get_trackview_group () const = 0; + /// Singleton instance, set up by Editor::Editor() + static PublicEditor* _instance; friend class PluginUIWindow; diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 27f9c87819..a7d6c04e71 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -230,7 +230,8 @@ RegionView::region_changed (Change what_changed) */ /* if (what_changed & Region::LayerChanged) { - region_layered (); + // this is handled by the playlist i believe + //region_layered (); } */ if (what_changed & Region::LockChanged) { @@ -285,7 +286,7 @@ RegionView::region_layered () { RouteTimeAxisView *rtv = dynamic_cast<RouteTimeAxisView*>(&get_time_axis_view()); assert(rtv); - rtv->view()->region_layered (this); + //rtv->view()->region_layered (this); } void diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 77c7f59afc..b0b6a577f7 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -266,8 +266,10 @@ SoundFileBox::setup_labels (const ustring& filename) samplerate.set_name ("NewSessionSR2Label"); } - length_clock.set (sf_info.length, true); - timecode_clock.set (sf_info.timecode, true); + double src_coef = (double) _session->nominal_frame_rate() / sf_info.samplerate; + + length_clock.set (sf_info.length * src_coef + 0.5, true); + timecode_clock.set (sf_info.timecode * src_coef + 0.5, true); // this is a hack that is fixed in trunk, i think (august 26th, 2007) diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index 0f52f07939..7539683da5 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -49,7 +49,6 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* group) : _trackview (tv) , owns_canvas_group(group == 0) , canvas_group(group ? group : new ArdourCanvas::Group(*_trackview.canvas_display)) - , canvas_rect(new ArdourCanvas::SimpleRect (*canvas_group)) , _samples_per_unit(_trackview.editor.get_current_zoom()) , rec_updating(false) , rec_active(false) @@ -63,11 +62,15 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* group) { /* set_position() will position the group */ + canvas_rect = new ArdourCanvas::SimpleRect (*canvas_group); 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_x2() = _trackview.editor.frame_to_pixel (max_frames - 1); canvas_rect->property_y2() = (double) tv.current_height(); - canvas_rect->property_outline_what() = (guint32) (0x2|0x8); // outline RHS and bottom + + // DR-way + // canvas_rect->property_outline_what() = (guint32) (0x2|0x8); // outline RHS and bottom + canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8); // outline ends and bottom // (Fill/Outline colours set in derived classes) canvas_rect->signal_event().connect (bind (mem_fun (_trackview.editor, &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview)); @@ -294,18 +297,12 @@ StreamView::apply_color (Gdk::Color& color, ColorTarget target) void StreamView::region_layered (RegionView* rv) { - - /* - Currently 'layer' has nothing to do with the desired canvas layer. - For now, ensure that multiple regionviews passed here in groups are - ordered by 'layer' (lowest to highest). - - (see AudioStreamView::redisplay_diskstream ()). - - We move them to the top layer as they arrive. - */ - - rv->get_canvas_group()->raise_to_top(); + /* don't ever leave it at the bottom, since then it doesn't + get events - the parent group does instead ... + we need to raise it above the streamview's + canvas_rect, hence the layer+1 here + */ + rv->get_canvas_group()->raise (rv->region()->layer() + 1); } void diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h index 7cb5830dcb..e8acb7cd48 100644 --- a/gtk2_ardour/streamview.h +++ b/gtk2_ardour/streamview.h @@ -74,7 +74,7 @@ public: void set_layer_display (LayerDisplay); - ArdourCanvas::Item* canvas_item() { return canvas_group; } + ArdourCanvas::Group* canvas_item() { return canvas_group; } enum ColorTarget { RegionColor, diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index 0973fb9c93..7858b536f8 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -83,7 +83,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie need_size_info = false; } - canvas_display = new Group (*canvas.root(), 0.0, 0.0); + canvas_display = new Group (*ed.get_trackview_group (), 0.0, 0.0); ghost_group = new Group (*canvas_display); ghost_group->lower_to_bottom(); @@ -240,6 +240,7 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent) */ canvas_display->get_bounds (ix1, iy1, ix2, iy2); + iy1 += editor.get_trackview_group_vertical_offset (); Group* pg = canvas_display->property_parent(); pg->i2w (ix1, iy1); diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index fa520f4ca1..6ea16c4b25 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 = new ArdourCanvas::SimpleRect (*group); vestigial_frame->property_x1() = (double) 0.0; vestigial_frame->property_y1() = (double) 1.0; - vestigial_frame->property_x2() = 2.0; + vestigial_frame->property_x2() = (double) 2.0; vestigial_frame->property_y2() = (double) trackview.current_height(); vestigial_frame->property_outline_what() = 0xF; vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get(); @@ -644,7 +644,7 @@ TimeAxisViewItem::get_canvas_frame() /** * */ -ArdourCanvas::Item* +ArdourCanvas::Group* TimeAxisViewItem::get_canvas_group() { return (group) ; diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h index 02becad3e7..cc1c641f57 100644 --- a/gtk2_ardour/time_axis_view_item.h +++ b/gtk2_ardour/time_axis_view_item.h @@ -216,7 +216,7 @@ class TimeAxisViewItem : public Selectable /** * */ - ArdourCanvas::Item* get_canvas_group(); + ArdourCanvas::Group* get_canvas_group(); /** * diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 9008f8b8cd..f09ef1b27f 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -571,23 +571,21 @@ get_xpm (std::string name) sys::path data_file_path; - if (!find_file_in_search_path (spath, name, data_file_path)) { + if(!find_file_in_search_path (spath, name, data_file_path)) { fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg; - /*NOTREACHED*/ } - + try { - xpm_map[name] = Gdk::Pixbuf::create_from_file (data_file_path.to_string()); - } - - catch(const Glib::Error& e) { + xpm_map[name] = Gdk::Pixbuf::create_from_file (data_file_path.to_string()); + } catch(const Glib::Error& e) { warning << "Caught Glib::Error: " << e.what() << endmsg; - } + } } return xpm_map[name]; } + Glib::RefPtr<Gdk::Pixbuf> get_icon (const char* cname) { @@ -608,15 +606,11 @@ get_icon (const char* cname) Glib::RefPtr<Gdk::Pixbuf> img; try { img = Gdk::Pixbuf::create_from_file (data_file_path.to_string()); + } catch (const Gdk::PixbufError &e) { + cerr << "Caught PixbufError: " << e.what() << endl; + } catch (...) { + g_message("Caught ... "); } - catch (const Gdk::PixbufError &e) - { - cerr << "Caught PixbufError: " << e.what() << endl; - } - catch (...) - { - g_message("Caught ... "); - } return img; } @@ -701,7 +695,7 @@ set_pango_fontsize () { long val = ARDOUR::Config->get_font_scale(); - /* FT2 rendering */ + /* FT2 rendering - used by GnomeCanvas, sigh */ pango_ft2_font_map_set_resolution ((PangoFT2FontMap*) pango_ft2_font_map_for_display(), val/1024, val/1024); |