NOOP, re-indent, remove trailing whitespace, sort includes
[ardour.git] / gtk2_ardour / time_axis_view.cc
index 059776bd92606326561f855021d0f67c6661fee8..2923f630761454ab405a0511dd7fd8817c0d28c1 100644 (file)
@@ -36,6 +36,8 @@
 #include "canvas/rectangle.h"
 #include "canvas/debug.h"
 
+#include "ardour/profile.h"
+
 #include "ardour_ui.h"
 #include "ardour_dialog.h"
 #include "global_signals.h"
@@ -58,20 +60,26 @@ using namespace std;
 using namespace Gtk;
 using namespace Gdk;
 using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
 using namespace PBD;
 using namespace Editing;
 using namespace ArdourCanvas;
 using Gtkmm2ext::Keyboard;
 
+#define TOP_LEVEL_WIDGET controls_ebox
+
 const double trim_handle_size = 6.0; /* pixels */
 uint32_t TimeAxisView::button_height = 0;
 uint32_t TimeAxisView::extra_height = 0;
 int const TimeAxisView::_max_order = 512;
+unsigned int TimeAxisView::name_width_px = 100; // TODO adjust with font-scaling on style-change
 PBD::Signal1<void,TimeAxisView*> TimeAxisView::CatchDeletion;
+Glib::RefPtr<Gtk::SizeGroup> TimeAxisView::controls_meters_size_group = Glib::RefPtr<Gtk::SizeGroup>();
 
 TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisView* rent, Canvas& /*canvas*/)
        : AxisView (sess)
-       , controls_table (2, 8)
+       , controls_table (3, 3)
+       , controls_button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_BOTH))
        , _name_editing (false)
        , height (0)
        , display_menu (0)
