Fix restore of track visibility from state files (#3245)
[ardour.git] / gtk2_ardour / time_axis_view.cc
index c797389b870363de6cfea94dd5170f6e991cb585..978ce6debba905a3eb99df60f7f7f7f4bebbcd9a 100644 (file)
 #include <libgnomecanvasmm/item.h>
 
 #include "pbd/error.h"
+#include "pbd/convert.h"
 
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/selector.h>
-#include <gtkmm2ext/stop_signal.h>
 
 #include "ardour/session.h"
 #include "ardour/utils.h"
@@ -65,14 +65,8 @@ using namespace ArdourCanvas;
 using Gtkmm2ext::Keyboard;
 
 const double trim_handle_size = 6.0; /* pixels */
-
-uint32_t TimeAxisView::hLargest = 0;
-uint32_t TimeAxisView::hLarge = 0;
-uint32_t TimeAxisView::hLarger = 0;
-uint32_t TimeAxisView::hNormal = 0;
-uint32_t TimeAxisView::hSmaller = 0;
-uint32_t TimeAxisView::hSmall = 0;
-bool TimeAxisView::need_size_info = true;
+uint32_t TimeAxisView::extra_height;
+uint32_t TimeAxisView::smaller_height;
 int const TimeAxisView::_max_order = 512;
 PBD::Signal1<void,TimeAxisView*> TimeAxisView::CatchDeletion;
 
@@ -83,12 +77,13 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
          _editor (ed),
          _order (0)
 {
-       if (need_size_info) {
-               compute_controls_size_info ();
-               need_size_info = false;
+       if (extra_height == 0) {
+               compute_heights ();
        }
+       
        _canvas_background = new Group (*ed.get_background_group (), 0.0, 0.0);
        _canvas_display = new Group (*ed.get_trackview_group (), 0.0, 0.0);
+       _canvas_display->hide(); // reveal as needed 
 
        selection_group = new Group (*_canvas_display);
        selection_group->hide();
@@ -99,7 +94,6 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
 
        control_parent = 0;
        display_menu = 0;
-       size_menu = 0;
        _hidden = false;
        in_destructor = false;
        height = 0;
@@ -145,12 +139,13 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        controls_table.show_all ();
        controls_table.set_no_show_all ();
 
-       resizer.set_size_request (10, 10);
+       resizer.set_size_request (10, 6);
        resizer.set_name ("ResizeHandle");
        resizer.signal_expose_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_expose));
        resizer.signal_button_press_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_button_press));
        resizer.signal_button_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_button_release));
        resizer.signal_motion_notify_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_motion));
+
        resizer.set_events (Gdk::BUTTON_PRESS_MASK|
                        Gdk::BUTTON_RELEASE_MASK|
                        Gdk::POINTER_MOTION_MASK|
@@ -163,8 +158,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        HSeparator* separator = manage (new HSeparator());
 
        controls_vbox.pack_start (controls_table, false, false);
-       controls_vbox.pack_end (*separator, false, false);
-       controls_vbox.pack_end (resizer_box, false, true);
+       controls_vbox.pack_end (resizer_box, false, false);
        controls_vbox.show ();
 
        //controls_ebox.set_name ("TimeAxisViewControlsBaseUnselected");
@@ -175,12 +169,16 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
        controls_ebox.signal_button_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::controls_ebox_button_release));
        controls_ebox.signal_scroll_event().connect (sigc::mem_fun (*this, &TimeAxisView::controls_ebox_scroll), true);
 
-       controls_hbox.pack_start (controls_ebox,true,true);
+       controls_hbox.pack_start (controls_ebox, false, false);
        controls_hbox.show ();
 
+       time_axis_vbox.pack_start (controls_hbox, true, true);
+       time_axis_vbox.pack_end (*separator, false, false);
+       time_axis_vbox.show();
+
        ColorsChanged.connect (sigc::mem_fun (*this, &TimeAxisView::color_handler));
 
-       GhostRegion::CatchDeletion.connect (*this, ui_bind (&TimeAxisView::erase_ghost, this, _1), gui_context());
+       GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&TimeAxisView::erase_ghost, this, _1), gui_context());
 }
 
 TimeAxisView::~TimeAxisView()
@@ -232,11 +230,11 @@ guint32
 TimeAxisView::show_at (double y, int& nth, VBox *parent)
 {
        if (control_parent) {
-               control_parent->reorder_child (controls_hbox, nth);
+               control_parent->reorder_child (time_axis_vbox, nth);
        } else {
                control_parent = parent;
-               parent->pack_start (controls_hbox, false, false);
-               parent->reorder_child (controls_hbox, nth);
+               parent->pack_start (time_axis_vbox, false, false);
+               parent->reorder_child (time_axis_vbox, nth);
        }
 
        _order = nth;
@@ -255,7 +253,7 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
        _canvas_display->raise_to_top ();
 
        if (_marked_for_display) {
-               controls_hbox.show ();
+               time_axis_vbox.show ();
                controls_ebox.show ();
                _canvas_background->show ();
        }
@@ -270,7 +268,7 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
                if (canvas_item_visible ((*i)->_canvas_display)) {
                        ++nth;
                        _effective_height += (*i)->show_at (y + _effective_height, nth, parent);
-               }
+               } 
        }
 
        return _effective_height;
