fixed width columns for LHS of editor route list
[ardour.git] / gtk2_ardour / editor_mouse.cc
index 034619c9321441c4e4fbde9f37db8660571e30bd..0d5f75f60d96c49fc732aa7dee4488d0b6cfcd55 100644 (file)
@@ -60,6 +60,7 @@
 #include "edit_note_dialog.h"
 #include "mouse_cursors.h"
 #include "editor_cursors.h"
+#include "verbose_cursor.h"
 
 #include "ardour/types.h"
 #include "ardour/profile.h"
@@ -206,7 +207,7 @@ Editor::which_grabber_cursor ()
                        boost::shared_ptr<Movable> m = _movable.lock();
                        if (m && m->locked()) {
                                c = _cursors->speaker;
-                       } 
+                       }
                        break;
                }
        }
@@ -372,24 +373,24 @@ Editor::mouse_mode_toggled (MouseMode m)
        mouse_mode = m;
 
        instant_save ();
-        
+
        if (!internal_editing()) {
                if (mouse_mode != MouseRange && _join_object_range_state == JOIN_OBJECT_RANGE_NONE) {
-                        
+
                        /* in all modes except range and joined object/range, hide the range selection,
                           show the object (region) selection.
                        */
-                        
+
                        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                                (*i)->hide_selection ();
                        }
-                        
+
                } else {
-                        
+
                        /*
                          in range or object/range mode, show the range selection.
                        */
-                        
+
                        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
                                (*i)->show_selection (selection->time);
                        }
@@ -711,7 +712,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        if (internal_editing()) {
                                /* trim notes if we're in internal edit mode and near the ends of the note */
                                ArdourCanvas::CanvasNote* cn = dynamic_cast<ArdourCanvas::CanvasNote*> (item);
-                               if (cn->big_enough_to_trim() && cn->mouse_near_ends()) {
+                               if (cn && cn->big_enough_to_trim() && cn->mouse_near_ends()) {
                                        _drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
                                } else {
                                        _drags->set (new NoteDrag (this, item), event);
@@ -769,7 +770,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                return true;
                        }
                        break;
-                       
+
                default:
                        break;
                }
@@ -797,12 +798,12 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        }
 
                        case FeatureLineItem:
-                       {                       
+                       {
                                if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
                                        remove_transient(item);
                                        return true;
                                }
-                               
+
                                _drags->set (new FeatureLineDrag (this, item), event);
                                return true;
                                break;
@@ -820,7 +821,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                        /* no region drags in internal edit mode */
                                        break;
                                }
-                               
+
                                /* click on a normal region view */
                                if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
                                        add_region_copy_drag (item, event, clicked_regionview);
@@ -829,7 +830,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                } else {
                                        add_region_drag (item, event, clicked_regionview);
                                }
-                               
+
                                if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty()) {
                                        _drags->add (new SelectionDrag (this, clicked_axisview->get_selection_rect (clicked_selection)->rect, SelectionDrag::SelectionMove));
                                }
@@ -876,7 +877,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                        _drags->set (new RubberbandSelectDrag (this, item), event);
                                }
                                break;
-                               
+
                        case AutomationTrackItem:
                                /* rubberband drag to select automation points */
                                _drags->set (new RubberbandSelectDrag (this, item), event);
@@ -904,7 +905,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                                        if (t) {
                                                                boost::shared_ptr<Playlist> pl = t->playlist ();
                                                                if (pl) {
-                                                                       
+
                                                                        boost::shared_ptr<Region> r = pl->top_region_at (event_frame (event));
                                                                        if (r) {
                                                                                RegionView* rv = rtv->view()->find_view (r);
@@ -1049,6 +1050,11 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
        case MouseObject:
                switch (item_type) {
                case RegionItem:
+                       if (internal_editing ()) {
+                               /* no region drags in internal edit mode */
+                               return false;
+                       }
+
                        if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) {
                                add_region_copy_drag (item, event, clicked_regionview);
                        } else {
@@ -1499,7 +1505,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
                default:
                        break;
-                        
+
                }
 
                 /* do any (de)selection operations that should occur on button release */
@@ -1549,8 +1555,6 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                break;
        }
 
-        cerr << "button release hits bottom\n";
-
        return false;
 }
 
@@ -1583,8 +1587,8 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                                set_canvas_cursor (_cursors->fader);
                        }
 
-                       set_verbose_canvas_cursor (cp->line().get_verbose_cursor_string (fraction), at_x, at_y);
-                       show_verbose_canvas_cursor ();
+                       _verbose_cursor->set (cp->line().get_verbose_cursor_string (fraction), at_x, at_y);
+                       _verbose_cursor->show ();
                }
                break;
 
@@ -1747,7 +1751,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                        set_canvas_cursor ();
                }
                break;
-               
+
        default:
                break;
        }
@@ -1799,7 +1803,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                        set_canvas_cursor (current_canvas_cursor);
                }
 
-               hide_verbose_canvas_cursor ();
+               _verbose_cursor->hide ();
                break;
 
        case RegionViewNameHighlight:
