introduce GUIObjectState; massive, pervasive changes in visibility and height management for track displays in the editor

git-svn-id: svn://localhost/ardour2/branches/3.0@9796 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-07-07 00:37:13 +00:00
parent d5bb729755
commit 10cb0a7646
31 changed files with 678 additions and 579 deletions

View file

@ -91,6 +91,7 @@ typedef uint64_t microseconds_t;
#include "engine_dialog.h" #include "engine_dialog.h"
#include "gain_meter.h" #include "gain_meter.h"
#include "global_port_matrix.h" #include "global_port_matrix.h"
#include "gui_object.h"
#include "gui_thread.h" #include "gui_thread.h"
#include "keyboard.h" #include "keyboard.h"
#include "location_ui.h" #include "location_ui.h"
@ -133,6 +134,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
: Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp) : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp)
, gui_object_state (new GUIObjectState)
, primary_clock (new AudioClock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true)) , primary_clock (new AudioClock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true))
, secondary_clock (new AudioClock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true)) , secondary_clock (new AudioClock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true))
, preroll_clock (new AudioClock (X_("preroll"), false, X_("PreRollClock"), true, false, true)) , preroll_clock (new AudioClock (X_("preroll"), false, X_("PreRollClock"), true, false, true))
@ -293,7 +295,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
keyboard = new ArdourKeyboard(*this); keyboard = new ArdourKeyboard(*this);
XMLNode* node = ARDOUR_UI::instance()->keyboard_settings(); XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();
if (node) { if (node) {
keyboard->set_state (*node, Stateful::loading_state_version); keyboard->set_state (*node, Stateful::loading_state_version);
@ -2195,6 +2196,8 @@ ARDOUR_UI::save_state (const string & name, bool switch_to_it)
} }
} }
node->add_child_nocopy (gui_object_state->get_state());
_session->add_extra_xml (*node); _session->add_extra_xml (*node);
save_state_canfail (name, switch_to_it); save_state_canfail (name, switch_to_it);

View file

@ -90,6 +90,7 @@ class TimeInfoBox;
class MidiTracer; class MidiTracer;
class WindowProxyBase; class WindowProxyBase;
class GlobalPortMatrixWindow; class GlobalPortMatrixWindow;
class GUIObjectState;
namespace Gtkmm2ext { namespace Gtkmm2ext {
class TearOff; class TearOff;
@ -193,6 +194,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void xrun_handler (framepos_t); void xrun_handler (framepos_t);
void create_xrun_marker (framepos_t); void create_xrun_marker (framepos_t);
GUIObjectState* gui_object_state;
AudioClock* primary_clock; AudioClock* primary_clock;
AudioClock* secondary_clock; AudioClock* secondary_clock;
AudioClock* preroll_clock; AudioClock* preroll_clock;

View file

@ -31,6 +31,7 @@
#include "ardour_ui.h" #include "ardour_ui.h"
#include "bundle_manager.h" #include "bundle_manager.h"
#include "global_port_matrix.h" #include "global_port_matrix.h"
#include "gui_object.h"
#include "gui_thread.h" #include "gui_thread.h"
#include "keyeditor.h" #include "keyeditor.h"
#include "location_ui.h" #include "location_ui.h"
@ -63,6 +64,14 @@ ARDOUR_UI::set_session (Session *s)
return; return;
} }
const XMLNodeList& children = _session->extra_xml (X_("UI"))->children();
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == GUIObjectState::xml_node_name) {
gui_object_state->load (**i);
break;
}
}
if (location_ui->get()) { if (location_ui->get()) {
location_ui->get()->set_session(s); location_ui->get()->set_session(s);
} }

View file

