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 ((*i)->set_marked_for_display (showit)) {
changed = true;
}
}
if (showit != (*i)->marked_for_display()) {
(*i)->set_visibility (showit);
/* now trigger a redisplay */
if (!no_redraw) {
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);
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? */
}
XMLProperty const * prop = node.property ("shown");
if (prop) {
set_visibility (string_is_affirmative (prop->value()));
set_gui_property ("visible", (yn ? "yes" : "no"));
} else {
set_visibility (false);
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)
{
@ -4103,9 +4114,7 @@ Editor::current_visual_state (bool with_tracks)
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()));
}
*(vs->gui_state) = *ARDOUR_UI::instance()->gui_object_state;
}
return vs;
@ -4161,21 +4170,13 @@ Editor::use_visual_state (VisualState& vs)
set_zoom_focus (vs.zoom_focus);
reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
for (list<TAVState>::iterator i = vs.track_states.begin(); i != vs.track_states.end(); ++i) {
TrackViewList::iterator t;
*ARDOUR_UI::instance()->gui_object_state = *vs.gui_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);
}
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(*i)->reset_visual_state ();
}
if (!vs.track_states.empty()) {
_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;
Editing::ZoomFocus zoom_focus;
std::list<TAVState> track_states;
GUIObjectState* gui_state;
};
std::list<VisualState*> undo_visual_stack;

View file

@ -468,20 +468,17 @@ 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 ();
} else {
tv->set_visibility (false);
}
n++;
} else {
tv->hide ();
}
}
/* 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
@ -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;
}
}
}
}
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 */

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)
{
@ -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);
cerr << "show existing auto track: " << show << " noredraw " << no_redraw << endl;
if (!no_redraw) {
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
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());
}
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;
}
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 ();
}
_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; }
@ -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',