Port level meters to trunk
[ardour.git] / gtk2_ardour / time_axis_view.cc
index 1b6c1f390c8e8f9ebf80a313fea80665d76d2fcf..4815aff0a0f6c823facc79a30193d2d4c237452a 100644 (file)
@@ -15,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #include <cstdlib>
@@ -37,7 +36,7 @@
 #include <ardour/session.h>
 #include <ardour/utils.h>
 #include <ardour/ladspa_plugin.h>
-#include <ardour/insert.h>
+#include <ardour/processor.h>
 #include <ardour/location.h>
 
 #include "ardour_ui.h"
@@ -55,6 +54,7 @@ using namespace Gtk;
 using namespace Gdk;
 using namespace sigc; 
 using namespace ARDOUR;
+using namespace PBD;
 using namespace Editing;
 using namespace ArdourCanvas;
 
@@ -71,7 +71,10 @@ bool TimeAxisView::need_size_info = true;
 TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisView* rent, Canvas& canvas) 
        : AxisView (sess), 
          editor (ed),
-         controls_table (2, 8)
+         height_style(Small),
+         y_position(0),
+         order(0),
+         controls_table (2, 7)
 {
        if (need_size_info) {
                compute_controls_size_info ();
@@ -125,13 +128,14 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
        controls_table.set_col_spacings (0);
        controls_table.set_homogeneous (true);
 
-       controls_table.attach (name_hbox, 0, 4, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+       controls_table.attach (name_hbox, 0, 4, 0, 1, Gtk::SHRINK|Gtk::EXPAND, Gtk::SHRINK|Gtk::EXPAND);
        controls_table.show_all ();
+       controls_table.set_no_show_all ();
 
        controls_vbox.pack_start (controls_table, false, false);
        controls_vbox.show ();
-
-       controls_ebox.set_name ("TimeAxisViewControlsBaseUnselected");
+       
+       //controls_ebox.set_name ("TimeAxisViewControlsBaseUnselected");
        controls_ebox.add (controls_vbox);
        controls_ebox.add_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK|SCROLL_MASK);
        controls_ebox.set_flags (CAN_FOCUS);
@@ -146,17 +150,13 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
 
        controls_frame.add (controls_hbox);
        controls_frame.set_name ("TimeAxisViewControlsBaseUnselected");
-       controls_frame.set_shadow_type (Gtk::SHADOW_OUT);
+       controls_frame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT);
 
-       ColorChanged.connect (mem_fun (*this, &TimeAxisView::color_handler));
+       ColorsChanged.connect (mem_fun (*this, &TimeAxisView::color_handler));
 }
 
 TimeAxisView::~TimeAxisView()
 {
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
-               delete *i;
-       }
-
        for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
                delete (*i)->rect;
                delete (*i)->start_trim;
@@ -220,11 +220,14 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
        order = nth;
        _hidden = false;
        
+       /* height in pixels depends on _order, so update it now we've changed _order */
+       set_height (height_style);
+       
        effective_height = height;
 
        /* now show children */
        
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                
                if ((*i)->marked_for_display()) {
                        (*i)->canvas_display->show();
@@ -284,18 +287,8 @@ TimeAxisView::controls_ebox_button_release (GdkEventButton* ev)
 void
 TimeAxisView::selection_click (GdkEventButton* ev)
 {
-       if (Keyboard::modifier_state_contains (ev->state, Keyboard::Shift)) {
-
-               if (editor.get_selection().selected (this)) {
-                       editor.get_selection().remove (this);
-               } else {
-                       editor.get_selection().add (this);
-               }
-
-       } else {
-
-               editor.get_selection().set (this);
-       }
+       Selection::Operation op = Keyboard::selection_type (ev->state);
+       editor.set_selected_track (*this, op, false);
 }
 
 void
@@ -318,7 +311,7 @@ TimeAxisView::hide ()
        
        /* now hide children */
        
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->hide ();
        }
        