@ -750,8 +750,8 @@ ARDOUR_UI::save_ardour_state ()
Config->save_state(); Config->save_state();
ui_config->save_state (); ui_config->save_state ();
XMLNode enode(static_cast<Stateful*>(editor)->get_state()); XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
XMLNode mnode(mixer->get_state()); XMLNode& mnode (mixer->get_state());
if (_session) { if (_session) {
_session->add_instant_xml (enode); _session->add_instant_xml (enode);

View file

@ -77,10 +77,17 @@ using namespace PBD;
using namespace Gtk; using namespace Gtk;
using namespace Editing; using namespace Editing;
AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session* sess, boost::shared_ptr<Route> rt, Canvas& canvas) AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas)
: AxisView(sess) : AxisView(sess)
, RouteTimeAxisView(ed, sess, rt, canvas) , RouteTimeAxisView(ed, sess, canvas)
{ {
}
void
AudioTimeAxisView::set_route (boost::shared_ptr<Route> rt)
{
RouteTimeAxisView::set_route (rt);
// Make sure things are sane... // Make sure things are sane...
assert(!is_track() || is_audio_track()); assert(!is_track() || is_audio_track());
@ -99,10 +106,6 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
controls_ebox.set_name ("AudioBusControlsBaseUnselected"); controls_ebox.set_name ("AudioBusControlsBaseUnselected");
} }
ensure_xml_node ();
set_state (*xml_node, Stateful::loading_state_version);
/* if set_state above didn't create a gain automation child, we need to make one */ /* if set_state above didn't create a gain automation child, we need to make one */
if (automation_child (GainAutomation) == 0) { if (automation_child (GainAutomation) == 0) {
create_automation_child (GainAutomation, false); create_automation_child (GainAutomation, false);
@ -156,18 +159,14 @@ AudioTimeAxisView::audio_view()
guint32 guint32
AudioTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent) AudioTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
{ {
ensure_xml_node (); set_gui_property ("visible", "yes");
xml_node->add_property ("shown-editor", "yes");
return TimeAxisView::show_at (y, nth, parent); return TimeAxisView::show_at (y, nth, parent);
} }
void void
AudioTimeAxisView::hide () AudioTimeAxisView::hide ()
{ {
ensure_xml_node (); set_gui_property ("visible", "no");
xml_node->add_property ("shown-editor", "no");
TimeAxisView::hide (); TimeAxisView::hide ();
} }
@ -204,10 +203,10 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
* since it will have been set visible by default. * since it will have been set visible by default.
*/ */
existing->second->set_visibility (show); existing->second->set_marked_for_display (show);
if (!no_redraw) { if (!no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
return; return;
@ -221,7 +220,6 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
param.type() == PanElevationAutomation || param.type() == PanElevationAutomation ||
param.type() == PanAzimuthAutomation) { param.type() == PanAzimuthAutomation) {
ensure_xml_node ();
ensure_pan_views (show); ensure_pan_views (show);
} else if (param.type() == PluginAutomation) { } else if (param.type() == PluginAutomation) {
@ -286,8 +284,8 @@ AudioTimeAxisView::update_gain_track_visibility ()
{ {
bool const showit = gain_automation_item->get_active(); bool const showit = gain_automation_item->get_active();
if (showit != gain_track->marked_for_display()) { if (showit != string_is_affirmative (gain_track->gui_property ("visible"))) {
gain_track->set_visibility (showit); gain_track->set_marked_for_display (showit);
/* now trigger a redisplay */ /* now trigger a redisplay */
@ -301,17 +299,17 @@ void
AudioTimeAxisView::update_pan_track_visibility () AudioTimeAxisView::update_pan_track_visibility ()
{ {
bool const showit = pan_automation_item->get_active(); bool const showit = pan_automation_item->get_active();
bool changed = false;
for (list<boost::shared_ptr<AutomationTimeAxisView> >::iterator i = pan_tracks.begin(); i != pan_tracks.end(); ++i) { for (list<boost::shared_ptr<AutomationTimeAxisView> >::iterator i = pan_tracks.begin(); i != pan_tracks.end(); ++i) {
if ((*i)->set_marked_for_display (showit)) {
if (showit != (*i)->marked_for_display()) { changed = true;
(*i)->set_visibility (showit);
/* now trigger a redisplay */
if (!no_redraw) {
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
}
} }
} }
if (changed) {
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
}
} }
void void
@ -326,8 +324,7 @@ AudioTimeAxisView::show_all_automation (bool apply_to_selection)
RouteTimeAxisView::show_all_automation (); RouteTimeAxisView::show_all_automation ();
no_redraw = false; no_redraw = false;
request_redraw ();
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
} }
} }
@ -343,7 +340,7 @@ AudioTimeAxisView::show_existing_automation (bool apply_to_selection)
no_redraw = false; no_redraw = false;
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -358,7 +355,7 @@ AudioTimeAxisView::hide_all_automation (bool apply_to_selection)
RouteTimeAxisView::hide_all_automation(); RouteTimeAxisView::hide_all_automation();
no_redraw = false; no_redraw = false;
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -462,13 +459,15 @@ AudioTimeAxisView::build_automation_action_menu (bool for_selection)
automation_items.push_back (CheckMenuElem (_("Fader"), sigc::mem_fun (*this, &AudioTimeAxisView::update_gain_track_visibility))); automation_items.push_back (CheckMenuElem (_("Fader"), sigc::mem_fun (*this, &AudioTimeAxisView::update_gain_track_visibility)));
gain_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ()); gain_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ());
gain_automation_item->set_active (gain_track->marked_for_display () && (!for_selection || _editor.get_selection().tracks.size() == 1)); gain_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
string_is_affirmative (gain_track->gui_property ("visible")));
_main_automation_menu_map[Evoral::Parameter(GainAutomation)] = gain_automation_item; _main_automation_menu_map[Evoral::Parameter(GainAutomation)] = gain_automation_item;
automation_items.push_back (CheckMenuElem (_("Pan"), sigc::mem_fun (*this, &AudioTimeAxisView::update_pan_track_visibility))); automation_items.push_back (CheckMenuElem (_("Pan"), sigc::mem_fun (*this, &AudioTimeAxisView::update_pan_track_visibility)));
pan_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ()); pan_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ());
pan_automation_item->set_active (pan_tracks.front()->marked_for_display () && (!for_selection || _editor.get_selection().tracks.size() == 1)); pan_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
string_is_affirmative (pan_tracks.front()->gui_property ("visible")));
set<Evoral::Parameter> const & params = _route->pannable()->what_can_be_automated (); set<Evoral::Parameter> const & params = _route->pannable()->what_can_be_automated ();
for (set<Evoral::Parameter>::iterator p = params.begin(); p != params.end(); ++p) { for (set<Evoral::Parameter>::iterator p = params.begin(); p != params.end(); ++p) {

View file

@ -65,9 +65,11 @@ class AutomationTimeAxisView;
class AudioTimeAxisView : public RouteTimeAxisView class AudioTimeAxisView : public RouteTimeAxisView
{ {
public: public:
AudioTimeAxisView (PublicEditor&, ARDOUR::Session*, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas); AudioTimeAxisView (PublicEditor&, ARDOUR::Session*, ArdourCanvas::Canvas& canvas);
virtual ~AudioTimeAxisView (); virtual ~AudioTimeAxisView ();
void set_route (boost::shared_ptr<ARDOUR::Route>);
AudioStreamView* audio_view(); AudioStreamView* audio_view();
void set_show_waveforms_recording (bool yn); void set_show_waveforms_recording (bool yn);

View file

@ -54,7 +54,6 @@ using namespace Editing;
Pango::FontDescription AutomationTimeAxisView::name_font; Pango::FontDescription AutomationTimeAxisView::name_font;
bool AutomationTimeAxisView::have_name_font = false; bool AutomationTimeAxisView::have_name_font = false;
const string AutomationTimeAxisView::state_node_name = "AutomationChild";
/** \a a the automatable object this time axis is to display data for. /** \a a the automatable object this time axis is to display data for.
@ -142,6 +141,13 @@ AutomationTimeAxisView::AutomationTimeAxisView (
ARDOUR_UI::instance()->set_tip(auto_button, _("automation state")); ARDOUR_UI::instance()->set_tip(auto_button, _("automation state"));
ARDOUR_UI::instance()->set_tip(hide_button, _("hide track")); ARDOUR_UI::instance()->set_tip(hide_button, _("hide track"));
string str = gui_property ("height");
if (!str.empty()) {
set_height (atoi (str));
} else {
set_height (preset_height (HeightNormal));
}
/* rearrange the name display */ /* rearrange the name display */
/* we never show these for automation tracks, so make /* we never show these for automation tracks, so make
@ -186,12 +192,6 @@ AutomationTimeAxisView::AutomationTimeAxisView (
controls_base_unselected_name = X_("AutomationTrackControlsBase"); controls_base_unselected_name = X_("AutomationTrackControlsBase");
controls_ebox.set_name (controls_base_unselected_name); controls_ebox.set_name (controls_base_unselected_name);
XMLNode* xml_node = get_state_node ();
if (xml_node) {
set_state (*xml_node, Stateful::loading_state_version);
}
/* ask for notifications of any new RegionViews */ /* ask for notifications of any new RegionViews */
if (show_regions) { if (show_regions) {
@ -403,19 +403,8 @@ AutomationTimeAxisView::set_height (uint32_t h)
uint32_t const normal = preset_height (HeightNormal); uint32_t const normal = preset_height (HeightNormal);
bool const changed_between_small_and_normal = ( (height < normal && h >= normal) || (height >= normal || h < normal) ); bool const changed_between_small_and_normal = ( (height < normal && h >= normal) || (height >= normal || h < normal) );
TimeAxisView* state_parent = get_parent_with_state ();
assert(state_parent);
XMLNode* xml_node = 0;
if (_control) {
xml_node = _control->extra_xml ("GUI");
} else {
/* XXX we need somewhere to store GUI info for per-region
* automation
*/
}
TimeAxisView::set_height (h); TimeAxisView::set_height (h);
_base_rect->property_y2() = h; _base_rect->property_y2() = h;
if (_line) { if (_line) {
@ -427,12 +416,6 @@ AutomationTimeAxisView::set_height (uint32_t h)
_view->update_contents_height(); _view->update_contents_height();
} }
char buf[32];
snprintf (buf, sizeof (buf), "%u", height);
if (xml_node) {
xml_node->add_property ("height", buf);
}
if (changed_between_small_and_normal || first_call_to_set_height) { if (changed_between_small_and_normal || first_call_to_set_height) {
first_call_to_set_height = false; first_call_to_set_height = false;
@ -483,12 +466,12 @@ AutomationTimeAxisView::set_samples_per_unit (double spu)
void void
AutomationTimeAxisView::hide_clicked () AutomationTimeAxisView::hide_clicked ()
{ {
// LAME fix for refreshing the hide button
hide_button.set_sensitive(false); hide_button.set_sensitive(false);
set_marked_for_display (false); set_marked_for_display (false);
hide (); RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(parent);
if (rtv) {
rtv->request_redraw ();
}
hide_button.set_sensitive(true); hide_button.set_sensitive(true);
} }
@ -951,61 +934,30 @@ AutomationTimeAxisView::color_handler ()
} }
int int
AutomationTimeAxisView::set_state (const XMLNode& node, int version) AutomationTimeAxisView::set_state_2X (const XMLNode& node, int /*version*/)
{ {
TimeAxisView::set_state (node, version); if (node.name() == X_("gain") && _parameter == Evoral::Parameter (GainAutomation)) {
XMLProperty const * shown = node.property (X_("shown"));
if (version < 3000) { if (shown) {
return set_state_2X (node, version); bool yn = string_is_affirmative (shown->value ());
} if (yn) {
_canvas_display->show (); /* FIXME: necessary? show_at? */
XMLProperty const * prop = node.property ("shown"); }
set_gui_property ("visible", (yn ? "yes" : "no"));
if (prop) { } else {
set_visibility (string_is_affirmative (prop->value())); set_gui_property ("visible", "no");
} else { }
set_visibility (false);
} }
return 0; return 0;
} }
int int
AutomationTimeAxisView::set_state_2X (const XMLNode& node, int /*version*/) AutomationTimeAxisView::set_state (const XMLNode& node, int /*version*/)
{ {
if (node.name() == X_("gain") && _parameter == Evoral::Parameter (GainAutomation)) {
XMLProperty const * shown = node.property (X_("shown"));
if (shown && string_is_affirmative (shown->value ())) {
set_marked_for_display (true);
_canvas_display->show (); /* FIXME: necessary? show_at? */
}
}
if (!_marked_for_display) {
hide ();
}
return 0; return 0;
} }
XMLNode*
AutomationTimeAxisView::get_state_node ()
{
if (_control) {
return _control->extra_xml ("GUI", true);
}
return 0;
}
void
AutomationTimeAxisView::update_extra_xml_shown (bool shown)
{
XMLNode* xml_node = get_state_node();
if (xml_node) {
xml_node->add_property ("shown", shown ? "yes" : "no");
}
}
void void
AutomationTimeAxisView::what_has_visible_automation (const boost::shared_ptr<Automatable>& automatable, set<Evoral::Parameter>& visible) AutomationTimeAxisView::what_has_visible_automation (const boost::shared_ptr<Automatable>& automatable, set<Evoral::Parameter>& visible)
{ {
@ -1037,35 +989,6 @@ AutomationTimeAxisView::what_has_visible_automation (const boost::shared_ptr<Aut
} }
} }
guint32
AutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
{
if (!canvas_item_visible (_canvas_display)) {
update_extra_xml_shown (true);
}
return TimeAxisView::show_at (y, nth, parent);
}
void
AutomationTimeAxisView::show ()
{
if (!canvas_item_visible (_canvas_display)) {
update_extra_xml_shown (true);
}
return TimeAxisView::show ();
}
void
AutomationTimeAxisView::hide ()
{
if (canvas_item_visible (_canvas_display)) {
update_extra_xml_shown (false);
}
TimeAxisView::hide ();
}
/** @return true if this view has any automation data to display */ /** @return true if this view has any automation data to display */
bool bool
@ -1087,3 +1010,18 @@ AutomationTimeAxisView::lines () const
return lines; return lines;
} }
string
AutomationTimeAxisView::state_id() const
{
if (_control) {
return string_compose ("automation %1", _control->id().to_s());
} else {
assert (_parameter);
return string_compose ("automation %1 %2/%3/%4",
_route->id(),
_parameter.type(),
_parameter.id(),
_parameter.channel());
}
}

View file

@ -97,10 +97,8 @@ class AutomationTimeAxisView : public TimeAxisView {
void reset_objects (PointSelection&); void reset_objects (PointSelection&);
int set_state (const XMLNode&, int version); int set_state (const XMLNode&, int version);
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
static const std::string state_node_name; std::string state_id() const;
XMLNode* get_state_node();
boost::shared_ptr<ARDOUR::AutomationControl> control() { return _control; } boost::shared_ptr<ARDOUR::AutomationControl> control() { return _control; }
boost::shared_ptr<AutomationController> controller() { return _controller; } boost::shared_ptr<AutomationController> controller() { return _controller; }
@ -156,9 +154,6 @@ class AutomationTimeAxisView : public TimeAxisView {
Gtk::CheckMenuItem* mode_discrete_item; Gtk::CheckMenuItem* mode_discrete_item;
Gtk::CheckMenuItem* mode_line_item; Gtk::CheckMenuItem* mode_line_item;
void hide ();
void show ();
void add_line (boost::shared_ptr<AutomationLine>); void add_line (boost::shared_ptr<AutomationLine>);
void clear_clicked (); void clear_clicked ();
@ -184,8 +179,6 @@ class AutomationTimeAxisView : public TimeAxisView {
PBD::ScopedConnectionList _list_connections; PBD::ScopedConnectionList _list_connections;
PBD::ScopedConnectionList _route_connections; PBD::ScopedConnectionList _route_connections;
void update_extra_xml_shown (bool editor_shown);
void entered (); void entered ();
void exited (); void exited ();

View file

@ -35,6 +35,8 @@
#include "ardour/utils.h" #include "ardour/utils.h"
#include "public_editor.h" #include "public_editor.h"
#include "ardour_ui.h"
#include "gui_object.h"
#include "axis_view.h" #include "axis_view.h"
#include "i18n.h" #include "i18n.h"
@ -49,7 +51,6 @@ AxisView::AxisView (ARDOUR::Session* sess)
: SessionHandlePtr (sess) : SessionHandlePtr (sess)
{ {
_selected = false; _selected = false;
_marked_for_display = false;
} }
AxisView::~AxisView() AxisView::~AxisView()
@ -95,3 +96,43 @@ AxisView::unique_random_color()
/* XXX need throttle here to make sure we don't spin for ever */ /* XXX need throttle here to make sure we don't spin for ever */
} }
} }
void
AxisView::set_gui_property (const string& property_name, const string& value)
{
ARDOUR_UI::instance()->gui_object_state->set (state_id(), property_name, value);
}
void
AxisView::set_gui_property (const string& property_name, int value)
{
ARDOUR_UI::instance()->gui_object_state->set (state_id(), property_name, value);
}
string
AxisView::gui_property (const string& property_name) const
{
return ARDOUR_UI::instance()->gui_object_state->get_string (state_id(), property_name);
}
bool
AxisView::marked_for_display () const
{
return string_is_affirmative (gui_property ("visible"));
}
bool
AxisView::set_marked_for_display (bool yn)
{
if (yn != marked_for_display()) {
if (yn) {
set_gui_property ("visible", "yes");
} else {
set_gui_property ("visible", "no");
}
return true; // things changed
}
return false;
}

View file

@ -55,16 +55,21 @@ class AxisView : public virtual Selectable, public PBD::ScopedConnectionList, pu
virtual std::string name() const = 0; virtual std::string name() const = 0;
virtual bool marked_for_display() const { return _marked_for_display; }
virtual void set_marked_for_display (bool yn) {
_marked_for_display = yn;
}
sigc::signal<void> Hiding; sigc::signal<void> Hiding;
void set_old_order_key (uint32_t ok) { _old_order_key = ok; } void set_old_order_key (uint32_t ok) { _old_order_key = ok; }
uint32_t old_order_key() const { return _old_order_key; } uint32_t old_order_key() const { return _old_order_key; }
virtual std::string state_id() const = 0;
std::string gui_property (const std::string& property_name) const;
void set_gui_property (const std::string& property_name, const std::string& value);
void set_gui_property (const std::string& property_name, int value);
void set_gui_property (const std::string& property_name, double value);
bool marked_for_display () const;
virtual bool set_marked_for_display (bool);
protected: protected:
AxisView (ARDOUR::Session* sess); AxisView (ARDOUR::Session* sess);

View file

@ -77,49 +77,50 @@
#include "control_protocol/control_protocol.h" #include "control_protocol/control_protocol.h"
#include "audio_clock.h"
#include "editor.h"
#include "debug.h"
#include "keyboard.h"
#include "marker.h"
#include "playlist_selector.h"
#include "audio_region_view.h"
#include "rgb_macros.h"
#include "selection.h"
#include "audio_streamview.h"
#include "time_axis_view.h"
#include "audio_time_axis.h"
#include "utils.h"
#include "crossfade_view.h"
#include "canvas-noevent-text.h"
#include "editing.h"
#include "public_editor.h"
#include "crossfade_edit.h"
#include "canvas_impl.h"
#include "actions.h" #include "actions.h"
#include "sfdb_ui.h"
#include "gui_thread.h"
#include "simpleline.h"
#include "rhythm_ferret.h"
#include "actions.h" #include "actions.h"
#include "tempo_lines.h"
#include "analysis_window.h" #include "analysis_window.h"
#include "audio_clock.h"
#include "audio_region_view.h"
#include "audio_streamview.h"
#include "audio_time_axis.h"
#include "automation_time_axis.h"
#include "bundle_manager.h" #include "bundle_manager.h"
#include "global_port_matrix.h" #include "canvas-noevent-text.h"
#include "canvas_impl.h"
#include "crossfade_edit.h"
#include "crossfade_view.h"
#include "debug.h"
#include "editing.h"
#include "editor.h"
#include "editor_cursors.h"
#include "editor_drag.h" #include "editor_drag.h"
#include "editor_group_tabs.h" #include "editor_group_tabs.h"
#include "automation_time_axis.h"
#include "editor_routes.h"
#include "midi_time_axis.h"
#include "mixer_strip.h"
#include "editor_route_groups.h"
#include "editor_regions.h"
#include "editor_locations.h" #include "editor_locations.h"
#include "editor_regions.h"
#include "editor_route_groups.h"
#include "editor_routes.h"
#include "editor_snapshots.h" #include "editor_snapshots.h"
#include "editor_summary.h" #include "editor_summary.h"
#include "region_layering_order_editor.h" #include "global_port_matrix.h"
#include "gui_object.h"
#include "gui_thread.h"
#include "keyboard.h"
#include "marker.h"
#include "midi_time_axis.h"
#include "mixer_strip.h"
#include "mouse_cursors.h" #include "mouse_cursors.h"
#include "editor_cursors.h" #include "playlist_selector.h"
#include "public_editor.h"
#include "region_layering_order_editor.h"
#include "rgb_macros.h"
#include "rhythm_ferret.h"
#include "selection.h"
#include "sfdb_ui.h"
#include "simpleline.h"
#include "tempo_lines.h"
#include "time_axis_view.h"
#include "utils.h"
#include "i18n.h" #include "i18n.h"
@ -4093,6 +4094,16 @@ Editor::reposition_and_zoom (framepos_t frame, double fpu)
} }
} }
Editor::VisualState::VisualState ()
: gui_state (new GUIObjectState)
{
}
Editor::VisualState::~VisualState ()
{
delete gui_state;
}
Editor::VisualState* Editor::VisualState*
Editor::current_visual_state (bool with_tracks) Editor::current_visual_state (bool with_tracks)
{ {
@ -4102,10 +4113,8 @@ Editor::current_visual_state (bool with_tracks)
vs->leftmost_frame = leftmost_frame; vs->leftmost_frame = leftmost_frame;
vs->zoom_focus = zoom_focus; vs->zoom_focus = zoom_focus;
if (with_tracks) { if (with_tracks) {
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { *(vs->gui_state) = *ARDOUR_UI::instance()->gui_object_state;
vs->track_states.push_back (TAVState ((*i), &(*i)->get_state()));
}
} }
return vs; return vs;
@ -4160,22 +4169,14 @@ Editor::use_visual_state (VisualState& vs)
set_zoom_focus (vs.zoom_focus); set_zoom_focus (vs.zoom_focus);
reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit); reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
*ARDOUR_UI::instance()->gui_object_state = *vs.gui_state;
for (list<TAVState>::iterator i = vs.track_states.begin(); i != vs.track_states.end(); ++i) { for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
TrackViewList::iterator t; (*i)->reset_visual_state ();
/* check if the track still exists - it could have been deleted */
if ((t = find (track_views.begin(), track_views.end(), i->first)) != track_views.end()) {
(*t)->set_state (*(i->second), Stateful::loading_state_version);
}
}
if (!vs.track_states.empty()) {
_routes->update_visibility ();
} }
_routes->update_visibility ();
_routes->resume_redisplay (); _routes->resume_redisplay ();
no_save_visual = false; no_save_visual = false;
@ -4840,9 +4841,11 @@ Editor::handle_new_route (RouteList& routes)
DataType dt = route->input()->default_type(); DataType dt = route->input()->default_type();
if (dt == ARDOUR::DataType::AUDIO) { if (dt == ARDOUR::DataType::AUDIO) {
rtv = new AudioTimeAxisView (*this, _session, route, *track_canvas); rtv = new AudioTimeAxisView (*this, _session, *track_canvas);
rtv->set_route (route);
} else if (dt == ARDOUR::DataType::MIDI) { } else if (dt == ARDOUR::DataType::MIDI) {
rtv = new MidiTimeAxisView (*this, _session, route, *track_canvas); rtv = new MidiTimeAxisView (*this, _session, *track_canvas);
rtv->set_route (route);
} else { } else {
throw unknown_type(); throw unknown_type();
} }

