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 "gain_meter.h"
#include "global_port_matrix.h"
#include "gui_object.h"
#include "gui_thread.h"
#include "keyboard.h"
#include "location_ui.h"
@ -133,6 +134,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **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))
, 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))
@ -293,7 +295,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
keyboard = new ArdourKeyboard(*this);
XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();
if (node) {
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);
save_state_canfail (name, switch_to_it);

View File

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

View File

@ -31,6 +31,7 @@
#include "ardour_ui.h"
#include "bundle_manager.h"
#include "global_port_matrix.h"
#include "gui_object.h"
#include "gui_thread.h"
#include "keyeditor.h"
#include "location_ui.h"
@ -63,6 +64,14 @@ ARDOUR_UI::set_session (Session *s)
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()) {
location_ui->get()->set_session(s);
}

View File

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

View File

@ -77,10 +77,17 @@ using namespace PBD;
using namespace Gtk;
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)
, 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...
assert(!is_track() || is_audio_track());
@ -99,10 +106,6 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
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 (automation_child (GainAutomation) == 0) {
create_automation_child (GainAutomation, false);
@ -156,18 +159,14 @@ AudioTimeAxisView::audio_view()
guint32
AudioTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
{
ensure_xml_node ();
xml_node->add_property ("shown-editor", "yes");
set_gui_property ("visible", "yes");
return TimeAxisView::show_at (y, nth, parent);
}
void
AudioTimeAxisView::hide ()
{
ensure_xml_node ();
xml_node->add_property ("shown-editor", "no");
set_gui_property ("visible", "no");
TimeAxisView::hide ();
}
@ -204,10 +203,10 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
* since it will have been set visible by default.
*/
existing->second->set_visibility (show);
existing->second->set_marked_for_display (show);
if (!no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
request_redraw ();
}
return;
@ -221,7 +220,6 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
param.type() == PanElevationAutomation ||
param.type() == PanAzimuthAutomation) {
ensure_xml_node ();
ensure_pan_views (show);
} else if (param.type() == PluginAutomation) {
@ -286,8 +284,8 @@ AudioTimeAxisView::update_gain_track_visibility ()
{
bool const showit = gain_automation_item->get_active();
if (showit != gain_track->marked_for_display()) {
gain_track->set_visibility (showit);
if (showit != string_is_affirmative (gain_track->gui_property ("visible"))) {
gain_track->set_marked_for_display (showit);
/* now trigger a redisplay */
@ -301,17 +299,17 @@ void
AudioTimeAxisView::update_pan_track_visibility ()
{
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) {
if (showit != (*i)->marked_for_display()) {
(*i)->set_visibility (showit);
/* now trigger a redisplay */
if (!no_redraw) {
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
}
if ((*i)->set_marked_for_display (showit)) {
changed = true;
}
}
if (changed) {
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
}
}
void
@ -326,8 +324,7 @@ AudioTimeAxisView::show_all_automation (bool apply_to_selection)
RouteTimeAxisView::show_all_automation ();
no_redraw = false;
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
request_redraw ();
}
}
@ -343,7 +340,7 @@ AudioTimeAxisView::show_existing_automation (bool apply_to_selection)
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();
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)));
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;
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->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 ();
for (set<Evoral::Parameter>::iterator p = params.begin(); p != params.end(); ++p) {

View File

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

View File

@ -54,7 +54,6 @@ using namespace Editing;
Pango::FontDescription AutomationTimeAxisView::name_font;
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.
@ -142,6 +141,13 @@ AutomationTimeAxisView::AutomationTimeAxisView (
ARDOUR_UI::instance()->set_tip(auto_button, _("automation state"));
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 */
/* we never show these for automation tracks, so make
@ -186,12 +192,6 @@ AutomationTimeAxisView::AutomationTimeAxisView (
controls_base_unselected_name = X_("AutomationTrackControlsBase");
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 */
if (show_regions) {
@ -403,19 +403,8 @@ AutomationTimeAxisView::set_height (uint32_t h)
uint32_t const normal = preset_height (HeightNormal);
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);
_base_rect->property_y2() = h;
if (_line) {
@ -427,12 +416,6 @@ AutomationTimeAxisView::set_height (uint32_t h)
_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) {
first_call_to_set_height = false;
@ -483,12 +466,12 @@ AutomationTimeAxisView::set_samples_per_unit (double spu)
void
AutomationTimeAxisView::hide_clicked ()
{
// LAME fix for refreshing the hide button
hide_button.set_sensitive(false);
set_marked_for_display (false);
hide ();
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(parent);
if (rtv) {
rtv->request_redraw ();
}
hide_button.set_sensitive(true);
}
@ -951,61 +934,30 @@ AutomationTimeAxisView::color_handler ()
}
int
AutomationTimeAxisView::set_state (const XMLNode& node, int version)
AutomationTimeAxisView::set_state_2X (const XMLNode& node, int /*version*/)
{
TimeAxisView::set_state (node, version);
if (version < 3000) {
return set_state_2X (node, version);
}
XMLProperty const * prop = node.property ("shown");
if (prop) {
set_visibility (string_is_affirmative (prop->value()));
} else {
set_visibility (false);
if (node.name() == X_("gain") && _parameter == Evoral::Parameter (GainAutomation)) {
XMLProperty const * shown = node.property (X_("shown"));
if (shown) {
bool yn = string_is_affirmative (shown->value ());
if (yn) {
_canvas_display->show (); /* FIXME: necessary? show_at? */
}
set_gui_property ("visible", (yn ? "yes" : "no"));
} else {
set_gui_property ("visible", "no");
}
}
return 0;
}
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;
}
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
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 */
bool
@ -1087,3 +1010,18 @@ AutomationTimeAxisView::lines () const
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&);
int set_state (const XMLNode&, int version);
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
static const std::string state_node_name;
XMLNode* get_state_node();
std::string state_id() const;
boost::shared_ptr<ARDOUR::AutomationControl> control() { return _control; }
boost::shared_ptr<AutomationController> controller() { return _controller; }
@ -156,9 +154,6 @@ class AutomationTimeAxisView : public TimeAxisView {
Gtk::CheckMenuItem* mode_discrete_item;
Gtk::CheckMenuItem* mode_line_item;
void hide ();
void show ();
void add_line (boost::shared_ptr<AutomationLine>);
void clear_clicked ();
@ -184,8 +179,6 @@ class AutomationTimeAxisView : public TimeAxisView {
PBD::ScopedConnectionList _list_connections;
PBD::ScopedConnectionList _route_connections;
void update_extra_xml_shown (bool editor_shown);
void entered ();
void exited ();

View File

@ -35,6 +35,8 @@
#include "ardour/utils.h"
#include "public_editor.h"
#include "ardour_ui.h"
#include "gui_object.h"
#include "axis_view.h"
#include "i18n.h"
@ -49,7 +51,6 @@ AxisView::AxisView (ARDOUR::Session* sess)
: SessionHandlePtr (sess)
{
_selected = false;
_marked_for_display = false;
}
AxisView::~AxisView()
@ -95,3 +96,43 @@ AxisView::unique_random_color()
/* 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 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;
void set_old_order_key (uint32_t ok) { _old_order_key = ok; }
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:
AxisView (ARDOUR::Session* sess);

View File

@ -77,49 +77,50 @@
#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 "sfdb_ui.h"
#include "gui_thread.h"
#include "simpleline.h"
#include "rhythm_ferret.h"
#include "actions.h"
#include "tempo_lines.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 "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_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_regions.h"
#include "editor_route_groups.h"
#include "editor_routes.h"
#include "editor_snapshots.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 "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"
@ -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::current_visual_state (bool with_tracks)
{
@ -4102,10 +4113,8 @@ Editor::current_visual_state (bool with_tracks)
vs->leftmost_frame = leftmost_frame;
vs->zoom_focus = zoom_focus;
if (with_tracks) {
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
vs->track_states.push_back (TAVState ((*i), &(*i)->get_state()));
}
if (with_tracks) {
*(vs->gui_state) = *ARDOUR_UI::instance()->gui_object_state;
}
return vs;
@ -4160,22 +4169,14 @@ Editor::use_visual_state (VisualState& vs)
set_zoom_focus (vs.zoom_focus);
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) {
TrackViewList::iterator t;
/* 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 ();
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(*i)->reset_visual_state ();
}
_routes->update_visibility ();
_routes->resume_redisplay ();
no_save_visual = false;
@ -4840,9 +4841,11 @@ Editor::handle_new_route (RouteList& routes)
DataType dt = route->input()->default_type();
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) {
rtv = new MidiTimeAxisView (*this, _session, route, *track_canvas);
rtv = new MidiTimeAxisView (*this, _session, *track_canvas);
rtv->set_route (route);
} else {
throw unknown_type();
}

View File

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

View File

@ -468,21 +468,18 @@ EditorRoutes::redisplay ()
route->set_order_key (N_ ("editor"), n);
}
bool visible = (*i)[_columns.visible];
bool visible = tv->marked_for_display ();
/* show or hide the TimeAxisView */
if (visible) {
tv->set_marked_for_display (true);
position += tv->show_at (position, n, &_editor->edit_controls_vbox);
tv->clip_to_viewport ();
n++;
} else {
tv->set_visibility (false);
tv->hide ();
}
n++;
}
/* 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
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];
if (tv) {
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
@ -700,7 +699,6 @@ EditorRoutes::update_visibility ()
for (i = rows.begin(); i != rows.end(); ++i) {
TimeAxisView *tv = (*i)[_columns.tv];
(*i)[_columns.visible] = tv->marked_for_display ();
cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl;
}
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();
// intialize our data items
_marked_for_display = true;
y_position = -1 ;
/* 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
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
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 KEYBOARD_MIN_HEIGHT = 140;
MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
boost::shared_ptr<Route> rt, Canvas& canvas)
MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas)
: AxisView(sess) // virtually inherited
, RouteTimeAxisView(ed, sess, rt, canvas)
, RouteTimeAxisView(ed, sess, canvas)
, _ignore_signals(false)
, _range_scroomer(0)
, _piano_roll_header(0)
@ -118,6 +117,13 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
, controller_menu (0)
, _step_editor (0)
{
}
void
MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
{
RouteTimeAxisView::set_route (rt);
subplugin_menu.set_name ("ArdourContextMenu");
_view = new MidiStreamView (*this);
@ -138,10 +144,6 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
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());
if (is_track()) {
@ -211,22 +213,23 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session* sess,
_channel_selector.mode_changed.connect(
sigc::mem_fun(*this, &MidiTimeAxisView::set_channel_mode));
XMLProperty *prop;
if ((prop = xml_node->property ("color-mode")) != 0) {
_color_mode = ColorMode (string_2_enum(prop->value(), _color_mode));
string prop = gui_property ("color-mode");
if (!prop.empty()) {
_color_mode = ColorMode (string_2_enum(prop, _color_mode));
if (_color_mode == ChannelColors) {
_channel_selector.set_channel_colors(CanvasNoteEvent::midi_channel_colors);
}
}
if ((prop = xml_node->property ("note-mode")) != 0) {
_note_mode = NoteMode (string_2_enum(prop->value(), _note_mode));
set_color_mode (_color_mode, true, false);
prop = gui_property ("note-mode");
if (!prop.empty()) {
_note_mode = NoteMode (string_2_enum (prop, _note_mode));
if (_percussion_mode_item) {
_percussion_mode_item->set_active (_note_mode == Percussive);
}
}
set_color_mode (_color_mode, true, false);
}
void
@ -301,25 +304,6 @@ MidiTimeAxisView::midi_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
MidiTimeAxisView::set_height (uint32_t h)
{
@ -330,7 +314,7 @@ MidiTimeAxisView::set_height (uint32_t h)
} else {
_midi_controls_box.hide();
}
if (height >= KEYBOARD_MIN_HEIGHT) {
if (is_track() && _range_scroomer)
_range_scroomer->show();
@ -754,7 +738,7 @@ MidiTimeAxisView::set_note_mode(NoteMode mode)
if (_note_mode != mode || midi_track()->note_mode() != mode) {
_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();
}
}
@ -773,7 +757,7 @@ MidiTimeAxisView::set_color_mode (ColorMode mode, bool force, bool redisplay)
}
_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) {
_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();
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.
*/
existing->second->set_visibility (show);
if (!no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
cerr << "show existing auto track: " << show << " noredraw " << no_redraw << endl;
if (existing->second->set_marked_for_display (show) && !no_redraw) {
request_redraw ();
}
return;
@ -1036,9 +1020,9 @@ MidiTimeAxisView::set_channel_mode (ChannelMode, uint16_t)
/* 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.
*/
changed = track->set_visibility (false) || changed;
changed = track->set_marked_for_display (false) || changed;
} 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;
if (changed) {
_route->gui_changed ("track_height", this);
request_redraw ();
}
}

View File

@ -59,13 +59,13 @@ class StepEditor;
class MidiTimeAxisView : public RouteTimeAxisView
{
public:
MidiTimeAxisView (PublicEditor&, ARDOUR::Session*, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas);
MidiTimeAxisView (PublicEditor&, ARDOUR::Session*, ArdourCanvas::Canvas& canvas);
virtual ~MidiTimeAxisView ();
void set_route (boost::shared_ptr<ARDOUR::Route>);
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 enter_internal_edit_mode ();
@ -109,7 +109,6 @@ class MidiTimeAxisView : public RouteTimeAxisView
private:
sigc::signal<void, std::string, std::string> _midi_patch_settings_changed;
void hide ();
void model_changed();
void custom_device_mode_changed();

View File

@ -127,7 +127,6 @@ MixerStrip::init ()
input_selector = 0;
output_selector = 0;
group_menu = 0;
_marked_for_display = false;
route_ops_menu = 0;
ignore_comment_edit = false;
ignore_toggle = false;
@ -527,25 +526,11 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
void
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 ((prop = xml_node->property ("strip-width")) != 0) {
set_width_enum (Width (string_2_enum (prop->value(), _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;
string str = gui_property ("strip-width");
if (!str.empty()) {
set_width_enum (Width (string_2_enum (str, _width)), this);
}
}
@ -561,12 +546,10 @@ MixerStrip::set_width_enum (Width w, void* owner)
_width_owner = owner;
ensure_xml_node ();
_width = w;
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 ();
@ -635,12 +618,10 @@ MixerStrip::set_packed (bool yn)
{
_packed = yn;
ensure_xml_node ();
if (_packed) {
xml_node->add_property ("shown-mixer", "yes");
set_gui_property ("visible", "yes");
} 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 ());
}
}
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 PBD::Signal1<void,MixerStrip*> CatchDeletion;
std::string state_id() const;
protected:
friend class Mixer_UI;
void set_packed (bool yn);

View File

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

View File

@ -1006,3 +1006,9 @@ MonitorSection::assign_controllables ()
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; }
std::string state_id() const;
private:
Gtk::VBox vpacker;
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)
, RouteUI(rt, sess)
, RouteUI(sess)
, TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas)
, _view (0)
, parent_canvas (canvas)
, button_table (3, 3)
, route_group_button (_("g"))
, playlist_button (_("p"))
, 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)
{
}
void
RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
{
RouteUI::set_route (rt);
gm.set_controls (_route, _route->shared_peak_meter(), _route->amp());
gm.get_level_meter().set_no_show_all();
gm.get_level_meter().setup_meters(50);
_has_state = true;
playlist_action_menu = 0;
automation_action_menu = 0;
plugins_submenu_item = 0;
mode_menu = 0;
_view = 0;
string str = gui_property ("height");
if (!str.empty()) {
set_height (atoi (str));
} else {
set_height (preset_height (HeightNormal));
}
if (!_route->is_hidden()) {
_marked_for_display = true;
set_gui_property ("visible", "yes");
}
mute_changed (0);
@ -213,12 +227,16 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
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()->SpeedChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::speed_changed, this), gui_context());
/* pick up the correct freeze state */
map_frozen ();
}
_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());
}
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
RouteTimeAxisView::build_automation_action_menu (bool for_selection)
{
@ -850,16 +852,10 @@ RouteTimeAxisView::set_height (uint32_t h)
TimeAxisView::set_height (h);
ensure_xml_node ();
if (_view) {
_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)) {
reset_meter();
@ -906,7 +902,7 @@ RouteTimeAxisView::set_height (uint32_t h)
if (height_changed && !no_redraw) {
/* 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 {
assert (menu);
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()
will have done that for us.
*/
if (!no_redraw) {
_route->gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
if (changed && !no_redraw) {
request_redraw ();
}
}
}
@ -1675,7 +1673,7 @@ RouteTimeAxisView::automation_track_hidden (Evoral::Parameter param)
}
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 */
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);
@ -1717,7 +1715,7 @@ RouteTimeAxisView::show_all_automation (bool apply_to_selection)
/* 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) {
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);
if (menu) {
@ -1754,7 +1752,7 @@ RouteTimeAxisView::show_existing_automation (bool apply_to_selection)
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 */
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);
@ -1787,7 +1785,7 @@ RouteTimeAxisView::hide_all_automation (bool apply_to_selection)
}
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) {
_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;
XMLProperty* prop;
XMLNode* node;
add_child (track);
track->Hiding.connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param));
_automation_tracks[param] = track;
if ((node = track->get_state_node()) != 0) {
if ((prop = node->property ("shown")) != 0) {
/* existing state overrides "show" argument */
show = string_is_affirmative (prop->value());
}
/* existing state overrides "show" argument */
string s = track->gui_property ("visible");
if (!s.empty()) {
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) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
if (show && !no_redraw) {
request_redraw ();
}
if (!EventTypeMap::instance().is_midi_parameter(param)) {
@ -2076,13 +2071,12 @@ RouteTimeAxisView::processor_menu_item_toggled (RouteTimeAxisView::ProcessorAuto
redraw = true;
}
if (pan->view && showit != pan->view->marked_for_display()) {
pan->view->set_visibility (showit);
if (pan->view && pan->view->set_marked_for_display (showit)) {
redraw = true;
}
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) {
_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);
}
ensure_xml_node ();
xml_node->add_property (N_("layer-display"), enum_2_string (d));
set_gui_property (X_("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));
#ifdef GUI_OBJECT_STATE_FIX_REQUIRED
if (update_xml) {
if (!underlay_xml_node) {
ensure_xml_node();
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");
prop->set_value(v->trackview().route()->id().to_s());
}
#endif
}
}
@ -2492,3 +2486,8 @@ RouteTimeAxisView::uncombine_regions ()
_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
{
public:
RouteTimeAxisView (PublicEditor&, ARDOUR::Session*, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas);
RouteTimeAxisView (PublicEditor&, ARDOUR::Session*, ArdourCanvas::Canvas& canvas);
virtual ~RouteTimeAxisView ();
void set_route (boost::shared_ptr<ARDOUR::Route>);
void show_selection (TimeSelection&);
void set_button_names ();
@ -137,6 +139,8 @@ public:
void meter_changed ();
void effective_gain_display () { gm.effective_gain_display(); }
std::string state_id() const;
static void setup_slider_pix ();
protected:

View File

@ -70,13 +70,6 @@ RouteUI::RouteUI (ARDOUR::Session* sess)
init ();
}
RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session* sess)
: AxisView(sess)
{
init ();
set_route (rt);
}
RouteUI::~RouteUI()
{
_route.reset (); /* drop reference to route, so that it can be cleaned up */
@ -93,7 +86,6 @@ void
RouteUI::init ()
{
self_destruct = true;
xml_node = 0;
mute_menu = 0;
solo_menu = 0;
sends_menu = 0;
@ -173,11 +165,6 @@ RouteUI::reset ()
delete mute_menu;
mute_menu = 0;
if (xml_node) {
/* do not delete the node - its owned by the route */
xml_node = 0;
}
denormal_menu_item = 0;
}
@ -1278,62 +1265,29 @@ RouteUI::set_color (const Gdk::Color & c)
_color = c;
ensure_xml_node ();
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 */
}
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
RouteUI::set_color_from_route ()
{
XMLProperty *prop;
const string str = gui_property ("color");
RouteUI::ensure_xml_node ();
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;
if (str.empty()) {
return 1;
}
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
@ -1787,3 +1741,11 @@ RouteUI::set_invert_sensitive (bool 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;
void request_redraw ();
virtual void set_color (const Gdk::Color & c);
void choose_color ();
@ -108,9 +110,6 @@ class RouteUI : public virtual AxisView
Gtk::Menu* solo_menu;
Gtk::Menu* sends_menu;
XMLNode *xml_node;
void ensure_xml_node ();
bool mute_press(GdkEventButton*);
bool mute_release(GdkEventButton*);
bool solo_press(GdkEventButton*);

View File

@ -103,7 +103,6 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
height = 0;
_effective_height = 0;
parent = rent;
_has_state = false;
last_name_entry_key_press_event = 0;
name_packing = NamePackingBits (0);
_resize_drag_start = -1;
@ -220,6 +219,47 @@ TimeAxisView::~TimeAxisView()
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.
*
* @param y y position.
@ -253,22 +293,22 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
_canvas_background->raise_to_top ();
_canvas_display->raise_to_top ();
if (_marked_for_display) {
time_axis_vbox.show ();
controls_ebox.show ();
_canvas_background->show ();
}
time_axis_vbox.show ();
controls_ebox.show ();
_canvas_background->show ();
_hidden = false;
_effective_height = current_height ();
/* now show children */
/* now show relevant children */
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
if (canvas_item_visible ((*i)->_canvas_display)) {
if ((*i)->marked_for_display()) {
++nth;
_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
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()) {
_canvas_background->hide ();
_canvas_display->hide ();
@ -349,44 +389,6 @@ TimeAxisView::selection_click (GdkEventButton* ev)
_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.
* @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;
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) {
(*i)->set_height ();
}
@ -964,84 +970,6 @@ TimeAxisView::set_parent (TimeAxisView& 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
TimeAxisView::reset_height ()
{
@ -1288,24 +1216,6 @@ TimeAxisView::resizer_expose (GdkEventExpose* event)
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
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 (_("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
* extended to create functional time-axis based views.
*/
class TimeAxisView : public virtual AxisView, public PBD::Stateful
class TimeAxisView : public virtual AxisView
{
private:
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);
virtual ~TimeAxisView ();
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
static PBD::Signal1<void,TimeAxisView*> CatchDeletion;
/** @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_entry ();
virtual bool set_visibility (bool);
virtual guint32 show_at (double y, int& nth, Gtk::VBox *parent);
virtual void hide ();
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 reset_height();
virtual void reset_visual_state ();
std::pair<TimeAxisView*, ARDOUR::layer_t> covers_y_position (double);
virtual void step_height (bool);
@ -196,7 +195,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
TimeAxisView* get_parent () { return parent; }
void set_parent (TimeAxisView& p);
bool has_state () const;
virtual LayerDisplay layer_display () const { return Overlaid; }
virtual StreamView* view () const { return 0; }
@ -205,7 +203,7 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
Children get_child_list ();
SelectionRect* get_selection_rect(uint32_t id);
static uint32_t preset_height (Height);
protected:
@ -270,18 +268,12 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
TimeAxisView* parent;
/** Find the parent with state */
TimeAxisView* get_parent_with_state();
Children children;
bool is_child (TimeAxisView*);
void remove_child (boost::shared_ptr<TimeAxisView>);
void add_child (boost::shared_ptr<TimeAxisView>);
virtual void hide ();
virtual void show ();
/* selection display */
ArdourCanvas::Group *selection_group;

View File

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