"The In-Flight Hack, 2006"
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 27 Apr 2006 09:04:24 +0000 (09:04 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 27 Apr 2006 09:04:24 +0000 (09:04 +0000)
a) measure lines extend the full height of the canvas
b) region name color bars and text positioning now adjusted to match
     font size for different display resolutions
c) vertical scrollbar limited to cover visible tracks only

git-svn-id: svn://localhost/trunk/ardour2@486 d708f5d6-7413-0410-9779-e7cbd77b26cf

23 files changed:
gtk2_ardour/analysis_window.cc
gtk2_ardour/ardour.menus
gtk2_ardour/ardour2_ui.rc
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/automation_time_axis.cc
gtk2_ardour/draginfo.h
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_tempodisplay.cc
gtk2_ardour/keyboard.cc
gtk2_ardour/main.cc
gtk2_ardour/regionview.cc
gtk2_ardour/time_axis_view_item.cc
gtk2_ardour/time_axis_view_item.h
libs/ardour/ardour/audioregion.h
libs/ardour/ardour/coreaudio_source.h
libs/ardour/ardour/filesource.h
libs/ardour/ardour/sndfilesource.h
libs/ardour/ardour/source.h
libs/ardour/audioregion.cc
libs/ardour/coreaudio_source.cc
libs/ardour/filesource.cc
libs/ardour/sndfilesource.cc

index 6c8e569822eaba0b522b2dc4c298c7b1ed2d54d7..014aeaaabc2e4def7d1fd409f19db3bfcd84a3ac 100644 (file)
@@ -1,5 +1,6 @@
 /*
     Copyright (C) 2006 Paul Davis
+    Written by Sampo Savolainen
 
     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
@@ -15,9 +16,9 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
+    $Id$
 */
 
-
 #include <gtkmm2ext/gtk_ui.h>
 #include <gtkmm/stock.h>
 #include <gtkmm/label.h>
@@ -54,7 +55,6 @@ AnalysisWindow::AnalysisWindow()
          display_model_composite_all_tracks_rb (_("Composite graph of all tracks"))
 
 {
-
        track_list_ready = false;
        
        // Left side: track list + controls
index b8f6b10f783e55a1c7191260278cf8f665486bbc..3abb0d4219f495106803676a9158cc558a6058ca 100644 (file)
                </menu>
                <menu action='Autoconnect'>
                    <menuitem action='AutoConnectNewTrackInputsToHardware'/>
+                  <separator/>
                    <menuitem action='AutoConnectNewTrackOutputsToHardware'/>
-                   <menuitem action='AutoConnectNewTrackOutputsToHardware'/>
+                   <menuitem action='AutoConnectNewTrackOutputsToMaster'/>
                    <menuitem action='ManuallyConnectNewTrackOutputs'/>
                </menu>
               <menu action='ControlSurfaces'/>
index acf3fabe1760e660b9b203b3075628fe0be8ac43..a17521193e7700ebb52b6f7325f577113eb47a66 100644 (file)
@@ -75,7 +75,7 @@ style "marker_text"
 
 style "time_axis_view_item_name"
 {
-       font_name = "sans medium 10"
+       font_name = "sans medium 8"
 }
 
 style "default_base" = "medium_text"
index 3944d3180ab2e7c21b56ac105378dd433a52c030..70031b102a2aa440c33651c9112e50b77c4eb271 100644 (file)
@@ -371,7 +371,7 @@ ARDOUR_UI::install_actions ()
        act = ActionManager::register_toggle_action (option_actions, X_("UseMIDIcontrol"), _("Use MIDI control"), mem_fun (*this, &ARDOUR_UI::toggle_use_midi_control));
        ActionManager::session_sensitive_actions.push_back (act);
 
-       act = ActionManager::register_toggle_action (option_actions, X_("AutoConnectNewTrackInputsToHardware"), _("Connect newtrack inputs to hardware"), mem_fun (*this, &ARDOUR_UI::toggle_AutoConnectNewTrackInputsToHardware));
+       act = ActionManager::register_toggle_action (option_actions, X_("AutoConnectNewTrackInputsToHardware"), _("Connect new track inputs to hardware"), mem_fun (*this, &ARDOUR_UI::toggle_AutoConnectNewTrackInputsToHardware));
        ActionManager::session_sensitive_actions.push_back (act);
 
        RadioAction::Group file_header_group;
index 3831e253b4029d3104c98bca900baef7e9b53bba..fbe15680115dcfb746856b70c89711046d75be7c 100644 (file)
@@ -275,8 +275,9 @@ AutomationTimeAxisView::clear_clicked ()
 }
 
 void