View file

@ -106,6 +106,7 @@ class ControlPoint;
class CrossfadeView; class CrossfadeView;
class DragManager; class DragManager;
class GroupedButtons; class GroupedButtons;
class GUIObjectState;
class Marker; class Marker;
class MidiRegionView; class MidiRegionView;
class MixerStrip; class MixerStrip;
@ -471,11 +472,13 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
typedef std::pair<TimeAxisView*,XMLNode*> TAVState; typedef std::pair<TimeAxisView*,XMLNode*> TAVState;
struct VisualState { struct VisualState {
VisualState();
~VisualState ();
double y_position; double y_position;
double frames_per_unit; double frames_per_unit;
framepos_t leftmost_frame; framepos_t leftmost_frame;
Editing::ZoomFocus zoom_focus; Editing::ZoomFocus zoom_focus;
std::list<TAVState> track_states; GUIObjectState* gui_state;
}; };
std::list<VisualState*> undo_visual_stack; std::list<VisualState*> undo_visual_stack;

View file

@ -468,21 +468,18 @@ EditorRoutes::redisplay ()
route->set_order_key (N_ ("editor"), n); route->set_order_key (N_ ("editor"), n);
} }
bool visible = (*i)[_columns.visible]; bool visible = tv->marked_for_display ();
/* show or hide the TimeAxisView */ /* show or hide the TimeAxisView */
if (visible) { if (visible) {
tv->set_marked_for_display (true);
position += tv->show_at (position, n, &_editor->edit_controls_vbox); position += tv->show_at (position, n, &_editor->edit_controls_vbox);
tv->clip_to_viewport (); tv->clip_to_viewport ();
n++;
} else { } else {
tv->set_visibility (false); tv->hide ();
} }
n++;
} }
/* whenever we go idle, update the track view list to reflect the new order. /* whenever we go idle, update the track view list to reflect the new order.
we can't do this here, because we could mess up something that is traversing we can't do this here, because we could mess up something that is traversing
the track order and has caused a redisplay of the list. the track order and has caused a redisplay of the list.
@ -534,14 +531,16 @@ EditorRoutes::visible_changed (std::string const & path)
TimeAxisView* tv = (*iter)[_columns.tv]; TimeAxisView* tv = (*iter)[_columns.tv];
if (tv) { if (tv) {
bool visible = (*iter)[_columns.visible]; bool visible = (*iter)[_columns.visible];
(*iter)[_columns.visible] = !visible;
if (tv->set_marked_for_display (!visible)) {
_redisplay_does_not_reset_order_keys = true;
_session->set_remote_control_ids();
update_visibility ();
redisplay ();
_redisplay_does_not_reset_order_keys = false;
}
} }
} }
_redisplay_does_not_reset_order_keys = true;
_session->set_remote_control_ids();
redisplay ();
_redisplay_does_not_reset_order_keys = false;
} }
void void
@ -700,7 +699,6 @@ EditorRoutes::update_visibility ()
for (i = rows.begin(); i != rows.end(); ++i) { for (i = rows.begin(); i != rows.end(); ++i) {
TimeAxisView *tv = (*i)[_columns.tv]; TimeAxisView *tv = (*i)[_columns.tv];
(*i)[_columns.visible] = tv->marked_for_display (); (*i)[_columns.visible] = tv->marked_for_display ();
cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl;
} }
resume_redisplay (); resume_redisplay ();

142
gtk2_ardour/gui_object.cc Normal file
View file

@ -0,0 +1,142 @@
/*
Copyright (C) 2011 Paul Davis
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <iostream>
#include <iomanip>
#include <sstream>
#include <boost/variant/static_visitor.hpp>
#include "gui_object.h"
#include "i18n.h"
using std::string;
const string GUIObjectState::xml_node_name (X_("GUIObjectState"));
GUIObjectState::~GUIObjectState ()
{
clear_maps ();
}
void
GUIObjectState::clear_maps ()
{
_property_maps.clear ();
}
class gos_string_vistor : public boost::static_visitor<> {
public:
gos_string_vistor (std::ostream& o)
: stream (o) {}
void operator() (const int64_t& i) {
stream << i;
}
#if 0
void operator() (const double& d) {
stream << std::setprecision (12) << d;
}
#endif
void operator() (const std::string& s) {
stream << s;
}
private:
std::ostream& stream;
};
XMLNode&
GUIObjectState::get_state () const
{
XMLNode* root = new XMLNode (xml_node_name);
for (StringPropertyMap::const_iterator i = _property_maps.begin(); i != _property_maps.end(); ++i) {
const PropertyMap& pmap (i->second);
XMLNode* id_node = new XMLNode (X_("Object"));
id_node->add_property ("id", i->first);
for (PropertyMap::const_iterator p = pmap.begin(); p != pmap.end(); ++p) {
std::stringstream ss;
gos_string_vistor gsv (ss);
boost::apply_visitor (gsv, p->second);
id_node->add_property (p->first.c_str(), ss.str());
}
root->add_child_nocopy (*id_node);
}
return *root;
}
int
GUIObjectState::set_state (const XMLNode& node)
{
if (node.name() != xml_node_name) {
return -1;
}
clear_maps ();
for (XMLNodeList::const_iterator i = node.children().begin(); i != node.children().end(); ++i) {
if ((*i)->name() == X_("Object")) {
XMLNode* child = (*i);
const XMLProperty* idp = child->property (X_("id"));
if (!idp) {
continue;
}
string id (idp->value());
for (XMLPropertyList::const_iterator p = child->properties().begin(); p != child->properties().end(); ++p) {
/* note that this always sets the property with
a string value, and so is not equivalent to
a call made by the program that passed a
scalar.
*/
if ((*p)->name() != X_("id")) {
set (id, (*p)->name(), (*p)->value());
}
}
}
}
return 0;
}
void
GUIObjectState::load (const XMLNode& node)
{
(void) set_state (node);
}
GUIObjectState&
GUIObjectState::operator= (const GUIObjectState& other)
{
_property_maps = other._property_maps;
return *this;
}