@@ -361,7 +359,7 @@ TimeAxisView::hide ()
        _canvas_background->hide ();
 
        if (control_parent) {
-               control_parent->remove (controls_hbox);
+               control_parent->remove (time_axis_vbox);
                control_parent = 0;
        }
 
@@ -390,9 +388,9 @@ TimeAxisView::step_height (bool bigger)
                set_height (height + step);
        } else {
                if (height > step) {
-                       set_height (std::max (height - step, hSmall));
-               } else if (height != hSmall) {
-                       set_height (hSmall);
+                       set_height (std::max (height - step, preset_height (HeightSmall)));
+               } else if (height != preset_height (HeightSmall)) {
+                       set_height (HeightSmall);
                }
        }
 }
@@ -407,10 +405,16 @@ TimeAxisView::set_heights (uint32_t h)
        }
 }
 
+void
+TimeAxisView::set_height (Height h)
+{
+       set_height (preset_height (h));
+}
+
 void
 TimeAxisView::set_height(uint32_t h)
 {
-       controls_ebox.property_height_request () = h;
+       time_axis_vbox.property_height_request () = h;
        height = h;
 
        for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
@@ -469,8 +473,8 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev)
                
                /* resize to show editable name display */
                
-               if ((*i)->current_height() <= hSmaller) {
-                       (*i)->set_height (hSmaller);
+               if ((*i)->current_height() <= preset_height (HeightSmaller)) {
+                       (*i)->set_height (HeightSmaller);
                }
                
                (*i)->name_entry.grab_focus();
@@ -593,23 +597,6 @@ TimeAxisView::popup_display_menu (guint32 when)
        display_menu->popup (1, when);
 }
 