-AutomationTimeAxisView::set_height (TrackHeight h)
+AutomationTimeAxisView::set_height (TrackHeight ht)
 {
+       uint32_t h = height_to_pixels (ht);
        bool changed = (height != (uint32_t) h);
 
        TimeAxisView* state_parent = get_parent_with_state ();
@@ -284,7 +285,7 @@ AutomationTimeAxisView::set_height (TrackHeight h)
 
        controls_table.show_all ();
 
-       TimeAxisView::set_height (h);
+       TimeAxisView::set_height (ht);
        base_rect->property_y2() = h;
 
        for (vector<AutomationLine*>::iterator i = lines.begin(); i != lines.end(); ++i) {
index 8b9213ea406b48df1efcecd3957e7f3ac813ea24..3db8bab1e8d3febd6880fc076bec12633e2b8983 100644 (file)
@@ -31,6 +31,7 @@ struct DragInfo {
     void (Editor::*finished_callback)(ArdourCanvas::Item*, GdkEvent*);
     TimeAxisView* last_trackview;
     bool x_constrained;
+    bool y_constrained;
     bool copy;
     bool was_rolling;
     bool first_move;
index bd6c1c99abde35870f96ab09d9e7cc5eb268a3df..744de49c9424a7d4ee14586268e16e2b56ef9c86 100644 (file)
@@ -368,7 +368,7 @@ Editor::reset_scrolling_region (Gtk::Allocation* alloc)
 
         for (pos = 0, i = rows.begin(); i != rows.end(); ++i) {
                TimeAxisView *tv = (*i)[route_display_columns.tv];
-               if (tv != 0) {
+               if (tv != 0 && !tv->hidden()) {
                        pos += tv->effective_height;
                        pos += track_spacing;
                }
index 8eb97f216538b5664089c959972a73d7565f51d8..79053a2e52170c44504c76f0c34c91a10381d160 100644 (file)
@@ -942,9 +942,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        break;
 
                case MarkerItem:
-
                        remove_marker (*item, event);
-
                        break;
 
                case RegionItem:
@@ -1598,9 +1596,16 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
         // if dragging with button2, the motion is x constrained, with Alt-button2 it is y constrained
 
        if (event->button.button == 2) {
-               drag_info.x_constrained = true;
+               if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Alt)) {
+                       drag_info.y_constrained = true;
+                       drag_info.x_constrained = false;
+               } else {
+                       drag_info.y_constrained = false;
+                       drag_info.x_constrained = true;
+               }
        } else {
                drag_info.x_constrained = false;
+               drag_info.y_constrained = false;
        }
 
        drag_info.grab_frame = event_frame(event, &drag_info.grab_x, &drag_info.grab_y);
@@ -2455,18 +2460,12 @@ Editor::control_point_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent*
        drag_info.cumulative_x_drag = cx - drag_info.grab_x ;
        drag_info.cumulative_y_drag = cy - drag_info.grab_y ;
 
-       bool x_constrained = false;
-
        if (drag_info.x_constrained) {
-               if (fabs(drag_info.cumulative_x_drag) < fabs(drag_info.cumulative_y_drag)) {
-                       cx = drag_info.grab_x;
-                       x_constrained = true;
-
-               } else {
-                       cy = drag_info.grab_y;
-               }
-       
-       } 
+               cx = drag_info.grab_x;
+       }
+       if (drag_info.y_constrained) {
+               cy = drag_info.grab_y;
+       }
 
        cp->line.parent_group().w2i (cx, cy);
 
@@ -2475,9 +2474,9 @@ Editor::control_point_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent*
        cy = min ((double) cp->line.height(), cy);
 
        //translate cx to frames
-       jack_nframes_t cx_frames = (jack_nframes_t) floor (cx * frames_per_unit);
+       jack_nframes_t cx_frames = unit_to_frame (cx);
 
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !x_constrained) {
+       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !drag_info.x_constrained) {
                snap_to (cx_frames);
        }
 
index 3b70286bcc238c962c83f8691a836b61bdca2809..3aa95d022f1d9462bdef750d86598cda90087089 100644 (file)
@@ -190,6 +190,9 @@ Editor::draw_measures ()
                }
        }
 