100
gtk2_ardour/gui_object.h Normal file
View file

@ -0,0 +1,100 @@
/*
Copyright (C) 2011 Paul Davis
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtk_ardour_gui_object_h__
#define __gtk_ardour_gui_object_h__
#include <map>
#include <string>
#include <boost/variant.hpp>
#include "pbd/xml++.h"
#include "pbd/id.h"
class GUIObjectState {
public:
GUIObjectState() {}
~GUIObjectState();
XMLNode& get_state () const;
int set_state (const XMLNode&);
static const std::string xml_node_name;
void load (const XMLNode&);
GUIObjectState& operator= (const GUIObjectState& other);
private:
typedef boost::variant<int64_t,std::string> Variant;
typedef std::map<std::string,Variant> PropertyMap;
typedef std::map<std::string,PropertyMap> StringPropertyMap;
StringPropertyMap _property_maps;
template<typename T> T get (const std::string& id, const std::string& prop_name, const T& type_determination_placeholder, bool* empty = 0) {
StringPropertyMap::iterator i = _property_maps.find (id);
if (i == _property_maps.end()) {
if (empty) {
*empty = true;
}
return T();
}
const PropertyMap& pmap (i->second);
PropertyMap::const_iterator p = pmap.find (prop_name);
if (p == pmap.end()) {
return T();
}
return boost::get<T> (p->second);
}
void clear_maps ();
public:
int get_int (const std::string& id, const std::string& prop_name) {
int i = 0;
return get (id, prop_name, i);
}
std::string get_string (const std::string& id, const std::string& prop_name) {
std::string s;
return get (id, prop_name, s);
}
template<typename T> void set (const std::string& id, const std::string& prop_name, const T& val) {
StringPropertyMap::iterator i = _property_maps.find (id);
if (i != _property_maps.end()) {
i->second[prop_name] = val;
// std::cerr << id << " REset " << prop_name << " = [" << val << "]\n";
} else {
_property_maps[id] = PropertyMap();
_property_maps[id][prop_name] = val;
// std::cerr << id << " set " << prop_name << " = [" << val << "]\n";
}
}
};
#endif /* __gtk_ardour_gui_object_h__ */

View file