@@ -93,61 +101,72 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        , _have_preresize_cursor (false)
        , _ebox_release_can_act (true)
 {
+       if (!controls_meters_size_group) {
+               controls_meters_size_group = SizeGroup::create (SIZE_GROUP_HORIZONTAL);
+       }
        if (extra_height == 0) {
                compute_heights ();
        }
 
-       _canvas_display = new Group (ed.get_trackview_group (), ArdourCanvas::Duple (0.0, 0.0));
+       _canvas_display = new ArdourCanvas::Container (ed.get_trackview_group (), ArdourCanvas::Duple (1.0, 0.0));
        CANVAS_DEBUG_NAME (_canvas_display, "main for TAV");
        _canvas_display->hide(); // reveal as needed
 
-       selection_group = new Group (_canvas_display);
+       _canvas_separator = new ArdourCanvas::Line(ed.get_trackview_group ());
+       CANVAS_DEBUG_NAME (_canvas_separator, "separator for TAV");
+       _canvas_separator->set_outline_color(RGBA_TO_UINT (0, 0, 0, 255));
+       _canvas_separator->set_outline_width(1.0);
+       _canvas_separator->hide();
+
+       selection_group = new ArdourCanvas::Container (_canvas_display);
        CANVAS_DEBUG_NAME (selection_group, "selection for TAV");
        selection_group->set_data (X_("timeselection"), (void *) 1);
        selection_group->hide();
-
-       _ghost_group = new Group (_canvas_display);
+       
+       _ghost_group = new ArdourCanvas::Container (_canvas_display);
        CANVAS_DEBUG_NAME (_ghost_group, "ghost for TAV");
        _ghost_group->lower_to_bottom();
        _ghost_group->show();
 
        name_label.set_name ("TrackLabel");
        name_label.set_alignment (0.0, 0.5);
+       name_label.set_width_chars (12);
        ARDOUR_UI::instance()->set_tip (name_label, _("Track/Bus name (double click to edit)"));
 
        Gtk::Entry* an_entry = new Gtk::Entry;
        Gtk::Requisition req;
        an_entry->size_request (req);
        name_label.set_size_request (-1, req.height);
+       name_label.set_ellipsize (Pango::ELLIPSIZE_MIDDLE);
        delete an_entry;
 
-       name_hbox.pack_start (name_label, true, true);
+       name_hbox.pack_end (name_label, true, true);
+
+       // set min. track-header width if fader is not visible
+       name_hbox.set_size_request(name_width_px, -1);
+
        name_hbox.show ();
        name_label.show ();
-       
-       controls_table.set_size_request (200);
+
        controls_table.set_row_spacings (2);
        controls_table.set_col_spacings (2);
        controls_table.set_border_width (2);
-       controls_table.set_homogeneous (true);
 
-       controls_table.attach (name_hbox, 0, 5, 0, 1,  Gtk::FILL|Gtk::EXPAND,  Gtk::FILL|Gtk::EXPAND, 3, 0);
+       if (ARDOUR::Profile->get_mixbus() ) {
+               controls_table.attach (name_hbox, 4, 5, 0, 2,  Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK, 0, 0);
+       } else {
+               controls_table.attach (name_hbox, 1, 2, 0, 2,  Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK, 0, 0);
+       }
        controls_table.show_all ();
        controls_table.set_no_show_all ();
 
-       HSeparator* separator = manage (new HSeparator());
-       separator->set_name("TrackSeparator");
-       separator->set_size_request(-1, 1);
-       separator->show();
-
        controls_vbox.pack_start (controls_table, false, false);
        controls_vbox.show ();
 
-       controls_hbox.pack_start (controls_vbox, true, true);
-       controls_hbox.show ();
+       top_hbox.pack_start (controls_vbox, true, true);
+       top_hbox.show ();
 
-       //controls_ebox.set_name ("TimeAxisViewControlsBaseUnselected");
-       controls_ebox.add (controls_hbox);
+       controls_ebox.add (time_axis_hbox);
        controls_ebox.add_events (Gdk::BUTTON_PRESS_MASK|
                                  Gdk::BUTTON_RELEASE_MASK|
                                  Gdk::POINTER_MOTION_MASK|
@@ -164,9 +183,20 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        controls_ebox.signal_leave_notify_event().connect (sigc::mem_fun (*this, &TimeAxisView::controls_ebox_leave));
        controls_ebox.show ();
 
-       time_axis_vbox.pack_start (controls_ebox, true, true, 0);
-       time_axis_vbox.pack_end (*separator, false, false);
+       time_axis_frame.set_shadow_type (Gtk::SHADOW_NONE);
+       time_axis_frame.add(top_hbox);
+       time_axis_frame.show();
+
+       HSeparator* separator = manage (new HSeparator());
+       separator->set_name("TrackSeparator");
+       separator->set_size_request(-1, 1);
+       separator->show();
+
+       time_axis_vbox.pack_start (*separator, false, false);
+       time_axis_vbox.pack_start (time_axis_frame, true, true);
        time_axis_vbox.show();
+       time_axis_hbox.pack_start (time_axis_vbox, true, true);
+       time_axis_hbox.show();
 
        ColorsChanged.connect (sigc::mem_fun (*this, &TimeAxisView::color_handler));
 
@@ -200,6 +230,9 @@ TimeAxisView::~TimeAxisView()
        delete _canvas_display;
        _canvas_display = 0;
 
+       delete _canvas_separator;
+       _canvas_separator = 0;
+
        delete display_menu;
        display_menu = 0;
 
@@ -214,9 +247,10 @@ TimeAxisView::hide ()
        }
 
        _canvas_display->hide ();
+       _canvas_separator->hide ();
 
        if (control_parent) {
-               control_parent->remove (time_axis_vbox);
+               control_parent->remove (TOP_LEVEL_WIDGET);
                control_parent = 0;
        }
 
@@ -248,24 +282,27 @@ guint32
 TimeAxisView::show_at (double y, int& nth, VBox *parent)
 {
        if (control_parent) {
-               control_parent->reorder_child (time_axis_vbox, nth);
+               control_parent->reorder_child (TOP_LEVEL_WIDGET, nth);
        } else {
                control_parent = parent;
-               parent->pack_start (time_axis_vbox, false, false);
-               parent->reorder_child (time_axis_vbox, nth);
+               parent->pack_start (TOP_LEVEL_WIDGET, false, false);
+               parent->reorder_child (TOP_LEVEL_WIDGET, nth);
        }
 
        _order = nth;
 
        if (_y_position != y) {
-               _canvas_display->set_y_position (y);
+               _canvas_separator->set (ArdourCanvas::Duple(0, y), ArdourCanvas::Duple(ArdourCanvas::COORD_MAX, y));
+               _canvas_display->set_y_position (y + 1);
                _y_position = y;
-
        }
 
        _canvas_display->raise_to_top ();
        _canvas_display->show ();
 
+       _canvas_separator->raise_to_top ();
+       _canvas_separator->show ();
+
        _hidden = false;
 
        _effective_height = current_height ();
@@ -287,6 +324,36 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
 bool
 TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
 {
+       switch (ev->direction) {
+       case GDK_SCROLL_UP:
+               if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
+                       /* See Editor::_stepping_axis_view for notes on this hack */
+                       Editor& e = dynamic_cast<Editor&> (_editor);
+                       if (!e.stepping_axis_view ()) {
+                               e.set_stepping_axis_view (this);
+                       }
+                       e.stepping_axis_view()->step_height (false);
+                       return true;
+               } 
+               break;
+
+       case GDK_SCROLL_DOWN:
+               if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
+                       /* See Editor::_stepping_axis_view for notes on this hack */
+                       Editor& e = dynamic_cast<Editor&> (_editor);
+                       if (!e.stepping_axis_view ()) {
+                               e.set_stepping_axis_view (this);
+                       }
+                       e.stepping_axis_view()->step_height (true);
+                       return true;
+               } 
+               break;
+
+       default:
+               /* no handling for left/right, yet */
+               break;
+       }
+
        /* Just forward to the normal canvas scroll method. The coordinate
           systems are different but since the canvas is always larger than the
           track headers, and aligned with the trackview area, this will work.
@@ -294,7 +361,7 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev)
           In the not too distant future this layout is going away anyway and
           headers will be on the canvas.
        */
-       return _editor.canvas_scroll_event (ev);
+       return _editor.canvas_scroll_event (ev, false);
 }
 
 bool