+       double x1, x2, y1, y2;
+       track_canvas.get_scroll_region (x1, y1, x2, y2);
+
        for (i = all_bbt_points->begin(); i != all_bbt_points->end(); ++i) {
 
                TempoMap::BBTPoint& p = (*i);
@@ -219,7 +222,7 @@ Editor::draw_measures ()
                                line = get_time_line ();
                                line->property_x1() = xpos;
                                line->property_x2() = xpos;
-                               line->property_y2() = 1000;
+                               line->property_y2() = y2;
                                line->property_color_rgba() = color;
                                line->raise_to_top();
                                line->show();
index c0bbea798ad1f0012b8e057fde3a9f9d7102f1f0..92dce01bb6a90fe57ab7c1ea8f402b46119862e5 100644 (file)
@@ -54,7 +54,7 @@ Keyboard* Keyboard::_the_keyboard = 0;
 /* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
 
 GdkModifierType Keyboard::RelevantModifierKeyMask = 
-                               GdkModifierType (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD3_MASK);
+                               GdkModifierType (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_MOD3_MASK);
 
 
 Keyboard::Keyboard ()
index 00b91e00e7c5f1ae9d28a09701d5dde378eb549e..76ec0f3da33adb79cd0e2006216109e4f662ee7c 100644 (file)
@@ -342,7 +342,7 @@ main (int argc, char *argv[])
        }
 
        if (no_splash) {
-               cerr << _("Copyright (C) 1999-2005 Paul Davis") << endl
+               cerr << _("Copyright (C) 1999-2006 Paul Davis") << endl
                     << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
                     << endl
                     << _("Ardour comes with ABSOLUTELY NO WARRANTY") << endl
index 2ae5699b4b30833147516404369753d21c8e79b6..dbca103239c31b791a5cd6bd28e642cd74bcddf2 100644 (file)
@@ -865,11 +865,15 @@ AudioRegionView::region_renamed ()
                str = region.name();
        }
 
+       if (region.speed_mismatch (trackview.session().frame_rate())) {
+               str = string ("*") + str;
+       }
+
        if (region.muted()) {
                str = string ("!") + str;
        }
 
-       set_item_name (region.name(), this);
+       set_item_name (str, this);
        set_name_text (str);
 }
 
index 270cbde0b8de227a20f4d69ead47a838681473df..f54688ddfb2b1f7dbf53124c01cf3d4e4e6974b5 100644 (file)
@@ -23,6 +23,8 @@
 #include <ardour/types.h>
 #include <ardour/ardour.h>
 
+#include <gtkmm2ext/utils.h>
+
 #include "public_editor.h"
 #include "time_axis_view_item.h"
 #include "time_axis_view.h"
@@ -38,15 +40,17 @@ using namespace Editing;
 using namespace Glib;
 
 //------------------------------------------------------------------------------
-/** Initialize static memeber data */
+/** Initialize const static memeber data */
+
 Pango::FontDescription TimeAxisViewItem::NAME_FONT;
 bool TimeAxisViewItem::have_name_font = false;
 const double TimeAxisViewItem::NAME_X_OFFSET = 15.0;
-const double TimeAxisViewItem::NAME_Y_OFFSET = 15.0 ;           /* XXX depends a lot on the font size, sigh. */
-const double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE = 15.0 ;     /* ditto */
-const double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH = 32.0 ;     /* ditto */
 const double TimeAxisViewItem::GRAB_HANDLE_LENGTH = 6 ;
 
+double TimeAxisViewItem::NAME_Y_OFFSET;
+double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
+double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
+
 
 //---------------------------------------------------------------------------------------//
 // Constructor / Desctructor
@@ -68,7 +72,26 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group&
        : trackview (tv)
 {
        if (!have_name_font) {
+
+               /* first constructed item sets up font info */
+
                NAME_FONT = get_font_for_style (N_("TimeAxisViewItemName"));
+               
+               Gtk::Window win;
+               Gtk::Label foo;
+               win.add (foo);
+
+               Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
+               int width;
+               int height;
+
+               layout->set_font_description (NAME_FONT);
+               Gtkmm2ext::get_ink_pixel_size (layout, width, height);
+
+               NAME_Y_OFFSET = height + 4;
+               NAME_HIGHLIGHT_SIZE = height + 6;
+               NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 2;
+
                have_name_font = true;
        }
 
@@ -150,7 +173,10 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group&
        if (visibility & ShowNameText) {
                name_text = new ArdourCanvas::Text (*group);
                name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET;
-               name_text->property_y() = (double) trackview.height + 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
+               /* trackview.height is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
+                  then NAME_Y_OFFSET to position the text in the vertical center of the highlight
+               */
+               name_text->property_y() = (double) trackview.height - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
                name_text->property_font_desc() = NAME_FONT;
                name_text->property_anchor() = Gtk::ANCHOR_NW;
 
@@ -872,6 +898,7 @@ TimeAxisViewItem::reset_name_width (double pixel_width)
        }
                        
        int width;
+       
        ustring ustr = fit_to_pixels (item_name, (int) floor (pixel_width - NAME_X_OFFSET), NAME_FONT, width);
 
        if (ustr.empty()) {
@@ -934,8 +961,8 @@ TimeAxisViewItem::remove_this_item(void* src)
 gint
 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
 {
-        item->ItemRemoved(item->get_item_name(), src) ; /* EMIT_SIGNAL */
-       delete item ;
-       item = 0 ;
-       return(false) ;
+       item->ItemRemoved (item->get_item_name(), src) ; /* EMIT_SIGNAL */
+       delete item;
+       item = 0;
+       return false;
 }
index b1e993944940e407cb0ecd982aa92738055b237b..c9e4fd5dd5883243966cf7f7a6841a114c60567b 100644 (file)
@@ -272,10 +272,13 @@ class TimeAxisViewItem : public sigc::trackable, public Selectable
     static Pango::FontDescription NAME_FONT ;
     static bool have_name_font;
     static const double NAME_X_OFFSET ;
-    static const double NAME_Y_OFFSET ;
-    static const double NAME_HIGHLIGHT_SIZE ;
-    static const double NAME_HIGHLIGHT_THRESH ;
     static const double GRAB_HANDLE_LENGTH ;
+    /* these are not constant, but vary with the pixel size
+       of the font used to display the item name.
+    */
+    static double NAME_Y_OFFSET ;
+    static double NAME_HIGHLIGHT_SIZE ;
+    static double NAME_HIGHLIGHT_THRESH ;
 
     /**
      * Handles the Removal of this time axis item
index c716bf97072f5c5862c4f6273d2ffeb1b0cfb538..a146a204176f81ec95dcbc064dbaaef17b03550a 100644 (file)
@@ -80,6 +80,8 @@ class AudioRegion : public Region
        bool equivalent (const AudioRegion&);
        bool size_equivalent (const AudioRegion&);
 
+       bool speed_mismatch (float) const;
+
        void lock_sources ();
        void unlock_sources ();
        Source& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; } 
index 6ae74b73040c62452ef1d03e7e2d04231707b031..4193623006e84bc4cfcf611acc11310fa1e48996 100644 (file)
@@ -32,6 +32,7 @@ class CoreAudioSource : public ExternalSource {
        ~CoreAudioSource ();
 
        jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
+       float sample_rate() const;
 
   private:
        ExtAudioFileRef af;
index df9cc46b9126a103b8b12d3d957db980251d4c2c..28a01f0a78e68893daab0963172e01ced8ce78ee 100644 (file)
@@ -58,6 +58,7 @@ class FileSource : public Source {
        void           mark_for_remove();
        string         peak_path(string audio_path);
        string         path() const { return _path; }
+       float sample_rate () const;
 
        virtual int            seek (jack_nframes_t frame) {return 0; }
        virtual jack_nframes_t last_capture_start_frame() const { return 0; }
@@ -129,9 +130,9 @@ class FileSource : public Source {
        };
 
        struct ChunkInfo {
-           string        name;
-           uint32_t size;
-           off64_t         offset;
+           std::string name;
+           uint32_t    size;
+           off64_t     offset;
            
            ChunkInfo (string s, uint32_t sz, off64_t o) 
                    : name (s), size (sz), offset (o) {}
index 37167e6a9af5bc6067eca07fda398d94b33a7ad0..2bd6042ec23b88fd255ac3652a63c2b5572a7b68 100644 (file)
@@ -33,9 +33,9 @@ class SndFileSource : public ExternalSource {
        SndFileSource (const XMLNode&);
        ~SndFileSource ();
 
-    jack_nframes_t length() const { return _info.frames; } 
-
+       jack_nframes_t length() const { return _info.frames; } 
        jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
+       float sample_rate () const;
 
   private:
        SNDFILE *sf;
index 88a478a42027887a0393b6617987dbc482228db4..2eee7a763459969aefe84e6a73971e506e83f922 100644 (file)
@@ -75,6 +75,8 @@ class Source : public Stateful, public sigc::trackable
                return 0;
        }
 
+       virtual float sample_rate () const { return 0; }
+
        uint32_t use_cnt() const { return _use_cnt; }
        void use ();
        void release ();
index c63c231f8632fd6c4bc2ff0bd1a085b7429e8703..95201ab6f76ab84712abe973b244f20212e6279f 100644 (file)
@@ -1392,6 +1392,19 @@ AudioRegion::resume_fade_out ()
        }
 }
 
+bool
+AudioRegion::speed_mismatch (float sr) const
+{
+       if (sources.empty()) {
+               /* impossible, but ... */
+               return false;
+       }
+
+       float fsr = sources.front()->sample_rate();
+
+       return fsr == sr;
+}
+
 extern "C" {
 
        int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit) 
index 3f786a2b14e0faae211b7b009b4295f11f9ee69f..d81630d6b7bf9136a6a2e8786e4ea103de1be100 100644 (file)
@@ -204,3 +204,10 @@ CoreAudioSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, ch
        return real_cnt;
 }
 