@ -67,7 +67,6 @@ ImageFrameTimeAxis::ImageFrameTimeAxis(const string & track_id, PublicEditor& ed
selection_group->hide(); selection_group->hide();
// intialize our data items // intialize our data items
_marked_for_display = true;
y_position = -1 ; y_position = -1 ;
/* create our new image frame view */ /* create our new image frame view */
@ -139,7 +138,7 @@ ImageFrameTimeAxis::set_height (uint32_t h)
} }
// tell those interested that we have had our height changed // tell those interested that we have had our height changed
gui_changed("track_height",(void*)0); /* EMIT_SIGNAL */ gui_changed("track_height",(void*)0); /* EMIT_SIGNAL */
} }
/** /**

View file

@ -117,7 +117,7 @@ MarkerTimeAxis::set_height (uint32_t h)
} }
// tell those interested that we have had our height changed // tell those interested that we have had our height changed
gui_changed("track_height",(void*)0) ; /* EMIT_SIGNAL */ gui_changed("track_height",(void*)0) ; /* EMIT_SIGNAL */
} }
/** /**

View file

@ -99,10 +99,9 @@ using namespace Editing;
static const uint32_t MIDI_CONTROLS_BOX_MIN_HEIGHT = 162; static const uint32_t MIDI_CONTROLS_BOX_MIN_HEIGHT = 162;
static const uint32_t KEYBOARD_MIN_HEIGHT = 140; static const uint32_t KEYBOARD_MIN_HEIGHT = 140;
MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess, MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas)
boost::shared_ptr<Route> rt, Canvas& canvas)
: AxisView(sess) // virtually inherited : AxisView(sess) // virtually inherited
, RouteTimeAxisView(ed, sess, rt, canvas) , RouteTimeAxisView(ed, sess, canvas)
, _ignore_signals(false) , _ignore_signals(false)
, _range_scroomer(0) , _range_scroomer(0)
, _piano_roll_header(0) , _piano_roll_header(0)
@ -118,6 +117,13 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
, controller_menu (0) , controller_menu (0)
, _step_editor (0) , _step_editor (0)
{ {
}
void
MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
{
RouteTimeAxisView::set_route (rt);
subplugin_menu.set_name ("ArdourContextMenu"); subplugin_menu.set_name ("ArdourContextMenu");
_view = new MidiStreamView (*this); _view = new MidiStreamView (*this);
@ -138,10 +144,6 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
processors_changed (RouteProcessorChange ()); processors_changed (RouteProcessorChange ());
ensure_xml_node ();
set_state (*xml_node, Stateful::loading_state_version);
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context()); _route->processors_changed.connect (*this, invalidator (*this), ui_bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context());
if (is_track()) { if (is_track()) {
@ -211,22 +213,23 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
_channel_selector.mode_changed.connect( _channel_selector.mode_changed.connect(
sigc::mem_fun(*this, &MidiTimeAxisView::set_channel_mode)); sigc::mem_fun(*this, &MidiTimeAxisView::set_channel_mode));
XMLProperty *prop; string prop = gui_property ("color-mode");
if ((prop = xml_node->property ("color-mode")) != 0) { if (!prop.empty()) {
_color_mode = ColorMode (string_2_enum(prop->value(), _color_mode)); _color_mode = ColorMode (string_2_enum(prop, _color_mode));
if (_color_mode == ChannelColors) { if (_color_mode == ChannelColors) {
_channel_selector.set_channel_colors(CanvasNoteEvent::midi_channel_colors); _channel_selector.set_channel_colors(CanvasNoteEvent::midi_channel_colors);
} }
} }
if ((prop = xml_node->property ("note-mode")) != 0) { set_color_mode (_color_mode, true, false);
_note_mode = NoteMode (string_2_enum(prop->value(), _note_mode));
prop = gui_property ("note-mode");
if (!prop.empty()) {
_note_mode = NoteMode (string_2_enum (prop, _note_mode));
if (_percussion_mode_item) { if (_percussion_mode_item) {
_percussion_mode_item->set_active (_note_mode == Percussive); _percussion_mode_item->set_active (_note_mode == Percussive);
} }
} }
set_color_mode (_color_mode, true, false);
} }
void void
@ -301,25 +304,6 @@ MidiTimeAxisView::midi_view()
return dynamic_cast<MidiStreamView*>(_view); return dynamic_cast<MidiStreamView*>(_view);
} }
guint32
MidiTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
{
ensure_xml_node ();
xml_node->add_property ("shown-editor", "yes");
guint32 ret = TimeAxisView::show_at (y, nth, parent);
return ret;
}
void
MidiTimeAxisView::hide ()
{
ensure_xml_node ();
xml_node->add_property ("shown-editor", "no");
TimeAxisView::hide ();
}
void void
MidiTimeAxisView::set_height (uint32_t h) MidiTimeAxisView::set_height (uint32_t h)
{ {
@ -330,7 +314,7 @@ MidiTimeAxisView::set_height (uint32_t h)
} else { } else {
_midi_controls_box.hide(); _midi_controls_box.hide();
} }
if (height >= KEYBOARD_MIN_HEIGHT) { if (height >= KEYBOARD_MIN_HEIGHT) {
if (is_track() && _range_scroomer) if (is_track() && _range_scroomer)
_range_scroomer->show(); _range_scroomer->show();
@ -754,7 +738,7 @@ MidiTimeAxisView::set_note_mode(NoteMode mode)
if (_note_mode != mode || midi_track()->note_mode() != mode) { if (_note_mode != mode || midi_track()->note_mode() != mode) {
_note_mode = mode; _note_mode = mode;
midi_track()->set_note_mode(mode); midi_track()->set_note_mode(mode);
xml_node->add_property ("note-mode", enum_2_string(_note_mode)); set_gui_property ("note-mode", enum_2_string(_note_mode));
_view->redisplay_track(); _view->redisplay_track();
} }
} }
@ -773,7 +757,7 @@ MidiTimeAxisView::set_color_mode (ColorMode mode, bool force, bool redisplay)
} }
_color_mode = mode; _color_mode = mode;
xml_node->add_property ("color-mode", enum_2_string(_color_mode)); set_gui_property ("color-mode", enum_2_string(_color_mode));
if (redisplay) { if (redisplay) {
_view->redisplay_track(); _view->redisplay_track();
} }
@ -827,7 +811,7 @@ MidiTimeAxisView::show_existing_automation (bool apply_to_selection)
const set<Evoral::Parameter> params = midi_track()->midi_playlist()->contained_automation(); const set<Evoral::Parameter> params = midi_track()->midi_playlist()->contained_automation();
for (set<Evoral::Parameter>::const_iterator i = params.begin(); i != params.end(); ++i) { for (set<Evoral::Parameter>::const_iterator i = params.begin(); i != params.end(); ++i) {
create_automation_child(*i, true); create_automation_child (*i, true);
} }
} }
@ -854,10 +838,10 @@ MidiTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
* since it will have been set visible by default. * since it will have been set visible by default.
*/ */
existing->second->set_visibility (show); cerr << "show existing auto track: " << show << " noredraw " << no_redraw << endl;
if (!no_redraw) { if (existing->second->set_marked_for_display (show) && !no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
return; return;
@ -1036,9 +1020,9 @@ MidiTimeAxisView::set_channel_mode (ChannelMode, uint16_t)
/* channel not in use. hiding it will trigger RouteTimeAxisView::automation_track_hidden() /* channel not in use. hiding it will trigger RouteTimeAxisView::automation_track_hidden()
which will cause a redraw. We don't want one per channel, so block that with no_redraw. which will cause a redraw. We don't want one per channel, so block that with no_redraw.
*/ */
changed = track->set_visibility (false) || changed; changed = track->set_marked_for_display (false) || changed;
} else { } else {
changed = track->set_visibility (true) || changed; changed = track->set_marked_for_display (true) || changed;
} }
} }
} }
@ -1053,7 +1037,7 @@ MidiTimeAxisView::set_channel_mode (ChannelMode, uint16_t)
controller_menu = 0; controller_menu = 0;
if (changed) { if (changed) {
_route->gui_changed ("track_height", this); request_redraw ();
} }
} }

View file

@ -59,13 +59,13 @@ class StepEditor;
class MidiTimeAxisView : public RouteTimeAxisView class MidiTimeAxisView : public RouteTimeAxisView
{ {
public: public:
MidiTimeAxisView (PublicEditor&, ARDOUR::Session*, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas); MidiTimeAxisView (PublicEditor&, ARDOUR::Session*, ArdourCanvas::Canvas& canvas);
virtual ~MidiTimeAxisView (); virtual ~MidiTimeAxisView ();
void set_route (boost::shared_ptr<ARDOUR::Route>);
MidiStreamView* midi_view(); MidiStreamView* midi_view();
/* overridden from parent to store display state */
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
void set_height (uint32_t); void set_height (uint32_t);
void enter_internal_edit_mode (); void enter_internal_edit_mode ();
@ -109,7 +109,6 @@ class MidiTimeAxisView : public RouteTimeAxisView
private: private:
sigc::signal<void, std::string, std::string> _midi_patch_settings_changed; sigc::signal<void, std::string, std::string> _midi_patch_settings_changed;
void hide ();
void model_changed(); void model_changed();
void custom_device_mode_changed(); void custom_device_mode_changed();

View file

@ -127,7 +127,6 @@ MixerStrip::init ()
input_selector = 0; input_selector = 0;
output_selector = 0; output_selector = 0;
group_menu = 0; group_menu = 0;
_marked_for_display = false;
route_ops_menu = 0; route_ops_menu = 0;
ignore_comment_edit = false; ignore_comment_edit = false;
ignore_toggle = false; ignore_toggle = false;
@ -527,25 +526,11 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
void void
MixerStrip::set_stuff_from_route () MixerStrip::set_stuff_from_route ()
{ {
XMLProperty *prop;
ensure_xml_node ();
/* if width is not set, it will be set by the MixerUI or editor */ /* if width is not set, it will be set by the MixerUI or editor */
if ((prop = xml_node->property ("strip-width")) != 0) { string str = gui_property ("strip-width");
set_width_enum (Width (string_2_enum (prop->value(), _width)), this); if (!str.empty()) {
} set_width_enum (Width (string_2_enum (str, _width)), this);
if ((prop = xml_node->property ("shown-mixer")) != 0) {
if (prop->value() == "no") {
_marked_for_display = false;
} else {
_marked_for_display = true;
}
} else {
/* backwards compatibility */
_marked_for_display = true;
} }
} }
@ -561,12 +546,10 @@ MixerStrip::set_width_enum (Width w, void* owner)
_width_owner = owner; _width_owner = owner;
ensure_xml_node ();
_width = w; _width = w;
if (_width_owner == this) { if (_width_owner == this) {
xml_node->add_property ("strip-width", enum_2_string (_width)); set_gui_property ("strip-width", enum_2_string (_width));
} }
set_button_names (); set_button_names ();
@ -635,12 +618,10 @@ MixerStrip::set_packed (bool yn)
{ {
_packed = yn; _packed = yn;
ensure_xml_node ();
if (_packed) { if (_packed) {
xml_node->add_property ("shown-mixer", "yes"); set_gui_property ("visible", "yes");
} else { } else {
xml_node->add_property ("shown-mixer", "no"); set_gui_property ("visible", "no");
} }
} }
@ -1961,3 +1942,9 @@ MixerStrip::midi_input_status_changed ()
midi_input_enable_button->set_active (mt->input_active ()); midi_input_enable_button->set_active (mt->input_active ());
} }
} }
string
MixerStrip::state_id () const
{
return string_compose ("strip %1", _route->id().to_s());
}