@@ -370,7 +363,7 @@ void
 TimeAxisView::set_height_pixels (uint32_t h)
 {
        height = h;
-       controls_frame.set_size_request (-1, height);
+       controls_frame.set_size_request (-1, height + ((order == 0) ? 1 : 0));
 
        if (canvas_item_visible (selection_group)) {
                /* resize the selection rect */
@@ -381,8 +374,48 @@ TimeAxisView::set_height_pixels (uint32_t h)
 bool
 TimeAxisView::name_entry_key_release (GdkEventKey* ev)
 {
+       PublicEditor::TrackViewList *allviews = 0;
+       PublicEditor::TrackViewList::iterator i;
+
        switch (ev->keyval) {
+       case GDK_Escape:
+               name_entry.select_region (0,0);
+               controls_ebox.grab_focus ();
+               name_entry_changed ();
+               return true;
+
+       /* Shift+Tab Keys Pressed. Note that for Shift+Tab, GDK actually
+        * generates a different ev->keyval, rather than setting 
+        * ev->state.
+        */
+       case GDK_ISO_Left_Tab:
        case GDK_Tab:
+               name_entry_changed ();
+               allviews = editor.get_valid_views (0);
+               if (allviews != 0) {
+                       i = find (allviews->begin(), allviews->end(), this);
+                       if (ev->keyval == GDK_Tab) {
+                               if (i != allviews->end()) {
+                                       do {
+                                               if (++i == allviews->end()) { return true; }
+                                       } while((*i)->hidden());
+                               }
+                       } else {
+                               if (i != allviews->begin()) {
+                                       do {
+                                               if (--i == allviews->begin()) { return true; }
+                                       } while ((*i)->hidden());
+                               }
+                       }
+
+                       if ((*i)->height_style == Small) {
+                               (*i)->set_height(Smaller);
+                       }
+                       
+                       (*i)->name_entry.grab_focus();
+               }
+               return true;
+
        case GDK_Up:
        case GDK_Down:
                name_entry_changed ();
@@ -432,6 +465,7 @@ TimeAxisView::name_entry_focus_out (GdkEventFocus* ev)
        last_name_entry_key_press_event = 0;
        name_entry_key_timeout.disconnect ();
        name_entry.set_name ("EditorTrackNameDisplay");
+       name_entry.select_region (0,0);
        
        /* do the real stuff */
 
@@ -483,12 +517,18 @@ TimeAxisView::popup_display_menu (guint32 when)
        if (display_menu == 0) {
                build_display_menu ();
        }
+
+       if (!get_selected()) {
+               editor.set_selected_track (*this, Selection::Set);
+       }
+
        display_menu->popup (1, when);  
 }
 
 gint
 TimeAxisView::size_click (GdkEventButton *ev)
 {
+       editor.set_selected_track (*this, Selection::Add);
        popup_size_menu (ev->time);
        return TRUE;
 }
@@ -505,12 +545,16 @@ TimeAxisView::popup_size_menu (guint32 when)
 void
 TimeAxisView::set_selected (bool yn)
 {
-       AxisView::set_selected (yn);
+       if (yn == _selected) {
+               return;
+       }
+       
+       Selectable::set_selected (yn);
 
        if (_selected) {
                controls_ebox.set_name (controls_base_selected_name);
                controls_frame.set_name (controls_base_selected_name);
-
+               
                /* propagate any existing selection, if the mode is right */
 
                if (editor.current_mouse_mode() == Editing::MouseRange && !editor.get_selection().time.empty()) {
@@ -528,11 +572,9 @@ TimeAxisView::set_selected (bool yn)
                   have to do this here.
                */
 
-               for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+               for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                        (*i)->set_selected (false);
                }
-
-               
        }
 }
 
@@ -567,15 +609,15 @@ TimeAxisView::build_display_menu ()
 void
 TimeAxisView::set_samples_per_unit (double spu)
 {
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->set_samples_per_unit (spu);
        }
 }
 
 void
-TimeAxisView::show_timestretch (jack_nframes_t start, jack_nframes_t end)
+TimeAxisView::show_timestretch (nframes_t start, nframes_t end)
 {
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->show_timestretch (start, end);
        }
 }
@@ -583,7 +625,7 @@ TimeAxisView::show_timestretch (jack_nframes_t start, jack_nframes_t end)
 void
 TimeAxisView::hide_timestretch ()
 {
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->hide_timestretch ();
        }
 }
@@ -596,7 +638,7 @@ TimeAxisView::show_selection (TimeSelection& ts)
        double y2;
        SelectionRect *rect;
 
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->show_selection (ts);
        }
 
@@ -615,7 +657,7 @@ TimeAxisView::show_selection (TimeSelection& ts)
        selection_group->raise_to_top();
        
        for (list<AudioRange>::iterator i = ts.begin(); i != ts.end(); ++i) {
-               jack_nframes_t start, end, cnt;
+               nframes_t start, end, cnt;
 
                start = (*i).start;
                end = (*i).end;
@@ -660,11 +702,9 @@ TimeAxisView::show_selection (TimeSelection& ts)
 void
 TimeAxisView::reshow_selection (TimeSelection& ts)
 {
-       cerr << name() << ": reshow selection" << endl;
-
        show_selection (ts);
 
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->show_selection (ts);
        }
 }
@@ -683,7 +723,7 @@ TimeAxisView::hide_selection ()
                selection_group->hide();
        }
        
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->hide_selection ();
        }
 }
@@ -728,8 +768,9 @@ TimeAxisView::get_selection_rect (uint32_t id)
 
        for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
                if ((*i)->id == id) {
+                       SelectionRect* ret = (*i);
                        free_selection_rects.erase (i);
-                       return (*i);
+                       return ret;
                }
        }
 
@@ -744,20 +785,20 @@ TimeAxisView::get_selection_rect (uint32_t id)
                rect->rect->property_y1() = 0.0;
                rect->rect->property_x2() = 0.0;
                rect->rect->property_y2() = 0.0;
-               rect->rect->property_fill_color_rgba() = color_map[cSelectionRectFill];
-               rect->rect->property_outline_color_rgba() = color_map[cSelectionRectOutline];
+               rect->rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectionRect.get();
+               rect->rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
                
                rect->start_trim = new SimpleRect (*selection_group);
                rect->start_trim->property_x1() = 0.0;
                rect->start_trim->property_x2() = 0.0;