+float
+CoreAudioSource::sample_rate() const
+{
+       /* XXX taybin fill me in please */
+
+       return 44100.0f;
+}
index d4f728c13b8c9482854dbcc6d4d2532462a9e1d6..568ce46bd1dce2489a5e701690e7fce8279cf0c3 100644 (file)
@@ -907,14 +907,20 @@ FileSource::check_header (jack_nframes_t rate, bool silent)
                                   _path, header.data.size, _length * sizeof (Sample)) << endmsg;
        }
 
-       if ((jack_nframes_t) header.format.nSamplesPerSec != rate) {
-               warning << string_compose(_("\"%1\" has a sample rate of %2 instead of %3 as used by this session"),
-                                  _path, header.format.nSamplesPerSec, rate) << endmsg;
-       }
+//     if ((jack_nframes_t) header.format.nSamplesPerSec != rate) {
+//             warning << string_compose(_("\"%1\" has a sample rate of %2 instead of %3 as used by this session"),
+//                                _path, header.format.nSamplesPerSec, rate) << endmsg;
+//     }
 
        return 0;
 }
 
+float
+FileSource::sample_rate () const
+{
+       return header.format.nSamplesPerSec;
+}
+
 int
 FileSource::write_header()
 {
index 522f94b5c2b20c3123d295fc7d7b8ab18c0f5965..e547b212a0ab2c7b9b7969598a99959f5787b33c 100644 (file)
@@ -109,6 +109,12 @@ SndFileSource::~SndFileSource ()
        }
 }
 
+float
+SndFileSource::sample_rate () const 
+{
+       return _info.samplerate;
+}
+
 jack_nframes_t
 SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
 {