View file

@ -118,6 +118,8 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
static sigc::signal<void,boost::shared_ptr<ARDOUR::Route> > SwitchIO; static sigc::signal<void,boost::shared_ptr<ARDOUR::Route> > SwitchIO;
static PBD::Signal1<void,MixerStrip*> CatchDeletion; static PBD::Signal1<void,MixerStrip*> CatchDeletion;
std::string state_id() const;
protected: protected:
friend class Mixer_UI; friend class Mixer_UI;
void set_packed (bool yn); void set_packed (bool yn);

View file

@ -750,7 +750,7 @@ Mixer_UI::redisplay_track_list ()
bool visible = (*i)[track_columns.visible]; bool visible = (*i)[track_columns.visible];
if (visible) { if (visible) {
strip->set_marked_for_display (true); strip->set_gui_property ("visible", "yes");
strip->route()->set_order_key (N_("signal"), order); strip->route()->set_order_key (N_("signal"), order);
if (!strip_redisplay_does_not_reset_order_keys) { if (!strip_redisplay_does_not_reset_order_keys) {
@ -778,7 +778,7 @@ Mixer_UI::redisplay_track_list ()
} else { } else {
strip->set_marked_for_display (false); strip->set_gui_property ("visible", "no");
if (strip->route()->is_master() || strip->route()->is_monitor()) { if (strip->route()->is_master() || strip->route()->is_monitor()) {
/* do nothing, these cannot be hidden */ /* do nothing, these cannot be hidden */

View file

@ -1006,3 +1006,9 @@ MonitorSection::assign_controllables ()
solo_boost_control->set_controllable (none); solo_boost_control->set_controllable (none);
} }
} }
string
MonitorSection::state_id() const
{
return "monitor-section";
}

View file

@ -44,6 +44,8 @@ class MonitorSection : public RouteUI
Gtkmm2ext::TearOff& tearoff() const { return *_tearoff; } Gtkmm2ext::TearOff& tearoff() const { return *_tearoff; }
std::string state_id() const;
private: private:
Gtk::VBox vpacker; Gtk::VBox vpacker;
Gtk::HBox hpacker; Gtk::HBox hpacker;

View file

@ -104,30 +104,44 @@ RouteTimeAxisView::setup_slider_pix ()
} }
} }
RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::shared_ptr<Route> rt, Canvas& canvas) RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas)
: AxisView(sess) : AxisView(sess)
, RouteUI(rt, sess) , RouteUI(sess)
, TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas) , TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas)
, _view (0)
, parent_canvas (canvas) , parent_canvas (canvas)
, button_table (3, 3) , button_table (3, 3)
, route_group_button (_("g")) , route_group_button (_("g"))
, playlist_button (_("p")) , playlist_button (_("p"))
, automation_button (_("a")) , automation_button (_("a"))
, automation_action_menu (0)
, plugins_submenu_item (0)
, route_group_menu (0)
, playlist_action_menu (0)
, mode_menu (0)
, color_mode_menu (0)
, gm (sess, slider, true, 115) , gm (sess, slider, true, 115)
{ {
}
void
RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
{
RouteUI::set_route (rt);
gm.set_controls (_route, _route->shared_peak_meter(), _route->amp()); gm.set_controls (_route, _route->shared_peak_meter(), _route->amp());
gm.get_level_meter().set_no_show_all(); gm.get_level_meter().set_no_show_all();
gm.get_level_meter().setup_meters(50); gm.get_level_meter().setup_meters(50);
_has_state = true; string str = gui_property ("height");
playlist_action_menu = 0; if (!str.empty()) {
automation_action_menu = 0; set_height (atoi (str));
plugins_submenu_item = 0; } else {
mode_menu = 0; set_height (preset_height (HeightNormal));
_view = 0; }
if (!_route->is_hidden()) { if (!_route->is_hidden()) {
_marked_for_display = true; set_gui_property ("visible", "yes");
} }
mute_changed (0); mute_changed (0);
@ -213,12 +227,16 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
if (is_track()) { if (is_track()) {
str = gui_property ("layer-display");
if (!str.empty()) {
set_layer_display (LayerDisplay (string_2_enum (str, _view->layer_display ())));
}
track()->FreezeChange.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::map_frozen, this), gui_context()); track()->FreezeChange.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::map_frozen, this), gui_context());
track()->SpeedChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::speed_changed, this), gui_context()); track()->SpeedChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::speed_changed, this), gui_context());
/* pick up the correct freeze state */ /* pick up the correct freeze state */
map_frozen (); map_frozen ();
} }
_editor.ZoomChanged.connect (sigc::mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit)); _editor.ZoomChanged.connect (sigc::mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit));
@ -354,22 +372,6 @@ RouteTimeAxisView::automation_click ()
automation_action_menu->popup (1, gtk_get_current_event_time()); automation_action_menu->popup (1, gtk_get_current_event_time());
} }
int
RouteTimeAxisView::set_state (const XMLNode& node, int version)
{
TimeAxisView::set_state (node, version);
XMLNodeList kids = node.children();
XMLNodeConstIterator iter;
const XMLProperty* prop;
if (_view && (prop = node.property ("layer-display"))) {
set_layer_display (LayerDisplay (string_2_enum (prop->value(), _view->layer_display ())));
}
return 0;
}
void void
RouteTimeAxisView::build_automation_action_menu (bool for_selection) RouteTimeAxisView::build_automation_action_menu (bool for_selection)
{ {
@ -850,16 +852,10 @@ RouteTimeAxisView::set_height (uint32_t h)
TimeAxisView::set_height (h); TimeAxisView::set_height (h);
ensure_xml_node ();
if (_view) { if (_view) {
_view->set_height ((double) current_height()); _view->set_height ((double) current_height());
} }
char buf[32];
snprintf (buf, sizeof (buf), "%u", height);
xml_node->add_property ("height", buf);
if (height >= preset_height (HeightNormal)) { if (height >= preset_height (HeightNormal)) {
reset_meter(); reset_meter();
@ -906,7 +902,7 @@ RouteTimeAxisView::set_height (uint32_t h)
if (height_changed && !no_redraw) { if (height_changed && !no_redraw) {
/* only emit the signal if the height really changed */ /* only emit the signal if the height really changed */
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -1644,14 +1640,16 @@ RouteTimeAxisView::toggle_automation_track (const Evoral::Parameter& param)
} else { } else {
assert (menu); assert (menu);
bool yn = menu->get_active(); bool yn = menu->get_active();
if (track->set_visibility (menu->get_active()) && yn) { bool changed = false;
if ((changed = track->set_marked_for_display (menu->get_active())) && yn) {
/* we made it visible, now trigger a redisplay. if it was hidden, then automation_track_hidden() /* we made it visible, now trigger a redisplay. if it was hidden, then automation_track_hidden()
will have done that for us. will have done that for us.
*/ */
if (!no_redraw) { if (changed && !no_redraw) {
_route->gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
} }
@ -1675,7 +1673,7 @@ RouteTimeAxisView::automation_track_hidden (Evoral::Parameter param)
} }
if (_route && !no_redraw) { if (_route && !no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -1691,7 +1689,7 @@ RouteTimeAxisView::show_all_automation (bool apply_to_selection)
/* Show our automation */ /* Show our automation */
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) { for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
i->second->set_visibility (true); i->second->set_marked_for_display (true);
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first); Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
@ -1717,7 +1715,7 @@ RouteTimeAxisView::show_all_automation (bool apply_to_selection)
/* Redraw */ /* Redraw */
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -1733,7 +1731,7 @@ RouteTimeAxisView::show_existing_automation (bool apply_to_selection)
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) { for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
if (i->second->has_automation()) { if (i->second->has_automation()) {
i->second->set_visibility (true); i->second->set_marked_for_display (true);
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first); Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
if (menu) { if (menu) {
@ -1754,7 +1752,7 @@ RouteTimeAxisView::show_existing_automation (bool apply_to_selection)
no_redraw = false; no_redraw = false;
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -1769,7 +1767,7 @@ RouteTimeAxisView::hide_all_automation (bool apply_to_selection)
/* Hide our automation */ /* Hide our automation */
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) { for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
i->second->set_visibility (false); i->second->set_marked_for_display (false);
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first); Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
@ -1787,7 +1785,7 @@ RouteTimeAxisView::hide_all_automation (bool apply_to_selection)
} }
no_redraw = false; no_redraw = false;
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -1894,7 +1892,7 @@ RouteTimeAxisView::processor_automation_track_hidden (RouteTimeAxisView::Process
} }
if (!no_redraw) { if (!no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -1930,26 +1928,23 @@ RouteTimeAxisView::add_automation_child (Evoral::Parameter param, boost::shared_
{ {
using namespace Menu_Helpers; using namespace Menu_Helpers;
XMLProperty* prop;
XMLNode* node;
add_child (track); add_child (track);
track->Hiding.connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param)); track->Hiding.connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param));
_automation_tracks[param] = track; _automation_tracks[param] = track;
if ((node = track->get_state_node()) != 0) { /* existing state overrides "show" argument */
if ((prop = node->property ("shown")) != 0) { string s = track->gui_property ("visible");
/* existing state overrides "show" argument */ if (!s.empty()) {
show = string_is_affirmative (prop->value()); show = string_is_affirmative (s);
}
} }
track->set_visibility (show); /* this might or might not change the visibility status, so don't rely on it */
track->set_marked_for_display (show);
if (!no_redraw) { if (show && !no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
if (!EventTypeMap::instance().is_midi_parameter(param)) { if (!EventTypeMap::instance().is_midi_parameter(param)) {
@ -2076,13 +2071,12 @@ RouteTimeAxisView::processor_menu_item_toggled (RouteTimeAxisView::ProcessorAuto
redraw = true; redraw = true;
} }
if (pan->view && showit != pan->view->marked_for_display()) { if (pan->view && pan->view->set_marked_for_display (showit)) {
pan->view->set_visibility (showit);
redraw = true; redraw = true;
} }
if (redraw && !no_redraw) { if (redraw && !no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ request_redraw ();
} }
} }
@ -2123,7 +2117,7 @@ RouteTimeAxisView::processors_changed (RouteProcessorChange c)
} }
if (deleted_processor_automation && !no_redraw) { if (deleted_processor_automation && !no_redraw) {
_route->gui_changed ("track_height", this); request_redraw ();
} }
} }
@ -2167,8 +2161,7 @@ RouteTimeAxisView::set_layer_display (LayerDisplay d, bool apply_to_selection)
_view->set_layer_display (d); _view->set_layer_display (d);
} }
ensure_xml_node (); set_gui_property (X_("layer-display"), enum_2_string (d));
xml_node->add_property (N_("layer-display"), enum_2_string (d));
} }
} }
@ -2317,9 +2310,9 @@ RouteTimeAxisView::add_underlay (StreamView* v, bool update_xml)
v->foreach_regionview(sigc::mem_fun(*this, &RouteTimeAxisView::add_ghost)); v->foreach_regionview(sigc::mem_fun(*this, &RouteTimeAxisView::add_ghost));
#ifdef GUI_OBJECT_STATE_FIX_REQUIRED
if (update_xml) { if (update_xml) {
if (!underlay_xml_node) { if (!underlay_xml_node) {
ensure_xml_node();
underlay_xml_node = xml_node->add_child("Underlays"); underlay_xml_node = xml_node->add_child("Underlays");
} }
@ -2327,6 +2320,7 @@ RouteTimeAxisView::add_underlay (StreamView* v, bool update_xml)
XMLProperty* prop = node->add_property("id"); XMLProperty* prop = node->add_property("id");
prop->set_value(v->trackview().route()->id().to_s()); prop->set_value(v->trackview().route()->id().to_s());
} }
#endif
} }
} }
@ -2492,3 +2486,8 @@ RouteTimeAxisView::uncombine_regions ()
_session->add_command (new StatefulDiffCommand (playlist)); _session->add_command (new StatefulDiffCommand (playlist));
} }
string
RouteTimeAxisView::state_id() const
{
return string_compose ("rtav %1", _route->id().to_s());
}