@@ -1817,7 +1821,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
 #endif
 
                _over_region_trim_target = false;
-               
+
                if (is_drawable()) {
                        set_canvas_cursor (current_canvas_cursor);
                }
@@ -1839,7 +1843,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
        case RegionViewName:
                /* see enter_handler() for notes */
                _over_region_trim_target = false;
-               
+
                if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) {
                        if (is_drawable() && mouse_mode == MouseObject) {
                                set_canvas_cursor (current_canvas_cursor);
@@ -2003,7 +2007,7 @@ bool
 Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from_autoscroll)
 {
        _last_motion_y = event->motion.y;
-       
+
        if (event->motion.is_hint) {
                gint x, y;
 
@@ -2044,7 +2048,7 @@ Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from
        if (_drags->active ()) {
                handled = _drags->motion_handler (event, from_autoscroll);
        }
-       
+
        if (!handled) {
                return false;
        }
@@ -2118,7 +2122,7 @@ Editor::edit_note (ArdourCanvas::Item* item)
 
        d.run ();
 }
-       
+
 
 void
 Editor::visible_order_range (int* low, int* high) const
@@ -2178,146 +2182,6 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event)
        }
 }
 
-void
-Editor::show_verbose_time_cursor (framepos_t frame, double offset, double xpos, double ypos)
-{
-       char buf[128];
-       Timecode::Time timecode;
-       Timecode::BBT_Time bbt;
-       int hours, mins;
-       framepos_t frame_rate;
-       float secs;
-
-       if (_session == 0) {
-               return;
-       }
-
-       AudioClock::Mode m;
-
-       if (Profile->get_sae() || Profile->get_small_screen()) {
-               m = ARDOUR_UI::instance()->primary_clock.mode();
-       } else {
-               m = ARDOUR_UI::instance()->secondary_clock.mode();
-       }
-
-       switch (m) {
-       case AudioClock::BBT:
-               _session->bbt_time (frame, bbt);
-               snprintf (buf, sizeof (buf), "%02" PRIu32 "|%02" PRIu32 "|%02" PRIu32, bbt.bars, bbt.beats, bbt.ticks);
-               break;
-
-       case AudioClock::Timecode:
-               _session->timecode_time (frame, timecode);
-               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%02" PRId32 ":%02" PRId32, timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
-               break;
-
-       case AudioClock::MinSec:
-               /* XXX this is copied from show_verbose_duration_cursor() */
-               frame_rate = _session->frame_rate();
-               hours = frame / (frame_rate * 3600);
-               frame = frame % (frame_rate * 3600);
-               mins = frame / (frame_rate * 60);
-               frame = frame % (frame_rate * 60);
-               secs = (float) frame / (float) frame_rate;
-               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%07.4f", hours, mins, secs);
-               break;
-
-       default:
-               snprintf (buf, sizeof(buf), "%" PRIi64, frame);
-               break;
-       }
-
-       if (xpos >= 0 && ypos >=0) {
-               set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset);
-       } else {
-               set_verbose_canvas_cursor (buf, _drags->current_pointer_x() + offset - horizontal_position(), _drags->current_pointer_y() + offset - vertical_adjustment.get_value() + canvas_timebars_vsize);
-       }
-       show_verbose_canvas_cursor ();
-}
-
-void
-Editor::show_verbose_duration_cursor (framepos_t start, framepos_t end, double offset, double xpos, double ypos)
-{
-       char buf[128];
-       Timecode::Time timecode;
-       Timecode::BBT_Time sbbt;
-       Timecode::BBT_Time ebbt;
-       int hours, mins;
-       framepos_t distance, frame_rate;
-       float secs;
-       Meter meter_at_start(_session->tempo_map().meter_at(start));
-
-       if (_session == 0) {
-               return;
-       }
-
-       AudioClock::Mode m;
-
-       if (Profile->get_sae() || Profile->get_small_screen()) {
-               m = ARDOUR_UI::instance()->primary_clock.mode ();
-       } else {
-               m = ARDOUR_UI::instance()->secondary_clock.mode ();
-       }
-
-       switch (m) {
-       case AudioClock::BBT:
-               _session->bbt_time (start, sbbt);
-               _session->bbt_time (end, ebbt);
-
-               /* subtract */
-               /* XXX this computation won't work well if the
-               user makes a selection that spans any meter changes.
-               */
-
-               ebbt.bars -= sbbt.bars;
-               if (ebbt.beats >= sbbt.beats) {
-                       ebbt.beats -= sbbt.beats;
-               } else {
-                       ebbt.bars--;
-                       ebbt.beats =  int(meter_at_start.beats_per_bar()) + ebbt.beats - sbbt.beats;
-               }
-               if (ebbt.ticks >= sbbt.ticks) {
-                       ebbt.ticks -= sbbt.ticks;
-               } else {
-                       ebbt.beats--;
-                       ebbt.ticks = int(Timecode::BBT_Time::ticks_per_beat) + ebbt.ticks - sbbt.ticks;
-               }
-
-               snprintf (buf, sizeof (buf), "%02" PRIu32 "|%02" PRIu32 "|%02" PRIu32, ebbt.bars, ebbt.beats, ebbt.ticks);
-               break;
-
-       case AudioClock::Timecode:
-               _session->timecode_duration (end - start, timecode);
-               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%02" PRId32 ":%02" PRId32, timecode.hours, timecode.minutes, timecode.seconds, timecode.frames);
-               break;
-
-       case AudioClock::MinSec:
-               /* XXX this stuff should be elsewhere.. */
-               distance = end - start;
-               frame_rate = _session->frame_rate();
-               hours = distance / (frame_rate * 3600);
-               distance = distance % (frame_rate * 3600);
-               mins = distance / (frame_rate * 60);
-               distance = distance % (frame_rate * 60);
-               secs = (float) distance / (float) frame_rate;
-               snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%07.4f", hours, mins, secs);
-               break;
-
-       default:
-               snprintf (buf, sizeof(buf), "%" PRIi64, end - start);
-               break;
-       }
-
-       if (xpos >= 0 && ypos >=0) {
-               set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset);
-       }
-       else {
-               set_verbose_canvas_cursor (buf, _drags->current_pointer_x() + offset, _drags->current_pointer_y() + offset);
-       }
-
-       show_verbose_canvas_cursor ();
-}
-
 void
 Editor::collect_new_region_view (RegionView* rv)
 {
@@ -2363,7 +2227,7 @@ Editor::point_trim (GdkEvent* event, framepos_t new_bound)
 
                                if (!(*i)->region()->locked()) {
                                        (*i)->region()->clear_changes ();
-                                       (*i)->region()->trim_front (new_bound, this);
+                                       (*i)->region()->trim_front (new_bound);
                                        _session->add_command(new StatefulDiffCommand ((*i)->region()));
                                }
                        }