-gint
-TimeAxisView::size_click (GdkEventButton *ev)
-{
-       conditionally_add_to_selection ();
-       popup_size_menu (ev->time);
-       return TRUE;
-}
-
-void
-TimeAxisView::popup_size_menu (guint32 when)
-{
-       if (size_menu == 0) {
-               build_size_menu ();
-       }
-       size_menu->popup (1, when);
-}
-
 void
 TimeAxisView::set_selected (bool yn)
 {
@@ -621,11 +608,11 @@ TimeAxisView::set_selected (bool yn)
 
        if (_selected) {
                controls_ebox.set_name (controls_base_selected_name);
-               controls_hbox.set_name (controls_base_selected_name);
+               time_axis_vbox.set_name (controls_base_selected_name);
                controls_vbox.set_name (controls_base_selected_name);
        } else {
                controls_ebox.set_name (controls_base_unselected_name);
-               controls_hbox.set_name (controls_base_unselected_name);
+               time_axis_vbox.set_name (controls_base_unselected_name);
                controls_vbox.set_name (controls_base_unselected_name);
                hide_selection ();
 
@@ -642,23 +629,6 @@ TimeAxisView::set_selected (bool yn)
        resizer.queue_draw ();
 }
 
-void
-TimeAxisView::build_size_menu ()
-{
-       using namespace Menu_Helpers;
-
-       size_menu = new Menu;
-       size_menu->set_name ("ArdourContextMenu");
-       MenuList& items = size_menu->items();
-
-       items.push_back (MenuElem (_("Largest"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_heights), hLargest)));
-       items.push_back (MenuElem (_("Large"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_heights), hLarge)));
-       items.push_back (MenuElem (_("Larger"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_heights), hLarger)));
-       items.push_back (MenuElem (_("Normal"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_heights), hNormal)));
-       items.push_back (MenuElem (_("Smaller"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_heights),hSmaller)));
-       items.push_back (MenuElem (_("Small"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_heights), hSmall)));
-}
-
 void
 TimeAxisView::build_display_menu ()
 {
@@ -998,6 +968,8 @@ TimeAxisView::get_parent_with_state ()
 XMLNode&
 TimeAxisView::get_state ()
 {
+       /* XXX: is this method used? */
+       
        XMLNode* node = new XMLNode ("TAV-" + name());
        char buf[32];
 
@@ -1012,27 +984,32 @@ TimeAxisView::set_state (const XMLNode& node, int /*version*/)
 {
        const XMLProperty *prop;
 
+       /* XXX: I think this might be vestigial */
        if ((prop = node.property ("marked-for-display")) != 0) {
                _marked_for_display = (prop->value() == "1");
        }
 
+       if ((prop = node.property ("shown-editor")) != 0) {
+               _marked_for_display = string_is_affirmative (prop->value ());
+       }
+
        if ((prop = node.property ("track-height")) != 0) {
 
                if (prop->value() == "largest") {
-                       set_height (hLargest);
+                       set_height (HeightLargest);
                } else if (prop->value() == "large") {
-                       set_height (hLarge);
+                       set_height (HeightLarge);
                } else if (prop->value() == "larger") {
-                       set_height (hLarger);
+                       set_height (HeightLarger);
                } else if (prop->value() == "normal") {
-                       set_height (hNormal);
+                       set_height (HeightNormal);
                } else if (prop->value() == "smaller") {
-                       set_height (hSmaller);
+                       set_height (HeightSmaller);
                } else if (prop->value() == "small") {
-                       set_height (hSmall);
+                       set_height (HeightSmall);
                } else {
                        error << string_compose(_("unknown track height name \"%1\" in XML GUI information"), prop->value()) << endmsg;
-                       set_height (Normal);
+                       set_height (HeightNormal);
                }
 
        } else if ((prop = node.property ("height")) != 0) {
@@ -1041,7 +1018,7 @@ TimeAxisView::set_state (const XMLNode& node, int /*version*/)
 
        } else {
 
-               set_height (hNormal);
+               set_height (HeightNormal);
        }
 
        return 0;
@@ -1058,14 +1035,14 @@ TimeAxisView::reset_height()
 }
 
 void
-TimeAxisView::compute_controls_size_info ()
+TimeAxisView::compute_heights ()
 {
        Gtk::Window window (Gtk::WINDOW_TOPLEVEL);
        Gtk::Table two_row_table (2, 8);
        Gtk::Table one_row_table (1, 8);
        Button* buttons[5];
        const int border_width = 2;
-       const int extra_height = (2 * border_width)
+       extra_height = (2 * border_width)
                //+ 2   // 2 pixels for the hseparator between TimeAxisView control areas
                + 10; // resizer button (3 x 2 pixel elements + 2 x 2 pixel gaps)
 
@@ -1091,36 +1068,9 @@ TimeAxisView::compute_controls_size_info ()
        one_row_table.show_all ();
        Gtk::Requisition req(one_row_table.size_request ());
 
-
        // height required to show 1 row of buttons
 
-       hSmaller = req.height + extra_height;
-
-       window.remove ();
-       window.add (two_row_table);
-
-       two_row_table.attach (*buttons[1], 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
-       two_row_table.attach (*buttons[2], 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
-       two_row_table.attach (*buttons[3], 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
-       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 ();
-       req = two_row_table.size_request ();
-
-       // height required to show all normal buttons
-
-       hNormal = /*req.height*/ 48 + extra_height;
-
-       // these heights are all just larger than normal. no more
-       // elements are visible (yet).
-
-       hLarger = hNormal + 50;
-       hLarge = hNormal + 150;
-       hLargest = hNormal + 250;
-
-       // height required to show track name
-
-       hSmall = 27;
+       smaller_height = req.height + extra_height;
 }
 
 void
@@ -1305,13 +1255,11 @@ TimeAxisView::idle_resize (uint32_t h)
 bool
 TimeAxisView::resizer_motion (GdkEventMotion* ev)
 {
-       if (_resize_drag_start < 0) {
-               return true;
-       }
-
-       int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
-       _editor.add_to_idle_resize (this, delta);
-       _resize_drag_start = ev->y_root;
+       if (_resize_drag_start >= 0) {
+                int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
+                _editor.add_to_idle_resize (this, delta);
+                _resize_drag_start = ev->y_root;
+        }
 
        return true;
 }
@@ -1347,13 +1295,47 @@ TimeAxisView::resizer_expose (GdkEventExpose* event)
        win->draw_line (light, 1, 5, w - 1, 5);
        win->draw_point (light, w - 1, 4);
 
-       /* handle/line #3 */
-
-       win->draw_line (dark, 0, 8, w - 2, 8);
-       win->draw_point (dark, 0, 9);
-       win->draw_line (light, 1, 9, w - 1, 9);
-       win->draw_point (light, w - 1, 8);
+       /* use vertical resize mouse cursor */
+       win->set_cursor(Gdk::Cursor(Gdk::SB_V_DOUBLE_ARROW));
 
        return true;
 }
 
+bool
+TimeAxisView::set_visibility (bool yn)
+{
+       if (yn != marked_for_display()) {
+               if (yn) {
+                       set_marked_for_display (true);
+                       canvas_display()->show();
+               } else {
+                       set_marked_for_display (false);
+                       hide ();
+               }
+               return true; // things changed
+       }
+       
+       return false;
+}
+
+uint32_t
+TimeAxisView::preset_height (Height h)
+{
+       switch (h) {
+       case HeightLargest:
+               return extra_height + 48 + 250;
+       case HeightLarger:
+               return extra_height + 48 + 150;
+       case HeightLarge:
+               return extra_height + 48 + 50;
+       case HeightNormal:
+               return extra_height + 48;
+       case HeightSmall:
+               return 27;
+       case HeightSmaller:
+               return smaller_height;
+       }
+
+       /* NOTREACHED */
+       return 0;
+}