View file

@ -70,9 +70,11 @@ class RouteGroupMenu;
class RouteTimeAxisView : public RouteUI, public TimeAxisView class RouteTimeAxisView : public RouteUI, public TimeAxisView
{ {
public: public:
RouteTimeAxisView (PublicEditor&, ARDOUR::Session*, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas); RouteTimeAxisView (PublicEditor&, ARDOUR::Session*, ArdourCanvas::Canvas& canvas);
virtual ~RouteTimeAxisView (); virtual ~RouteTimeAxisView ();
void set_route (boost::shared_ptr<ARDOUR::Route>);
void show_selection (TimeSelection&); void show_selection (TimeSelection&);
void set_button_names (); void set_button_names ();
@ -137,6 +139,8 @@ public:
void meter_changed (); void meter_changed ();
void effective_gain_display () { gm.effective_gain_display(); } void effective_gain_display () { gm.effective_gain_display(); }
std::string state_id() const;
static void setup_slider_pix (); static void setup_slider_pix ();
protected: protected:

View file

@ -70,13 +70,6 @@ RouteUI::RouteUI (ARDOUR::Session* sess)
init (); init ();
} }
RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session* sess)
: AxisView(sess)
{
init ();
set_route (rt);
}
RouteUI::~RouteUI() RouteUI::~RouteUI()
{ {
_route.reset (); /* drop reference to route, so that it can be cleaned up */ _route.reset (); /* drop reference to route, so that it can be cleaned up */
@ -93,7 +86,6 @@ void
RouteUI::init () RouteUI::init ()
{ {
self_destruct = true; self_destruct = true;
xml_node = 0;
mute_menu = 0; mute_menu = 0;
solo_menu = 0; solo_menu = 0;
sends_menu = 0; sends_menu = 0;
@ -173,11 +165,6 @@ RouteUI::reset ()
delete mute_menu; delete mute_menu;
mute_menu = 0; mute_menu = 0;
if (xml_node) {
/* do not delete the node - its owned by the route */
xml_node = 0;
}
denormal_menu_item = 0; denormal_menu_item = 0;
} }
@ -1278,62 +1265,29 @@ RouteUI::set_color (const Gdk::Color & c)
_color = c; _color = c;
ensure_xml_node ();
snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue()); snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue());
xml_node->add_property ("color", buf); set_gui_property ("color", buf);
_route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */ _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
} }
void
RouteUI::ensure_xml_node ()
{
if (xml_node == 0) {
if ((xml_node = _route->extra_xml ("GUI")) == 0) {
xml_node = new XMLNode ("GUI");
_route->add_extra_xml (*xml_node);
} else {
/* the Route has one; it may have been loaded */
if (Stateful::loading_state_version != 0 && Stateful::loading_state_version < 3000) {
/* the GUI extra XML is in 2.X format; we must convert it to the new
format to avoid problems later
*/
XMLNode* new_xml_node = new XMLNode (X_("GUI"));
XMLPropertyList old_gui_props = xml_node->properties ();
for (XMLPropertyIterator i = old_gui_props.begin(); i != old_gui_props.end(); ++i) {
new_xml_node->add_property ((*i)->name().c_str (), (*i)->value().c_str ());
}
/* we can't fix up the automation track nodes,
* because the data is no longer stored
* per-route, but per Controllable.
*/
_route->add_extra_xml (*new_xml_node);
xml_node = new_xml_node;
}
}
}
}
int int
RouteUI::set_color_from_route () RouteUI::set_color_from_route ()
{ {
XMLProperty *prop; const string str = gui_property ("color");
RouteUI::ensure_xml_node (); if (str.empty()) {
return 1;
if ((prop = xml_node->property ("color")) != 0) {
int r, g, b;
sscanf (prop->value().c_str(), "%d:%d:%d", &r, &g, &b);
_color.set_red(r);
_color.set_green(g);
_color.set_blue(b);
return 0;
} }
return 1;
int r, g, b;
sscanf (str.c_str(), "%d:%d:%d", &r, &g, &b);
_color.set_red (r);
_color.set_green (g);
_color.set_blue (b);
return 0;
} }
void void
@ -1787,3 +1741,11 @@ RouteUI::set_invert_sensitive (bool yn)
(*b)->set_sensitive (yn); (*b)->set_sensitive (yn);
} }
} }
void
RouteUI::request_redraw ()
{
if (_route) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
}

View file

@ -77,6 +77,8 @@ class RouteUI : public virtual AxisView
boost::shared_ptr<ARDOUR::Route> _route; boost::shared_ptr<ARDOUR::Route> _route;
void request_redraw ();
virtual void set_color (const Gdk::Color & c); virtual void set_color (const Gdk::Color & c);
void choose_color (); void choose_color ();
@ -108,9 +110,6 @@ class RouteUI : public virtual AxisView
Gtk::Menu* solo_menu; Gtk::Menu* solo_menu;
Gtk::Menu* sends_menu; Gtk::Menu* sends_menu;
XMLNode *xml_node;
void ensure_xml_node ();
bool mute_press(GdkEventButton*); bool mute_press(GdkEventButton*);
bool mute_release(GdkEventButton*); bool mute_release(GdkEventButton*);
bool solo_press(GdkEventButton*); bool solo_press(GdkEventButton*);

View file