@@ -480,7 +547,7 @@ TimeAxisView::set_height (uint32_t h)
                h = preset_height (HeightSmall);
        }
 
-       time_axis_vbox.property_height_request () = h;
+       TOP_LEVEL_WIDGET.property_height_request () = h;
        height = h;
 
        char buf[32];
@@ -559,6 +626,8 @@ TimeAxisView::begin_name_edit ()
 
                name_entry = manage (new Gtkmm2ext::FocusEntry);
                
+               name_entry->set_width_chars(8); // min width, entry expands
+
                name_entry->set_name ("EditorTrackNameDisplay");
                name_entry->signal_key_press_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_key_press), false);
                name_entry->signal_key_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_key_release), false);
@@ -570,7 +639,7 @@ TimeAxisView::begin_name_edit ()
                        name_hbox.remove (name_label);
                }
                
-               name_hbox.pack_start (*name_entry);
+               name_hbox.pack_end (*name_entry, true, true);
                name_entry->show ();
 
                name_entry->select_region (0, -1);
@@ -615,7 +684,7 @@ TimeAxisView::end_name_edit (int response)
 
        /* put the name label back */
 
-       name_hbox.pack_start (name_label);
+       name_hbox.pack_end (name_label);
        name_label.show ();
 
        if (edit_next) {
@@ -644,7 +713,7 @@ TimeAxisView::end_name_edit (int response)
                }
 
                if ((i != allviews.end()) && (*i != this) && !(*i)->hidden()) {
-                       _editor.ensure_time_axis_view_is_visible (**i);
+                       _editor.ensure_time_axis_view_is_visible (**i, false);
                        (*i)->begin_name_edit ();
                } 
 
@@ -675,7 +744,7 @@ TimeAxisView::end_name_edit (int response)
                }
                
                if ((i != allviews.end()) && (*i != this) && !(*i)->hidden()) {
-                       _editor.ensure_time_axis_view_is_visible (**i);
+                       _editor.ensure_time_axis_view_is_visible (**i, false);
                        (*i)->begin_name_edit ();
                } 
        }
