2 Copyright (C) 2000-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <gtkmm2ext/barcontroller.h>
22 #include "pbd/memento_command.h"
23 #include "ardour/automation_control.h"
24 #include "ardour/event_type_map.h"
25 #include "ardour/route.h"
26 #include "ardour/session.h"
28 #include "ardour_ui.h"
29 #include "automation_time_axis.h"
30 #include "automation_streamview.h"
31 #include "route_time_axis.h"
32 #include "automation_line.h"
33 #include "public_editor.h"
34 #include "simplerect.h"
35 #include "selection.h"
36 #include "rgb_macros.h"
37 #include "automation_selectable.h"
38 #include "point_selection.h"
39 #include "canvas_impl.h"
45 using namespace ARDOUR;
48 using namespace Gtkmm2ext;
49 using namespace Editing;
51 Pango::FontDescription* AutomationTimeAxisView::name_font = 0;
52 bool AutomationTimeAxisView::have_name_font = false;
53 const string AutomationTimeAxisView::state_node_name = "AutomationChild";
56 /** \a a the automatable object this time axis is to display data for.
57 * For route/track automation (e.g. gain) pass the route for both \r and \a.
58 * For route child (e.g. plugin) automation, pass the child for \a.
59 * For region automation (e.g. MIDI CC), pass null for \a.
61 AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
62 boost::shared_ptr<Automatable> a, boost::shared_ptr<AutomationControl> c,
63 PublicEditor& e, TimeAxisView& parent, bool show_regions,
64 ArdourCanvas::Canvas& canvas, const string & nom, const string & nomparent)
66 TimeAxisView (s, e, &parent, canvas),
70 _controller(AutomationController::create(a, c->parameter(), c)),
72 _view (show_regions ? new AutomationStreamView(*this) : NULL),
74 auto_button (X_("")) /* force addition of a label */
76 if (!have_name_font) {
77 name_font = get_font_for_style (X_("AutomationTrackName"));
78 have_name_font = true;
86 mode_discrete_item = 0;
89 ignore_state_request = false;
90 first_call_to_set_height = true;
92 _base_rect = new SimpleRect(*_canvas_display);
93 _base_rect->property_x1() = 0.0;
94 _base_rect->property_y1() = 0.0;
95 _base_rect->property_x2() = LONG_MAX - 2;
96 _base_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackOutline.get();
98 /* outline ends and bottom */
99 _base_rect->property_outline_what() = (guint32) (0x1|0x2|0x8);
100 _base_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_AutomationTrackFill.get();
102 _base_rect->set_data ("trackview", this);
104 _base_rect->signal_event().connect (bind (
105 mem_fun (_editor, &PublicEditor::canvas_automation_track_event),
109 _base_rect->lower_to_bottom();
112 hide_button.add (*(manage (new Gtk::Image (::get_icon("hide")))));
114 auto_button.set_name ("TrackVisualButton");
115 hide_button.set_name ("TrackRemoveButton");
117 auto_button.unset_flags (Gtk::CAN_FOCUS);
118 hide_button.unset_flags (Gtk::CAN_FOCUS);
120 controls_table.set_no_show_all();
122 ARDOUR_UI::instance()->tooltips().set_tip(auto_button, _("automation state"));
123 ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("hide track"));
125 /* rearrange the name display */
127 /* we never show these for automation tracks, so make
128 life easier and remove them.
133 /* move the name label over a bit */
135 string shortpname = _name;
136 bool shortened = false;
139 shortpname = fit_to_pixels (_name, 60, *name_font, ignore_width, true);
141 if (shortpname != _name ){
145 name_label.set_text (shortpname);
146 name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
148 if (nomparent.length()) {
150 /* limit the plug name string */
152 string pname = fit_to_pixels (nomparent, 60, *name_font, ignore_width, true);
153 if (pname != nomparent) {
157 plugname = new Label (pname);
158 plugname->set_name (X_("TrackPlugName"));
160 name_label.set_name (X_("TrackParameterName"));
161 controls_table.remove (name_hbox);
162 controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
163 plugname_packed = true;
164 controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
167 plugname_packed = false;
171 string tipname = nomparent;
172 if (!tipname.empty()) {
176 ARDOUR_UI::instance()->tooltips().set_tip(controls_ebox, tipname);
179 /* add the buttons */
180 controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
182 controls_table.attach (auto_button, 5, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
184 /* add bar controller */
185 controls_table.attach (*_controller.get(), 0, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
187 controls_table.show_all ();
189 hide_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::hide_clicked));
190 auto_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::auto_clicked));
192 controls_base_selected_name = X_("AutomationTrackControlsBaseSelected");
193 controls_base_unselected_name = X_("AutomationTrackControlsBase");
194 controls_ebox.set_name (controls_base_unselected_name);
196 XMLNode* xml_node = get_parent_with_state()->get_automation_child_xml_node (
197 _control->parameter());
200 set_state (*xml_node, Stateful::loading_state_version);
203 /* ask for notifications of any new RegionViews */
209 /* no regions, just a single line for the entire track (e.g. bus gain) */
211 boost::shared_ptr<AutomationLine> line(new AutomationLine (
212 ARDOUR::EventTypeMap::instance().to_symbol(_control->parameter()),
217 line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
218 line->queue_reset ();
222 /* make sure labels etc. are correct */
224 automation_state_changed ();
225 ColorsChanged.connect (mem_fun (*this, &AutomationTimeAxisView::color_handler));
228 AutomationTimeAxisView::~AutomationTimeAxisView ()
233 AutomationTimeAxisView::auto_clicked ()
235 using namespace Menu_Helpers;
237 if (automation_menu == 0) {
238 automation_menu = manage (new Menu);
239 automation_menu->set_name ("ArdourContextMenu");
240 MenuList& items (automation_menu->items());
242 items.push_back (MenuElem (_("Manual"), bind (mem_fun(*this,
243 &AutomationTimeAxisView::set_automation_state), (AutoState) Off)));
244 items.push_back (MenuElem (_("Play"), bind (mem_fun(*this,
245 &AutomationTimeAxisView::set_automation_state), (AutoState) Play)));
246 items.push_back (MenuElem (_("Write"), bind (mem_fun(*this,
247 &AutomationTimeAxisView::set_automation_state), (AutoState) Write)));
248 items.push_back (MenuElem (_("Touch"), bind (mem_fun(*this,
249 &AutomationTimeAxisView::set_automation_state), (AutoState) Touch)));
252 automation_menu->popup (1, gtk_get_current_event_time());
256 AutomationTimeAxisView::set_automation_state (AutoState state)
258 if (!ignore_state_request) {
260 _automatable->set_parameter_automation_state (_control->parameter(), state);
263 if (_route == _automatable) { // This is a time axis for route (not region) automation
264 _route->set_parameter_automation_state (_control->parameter(), state);
267 if (_control->list())
268 _control->alist()->set_automation_state(state);
273 _view->set_automation_state (state);
278 AutomationTimeAxisView::automation_state_changed ()
282 /* update button label */
287 state = _control->alist()->automation_state ();
290 switch (state & (Off|Play|Touch|Write)) {
292 auto_button.set_label (_("Manual"));
294 ignore_state_request = true;
295 auto_off_item->set_active (true);
296 auto_play_item->set_active (false);
297 auto_touch_item->set_active (false);
298 auto_write_item->set_active (false);
299 ignore_state_request = false;
303 auto_button.set_label (_("Play"));
304 if (auto_play_item) {
305 ignore_state_request = true;
306 auto_play_item->set_active (true);
307 auto_off_item->set_active (false);
308 auto_touch_item->set_active (false);
309 auto_write_item->set_active (false);
310 ignore_state_request = false;
314 auto_button.set_label (_("Write"));
315 if (auto_write_item) {
316 ignore_state_request = true;
317 auto_write_item->set_active (true);
318 auto_off_item->set_active (false);
319 auto_play_item->set_active (false);
320 auto_touch_item->set_active (false);
321 ignore_state_request = false;
325 auto_button.set_label (_("Touch"));
326 if (auto_touch_item) {
327 ignore_state_request = true;
328 auto_touch_item->set_active (true);
329 auto_off_item->set_active (false);
330 auto_play_item->set_active (false);
331 auto_write_item->set_active (false);
332 ignore_state_request = false;
336 auto_button.set_label (_("???"));
342 AutomationTimeAxisView::interpolation_changed ()
344 AutomationList::InterpolationStyle style = _control->list()->interpolation();
346 if (mode_line_item && mode_discrete_item) {
347 if (style == AutomationList::Discrete) {
348 mode_discrete_item->set_active(true);
349 mode_line_item->set_active(false);
351 mode_line_item->set_active(true);
352 mode_discrete_item->set_active(false);
357 _line->set_interpolation(style);
362 AutomationTimeAxisView::set_interpolation (AutomationList::InterpolationStyle style)
364 _control->list()->set_interpolation(style);
366 _line->set_interpolation(style);
371 AutomationTimeAxisView::clear_clicked ()
373 _session.begin_reversible_command (_("clear automation"));
377 _session.commit_reversible_command ();
381 AutomationTimeAxisView::set_height (uint32_t h)
383 bool changed = (height != (uint32_t) h) || first_call_to_set_height;
384 bool changed_between_small_and_normal = (
385 (height < hNormal && h >= hNormal)
386 || (height >= hNormal || h < hNormal) );
388 TimeAxisView* state_parent = get_parent_with_state ();
389 assert(state_parent);
390 XMLNode* xml_node = state_parent->get_automation_child_xml_node (_control->parameter());
392 TimeAxisView::set_height (h);
393 _base_rect->property_y2() = h;
396 _line->set_height(h);
399 _view->set_height(h);
400 _view->update_contents_height();
404 snprintf (buf, sizeof (buf), "%u", height);
406 xml_node->add_property ("height", buf);
409 if (changed_between_small_and_normal || first_call_to_set_height) {
411 first_call_to_set_height = false;
414 controls_table.remove (name_hbox);
417 if (plugname_packed) {
418 controls_table.remove (*plugname);
419 plugname_packed = false;
421 controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
422 plugname_packed = true;
423 controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
425 controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
429 name_hbox.show_all ();
432 hide_button.show_all();
434 } else if (h >= hSmall) {
435 controls_table.remove (name_hbox);
437 if (plugname_packed) {
438 controls_table.remove (*plugname);
439 plugname_packed = false;
442 controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
443 controls_table.hide_all ();
446 name_hbox.show_all ();
451 } else if (h >= hNormal){
452 cerr << "track grown, but neither changed_between_small_and_normal nor first_call_to_set_height set!" << endl;
456 /* only emit the signal if the height really changed */
457 _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
462 AutomationTimeAxisView::set_samples_per_unit (double spu)
464 TimeAxisView::set_samples_per_unit (spu);
470 _view->set_samples_per_unit (spu);
474 AutomationTimeAxisView::hide_clicked ()
476 // LAME fix for refreshing the hide button
477 hide_button.set_sensitive(false);
479 set_marked_for_display (false);
482 hide_button.set_sensitive(true);
486 AutomationTimeAxisView::build_display_menu ()
488 using namespace Menu_Helpers;
490 /* get the size menu ready */
496 TimeAxisView::build_display_menu ();
498 /* now fill it with our stuff */
500 MenuList& items = display_menu->items();
502 items.push_back (MenuElem (_("Height"), *size_menu));
503 items.push_back (SeparatorElem());
504 items.push_back (MenuElem (_("Hide"), mem_fun(*this, &AutomationTimeAxisView::hide_clicked)));
505 items.push_back (SeparatorElem());
506 items.push_back (MenuElem (_("Clear"), mem_fun(*this, &AutomationTimeAxisView::clear_clicked)));
507 items.push_back (SeparatorElem());
511 Menu* auto_state_menu = manage (new Menu);
512 auto_state_menu->set_name ("ArdourContextMenu");
513 MenuList& as_items = auto_state_menu->items();
515 as_items.push_back (CheckMenuElem (_("Manual"), bind (
516 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
518 auto_off_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
520 as_items.push_back (CheckMenuElem (_("Play"), bind (
521 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
523 auto_play_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
525 as_items.push_back (CheckMenuElem (_("Write"), bind (
526 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
527 (AutoState) Write)));
528 auto_write_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
530 as_items.push_back (CheckMenuElem (_("Touch"), bind (
531 mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
532 (AutoState) Touch)));
533 auto_touch_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
535 items.push_back (MenuElem (_("State"), *auto_state_menu));
539 if (EventTypeMap::instance().is_midi_parameter(_control->parameter())) {
541 Menu* auto_mode_menu = manage (new Menu);
542 auto_mode_menu->set_name ("ArdourContextMenu");
543 MenuList& am_items = auto_mode_menu->items();
545 RadioMenuItem::Group group;
547 am_items.push_back (RadioMenuElem (group, _("Discrete"), bind (
548 mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
549 AutomationList::Discrete)));
550 mode_discrete_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
551 mode_discrete_item->set_active(_control->list()->interpolation() == AutomationList::Discrete);
553 am_items.push_back (RadioMenuElem (group, _("Linear"), bind (
554 mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
555 AutomationList::Linear)));
556 mode_line_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
558 // Set default interpolation type to linear if this isn't a (usually) discrete controller
559 if (EventTypeMap::instance().interpolation_of(_control->parameter()) == Evoral::ControlList::Linear) {
560 mode_line_item->set_active(_control->list()->interpolation() == AutomationList::Linear);
563 items.push_back (MenuElem (_("Mode"), *auto_mode_menu));
566 /* make sure the automation menu state is correct */
568 automation_state_changed ();
569 interpolation_changed ();
573 AutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* /*item*/, GdkEvent* /*event*/, nframes_t when, double y)
580 _canvas_display->w2i (x, y);
582 /* compute vertical fractional position */
584 y = 1.0 - (y / height);
588 _line->view_to_model_coord (x, y);
590 _session.begin_reversible_command (_("add automation event"));
591 XMLNode& before = _control->alist()->get_state();
593 _control->alist()->add (when, y);
595 XMLNode& after = _control->alist()->get_state();
596 _session.commit_reversible_command (new MementoCommand<ARDOUR::AutomationList>(*_control->alist(), &before, &after));
598 _session.set_dirty ();
602 AutomationTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
604 return (_line ? cut_copy_clear_one (*_line, selection, op) : false);
608 AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& selection, CutCopyOp op)
610 boost::shared_ptr<Evoral::ControlList> what_we_got;
611 boost::shared_ptr<AutomationList> alist (line.the_list());
614 XMLNode &before = alist->get_state();
618 if ((what_we_got = alist->cut (selection.time.front().start, selection.time.front().end)) != 0) {
619 _editor.get_cut_buffer().add (what_we_got);
620 _session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
625 if ((what_we_got = alist->copy (selection.time.front().start, selection.time.front().end)) != 0) {
626 _editor.get_cut_buffer().add (what_we_got);
631 if ((what_we_got = alist->cut (selection.time.front().start, selection.time.front().end)) != 0) {
632 _session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
639 for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
640 double when = (*x)->when;
641 double val = (*x)->value;
642 line.model_to_view_coord (when, val);
652 AutomationTimeAxisView::reset_objects (PointSelection& selection)
654 reset_objects_one (*_line, selection);
658 AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection& selection)
660 boost::shared_ptr<AutomationList> alist(line.the_list());
662 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), &alist->get_state(), 0));
664 for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
666 if (&(*i).track != this) {
670 alist->reset_range ((*i).start, (*i).end);
675 AutomationTimeAxisView::cut_copy_clear_objects (PointSelection& selection, CutCopyOp op)
677 return cut_copy_clear_objects_one (*_line, selection, op);
681 AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointSelection& selection, CutCopyOp op)
683 boost::shared_ptr<Evoral::ControlList> what_we_got;
684 boost::shared_ptr<AutomationList> alist(line.the_list());
687 XMLNode &before = alist->get_state();
689 for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
691 if (&(*i).track != this) {
697 if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
698 _editor.get_cut_buffer().add (what_we_got);
699 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
704 if ((what_we_got = alist->copy ((*i).start, (*i).end)) != 0) {
705 _editor.get_cut_buffer().add (what_we_got);
710 if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
711 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
721 for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
722 double when = (*x)->when;
723 double val = (*x)->value;
724 line.model_to_view_coord (when, val);
734 AutomationTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size_t nth)
736 return paste_one (*_line, pos, times, selection, nth);
740 AutomationTimeAxisView::paste_one (AutomationLine& line, nframes_t pos, float times, Selection& selection, size_t nth)
742 AutomationSelection::iterator p;
743 boost::shared_ptr<AutomationList> alist(line.the_list());
745 for (p = selection.lines.begin(); p != selection.lines.end() && nth; ++p, --nth) {}
747 if (p == selection.lines.end()) {
751 /* Make a copy of the list because we have to scale the
752 values from view coordinates to model coordinates, and we're
753 not supposed to modify the points in the selection.
756 AutomationList copy (**p);
758 for (AutomationList::iterator x = copy.begin(); x != copy.end(); ++x) {
759 double when = (*x)->when;
760 double val = (*x)->value;
761 line.view_to_model_coord (when, val);
766 XMLNode &before = alist->get_state();
767 alist->paste (copy, pos, times);
768 _session.add_command (new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
774 AutomationTimeAxisView::get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable*>& results)
776 if (_line && touched (top, bot)) {
780 /* remember: this is X Window - coordinate space starts in upper left and moves down.
781 _y_position is the "origin" or "top" of the track.
784 double mybot = _y_position + height;
786 if (_y_position >= top && mybot <= bot) {
788 /* _y_position is below top, mybot is above bot, so we're fully
797 /* top and bot are within _y_position .. mybot */
799 topfrac = 1.0 - ((top - _y_position) / height);
800 botfrac = 1.0 - ((bot - _y_position) / height);
804 _line->get_selectables (start, end, botfrac, topfrac, results);
809 AutomationTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& result)
812 _line->get_inverted_selectables (sel, result);
816 AutomationTimeAxisView::set_selected_points (PointSelection& points)
819 _line->set_selected_points (points);
823 AutomationTimeAxisView::clear_lines ()
826 automation_connection.disconnect ();
830 AutomationTimeAxisView::add_line (boost::shared_ptr<AutomationLine> line)
834 assert(line->the_list() == _control->list());
836 automation_connection = _control->alist()->automation_state_changed.connect
837 (mem_fun(*this, &AutomationTimeAxisView::automation_state_changed));
840 //_controller = AutomationController::create(_session, line->the_list(), _control);
842 line->set_height (height);
844 /* pick up the current state */
845 automation_state_changed ();
851 AutomationTimeAxisView::entered()
854 _line->track_entered();
858 AutomationTimeAxisView::exited ()
861 _line->track_exited();
865 AutomationTimeAxisView::color_handler ()
873 AutomationTimeAxisView::set_state (const XMLNode& node, int version)
875 TimeAxisView::set_state (node, version);
877 XMLProperty const * type = node.property ("automation-id");
878 if (type && type->value () == ARDOUR::EventTypeMap::instance().to_symbol (_control->parameter())) {
879 XMLProperty const * shown = node.property ("shown");
880 if (shown && shown->value () == "yes") {
881 set_marked_for_display (true);
882 _canvas_display->show (); /* FIXME: necessary? show_at? */
886 if (!_marked_for_display) {
894 AutomationTimeAxisView::get_state_node ()
896 TimeAxisView* state_parent = get_parent_with_state ();
899 return state_parent->get_automation_child_xml_node (_control->parameter());
906 AutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
908 XMLNode* xml_node = get_state_node();
910 xml_node->add_property ("shown", editor_shown ? "yes" : "no");
915 AutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
917 update_extra_xml_shown (true);
919 return TimeAxisView::show_at (y, nth, parent);
923 AutomationTimeAxisView::hide ()
925 update_extra_xml_shown (false);
927 TimeAxisView::hide ();