-               rect->start_trim->property_fill_color_rgba() = color_map[cSelectionStartFill];
-               rect->start_trim->property_outline_color_rgba() = color_map[cSelectionStartOutline];
+               rect->start_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+               rect->start_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
                
                rect->end_trim = new SimpleRect (*selection_group);
                rect->end_trim->property_x1() = 0.0;
                rect->end_trim->property_x2() = 0.0;
-               rect->end_trim->property_fill_color_rgba() = color_map[cSelectionEndFill];
-               rect->end_trim->property_outline_color_rgba() = color_map[cSelectionEndOutline];
+               rect->end_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+               rect->end_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
 
                free_selection_rects.push_front (rect);
 
@@ -772,22 +813,24 @@ TimeAxisView::get_selection_rect (uint32_t id)
        return rect;
 }
 
+struct null_deleter { void operator()(void const *) const {} };
+
 bool
 TimeAxisView::is_child (TimeAxisView* tav)
 {
-       return find (children.begin(), children.end(), tav) != children.end();
+       return find (children.begin(), children.end(), boost::shared_ptr<TimeAxisView>(tav, null_deleter())) != children.end();
 }
 
 void
-TimeAxisView::add_child (TimeAxisView* child)
+TimeAxisView::add_child (boost::shared_ptr<TimeAxisView> child)
 {
        children.push_back (child);
 }
 
 void
-TimeAxisView::remove_child (TimeAxisView* child)
+TimeAxisView::remove_child (boost::shared_ptr<TimeAxisView> child)
 {
-       vector<TimeAxisView*>::iterator i;
+       Children::iterator i;
 
        if ((i = find (children.begin(), children.end(), child)) != children.end()) {
                children.erase (i);
@@ -795,7 +838,7 @@ TimeAxisView::remove_child (TimeAxisView* child)
 }
 
 void
-TimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable*>& result)
+TimeAxisView::get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable*>& result)
 {
        return;
 }
@@ -813,7 +856,7 @@ TimeAxisView::touched (double top, double bot)
           y_position is the "origin" or "top" of the track.
         */
 
-       double mybot = y_position + height; // XXX need to include Editor::track_spacing; 
+       double mybot = y_position + height;
        
        return ((y_position <= bot && y_position >= top) || 
                ((mybot <= bot) && (top < mybot)) || 
@@ -880,8 +923,8 @@ TimeAxisView::reset_height()
 {
        set_height_pixels (height);
 
-       for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
-               (*i)->set_height ((TrackHeight)(*i)->height);
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
+               (*i)->set_height_pixels ((TrackHeight)(*i)->height);
        }
 }
        
@@ -935,12 +978,10 @@ TimeAxisView::compute_controls_size_info ()
                buttons[i]->set_name ("TrackMuteButton");
        }
 
-       Gtk::Requisition req;
-
        one_row_table.attach (*buttons[0], 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
        
        one_row_table.show_all ();
-       one_row_table.size_request (req);
+       Gtk::Requisition req(one_row_table.size_request ());
 
 
        // height required to show 1 row of buttons
@@ -956,7 +997,7 @@ TimeAxisView::compute_controls_size_info ()
        two_row_table.attach (*buttons[4], 8, 9, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
 
        two_row_table.show_all ();
-       two_row_table.size_request (req);
+       req = two_row_table.size_request ();
 
        // height required to show all normal buttons 
 
@@ -1015,22 +1056,52 @@ TimeAxisView::hide_name_entry ()
 }
 
 void
-TimeAxisView::color_handler (ColorID id, uint32_t val)
+TimeAxisView::color_handler ()
 {
-       switch (id) {
-       case cSelectionRectFill:
-               break;
-       case cSelectionRectOutline:
-               break;
-       case cSelectionStartFill:
-               break;
-       case cSelectionStartOutline:
-               break;
-       case cSelectionEndFill:
-               break;
-       case cSelectionEndOutline:
-               break;
-       default:
-               break;
+       
+       for (list<SelectionRect*>::iterator i = used_selection_rects.begin(); i != used_selection_rects.end(); ++i) {
+
+               (*i)->rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectionRect.get();
+               (*i)->rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+
+               (*i)->start_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+               (*i)->start_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+
+               (*i)->end_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+               (*i)->end_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+       }
+
+       for (list<SelectionRect*>::iterator i = free_selection_rects.begin(); i != free_selection_rects.end(); ++i) {
+
+               (*i)->rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectionRect.get();
+               (*i)->rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+
+               (*i)->start_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+               (*i)->start_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+
+               (*i)->end_trim->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
+               (*i)->end_trim->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_Selection.get();
        }
 }
+
+TimeAxisView*
+TimeAxisView::covers_y_position (double y)
+{
+       if (hidden()) {
+               return 0;
+       }
+
+       if (y_position <= y && y < (y_position + height)) {
+               return this;
+       }
+
+       for (Children::iterator i = children.begin(); i != children.end(); ++i) {
+               TimeAxisView* tv;
+
+               if ((tv = (*i)->covers_y_position (y)) != 0) {
+                       return tv;
+               }
+       }
+
+       return 0;
+}