@@ -714,6 +783,10 @@ TimeAxisView::popup_display_menu (guint32 when)
 void
 TimeAxisView::set_selected (bool yn)
 {
+       if (can_edit_name() && name_entry && name_entry->get_visible()) {
+               end_name_edit (RESPONSE_CANCEL);
+       }
+
        if (yn == _selected) {
                return;
        }
@@ -721,13 +794,18 @@ TimeAxisView::set_selected (bool yn)
        Selectable::set_selected (yn);
 
        if (_selected) {
+               time_axis_frame.set_shadow_type (Gtk::SHADOW_IN);
+               time_axis_frame.set_name ("MixerStripSelectedFrame");
                controls_ebox.set_name (controls_base_selected_name);
-               time_axis_vbox.set_name (controls_base_selected_name);
                controls_vbox.set_name (controls_base_selected_name);
+               time_axis_vbox.set_name (controls_base_selected_name);
        } else {
+               time_axis_frame.set_shadow_type (Gtk::SHADOW_NONE);
+               time_axis_frame.set_name (controls_base_unselected_name);
                controls_ebox.set_name (controls_base_unselected_name);
-               time_axis_vbox.set_name (controls_base_unselected_name);
                controls_vbox.set_name (controls_base_unselected_name);
+               time_axis_vbox.set_name (controls_base_unselected_name);
+
                hide_selection ();
 
                /* children will be set for the yn=true case. but when deselecting
@@ -739,6 +817,9 @@ TimeAxisView::set_selected (bool yn)
                        (*i)->set_selected (false);
                }
        }
+
+       time_axis_frame.show();
+
 }
 
 void
@@ -784,7 +865,8 @@ TimeAxisView::show_selection (TimeSelection& ts)
        double x1;
        double x2;
        double y2;
-       SelectionRect *rect;
+       SelectionRect *rect;    time_axis_frame.show();
+
 
        for (Children::iterator i = children.begin(); i != children.end(); ++i) {
                (*i)->show_selection (ts);
@@ -816,14 +898,14 @@ TimeAxisView::show_selection (TimeSelection& ts)
 
                x1 = _editor.sample_to_pixel (start);
                x2 = _editor.sample_to_pixel (start + cnt - 1);
-               y2 = current_height();
+               y2 = current_height() - 1;
 
-               rect->rect->set (ArdourCanvas::Rect (x1, 1, x2, y2));
+               rect->rect->set (ArdourCanvas::Rect (x1, 0, x2, y2));
 
                // trim boxes are at the top for selections
 
                if (x2 > x1) {
-                       rect->start_trim->set (ArdourCanvas::Rect (x1, 1, x1 + trim_handle_size, y2));
+                       rect->start_trim->set (ArdourCanvas::Rect (x1, 0, x1 + trim_handle_size, y2));
                        rect->end_trim->set (ArdourCanvas::Rect (x2 - trim_handle_size, 1, x2, y2));
 
                        rect->start_trim->show();
@@ -925,12 +1007,12 @@ TimeAxisView::get_selection_rect (uint32_t id)
                rect->rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SelectionRect());
 
                rect->start_trim = new ArdourCanvas::Rectangle (selection_group);
-               CANVAS_DEBUG_NAME (rect->rect, "selection rect start trim");
+               CANVAS_DEBUG_NAME (rect->start_trim, "selection rect start trim");
                rect->start_trim->set_outline (false);
                rect->start_trim->set_fill (false);
 
                rect->end_trim = new ArdourCanvas::Rectangle (selection_group);
-               CANVAS_DEBUG_NAME (rect->rect, "selection rect end trim");
+               CANVAS_DEBUG_NAME (rect->end_trim, "selection rect end trim");
                rect->end_trim->set_outline (false);
                rect->end_trim->set_fill (false);
 
@@ -1054,38 +1136,27 @@ TimeAxisView::reset_height ()
 void
 TimeAxisView::compute_heights ()
 {
+       // TODO this function should be re-evaluated when font-scaling changes (!)
        Gtk::Window window (Gtk::WINDOW_TOPLEVEL);
-       Gtk::Table two_row_table (2, 8);
-       Gtk::Table one_row_table (1, 8);
-       Button* buttons[5];
+       Gtk::Table one_row_table (1, 1);
+       ArdourButton* test_button = manage (new ArdourButton);
        const int border_width = 2;
-
-       const int separator_height = 2;
-       extra_height = (2 * border_width) + separator_height;
+       const int frame_height = 2;
+       extra_height = (2 * border_width) + frame_height;
 
        window.add (one_row_table);
+       test_button->set_name ("mute button");
+       test_button->set_text (_("M"));
+       test_button->set_tweaks (ArdourButton::TrackHeader);
 
        one_row_table.set_border_width (border_width);
-       one_row_table.set_row_spacings (0);
-       one_row_table.set_col_spacings (0);
-       one_row_table.set_homogeneous (true);
-
-       two_row_table.set_border_width (border_width);
-       two_row_table.set_row_spacings (0);
-       two_row_table.set_col_spacings (0);
-       two_row_table.set_homogeneous (true);
-
-       for (int i = 0; i < 5; ++i) {
-               buttons[i] = manage (new Button (X_("f")));
-               buttons[i]->set_name ("TrackMuteButton");
-       }
-
-       one_row_table.attach (*buttons[0], 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
+       one_row_table.set_row_spacings (2);
+       one_row_table.set_col_spacings (2);
 
+       one_row_table.attach (*test_button, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
        one_row_table.show_all ();
-       Gtk::Requisition req(one_row_table.size_request ());
 
-       // height required to show 1 row of buttons
+       Gtk::Requisition req(one_row_table.size_request ());
        button_height = req.height;
 }