@@ -2371,7 +2235,7 @@ Editor::point_trim (GdkEvent* event, framepos_t new_bound)
                } else {
                        if (!rv->region()->locked()) {
                                rv->region()->clear_changes ();
-                               rv->region()->trim_front (new_bound, this);
+                               rv->region()->trim_front (new_bound);
                                _session->add_command(new StatefulDiffCommand (rv->region()));
                        }
                }
@@ -2388,7 +2252,7 @@ Editor::point_trim (GdkEvent* event, framepos_t new_bound)
                        {
                                if (!(*i)->region()->locked()) {
                                        (*i)->region()->clear_changes();
-                                       (*i)->region()->trim_end (new_bound, this);
+                                       (*i)->region()->trim_end (new_bound);
                                        _session->add_command(new StatefulDiffCommand ((*i)->region()));
                                }
                        }
@@ -2397,7 +2261,7 @@ Editor::point_trim (GdkEvent* event, framepos_t new_bound)
 
                        if (!rv->region()->locked()) {
                                rv->region()->clear_changes ();
-                               rv->region()->trim_end (new_bound, this);
+                               rv->region()->trim_end (new_bound);
                                _session->add_command (new StatefulDiffCommand (rv->region()));
                        }
                }
@@ -2565,7 +2429,7 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent* event, Region
        if (!region_view->region()->playlist()) {
                return;
        }
-        
+
        if (Config->get_edit_mode() == Splice) {
                return;
        }
@@ -2694,12 +2558,12 @@ Editor::update_join_object_range_location (double x, double y)
           entered_{track,regionview} is not always setup (e.g. if the mouse is over a TimeSelection), and to get a Region
           that we're over requires searching the playlist.
        */
-          
+
        if (join_object_range_button.get_active() == false || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
                _join_object_range_state = JOIN_OBJECT_RANGE_NONE;
                return;
        }
-       
+
        if (mouse_mode == MouseObject) {
                _join_object_range_state = JOIN_OBJECT_RANGE_OBJECT;
        } else if (mouse_mode == MouseRange) {
@@ -2708,7 +2572,7 @@ Editor::update_join_object_range_location (double x, double y)
 
        /* XXX: maybe we should make entered_track work in all cases, rather than resorting to this */
        pair<TimeAxisView*, int> tvp = trackview_by_y_position (y + vertical_adjustment.get_value() - canvas_timebars_vsize);
-       
+
        if (tvp.first) {
 
                RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
@@ -2751,6 +2615,8 @@ Editor::remove_midi_note (ArdourCanvas::Item* item, GdkEvent *)
 void
 Editor::set_canvas_cursor_for_region_view (double x, RegionView* rv)
 {
+       assert (rv);
+
        ArdourCanvas::Group* g = rv->get_canvas_group ();
        ArdourCanvas::Group* p = g->get_parent_group ();
 
@@ -2779,3 +2645,12 @@ Editor::set_canvas_cursor_for_region_view (double x, RegionView* rv)
                }
        }
 }
+
+/** Obtain the pointer position in world coordinates */
+void
+Editor::get_pointer_position (double& x, double& y) const
+{
+       int px, py;
+       track_canvas->get_pointer (px, py);
+       track_canvas->window_to_world (px, py, x, y);
+}