@ -103,7 +103,6 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
height = 0; height = 0;
_effective_height = 0; _effective_height = 0;
parent = rent; parent = rent;
_has_state = false;
last_name_entry_key_press_event = 0; last_name_entry_key_press_event = 0;
name_packing = NamePackingBits (0); name_packing = NamePackingBits (0);
_resize_drag_start = -1; _resize_drag_start = -1;
@ -220,6 +219,47 @@ TimeAxisView::~TimeAxisView()
delete _size_menu; delete _size_menu;
} }
#if 0
void
TimeAxisView::show ()
{
canvas_display()->show();
canvas_background()->show();
}
#endif
void
TimeAxisView::hide ()
{
if (_hidden) {
return;
}
_canvas_display->hide ();
_canvas_background->hide ();
if (control_parent) {
control_parent->remove (time_axis_vbox);
control_parent = 0;
}
_y_position = -1;
_hidden = true;
/* now hide children */
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
(*i)->hide ();
}
/* if its hidden, it cannot be selected */
_editor.get_selection().remove (this);
/* and neither can its regions */
_editor.get_selection().remove_regions (this);
Hiding ();
}
/** Display this TimeAxisView as the nth component of the parent box, at y. /** Display this TimeAxisView as the nth component of the parent box, at y.
* *
* @param y y position. * @param y y position.
@ -253,22 +293,22 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
_canvas_background->raise_to_top (); _canvas_background->raise_to_top ();
_canvas_display->raise_to_top (); _canvas_display->raise_to_top ();
if (_marked_for_display) { time_axis_vbox.show ();
time_axis_vbox.show (); controls_ebox.show ();
controls_ebox.show (); _canvas_background->show ();
_canvas_background->show ();
}
_hidden = false; _hidden = false;
_effective_height = current_height (); _effective_height = current_height ();
/* now show children */ /* now show relevant children */
for (Children::iterator i = children.begin(); i != children.end(); ++i) { for (Children::iterator i = children.begin(); i != children.end(); ++i) {
if (canvas_item_visible ((*i)->_canvas_display)) { if ((*i)->marked_for_display()) {
++nth; ++nth;
_effective_height += (*i)->show_at (y + _effective_height, nth, parent); _effective_height += (*i)->show_at (y + _effective_height, nth, parent);
} else {
(*i)->hide ();
} }
} }
@ -278,7 +318,7 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
void void
TimeAxisView::clip_to_viewport () TimeAxisView::clip_to_viewport ()
{ {
if (_marked_for_display) { if (marked_for_display()) {
if (_y_position + _effective_height < _editor.get_trackview_group_vertical_offset () || _y_position > _editor.get_trackview_group_vertical_offset () + _canvas_display->get_canvas()->get_height()) { if (_y_position + _effective_height < _editor.get_trackview_group_vertical_offset () || _y_position > _editor.get_trackview_group_vertical_offset () + _canvas_display->get_canvas()->get_height()) {
_canvas_background->hide (); _canvas_background->hide ();
_canvas_display->hide (); _canvas_display->hide ();
@ -349,44 +389,6 @@ TimeAxisView::selection_click (GdkEventButton* ev)
_editor.set_selected_track (*this, op, false); _editor.set_selected_track (*this, op, false);
} }
void
TimeAxisView::show ()
{
canvas_display()->show();
canvas_background()->show();
}
void
TimeAxisView::hide ()
{
if (_hidden) {
return;
}
_canvas_display->hide ();
_canvas_background->hide ();
if (control_parent) {
control_parent->remove (time_axis_vbox);
control_parent = 0;
}
_y_position = -1;
_hidden = true;
/* now hide children */
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
(*i)->hide ();
}
/* if its hidden, it cannot be selected */
_editor.get_selection().remove (this);
/* and neither can its regions */
_editor.get_selection().remove_regions (this);
Hiding ();
}
/** Steps through the defined heights for this TrackView. /** Steps through the defined heights for this TrackView.
* @param coarser true if stepping should decrease in size, otherwise false. * @param coarser true if stepping should decrease in size, otherwise false.
@ -447,6 +449,10 @@ TimeAxisView::set_height (uint32_t h)
time_axis_vbox.property_height_request () = h; time_axis_vbox.property_height_request () = h;
height = h; height = h;
char buf[32];
snprintf (buf, sizeof (buf), "%u", height);
set_gui_property ("height", buf);
for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
(*i)->set_height (); (*i)->set_height ();
} }
@ -964,84 +970,6 @@ TimeAxisView::set_parent (TimeAxisView& p)
parent = &p; parent = &p;
} }
bool
TimeAxisView::has_state () const
{
return _has_state;
}
TimeAxisView*
TimeAxisView::get_parent_with_state ()
{
if (parent == 0) {
return 0;
}
if (parent->has_state()) {
return parent;
}
return parent->get_parent_with_state ();
}
XMLNode&
TimeAxisView::get_state ()
{
/* XXX: is this method used? */
XMLNode* node = new XMLNode ("TAV-" + name());
char buf[32];
snprintf (buf, sizeof(buf), "%u", height);
node->add_property ("height", buf);
node->add_property ("marked-for-display", (_marked_for_display ? "1" : "0"));
return *node;
}
int
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_enum (HeightLargest);
} else if (prop->value() == "large") {
set_height_enum (HeightLarge);
} else if (prop->value() == "larger") {
set_height_enum (HeightLarger);
} else if (prop->value() == "normal") {
set_height_enum (HeightNormal);
} else if (prop->value() == "smaller" || prop->value() == "small") {
set_height_enum (HeightSmall);
} else {
error << string_compose(_("unknown track height name \"%1\" in XML GUI information"), prop->value()) << endmsg;
set_height_enum (HeightNormal);
}
} else if ((prop = node.property ("height")) != 0) {
set_height (atoi (prop->value()));
} else {
set_height_enum (HeightNormal);
}
return 0;
}
void void
TimeAxisView::reset_height () TimeAxisView::reset_height ()
{ {
@ -1288,24 +1216,6 @@ TimeAxisView::resizer_expose (GdkEventExpose* event)
return true; return true;
} }
bool
TimeAxisView::set_visibility (bool yn)
{
if (yn != marked_for_display()) {
if (yn) {
set_marked_for_display (true);
show ();
} else {
set_marked_for_display (false);
hide ();
}
return true; // things changed
}
return false;
}
uint32_t uint32_t
TimeAxisView::preset_height (Height h) TimeAxisView::preset_height (Height h)
{ {
@ -1362,3 +1272,17 @@ TimeAxisView::build_size_menu ()
items.push_back (MenuElem (_("Normal"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_height_enum), HeightNormal, true))); items.push_back (MenuElem (_("Normal"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_height_enum), HeightNormal, true)));
items.push_back (MenuElem (_("Small"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_height_enum), HeightSmall, true))); items.push_back (MenuElem (_("Small"), sigc::bind (sigc::mem_fun (*this, &TimeAxisView::set_height_enum), HeightSmall, true)));
} }
void
TimeAxisView::reset_visual_state ()
{
/* this method is not required to trigger a global redraw */
string str = gui_property ("height");
if (!str.empty()) {
set_height (atoi (str));
} else {
set_height (preset_height (HeightNormal));
}
}

View file

@ -74,7 +74,7 @@ class StreamView;
* This class provides the basic LHS controls and display methods. This should be * This class provides the basic LHS controls and display methods. This should be
* extended to create functional time-axis based views. * extended to create functional time-axis based views.
*/ */
class TimeAxisView : public virtual AxisView, public PBD::Stateful class TimeAxisView : public virtual AxisView
{ {
private: private:
enum NamePackingBits { enum NamePackingBits {
@ -87,9 +87,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
TimeAxisView(ARDOUR::Session* sess, PublicEditor& ed, TimeAxisView* parent, ArdourCanvas::Canvas& canvas); TimeAxisView(ARDOUR::Session* sess, PublicEditor& ed, TimeAxisView* parent, ArdourCanvas::Canvas& canvas);
virtual ~TimeAxisView (); virtual ~TimeAxisView ();
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
static PBD::Signal1<void,TimeAxisView*> CatchDeletion; static PBD::Signal1<void,TimeAxisView*> CatchDeletion;
/** @return index of this TimeAxisView within its parent */ /** @return index of this TimeAxisView within its parent */
@ -129,8 +126,8 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
void show_name_label (); void show_name_label ();
void show_name_entry (); void show_name_entry ();
virtual bool set_visibility (bool);
virtual guint32 show_at (double y, int& nth, Gtk::VBox *parent); virtual guint32 show_at (double y, int& nth, Gtk::VBox *parent);
virtual void hide ();
void clip_to_viewport (); void clip_to_viewport ();
@ -152,6 +149,8 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
void set_height_enum (Height, bool apply_to_selection = false); void set_height_enum (Height, bool apply_to_selection = false);
void reset_height(); void reset_height();
virtual void reset_visual_state ();
std::pair<TimeAxisView*, ARDOUR::layer_t> covers_y_position (double); std::pair<TimeAxisView*, ARDOUR::layer_t> covers_y_position (double);
virtual void step_height (bool); virtual void step_height (bool);
@ -196,7 +195,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
TimeAxisView* get_parent () { return parent; } TimeAxisView* get_parent () { return parent; }
void set_parent (TimeAxisView& p); void set_parent (TimeAxisView& p);
bool has_state () const;
virtual LayerDisplay layer_display () const { return Overlaid; } virtual LayerDisplay layer_display () const { return Overlaid; }
virtual StreamView* view () const { return 0; } virtual StreamView* view () const { return 0; }
@ -205,7 +203,7 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
Children get_child_list (); Children get_child_list ();
SelectionRect* get_selection_rect(uint32_t id); SelectionRect* get_selection_rect(uint32_t id);
static uint32_t preset_height (Height); static uint32_t preset_height (Height);
protected: protected:
@ -270,18 +268,12 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
TimeAxisView* parent; TimeAxisView* parent;
/** Find the parent with state */
TimeAxisView* get_parent_with_state();
Children children; Children children;
bool is_child (TimeAxisView*); bool is_child (TimeAxisView*);
void remove_child (boost::shared_ptr<TimeAxisView>); void remove_child (boost::shared_ptr<TimeAxisView>);
void add_child (boost::shared_ptr<TimeAxisView>); void add_child (boost::shared_ptr<TimeAxisView>);
virtual void hide ();
virtual void show ();
/* selection display */ /* selection display */
ArdourCanvas::Group *selection_group; ArdourCanvas::Group *selection_group;

View file

@ -120,6 +120,7 @@ gtk2_ardour_sources = [
'gtk-custom-hruler.c', 'gtk-custom-hruler.c',
'gtk-custom-ruler.c', 'gtk-custom-ruler.c',
'gtk_pianokeyboard.c', 'gtk_pianokeyboard.c',
'gui_object.cc',
'insert_time_dialog.cc', 'insert_time_dialog.cc',
'interthread_progress_window.cc', 'interthread_progress_window.cc',
'io_selector.cc', 'io_selector.cc',