mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
major, substantive reworking of how we store GUI information (visibility, height) for automation data. old design stored (insufficient) identifying information plus actual data in a GUI-only XML node; new scheme adds GUI data via extra_xml node to each AutomationControl object. reworked public/private methods for showing/hiding TimeAxisView objects; changed labelling of automation tracks to just show the name of the controlled parameter - more info can be viewed in the tooltip for the track headers. NOTE: Session file format ALTERED. No data loss but track visibility may be different than previous ardour3 versions
git-svn-id: svn://localhost/ardour2/branches/3.0@9703 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
7468fdb9ca
commit
1060243302
30 changed files with 284 additions and 499 deletions
|
|
@ -190,6 +190,29 @@ AudioTimeAxisView::append_extra_display_menu_items ()
|
||||||
void
|
void
|
||||||
AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool show)
|
AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool show)
|
||||||
{
|
{
|
||||||
|
if (param.type() == NullAutomation) {
|
||||||
|
cerr << "WARNING: Attempt to create NullAutomation child, ignoring" << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomationTracks::iterator existing = _automation_tracks.find (param);
|
||||||
|
|
||||||
|
if (existing != _automation_tracks.end()) {
|
||||||
|
|
||||||
|
/* automation track created because we had existing data for
|
||||||
|
* the processor, but visibility may need to be controlled
|
||||||
|
* 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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (param.type() == GainAutomation) {
|
if (param.type() == GainAutomation) {
|
||||||
|
|
||||||
create_gain_automation_child (param, show);
|
create_gain_automation_child (param, show);
|
||||||
|
|
@ -264,16 +287,7 @@ AudioTimeAxisView::update_gain_track_visibility ()
|
||||||
bool const showit = gain_automation_item->get_active();
|
bool const showit = gain_automation_item->get_active();
|
||||||
|
|
||||||
if (showit != gain_track->marked_for_display()) {
|
if (showit != gain_track->marked_for_display()) {
|
||||||
if (showit) {
|
gain_track->set_visibility (showit);
|
||||||
gain_track->set_marked_for_display (true);
|
|
||||||
gain_track->canvas_display()->show();
|
|
||||||
gain_track->canvas_background()->show();
|
|
||||||
gain_track->get_state_node()->add_property ("shown", X_("yes"));
|
|
||||||
} else {
|
|
||||||
gain_track->set_marked_for_display (false);
|
|
||||||
gain_track->hide ();
|
|
||||||
gain_track->get_state_node()->add_property ("shown", X_("no"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now trigger a redisplay */
|
/* now trigger a redisplay */
|
||||||
|
|
||||||
|
|
@ -291,17 +305,7 @@ AudioTimeAxisView::update_pan_track_visibility ()
|
||||||
for (list<boost::shared_ptr<AutomationTimeAxisView> >::iterator i = pan_tracks.begin(); i != pan_tracks.end(); ++i) {
|
for (list<boost::shared_ptr<AutomationTimeAxisView> >::iterator i = pan_tracks.begin(); i != pan_tracks.end(); ++i) {
|
||||||
|
|
||||||
if (showit != (*i)->marked_for_display()) {
|
if (showit != (*i)->marked_for_display()) {
|
||||||
if (showit) {
|
(*i)->set_visibility (showit);
|
||||||
(*i)->set_marked_for_display (true);
|
|
||||||
(*i)->canvas_display()->show();
|
|
||||||
(*i)->canvas_background()->show();
|
|
||||||
(*i)->get_state_node()->add_property ("shown", X_("yes"));
|
|
||||||
} else {
|
|
||||||
(*i)->set_marked_for_display (false);
|
|
||||||
(*i)->hide ();
|
|
||||||
(*i)->get_state_node()->add_property ("shown", X_("no"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now trigger a redisplay */
|
/* now trigger a redisplay */
|
||||||
if (!no_redraw) {
|
if (!no_redraw) {
|
||||||
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
|
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
|
||||||
|
|
@ -472,24 +476,6 @@ AudioTimeAxisView::build_automation_action_menu (bool for_selection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AudioTimeAxisView::add_processor_to_subplugin_menu (boost::weak_ptr<Processor> wp)
|
|
||||||
{
|
|
||||||
/* we use this override to veto the Amp processor from the plugin menu,
|
|
||||||
as its automation lane can be accessed using the special "Fader" menu
|
|
||||||
option
|
|
||||||
*/
|
|
||||||
|
|
||||||
boost::shared_ptr<Processor> p = wp.lock ();
|
|
||||||
if (!p) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (boost::dynamic_pointer_cast<Amp> (p) == 0) {
|
|
||||||
RouteTimeAxisView::add_processor_to_subplugin_menu (wp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioTimeAxisView::enter_internal_edit_mode ()
|
AudioTimeAxisView::enter_internal_edit_mode ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,6 @@ class AudioTimeAxisView : public RouteTimeAxisView
|
||||||
|
|
||||||
/* Overridden from parent to store display state */
|
/* Overridden from parent to store display state */
|
||||||
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
||||||
void hide ();
|
|
||||||
|
|
||||||
void enter_internal_edit_mode ();
|
void enter_internal_edit_mode ();
|
||||||
void leave_internal_edit_mode ();
|
void leave_internal_edit_mode ();
|
||||||
|
|
@ -101,6 +100,8 @@ class AudioTimeAxisView : public RouteTimeAxisView
|
||||||
void show_existing_automation (bool apply_to_selection = false);
|
void show_existing_automation (bool apply_to_selection = false);
|
||||||
void hide_all_automation (bool apply_to_selection = false);
|
void hide_all_automation (bool apply_to_selection = false);
|
||||||
|
|
||||||
|
void hide ();
|
||||||
|
|
||||||
void gain_hidden ();
|
void gain_hidden ();
|
||||||
void pan_hidden ();
|
void pan_hidden ();
|
||||||
|
|
||||||
|
|
@ -110,8 +111,6 @@ class AudioTimeAxisView : public RouteTimeAxisView
|
||||||
void update_gain_track_visibility ();
|
void update_gain_track_visibility ();
|
||||||
void update_pan_track_visibility ();
|
void update_pan_track_visibility ();
|
||||||
|
|
||||||
void add_processor_to_subplugin_menu (boost::weak_ptr<ARDOUR::Processor>);
|
|
||||||
|
|
||||||
Gtk::CheckMenuItem* gain_automation_item;
|
Gtk::CheckMenuItem* gain_automation_item;
|
||||||
std::list<boost::shared_ptr<AutomationTimeAxisView> > pan_tracks;
|
std::list<boost::shared_ptr<AutomationTimeAxisView> > pan_tracks;
|
||||||
Gtk::CheckMenuItem* pan_automation_item;
|
Gtk::CheckMenuItem* pan_automation_item;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <gtkmm2ext/barcontroller.h>
|
#include <gtkmm2ext/barcontroller.h>
|
||||||
|
|
||||||
#include "pbd/memento_command.h"
|
#include "pbd/memento_command.h"
|
||||||
|
#include "pbd/stacktrace.h"
|
||||||
|
|
||||||
#include "ardour/automation_control.h"
|
#include "ardour/automation_control.h"
|
||||||
#include "ardour/event_type_map.h"
|
#include "ardour/event_type_map.h"
|
||||||
#include "ardour/route.h"
|
#include "ardour/route.h"
|
||||||
|
|
@ -147,51 +150,22 @@ AutomationTimeAxisView::AutomationTimeAxisView (
|
||||||
|
|
||||||
hide_name_entry();
|
hide_name_entry();
|
||||||
|
|
||||||
/* move the name label over a bit */
|
/* keep the parameter name short */
|
||||||
|
|
||||||
string shortpname = _name;
|
string shortpname = _name;
|
||||||
bool shortened = false;
|
|
||||||
|
|
||||||
int ignore_width;
|
int ignore_width;
|
||||||
shortpname = fit_to_pixels (_name, 60, name_font, ignore_width, true);
|
shortpname = fit_to_pixels (_name, 60, name_font, ignore_width, true);
|
||||||
|
|
||||||
if (shortpname != _name ){
|
|
||||||
shortened = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
name_label.set_text (shortpname);
|
name_label.set_text (shortpname);
|
||||||
name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||||
name_label.set_name (X_("TrackParameterName"));
|
name_label.set_name (X_("TrackParameterName"));
|
||||||
|
|
||||||
if (nomparent.length()) {
|
|
||||||
|
|
||||||
/* limit the plug name string */
|
|
||||||
|
|
||||||
string pname = fit_to_pixels (nomparent, 60, name_font, ignore_width, true);
|
|
||||||
if (pname != nomparent) {
|
|
||||||
shortened = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
plugname = new Label (pname);
|
|
||||||
plugname->set_name (X_("TrackPlugName"));
|
|
||||||
plugname->show();
|
|
||||||
controls_table.remove (name_hbox);
|
|
||||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
|
||||||
plugname_packed = true;
|
|
||||||
controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
|
||||||
} else {
|
|
||||||
plugname = 0;
|
|
||||||
plugname_packed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shortened) {
|
|
||||||
string tipname = nomparent;
|
string tipname = nomparent;
|
||||||
if (!tipname.empty()) {
|
if (!tipname.empty()) {
|
||||||
tipname += ": ";
|
tipname += ": ";
|
||||||
}
|
}
|
||||||
tipname += _name;
|
tipname += _name;
|
||||||
ARDOUR_UI::instance()->set_tip(controls_ebox, tipname);
|
ARDOUR_UI::instance()->set_tip(controls_ebox, tipname);
|
||||||
}
|
|
||||||
|
|
||||||
/* add the buttons */
|
/* add the buttons */
|
||||||
controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||||
|
|
@ -212,7 +186,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (
|
||||||
controls_base_unselected_name = X_("AutomationTrackControlsBase");
|
controls_base_unselected_name = X_("AutomationTrackControlsBase");
|
||||||
controls_ebox.set_name (controls_base_unselected_name);
|
controls_ebox.set_name (controls_base_unselected_name);
|
||||||
|
|
||||||
XMLNode* xml_node = get_parent_with_state()->get_automation_child_xml_node (_parameter);
|
XMLNode* xml_node = get_state_node ();
|
||||||
|
|
||||||
if (xml_node) {
|
if (xml_node) {
|
||||||
set_state (*xml_node, Stateful::loading_state_version);
|
set_state (*xml_node, Stateful::loading_state_version);
|
||||||
|
|
@ -435,7 +409,7 @@ AutomationTimeAxisView::set_height (uint32_t h)
|
||||||
|
|
||||||
TimeAxisView* state_parent = get_parent_with_state ();
|
TimeAxisView* state_parent = get_parent_with_state ();
|
||||||
assert(state_parent);
|
assert(state_parent);
|
||||||
XMLNode* xml_node = state_parent->get_automation_child_xml_node (_parameter);
|
XMLNode* xml_node = _control->extra_xml ("GUI");
|
||||||
|
|
||||||
TimeAxisView::set_height (h);
|
TimeAxisView::set_height (h);
|
||||||
_base_rect->property_y2() = h;
|
_base_rect->property_y2() = h;
|
||||||
|
|
@ -460,19 +434,6 @@ AutomationTimeAxisView::set_height (uint32_t h)
|
||||||
first_call_to_set_height = false;
|
first_call_to_set_height = false;
|
||||||
|
|
||||||
if (h >= preset_height (HeightNormal)) {
|
if (h >= preset_height (HeightNormal)) {
|
||||||
controls_table.remove (name_hbox);
|
|
||||||
|
|
||||||
if (plugname) {
|
|
||||||
if (plugname_packed) {
|
|
||||||
controls_table.remove (*plugname);
|
|
||||||
plugname_packed = false;
|
|
||||||
}
|
|
||||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
|
||||||
plugname_packed = true;
|
|
||||||
controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
|
||||||
} else {
|
|
||||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
|
||||||
}
|
|
||||||
hide_name_entry ();
|
hide_name_entry ();
|
||||||
show_name_label ();
|
show_name_label ();
|
||||||
name_hbox.show_all ();
|
name_hbox.show_all ();
|
||||||
|
|
@ -481,14 +442,6 @@ AutomationTimeAxisView::set_height (uint32_t h)
|
||||||
hide_button.show_all();
|
hide_button.show_all();
|
||||||
|
|
||||||
} else if (h >= preset_height (HeightSmall)) {
|
} else if (h >= preset_height (HeightSmall)) {
|
||||||
controls_table.remove (name_hbox);
|
|
||||||
if (plugname) {
|
|
||||||
if (plugname_packed) {
|
|
||||||
controls_table.remove (*plugname);
|
|
||||||
plugname_packed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
|
||||||
controls_table.hide_all ();
|
controls_table.hide_all ();
|
||||||
hide_name_entry ();
|
hide_name_entry ();
|
||||||
show_name_label ();
|
show_name_label ();
|
||||||
|
|
@ -989,24 +942,18 @@ AutomationTimeAxisView::set_state (const XMLNode& node, int version)
|
||||||
return set_state_2X (node, version);
|
return set_state_2X (node, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLProperty const * type = node.property ("automation-id");
|
XMLProperty const * prop = node.property ("shown");
|
||||||
if (type && type->value () == ARDOUR::EventTypeMap::instance().to_symbol (_parameter)) {
|
|
||||||
XMLProperty const * shown = node.property ("shown");
|
|
||||||
if (shown && shown->value () == "yes") {
|
|
||||||
set_marked_for_display (true);
|
|
||||||
_canvas_display->show (); /* FIXME: necessary? show_at? */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_marked_for_display) {
|
if (prop) {
|
||||||
hide();
|
set_visibility (string_is_affirmative (prop->value()));
|
||||||
|
} else {
|
||||||
|
set_visibility (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
||||||
AutomationTimeAxisView::set_state_2X (const XMLNode& node, int /*version*/)
|
AutomationTimeAxisView::set_state_2X (const XMLNode& node, int /*version*/)
|
||||||
{
|
{
|
||||||
if (node.name() == X_("gain") && _parameter == Evoral::Parameter (GainAutomation)) {
|
if (node.name() == X_("gain") && _parameter == Evoral::Parameter (GainAutomation)) {
|
||||||
|
|
@ -1027,50 +974,77 @@ AutomationTimeAxisView::set_state_2X (const XMLNode& node, int /*version*/)
|
||||||
XMLNode*
|
XMLNode*
|
||||||
AutomationTimeAxisView::get_state_node ()
|
AutomationTimeAxisView::get_state_node ()
|
||||||
{
|
{
|
||||||
TimeAxisView* state_parent = get_parent_with_state ();
|
return _control->extra_xml ("GUI", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (state_parent) {
|
void
|
||||||
return state_parent->get_automation_child_xml_node (_parameter);
|
AutomationTimeAxisView::update_extra_xml_shown (bool shown)
|
||||||
} else {
|
{
|
||||||
return 0;
|
XMLNode* xml_node = get_state_node();
|
||||||
|
if (xml_node) {
|
||||||
|
xml_node->add_property ("shown", shown ? "yes" : "no");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
|
AutomationTimeAxisView::what_has_visible_automation (const boost::shared_ptr<Automatable>& automatable, set<Evoral::Parameter>& visible)
|
||||||
{
|
{
|
||||||
XMLNode* xml_node = get_state_node();
|
/* this keeps "knowledge" of how we store visibility information
|
||||||
if (xml_node) {
|
in XML private to this class.
|
||||||
xml_node->add_property ("shown", editor_shown ? "yes" : "no");
|
*/
|
||||||
|
|
||||||
|
assert (automatable);
|
||||||
|
|
||||||
|
Automatable::Controls& controls (automatable->controls());
|
||||||
|
|
||||||
|
for (Automatable::Controls::iterator i = controls.begin(); i != controls.end(); ++i) {
|
||||||
|
|
||||||
|
boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (i->second);
|
||||||
|
|
||||||
|
if (ac) {
|
||||||
|
|
||||||
|
const XMLNode* gui_node = ac->extra_xml ("GUI");
|
||||||
|
|
||||||
|
if (gui_node) {
|
||||||
|
const XMLProperty* prop = gui_node->property ("shown");
|
||||||
|
if (prop) {
|
||||||
|
if (string_is_affirmative (prop->value())) {
|
||||||
|
visible.insert (i->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guint32
|
guint32
|
||||||
AutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
|
AutomationTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent)
|
||||||
{
|
{
|
||||||
|
if (!canvas_item_visible (_canvas_display)) {
|
||||||
update_extra_xml_shown (true);
|
update_extra_xml_shown (true);
|
||||||
|
}
|
||||||
|
|
||||||
return TimeAxisView::show_at (y, nth, parent);
|
return TimeAxisView::show_at (y, nth, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationTimeAxisView::hide ()
|
AutomationTimeAxisView::show ()
|
||||||
{
|
{
|
||||||
update_extra_xml_shown (false);
|
if (!canvas_item_visible (_canvas_display)) {
|
||||||
|
update_extra_xml_shown (true);
|
||||||
TimeAxisView::hide ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
AutomationTimeAxisView::set_visibility (bool yn)
|
|
||||||
{
|
|
||||||
bool changed = TimeAxisView::set_visibility (yn);
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
get_state_node()->add_property ("shown", yn ? X_("yes") : X_("no"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
return TimeAxisView::show ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomationTimeAxisView::hide ()
|
||||||
|
{
|
||||||
|
if (canvas_item_visible (_canvas_display)) {
|
||||||
|
update_extra_xml_shown (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeAxisView::hide ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return true if this view has any automation data to display */
|
/** @return true if this view has any automation data to display */
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
|
|
||||||
virtual void set_height (uint32_t);
|
virtual void set_height (uint32_t);
|
||||||
void set_samples_per_unit (double);
|
void set_samples_per_unit (double);
|
||||||
bool set_visibility (bool yn);
|
|
||||||
std::string name() const { return _name; }
|
std::string name() const { return _name; }
|
||||||
|
|
||||||
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, framepos_t, double);
|
void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, framepos_t, double);
|
||||||
|
|
@ -99,7 +98,6 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
|
|
||||||
int set_state (const XMLNode&, int version);
|
int set_state (const XMLNode&, int version);
|
||||||
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
||||||
void hide ();
|
|
||||||
|
|
||||||
static const std::string state_node_name;
|
static const std::string state_node_name;
|
||||||
XMLNode* get_state_node();
|
XMLNode* get_state_node();
|
||||||
|
|
@ -120,6 +118,8 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
return _route;
|
return _route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void what_has_visible_automation (const boost::shared_ptr<ARDOUR::Automatable>& automatable, std::set<Evoral::Parameter>& visible);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** parent route */
|
/** parent route */
|
||||||
boost::shared_ptr<ARDOUR::Route> _route;
|
boost::shared_ptr<ARDOUR::Route> _route;
|
||||||
|
|
@ -156,6 +156,9 @@ class AutomationTimeAxisView : public TimeAxisView {
|
||||||
Gtk::CheckMenuItem* mode_discrete_item;
|
Gtk::CheckMenuItem* mode_discrete_item;
|
||||||
Gtk::CheckMenuItem* mode_line_item;
|
Gtk::CheckMenuItem* mode_line_item;
|
||||||
|
|
||||||
|
void hide ();
|
||||||
|
void show ();
|
||||||
|
|
||||||
void add_line (boost::shared_ptr<AutomationLine>);
|
void add_line (boost::shared_ptr<AutomationLine>);
|
||||||
|
|
||||||
void clear_clicked ();
|
void clear_clicked ();
|
||||||
|
|
|
||||||
|
|
@ -439,8 +439,7 @@ EditorRoutes::redisplay ()
|
||||||
position += tv->show_at (position, n, &_editor->edit_controls_vbox);
|
position += tv->show_at (position, n, &_editor->edit_controls_vbox);
|
||||||
tv->clip_to_viewport ();
|
tv->clip_to_viewport ();
|
||||||
} else {
|
} else {
|
||||||
tv->set_marked_for_display (false);
|
tv->set_visibility (false);
|
||||||
tv->hide ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
|
|
|
||||||
|
|
@ -846,19 +846,47 @@ MidiTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
AutomationTracks::iterator existing = _automation_tracks.find (param);
|
AutomationTracks::iterator existing = _automation_tracks.find (param);
|
||||||
|
|
||||||
if (existing != _automation_tracks.end()) {
|
if (existing != _automation_tracks.end()) {
|
||||||
|
|
||||||
|
/* automation track created because we had existing data for
|
||||||
|
* the processor, but visibility may need to be controlled
|
||||||
|
* 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 */
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.type() == GainAutomation) {
|
boost::shared_ptr<AutomationTimeAxisView> track;
|
||||||
|
|
||||||
|
switch (param.type()) {
|
||||||
|
|
||||||
|
case GainAutomation:
|
||||||
create_gain_automation_child (param, show);
|
create_gain_automation_child (param, show);
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
/* These controllers are region "automation", so we do not create
|
case PluginAutomation:
|
||||||
* an AutomationList/Line for the track */
|
/* handled elsewhere */
|
||||||
|
break;
|
||||||
|
|
||||||
boost::shared_ptr<AutomationTimeAxisView> track (
|
case MidiCCAutomation:
|
||||||
new AutomationTimeAxisView (
|
case MidiPgmChangeAutomation:
|
||||||
|
case MidiPitchBenderAutomation:
|
||||||
|
case MidiChannelPressureAutomation:
|
||||||
|
case MidiSystemExclusiveAutomation:
|
||||||
|
/* These controllers are region "automation" - they are owned
|
||||||
|
* by regions (and their MidiModels), not by the track. As a
|
||||||
|
* result we do not create an AutomationList/Line for the track
|
||||||
|
* ... except here we are doing something!! XXX
|
||||||
|
*/
|
||||||
|
|
||||||
|
track.reset (new AutomationTimeAxisView (
|
||||||
_session,
|
_session,
|
||||||
_route,
|
_route,
|
||||||
boost::shared_ptr<Automatable> (),
|
boost::shared_ptr<Automatable> (),
|
||||||
|
|
@ -869,18 +897,20 @@ MidiTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
|
||||||
true,
|
true,
|
||||||
parent_canvas,
|
parent_canvas,
|
||||||
_route->describe_parameter(param)
|
_route->describe_parameter(param)
|
||||||
)
|
));
|
||||||
);
|
|
||||||
|
|
||||||
if (_view) {
|
if (_view) {
|
||||||
_view->foreach_regionview (sigc::mem_fun (*track.get(), &TimeAxisView::add_ghost));
|
_view->foreach_regionview (sigc::mem_fun (*track.get(), &TimeAxisView::add_ghost));
|
||||||
}
|
}
|
||||||
|
|
||||||
add_automation_child (param, track, show);
|
add_automation_child (param, track, show);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error << "MidiTimeAxisView: unknown automation child " << EventTypeMap::instance().to_symbol(param) << endmsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTimeAxisView::route_active_changed ()
|
MidiTimeAxisView::route_active_changed ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@ class MidiTimeAxisView : public RouteTimeAxisView
|
||||||
/* overridden from parent to store display state */
|
/* overridden from parent to store display state */
|
||||||
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
||||||
void set_height (uint32_t);
|
void set_height (uint32_t);
|
||||||
void hide ();
|
|
||||||
|
|
||||||
void enter_internal_edit_mode ();
|
void enter_internal_edit_mode ();
|
||||||
void leave_internal_edit_mode ();
|
void leave_internal_edit_mode ();
|
||||||
|
|
@ -110,6 +109,7 @@ class MidiTimeAxisView : public RouteTimeAxisView
|
||||||
private:
|
private:
|
||||||
sigc::signal<void, std::string, std::string> _midi_patch_settings_changed;
|
sigc::signal<void, std::string, std::string> _midi_patch_settings_changed;
|
||||||
|
|
||||||
|
void hide ();
|
||||||
void model_changed();
|
void model_changed();
|
||||||
void custom_device_mode_changed();
|
void custom_device_mode_changed();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -359,19 +359,6 @@ RouteTimeAxisView::set_state (const XMLNode& node, int version)
|
||||||
set_layer_display (LayerDisplay (string_2_enum (prop->value(), _view->layer_display ())));
|
set_layer_display (LayerDisplay (string_2_enum (prop->value(), _view->layer_display ())));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (iter = kids.begin(); iter != kids.end(); ++iter) {
|
|
||||||
if ((*iter)->name() == AutomationTimeAxisView::state_node_name) {
|
|
||||||
if ((prop = (*iter)->property ("automation-id")) != 0) {
|
|
||||||
|
|
||||||
Evoral::Parameter param = ARDOUR::EventTypeMap::instance().new_parameter(prop->value());
|
|
||||||
bool show = ((prop = (*iter)->property ("shown")) != 0) && string_is_affirmative (prop->value());
|
|
||||||
create_automation_child(param, show);
|
|
||||||
} else {
|
|
||||||
warning << "Automation child has no ID" << endmsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1664,9 +1651,6 @@ RouteTimeAxisView::automation_track_hidden (Evoral::Parameter param)
|
||||||
|
|
||||||
Gtk::CheckMenuItem* menu = automation_child_menu_item (param);
|
Gtk::CheckMenuItem* menu = automation_child_menu_item (param);
|
||||||
|
|
||||||
// if Evoral::Parameter::operator< doesn't obey strict weak ordering, we may crash here....
|
|
||||||
track->get_state_node()->add_property (X_("shown"), X_("no"));
|
|
||||||
|
|
||||||
if (menu && !_hidden) {
|
if (menu && !_hidden) {
|
||||||
ignore_toggle = true;
|
ignore_toggle = true;
|
||||||
menu->set_active (false);
|
menu->set_active (false);
|
||||||
|
|
@ -1690,9 +1674,7 @@ RouteTimeAxisView::show_all_automation (bool apply_to_selection)
|
||||||
/* Show our automation */
|
/* Show our automation */
|
||||||
|
|
||||||
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
||||||
i->second->set_marked_for_display (true);
|
i->second->set_visibility (true);
|
||||||
i->second->canvas_display()->show();
|
|
||||||
i->second->get_state_node()->add_property ("shown", X_("yes"));
|
|
||||||
|
|
||||||
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
|
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
|
||||||
|
|
||||||
|
|
@ -1734,9 +1716,7 @@ RouteTimeAxisView::show_existing_automation (bool apply_to_selection)
|
||||||
|
|
||||||
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
||||||
if (i->second->has_automation()) {
|
if (i->second->has_automation()) {
|
||||||
i->second->set_marked_for_display (true);
|
i->second->set_visibility (true);
|
||||||
i->second->canvas_display()->show();
|
|
||||||
i->second->get_state_node()->add_property ("shown", X_("yes"));
|
|
||||||
|
|
||||||
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
|
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
|
||||||
if (menu) {
|
if (menu) {
|
||||||
|
|
@ -1745,7 +1725,6 @@ RouteTimeAxisView::show_existing_automation (bool apply_to_selection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Show processor automation */
|
/* Show processor automation */
|
||||||
|
|
||||||
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
for (list<ProcessorAutomationInfo*>::iterator i = processor_automation.begin(); i != processor_automation.end(); ++i) {
|
||||||
|
|
@ -1773,9 +1752,7 @@ RouteTimeAxisView::hide_all_automation (bool apply_to_selection)
|
||||||
/* Hide our automation */
|
/* Hide our automation */
|
||||||
|
|
||||||
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) {
|
||||||
i->second->set_marked_for_display (false);
|
i->second->set_visibility (false);
|
||||||
i->second->hide ();
|
|
||||||
i->second->get_state_node()->add_property ("shown", X_("no"));
|
|
||||||
|
|
||||||
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
|
Gtk::CheckMenuItem* menu = automation_child_menu_item (i->first);
|
||||||
|
|
||||||
|
|
@ -1854,25 +1831,6 @@ RouteTimeAxisView::find_processor_automation_node (boost::shared_ptr<Processor>
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string
|
|
||||||
legalize_for_xml_node (string str)
|
|
||||||
{
|
|
||||||
string::size_type pos;
|
|
||||||
string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=:";
|
|
||||||
string legal;
|
|
||||||
|
|
||||||
legal = str;
|
|
||||||
pos = 0;
|
|
||||||
|
|
||||||
while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
|
|
||||||
legal.replace (pos, 1, "_");
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return legal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor> processor, Evoral::Parameter what)
|
RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor> processor, Evoral::Parameter what)
|
||||||
{
|
{
|
||||||
|
|
@ -1893,37 +1851,21 @@ RouteTimeAxisView::add_processor_automation_curve (boost::shared_ptr<Processor>
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = processor->describe_parameter (what);
|
|
||||||
|
|
||||||
/* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
|
|
||||||
|
|
||||||
/* FIXME: ew */
|
|
||||||
|
|
||||||
char state_name[256];
|
|
||||||
snprintf (state_name, sizeof (state_name), "%s-%" PRIu32, legalize_for_xml_node (processor->name()).c_str(), what.id());
|
|
||||||
|
|
||||||
boost::shared_ptr<AutomationControl> control
|
boost::shared_ptr<AutomationControl> control
|
||||||
= boost::dynamic_pointer_cast<AutomationControl>(processor->control(what, true));
|
= boost::dynamic_pointer_cast<AutomationControl>(processor->control(what, true));
|
||||||
|
|
||||||
pan->view = boost::shared_ptr<AutomationTimeAxisView>(
|
pan->view = boost::shared_ptr<AutomationTimeAxisView>(
|
||||||
new AutomationTimeAxisView (_session, _route, processor, control, control->parameter (),
|
new AutomationTimeAxisView (_session, _route, processor, control, control->parameter (),
|
||||||
_editor, *this, false, parent_canvas, name, state_name));
|
_editor, *this, false, parent_canvas,
|
||||||
|
processor->describe_parameter (what), processor->name()));
|
||||||
|
|
||||||
pan->view->Hiding.connect (sigc::bind (sigc::mem_fun(*this, &RouteTimeAxisView::processor_automation_track_hidden), pan, processor));
|
pan->view->Hiding.connect (sigc::bind (sigc::mem_fun(*this, &RouteTimeAxisView::processor_automation_track_hidden), pan, processor));
|
||||||
|
|
||||||
if (!pan->view->marked_for_display()) {
|
add_automation_child (control->parameter(), pan->view, pan->view->marked_for_display ());
|
||||||
pan->view->hide ();
|
|
||||||
} else {
|
|
||||||
pan->menu_item->set_active (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
add_automation_child (control->parameter(), pan->view, true);
|
|
||||||
|
|
||||||
if (_view) {
|
if (_view) {
|
||||||
_view->foreach_regionview (sigc::mem_fun(*pan->view.get(), &TimeAxisView::add_ghost));
|
_view->foreach_regionview (sigc::mem_fun(*pan->view.get(), &TimeAxisView::add_ghost));
|
||||||
}
|
}
|
||||||
|
|
||||||
processor->mark_automation_visible (what, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1933,8 +1875,6 @@ RouteTimeAxisView::processor_automation_track_hidden (RouteTimeAxisView::Process
|
||||||
pan->menu_item->set_active (false);
|
pan->menu_item->set_active (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
i->mark_automation_visible (pan->what, false);
|
|
||||||
|
|
||||||
if (!no_redraw) {
|
if (!no_redraw) {
|
||||||
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
@ -1944,21 +1884,24 @@ void
|
||||||
RouteTimeAxisView::add_existing_processor_automation_curves (boost::weak_ptr<Processor> p)
|
RouteTimeAxisView::add_existing_processor_automation_curves (boost::weak_ptr<Processor> p)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Processor> processor (p.lock ());
|
boost::shared_ptr<Processor> processor (p.lock ());
|
||||||
|
|
||||||
if (!processor) {
|
if (!processor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
set<Evoral::Parameter> s;
|
set<Evoral::Parameter> existing;
|
||||||
|
|
||||||
|
processor->what_has_data (existing);
|
||||||
|
|
||||||
|
for (set<Evoral::Parameter>::iterator i = existing.begin(); i != existing.end(); ++i) {
|
||||||
|
|
||||||
|
Evoral::Parameter param (*i);
|
||||||
boost::shared_ptr<AutomationLine> al;
|
boost::shared_ptr<AutomationLine> al;
|
||||||
|
|
||||||
processor->what_has_visible_data (s);
|
if ((al = find_processor_automation_curve (processor, param)) != 0) {
|
||||||
|
|
||||||
for (set<Evoral::Parameter>::iterator i = s.begin(); i != s.end(); ++i) {
|
|
||||||
|
|
||||||
if ((al = find_processor_automation_curve (processor, *i)) != 0) {
|
|
||||||
al->queue_reset ();
|
al->queue_reset ();
|
||||||
} else {
|
} else {
|
||||||
add_processor_automation_curve (processor, (*i));
|
add_processor_automation_curve (processor, param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1975,19 +1918,16 @@ RouteTimeAxisView::add_automation_child (Evoral::Parameter param, boost::shared_
|
||||||
|
|
||||||
track->Hiding.connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param));
|
track->Hiding.connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param));
|
||||||
|
|
||||||
bool hideit = (!show);
|
_automation_tracks[param] = track;
|
||||||
|
|
||||||
if ((node = track->get_state_node()) != 0) {
|
if ((node = track->get_state_node()) != 0) {
|
||||||
if ((prop = node->property ("shown")) != 0) {
|
if ((prop = node->property ("shown")) != 0) {
|
||||||
if (string_is_affirmative (prop->value())) {
|
/* existing state overrides "show" argument */
|
||||||
hideit = false;
|
show = string_is_affirmative (prop->value());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_automation_tracks[param] = track;
|
track->set_visibility (show);
|
||||||
|
|
||||||
track->set_visibility (!hideit);
|
|
||||||
|
|
||||||
if (!no_redraw) {
|
if (!no_redraw) {
|
||||||
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||||
|
|
@ -2013,14 +1953,20 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::weak_ptr<Processor> p
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we use this override to veto the Amp processor from the plugin menu,
|
||||||
|
as its automation lane can be accessed using the special "Fader" menu
|
||||||
|
option
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (boost::dynamic_pointer_cast<Amp> (processor) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
using namespace Menu_Helpers;
|
using namespace Menu_Helpers;
|
||||||
ProcessorAutomationInfo *rai;
|
ProcessorAutomationInfo *rai;
|
||||||
list<ProcessorAutomationInfo*>::iterator x;
|
list<ProcessorAutomationInfo*>::iterator x;
|
||||||
|
|
||||||
const std::set<Evoral::Parameter>& automatable = processor->what_can_be_automated ();
|
const std::set<Evoral::Parameter>& automatable = processor->what_can_be_automated ();
|
||||||
std::set<Evoral::Parameter> has_visible_automation;
|
|
||||||
|
|
||||||
processor->what_has_visible_data(has_visible_automation);
|
|
||||||
|
|
||||||
if (automatable.empty()) {
|
if (automatable.empty()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -2053,6 +1999,9 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::weak_ptr<Processor> p
|
||||||
|
|
||||||
items.clear ();
|
items.clear ();
|
||||||
|
|
||||||
|
std::set<Evoral::Parameter> has_visible_automation;
|
||||||
|
AutomationTimeAxisView::what_has_visible_automation (processor, has_visible_automation);
|
||||||
|
|
||||||
for (std::set<Evoral::Parameter>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
|
for (std::set<Evoral::Parameter>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
|
||||||
|
|
||||||
ProcessorAutomationNode* pan;
|
ProcessorAutomationNode* pan;
|
||||||
|
|
@ -2109,24 +2058,12 @@ RouteTimeAxisView::processor_menu_item_toggled (RouteTimeAxisView::ProcessorAuto
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pan->view && showit != pan->view->marked_for_display()) {
|
if (pan->view && showit != pan->view->marked_for_display()) {
|
||||||
|
pan->view->set_visibility (showit);
|
||||||
if (showit) {
|
|
||||||
pan->view->set_marked_for_display (true);
|
|
||||||
pan->view->canvas_display()->show();
|
|
||||||
pan->view->canvas_background()->show();
|
|
||||||
} else {
|
|
||||||
rai->processor->mark_automation_visible (pan->what, true);
|
|
||||||
pan->view->set_marked_for_display (false);
|
|
||||||
pan->view->hide ();
|
|
||||||
}
|
|
||||||
|
|
||||||
redraw = true;
|
redraw = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redraw && !no_redraw) {
|
if (redraw && !no_redraw) {
|
||||||
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,10 +117,6 @@ public:
|
||||||
|
|
||||||
virtual void create_automation_child (const Evoral::Parameter& param, bool show) = 0;
|
virtual void create_automation_child (const Evoral::Parameter& param, bool show) = 0;
|
||||||
|
|
||||||
/* make sure we get the right version of this */
|
|
||||||
|
|
||||||
XMLNode* get_automation_child_xml_node (Evoral::Parameter param) { return RouteUI::get_automation_child_xml_node (param); }
|
|
||||||
|
|
||||||
typedef std::map<Evoral::Parameter, boost::shared_ptr<AutomationTimeAxisView> > AutomationTracks;
|
typedef std::map<Evoral::Parameter, boost::shared_ptr<AutomationTimeAxisView> > AutomationTracks;
|
||||||
AutomationTracks automation_tracks() { return _automation_tracks; }
|
AutomationTracks automation_tracks() { return _automation_tracks; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1306,18 +1306,10 @@ RouteUI::ensure_xml_node ()
|
||||||
new_xml_node->add_property ((*i)->name().c_str (), (*i)->value().c_str ());
|
new_xml_node->add_property ((*i)->name().c_str (), (*i)->value().c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNodeList old_children = xml_node->children ();
|
/* we can't fix up the automation track nodes,
|
||||||
for (XMLNodeConstIterator i = old_children.begin(); i != old_children.end(); ++i) {
|
* because the data is no longer stored
|
||||||
XMLNode* new_child = new XMLNode (AutomationTimeAxisView::state_node_name);
|
* per-route, but per Controllable.
|
||||||
new_child->add_property (X_("automation-id"), (*i)->name());
|
*/
|
||||||
|
|
||||||
XMLPropertyList old_props = (*i)->properties ();
|
|
||||||
for (XMLPropertyIterator j = old_props.begin(); j != old_props.end(); ++j) {
|
|
||||||
new_child->add_property ((*j)->name().c_str (), (*j)->value().c_str ());
|
|
||||||
}
|
|
||||||
|
|
||||||
new_xml_node->add_child_nocopy (*new_child);
|
|
||||||
}
|
|
||||||
|
|
||||||
_route->add_extra_xml (*new_xml_node);
|
_route->add_extra_xml (*new_xml_node);
|
||||||
xml_node = new_xml_node;
|
xml_node = new_xml_node;
|
||||||
|
|
@ -1326,34 +1318,6 @@ RouteUI::ensure_xml_node ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode*
|
|
||||||
RouteUI::get_automation_child_xml_node (Evoral::Parameter param)
|
|
||||||
{
|
|
||||||
ensure_xml_node ();
|
|
||||||
|
|
||||||
XMLNodeList kids = xml_node->children();
|
|
||||||
XMLNodeConstIterator iter;
|
|
||||||
|
|
||||||
const string sym = ARDOUR::EventTypeMap::instance().to_symbol(param);
|
|
||||||
|
|
||||||
for (iter = kids.begin(); iter != kids.end(); ++iter) {
|
|
||||||
|
|
||||||
if ((*iter)->name() == AutomationTimeAxisView::state_node_name) {
|
|
||||||
XMLProperty* type = (*iter)->property("automation-id");
|
|
||||||
if (type && type->value() == sym) {
|
|
||||||
return *iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Didn't find it, make a new one
|
|
||||||
XMLNode* child = new XMLNode (AutomationTimeAxisView::state_node_name);
|
|
||||||
child->add_property("automation-id", sym);
|
|
||||||
xml_node->add_child_nocopy (*child);
|
|
||||||
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
RouteUI::set_color_from_route ()
|
RouteUI::set_color_from_route ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -111,8 +111,6 @@ class RouteUI : public virtual AxisView
|
||||||
XMLNode *xml_node;
|
XMLNode *xml_node;
|
||||||
void ensure_xml_node ();
|
void ensure_xml_node ();
|
||||||
|
|
||||||
virtual XMLNode* get_automation_child_xml_node (Evoral::Parameter);
|
|
||||||
|
|
||||||
bool mute_press(GdkEventButton*);
|
bool mute_press(GdkEventButton*);
|
||||||
bool mute_release(GdkEventButton*);
|
bool mute_release(GdkEventButton*);
|
||||||
bool solo_press(GdkEventButton*);
|
bool solo_press(GdkEventButton*);
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,13 @@ TimeAxisView::selection_click (GdkEventButton* ev)
|
||||||
_editor.set_selected_track (*this, op, false);
|
_editor.set_selected_track (*this, op, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimeAxisView::show ()
|
||||||
|
{
|
||||||
|
canvas_display()->show();
|
||||||
|
canvas_background()->show();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimeAxisView::hide ()
|
TimeAxisView::hide ()
|
||||||
{
|
{
|
||||||
|
|
@ -1287,7 +1294,7 @@ TimeAxisView::set_visibility (bool yn)
|
||||||
if (yn != marked_for_display()) {
|
if (yn != marked_for_display()) {
|
||||||
if (yn) {
|
if (yn) {
|
||||||
set_marked_for_display (true);
|
set_marked_for_display (true);
|
||||||
canvas_display()->show();
|
show ();
|
||||||
} else {
|
} else {
|
||||||
set_marked_for_display (false);
|
set_marked_for_display (false);
|
||||||
hide ();
|
hide ();
|
||||||
|
|
@ -1298,6 +1305,7 @@ TimeAxisView::set_visibility (bool yn)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
TimeAxisView::preset_height (Height h)
|
TimeAxisView::preset_height (Height h)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -136,9 +136,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
|
||||||
|
|
||||||
bool touched (double top, double bot);
|
bool touched (double top, double bot);
|
||||||
|
|
||||||
/** Hide this TrackView */
|
|
||||||
virtual void hide ();
|
|
||||||
|
|
||||||
/** @return true if hidden, otherwise false */
|
/** @return true if hidden, otherwise false */
|
||||||
bool hidden () const { return _hidden; }
|
bool hidden () const { return _hidden; }
|
||||||
|
|
||||||
|
|
@ -201,10 +198,6 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
|
||||||
void set_parent (TimeAxisView& p);
|
void set_parent (TimeAxisView& p);
|
||||||
bool has_state () const;
|
bool has_state () const;
|
||||||
|
|
||||||
/* call this on the parent */
|
|
||||||
|
|
||||||
virtual XMLNode* get_automation_child_xml_node (Evoral::Parameter) { return 0; }
|
|
||||||
|
|
||||||
virtual LayerDisplay layer_display () const { return Overlaid; }
|
virtual LayerDisplay layer_display () const { return Overlaid; }
|
||||||
virtual StreamView* view () const { return 0; }
|
virtual StreamView* view () const { return 0; }
|
||||||
|
|
||||||
|
|
@ -286,6 +279,9 @@ class TimeAxisView : public virtual AxisView, public PBD::Stateful
|
||||||
void remove_child (boost::shared_ptr<TimeAxisView>);
|
void remove_child (boost::shared_ptr<TimeAxisView>);
|
||||||
void add_child (boost::shared_ptr<TimeAxisView>);
|
void add_child (boost::shared_ptr<TimeAxisView>);
|
||||||
|
|
||||||
|
virtual void hide ();
|
||||||
|
virtual void show ();
|
||||||
|
|
||||||
/* selection display */
|
/* selection display */
|
||||||
|
|
||||||
ArdourCanvas::Group *selection_group;
|
ArdourCanvas::Group *selection_group;
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,8 @@ UIConfiguration::set_state (const XMLNode& root, int /*version*/)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stateful::save_extra_xml (root);
|
||||||
|
|
||||||
XMLNodeList nlist = root.children();
|
XMLNodeList nlist = root.children();
|
||||||
XMLNodeConstIterator niter;
|
XMLNodeConstIterator niter;
|
||||||
XMLNode *node;
|
XMLNode *node;
|
||||||
|
|
@ -236,12 +238,10 @@ UIConfiguration::set_state (const XMLNode& root, int /*version*/)
|
||||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
||||||
|
|
||||||
node = *niter;
|
node = *niter;
|
||||||
|
|
||||||
if (node->name() == "Canvas" || node->name() == "UI") {
|
if (node->name() == "Canvas" || node->name() == "UI") {
|
||||||
set_variables (*node);
|
set_variables (*node);
|
||||||
|
|
||||||
} else if (node->name() == "Extra") {
|
|
||||||
_extra_xml = new XMLNode (*node);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,8 @@ public:
|
||||||
|
|
||||||
void protect_automation ();
|
void protect_automation ();
|
||||||
|
|
||||||
void what_has_visible_data(std::set<Evoral::Parameter>&) const;
|
|
||||||
const std::set<Evoral::Parameter>& what_can_be_automated() const { return _can_automate_list; }
|
const std::set<Evoral::Parameter>& what_can_be_automated() const { return _can_automate_list; }
|
||||||
|
void what_has_existing_automation (std::set<Evoral::Parameter>&) const;
|
||||||
void mark_automation_visible(Evoral::Parameter, bool);
|
|
||||||
|
|
||||||
inline bool should_snapshot (framepos_t now) {
|
inline bool should_snapshot (framepos_t now) {
|
||||||
return (_last_automation_snapshot > now
|
return (_last_automation_snapshot > now
|
||||||
|
|
@ -91,8 +89,6 @@ public:
|
||||||
return _automation_interval;
|
return _automation_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef Evoral::ControlSet::Controls Controls;
|
|
||||||
|
|
||||||
static const std::string xml_node_name;
|
static const std::string xml_node_name;
|
||||||
|
|
||||||
int set_automation_xml_state (const XMLNode&, Evoral::Parameter default_param);
|
int set_automation_xml_state (const XMLNode&, Evoral::Parameter default_param);
|
||||||
|
|
@ -108,7 +104,6 @@ public:
|
||||||
int load_automation (const std::string& path);
|
int load_automation (const std::string& path);
|
||||||
int old_set_automation_state(const XMLNode&);
|
int old_set_automation_state(const XMLNode&);
|
||||||
|
|
||||||
std::set<Evoral::Parameter> _visible_controls;
|
|
||||||
std::set<Evoral::Parameter> _can_automate_list;
|
std::set<Evoral::Parameter> _can_automate_list;
|
||||||
|
|
||||||
framepos_t _last_automation_snapshot;
|
framepos_t _last_automation_snapshot;
|
||||||
|
|
|
||||||
|
|
@ -79,22 +79,6 @@ Automatable::old_set_automation_state (const XMLNode& node)
|
||||||
warning << _("Automation node has no path property") << endmsg;
|
warning << _("Automation node has no path property") << endmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("visible")) != 0) {
|
|
||||||
uint32_t what;
|
|
||||||
stringstream sstr;
|
|
||||||
|
|
||||||
_visible_controls.clear ();
|
|
||||||
|
|
||||||
sstr << prop->value();
|
|
||||||
while (1) {
|
|
||||||
sstr >> what;
|
|
||||||
if (sstr.fail()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mark_automation_visible (Evoral::Parameter(PluginAutomation, 0, what), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_last_automation_snapshot = 0;
|
_last_automation_snapshot = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -167,17 +151,6 @@ Automatable::add_control(boost::shared_ptr<Evoral::Control> ac)
|
||||||
automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up
|
automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Automatable::what_has_visible_data(set<Evoral::Parameter>& s) const
|
|
||||||
{
|
|
||||||
Glib::Mutex::Lock lm (control_lock());
|
|
||||||
set<Evoral::Parameter>::const_iterator li;
|
|
||||||
|
|
||||||
for (li = _visible_controls.begin(); li != _visible_controls.end(); ++li) {
|
|
||||||
s.insert (*li);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
string
|
||||||
Automatable::describe_parameter (Evoral::Parameter param)
|
Automatable::describe_parameter (Evoral::Parameter param)
|
||||||
{
|
{
|
||||||
|
|
@ -205,20 +178,6 @@ Automatable::can_automate (Evoral::Parameter what)
|
||||||
_can_automate_list.insert (what);
|
_can_automate_list.insert (what);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Automatable::mark_automation_visible (Evoral::Parameter what, bool yn)
|
|
||||||
{
|
|
||||||
if (yn) {
|
|
||||||
_visible_controls.insert (what);
|
|
||||||
} else {
|
|
||||||
set<Evoral::Parameter>::iterator i;
|
|
||||||
|
|
||||||
if ((i = _visible_controls.find (what)) != _visible_controls.end()) {
|
|
||||||
_visible_controls.erase (i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \a legacy_param is used for loading legacy sessions where an object (IO, Panner)
|
/** \a legacy_param is used for loading legacy sessions where an object (IO, Panner)
|
||||||
* had a single automation parameter, with it's type implicit. Derived objects should
|
* had a single automation parameter, with it's type implicit. Derived objects should
|
||||||
* pass that type and it will be used for the untyped AutomationList found.
|
* pass that type and it will be used for the untyped AutomationList found.
|
||||||
|
|
@ -230,8 +189,6 @@ Automatable::set_automation_xml_state (const XMLNode& node, Evoral::Parameter le
|
||||||
|
|
||||||
/* Don't clear controls, since some may be special derived Controllable classes */
|
/* Don't clear controls, since some may be special derived Controllable classes */
|
||||||
|
|
||||||
_visible_controls.clear ();
|
|
||||||
|
|
||||||
XMLNodeList nlist = node.children();
|
XMLNodeList nlist = node.children();
|
||||||
XMLNodeIterator niter;
|
XMLNodeIterator niter;
|
||||||
|
|
||||||
|
|
@ -292,8 +249,7 @@ Automatable::get_automation_xml_state ()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
|
for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
|
||||||
boost::shared_ptr<AutomationList> l
|
boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(li->second->list());
|
||||||
= boost::dynamic_pointer_cast<AutomationList>(li->second->list());
|
|
||||||
if (!l->empty()) {
|
if (!l->empty()) {
|
||||||
node->add_child_nocopy (l->get_state ());
|
node->add_child_nocopy (l->get_state ());
|
||||||
}
|
}
|
||||||
|
|
@ -364,11 +320,9 @@ void
|
||||||
Automatable::protect_automation ()
|
Automatable::protect_automation ()
|
||||||
{
|
{
|
||||||
typedef set<Evoral::Parameter> ParameterSet;
|
typedef set<Evoral::Parameter> ParameterSet;
|
||||||
ParameterSet automated_params;
|
const ParameterSet& automated_params = what_can_be_automated ();
|
||||||
|
|
||||||
what_has_data(automated_params);
|
for (ParameterSet::const_iterator i = automated_params.begin(); i != automated_params.end(); ++i) {
|
||||||
|
|
||||||
for (ParameterSet::iterator i = automated_params.begin(); i != automated_params.end(); ++i) {
|
|
||||||
|
|
||||||
boost::shared_ptr<Evoral::Control> c = control(*i);
|
boost::shared_ptr<Evoral::Control> c = control(*i);
|
||||||
boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list());
|
boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list());
|
||||||
|
|
|
||||||
|
|
@ -185,33 +185,12 @@ XMLNode&
|
||||||
Pannable::state (bool full)
|
Pannable::state (bool full)
|
||||||
{
|
{
|
||||||
XMLNode* node = new XMLNode (X_("Pannable"));
|
XMLNode* node = new XMLNode (X_("Pannable"));
|
||||||
XMLNode* control_node;
|
|
||||||
char buf[32];
|
|
||||||
|
|
||||||
control_node = new XMLNode (X_("azimuth"));
|
node->add_child_nocopy (pan_azimuth_control->get_state());
|
||||||
snprintf (buf, sizeof(buf), "%.12g", pan_azimuth_control->get_value());
|
node->add_child_nocopy (pan_width_control->get_state());
|
||||||
control_node->add_property (X_("value"), buf);
|
node->add_child_nocopy (pan_elevation_control->get_state());
|
||||||
node->add_child_nocopy (*control_node);
|
node->add_child_nocopy (pan_frontback_control->get_state());
|
||||||
|
node->add_child_nocopy (pan_lfe_control->get_state());
|
||||||
control_node = new XMLNode (X_("width"));
|
|
||||||
snprintf (buf, sizeof(buf), "%.12g", pan_width_control->get_value());
|
|
||||||
control_node->add_property (X_("value"), buf);
|
|
||||||
node->add_child_nocopy (*control_node);
|
|
||||||
|
|
||||||
control_node = new XMLNode (X_("elevation"));
|
|
||||||
snprintf (buf, sizeof(buf), "%.12g", pan_elevation_control->get_value());
|
|
||||||
control_node->add_property (X_("value"), buf);
|
|
||||||
node->add_child_nocopy (*control_node);
|
|
||||||
|
|
||||||
control_node = new XMLNode (X_("frontback"));
|
|
||||||
snprintf (buf, sizeof(buf), "%.12g", pan_frontback_control->get_value());
|
|
||||||
control_node->add_property (X_("value"), buf);
|
|
||||||
node->add_child_nocopy (*control_node);
|
|
||||||
|
|
||||||
control_node = new XMLNode (X_("lfe"));
|
|
||||||
snprintf (buf, sizeof(buf), "%.12g", pan_lfe_control->get_value());
|
|
||||||
control_node->add_property (X_("value"), buf);
|
|
||||||
node->add_child_nocopy (*control_node);
|
|
||||||
|
|
||||||
node->add_child_nocopy (get_automation_xml_state ());
|
node->add_child_nocopy (get_automation_xml_state ());
|
||||||
|
|
||||||
|
|
@ -219,45 +198,27 @@ Pannable::state (bool full)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Pannable::set_state (const XMLNode& root, int /*version - not used*/)
|
Pannable::set_state (const XMLNode& root, int version)
|
||||||
{
|
{
|
||||||
if (root.name() != X_("Pannable")) {
|
if (root.name() != X_("Pannable")) {
|
||||||
warning << string_compose (_("Pannable given XML data for %1 - ignored"), root.name()) << endmsg;
|
warning << string_compose (_("Pannable given XML data for %1 - ignored"), root.name()) << endmsg;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNodeList nlist;
|
const XMLNodeList& nlist (root.children());
|
||||||
XMLNodeConstIterator niter;
|
XMLNodeConstIterator niter;
|
||||||
const XMLProperty *prop;
|
|
||||||
|
|
||||||
nlist = root.children();
|
|
||||||
|
|
||||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
||||||
if ((*niter)->name() == X_("azimuth")) {
|
if ((*niter)->name() == pan_azimuth_control->name()) {
|
||||||
prop = (*niter)->property (X_("value"));
|
pan_azimuth_control->set_state (**niter, version);
|
||||||
if (prop) {
|
} else if ((*niter)->name() == pan_width_control->name()) {
|
||||||
pan_azimuth_control->set_value (atof (prop->value()));
|
pan_width_control->set_state (**niter, version);
|
||||||
}
|
} else if ((*niter)->name() == pan_elevation_control->name()) {
|
||||||
} else if ((*niter)->name() == X_("width")) {
|
pan_elevation_control->set_state (**niter, version);
|
||||||
prop = (*niter)->property (X_("value"));
|
} else if ((*niter)->name() == pan_frontback_control->name()) {
|
||||||
if (prop) {
|
pan_frontback_control->set_state (**niter, version);
|
||||||
pan_width_control->set_value (atof (prop->value()));
|
} else if ((*niter)->name() == pan_lfe_control->name()) {
|
||||||
}
|
pan_lfe_control->set_state (**niter, version);
|
||||||
} else if ((*niter)->name() == X_("elevation")) {
|
|
||||||
prop = (*niter)->property (X_("value"));
|
|
||||||
if (prop) {
|
|
||||||
pan_elevation_control->set_value (atof (prop->value()));
|
|
||||||
}
|
|
||||||
} else if ((*niter)->name() == X_("azimuth")) {
|
|
||||||
prop = (*niter)->property (X_("value"));
|
|
||||||
if (prop) {
|
|
||||||
pan_frontback_control->set_value (atof (prop->value()));
|
|
||||||
}
|
|
||||||
} else if ((*niter)->name() == X_("lfe")) {
|
|
||||||
prop = (*niter)->property (X_("value"));
|
|
||||||
if (prop) {
|
|
||||||
pan_lfe_control->set_value (atof (prop->value()));
|
|
||||||
}
|
|
||||||
} else if ((*niter)->name() == Automatable::xml_node_name) {
|
} else if ((*niter)->name() == Automatable::xml_node_name) {
|
||||||
set_automation_xml_state (**niter, PanAzimuthAutomation);
|
set_automation_xml_state (**niter, PanAzimuthAutomation);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,21 +123,7 @@ Processor::state (bool full_state)
|
||||||
|
|
||||||
if (full_state) {
|
if (full_state) {
|
||||||
XMLNode& automation = Automatable::get_automation_xml_state();
|
XMLNode& automation = Automatable::get_automation_xml_state();
|
||||||
if (!automation.children().empty()
|
if (!automation.children().empty() || !automation.properties().empty()) {
|
||||||
|| !automation.properties().empty()
|
|
||||||
|| !_visible_controls.empty()) {
|
|
||||||
|
|
||||||
stringstream sstr;
|
|
||||||
for (set<Evoral::Parameter>::iterator x = _visible_controls.begin();
|
|
||||||
x != _visible_controls.end(); ++x) {
|
|
||||||
|
|
||||||
if (x != _visible_controls.begin()) {
|
|
||||||
sstr << ' ';
|
|
||||||
}
|
|
||||||
sstr << (*x).id();
|
|
||||||
}
|
|
||||||
|
|
||||||
automation.add_property ("visible", sstr.str());
|
|
||||||
node->add_child_nocopy (automation);
|
node->add_child_nocopy (automation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -206,6 +192,8 @@ Processor::set_state (const XMLNode& node, int version)
|
||||||
XMLNodeList nlist = node.children();
|
XMLNodeList nlist = node.children();
|
||||||
XMLNodeIterator niter;
|
XMLNodeIterator niter;
|
||||||
|
|
||||||
|
Stateful::save_extra_xml (node);
|
||||||
|
|
||||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
||||||
|
|
||||||
if ((*niter)->name() == X_("Automation")) {
|
if ((*niter)->name() == X_("Automation")) {
|
||||||
|
|
@ -218,25 +206,6 @@ Processor::set_state (const XMLNode& node, int version)
|
||||||
set_automation_xml_state (*(*niter), Evoral::Parameter(PluginAutomation));
|
set_automation_xml_state (*(*niter), Evoral::Parameter(PluginAutomation));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prop = (*niter)->property ("visible")) != 0) {
|
|
||||||
uint32_t what;
|
|
||||||
stringstream sstr;
|
|
||||||
|
|
||||||
_visible_controls.clear ();
|
|
||||||
|
|
||||||
sstr << prop->value();
|
|
||||||
while (1) {
|
|
||||||
sstr >> what;
|
|
||||||
if (sstr.fail()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// FIXME: other automation types?
|
|
||||||
mark_automation_visible (Evoral::Parameter(PluginAutomation, 0, what), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ((*niter)->name() == "Extra") {
|
|
||||||
_extra_xml = new XMLNode (*(*niter));
|
|
||||||
} else if ((*niter)->name() == "Redirect") {
|
} else if ((*niter)->name() == "Redirect") {
|
||||||
if ( !(legacy_active = (*niter)->property("active"))) {
|
if ( !(legacy_active = (*niter)->property("active"))) {
|
||||||
error << string_compose(_("No %1 property flag in element %2"), "active", (*niter)->name()) << endl;
|
error << string_compose(_("No %1 property flag in element %2"), "active", (*niter)->name()) << endl;
|
||||||
|
|
|
||||||
|
|
@ -268,14 +268,14 @@ RCConfiguration::set_state (const XMLNode& root, int /*version*/)
|
||||||
|
|
||||||
_midi_port_states.clear ();
|
_midi_port_states.clear ();
|
||||||
|
|
||||||
|
Stateful::save_extra_xml (root);
|
||||||
|
|
||||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
||||||
|
|
||||||
node = *niter;
|
node = *niter;
|
||||||
|
|
||||||
if (node->name() == "Config") {
|
if (node->name() == "Config") {
|
||||||
set_variables (*node);
|
set_variables (*node);
|
||||||
} else if (node->name() == "Extra") {
|
|
||||||
_extra_xml = new XMLNode (*node);
|
|
||||||
} else if (node->name() == ControlProtocolManager::state_node_name) {
|
} else if (node->name() == ControlProtocolManager::state_node_name) {
|
||||||
_control_protocol_state = new XMLNode (*node);
|
_control_protocol_state = new XMLNode (*node);
|
||||||
} else if (node->name() == MIDI::Port::state_node_name) {
|
} else if (node->name() == MIDI::Port::state_node_name) {
|
||||||
|
|
|
||||||
|
|
@ -1251,15 +1251,7 @@ Region::_set_state (const XMLNode& node, int /*version*/, PropertyChange& what_c
|
||||||
const XMLProperty* prop;
|
const XMLProperty* prop;
|
||||||
const XMLNodeList& nlist = node.children();
|
const XMLNodeList& nlist = node.children();
|
||||||
|
|
||||||
for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
Stateful::save_extra_xml (node);
|
||||||
|
|
||||||
XMLNode *child = (*niter);
|
|
||||||
|
|
||||||
if (child->name () == "Extra") {
|
|
||||||
delete _extra_xml;
|
|
||||||
_extra_xml = new XMLNode (*child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
what_changed = set_values (node);
|
what_changed = set_values (node);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1902,6 +1902,8 @@ Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
|
||||||
nlist = node.children();
|
nlist = node.children();
|
||||||
XMLNode processor_state (X_("processor_state"));
|
XMLNode processor_state (X_("processor_state"));
|
||||||
|
|
||||||
|
Stateful::save_extra_xml (node);
|
||||||
|
|
||||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
|
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
|
||||||
|
|
||||||
child = *niter;
|
child = *niter;
|
||||||
|
|
@ -2015,10 +2017,6 @@ Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
|
||||||
XMLNode *cmt = *(child->children().begin());
|
XMLNode *cmt = *(child->children().begin());
|
||||||
_comment = cmt->content();
|
_comment = cmt->content();
|
||||||
|
|
||||||
} else if (child->name() == X_("Extra")) {
|
|
||||||
|
|
||||||
_extra_xml = new XMLNode (*child);
|
|
||||||
|
|
||||||
} else if (child->name() == Controllable::xml_node_name && (prop = child->property("name")) != 0) {
|
} else if (child->name() == Controllable::xml_node_name && (prop = child->property("name")) != 0) {
|
||||||
if (prop->value() == "solo") {
|
if (prop->value() == "solo") {
|
||||||
_solo_control->set_state (*child, version);
|
_solo_control->set_state (*child, version);
|
||||||
|
|
@ -2255,6 +2253,8 @@ Route::_set_state_2X (const XMLNode& node, int version)
|
||||||
|
|
||||||
set_processor_state_2X (redirect_nodes, version);
|
set_processor_state_2X (redirect_nodes, version);
|
||||||
|
|
||||||
|
Stateful::save_extra_xml (node);
|
||||||
|
|
||||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
|
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
|
||||||
child = *niter;
|
child = *niter;
|
||||||
|
|
||||||
|
|
@ -2265,10 +2265,6 @@ Route::_set_state_2X (const XMLNode& node, int version)
|
||||||
XMLNode *cmt = *(child->children().begin());
|
XMLNode *cmt = *(child->children().begin());
|
||||||
_comment = cmt->content();
|
_comment = cmt->content();
|
||||||
|
|
||||||
} else if (child->name() == X_("extra")) {
|
|
||||||
|
|
||||||
_extra_xml = new XMLNode (*child);
|
|
||||||
|
|
||||||
} else if (child->name() == Controllable::xml_node_name && (prop = child->property("name")) != 0) {
|
} else if (child->name() == Controllable::xml_node_name && (prop = child->property("name")) != 0) {
|
||||||
if (prop->value() == X_("solo")) {
|
if (prop->value() == X_("solo")) {
|
||||||
_solo_control->set_state (*child, version);
|
_solo_control->set_state (*child, version);
|
||||||
|
|
|
||||||
|
|
@ -1250,9 +1250,7 @@ Session::set_state (const XMLNode& node, int version)
|
||||||
|
|
||||||
IO::disable_connecting ();
|
IO::disable_connecting ();
|
||||||
|
|
||||||
if ((child = find_named_node (node, "Extra")) != 0) {
|
Stateful::save_extra_xml (node);
|
||||||
_extra_xml = new XMLNode (*child);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
|
if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
|
||||||
load_options (*child);
|
load_options (*child);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ public:
|
||||||
virtual void set_double(double val, bool to_list=false, double frame=0);
|
virtual void set_double(double val, bool to_list=false, double frame=0);
|
||||||
virtual double get_double(bool from_list=false, double frame=0) const;
|
virtual double get_double(bool from_list=false, double frame=0) const;
|
||||||
|
|
||||||
|
|
||||||
/** Get the latest user-set value
|
/** Get the latest user-set value
|
||||||
* (which may not equal get_value() when automation is playing back).
|
* (which may not equal get_value() when automation is playing back).
|
||||||
*
|
*
|
||||||
|
|
@ -51,7 +50,6 @@ public:
|
||||||
|
|
||||||
void set_list(boost::shared_ptr<ControlList>);
|
void set_list(boost::shared_ptr<ControlList>);
|
||||||
|
|
||||||
|
|
||||||
boost::shared_ptr<ControlList> list() { return _list; }
|
boost::shared_ptr<ControlList> list() { return _list; }
|
||||||
boost::shared_ptr<const ControlList> list() const { return _list; }
|
boost::shared_ptr<const ControlList> list() const { return _list; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,11 @@ void
|
||||||
ControlSet::what_has_data (set<Parameter>& s) const
|
ControlSet::what_has_data (set<Parameter>& s) const
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lm (_control_lock);
|
Glib::Mutex::Lock lm (_control_lock);
|
||||||
|
|
||||||
for (Controls::const_iterator li = _controls.begin(); li != _controls.end(); ++li) {
|
for (Controls::const_iterator li = _controls.begin(); li != _controls.end(); ++li) {
|
||||||
s.insert(li->first);
|
if (li->second->list() && !li->second->list()->empty()) {
|
||||||
|
s.insert (li->first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,14 @@ CairoEditableText::set_text (CairoTextCell* cell, const string& text)
|
||||||
bool
|
bool
|
||||||
CairoEditableText::on_expose_event (GdkEventExpose* ev)
|
CairoEditableText::on_expose_event (GdkEventExpose* ev)
|
||||||
{
|
{
|
||||||
Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
|
Glib::RefPtr<Gdk::Window> win = get_window ();
|
||||||
|
|
||||||
|
if (!win) {
|
||||||
|
std::cerr << "CET: no window to draw on\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cairo::RefPtr<Cairo::Context> context = win->create_cairo_context();
|
||||||
|
|
||||||
if (cells.empty()) {
|
if (cells.empty()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <cairomm/cairomm.h>
|
#include <cairomm/cairomm.h>
|
||||||
#include <gtkmm.h>
|
#include <gtkmm/misc.h>
|
||||||
|
|
||||||
class CairoCell
|
class CairoCell
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,10 @@ Controllable::get_state ()
|
||||||
snprintf (buf, sizeof (buf), "%2.12f", get_value());
|
snprintf (buf, sizeof (buf), "%2.12f", get_value());
|
||||||
node->add_property (X_("value"), buf);
|
node->add_property (X_("value"), buf);
|
||||||
|
|
||||||
|
if (_extra_xml) {
|
||||||
|
node->add_child_copy (*_extra_xml);
|
||||||
|
}
|
||||||
|
|
||||||
return *node;
|
return *node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,6 +127,8 @@ Controllable::set_state (const XMLNode& node, int /*version*/)
|
||||||
LocaleGuard lg (X_("POSIX"));
|
LocaleGuard lg (X_("POSIX"));
|
||||||
const XMLProperty* prop;
|
const XMLProperty* prop;
|
||||||
|
|
||||||
|
Stateful::save_extra_xml (node);
|
||||||
|
|
||||||
if ((prop = node.property (X_("id"))) != 0) {
|
if ((prop = node.property (X_("id"))) != 0) {
|
||||||
_id = prop->value();
|
_id = prop->value();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@ class Stateful {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void add_extra_xml (XMLNode&);
|
void add_extra_xml (XMLNode&);
|
||||||
XMLNode *extra_xml (const std::string& str);
|
XMLNode *extra_xml (const std::string& str, bool add_if_missing = false);
|
||||||
|
void save_extra_xml (const XMLNode&);
|
||||||
|
|
||||||
const PBD::ID& id() const { return _id; }
|
const PBD::ID& id() const { return _id; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,22 +68,37 @@ Stateful::add_extra_xml (XMLNode& node)
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLNode *
|
XMLNode *
|
||||||
Stateful::extra_xml (const string& str)
|
Stateful::extra_xml (const string& str, bool add_if_missing)
|
||||||
{
|
{
|
||||||
if (_extra_xml == 0) {
|
XMLNode* node = 0;
|
||||||
return 0;
|
|
||||||
|
if (_extra_xml) {
|
||||||
|
node = _extra_xml->child (str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const XMLNodeList& nlist = _extra_xml->children();
|
if (!node && add_if_missing) {
|
||||||
XMLNodeConstIterator i;
|
node = new XMLNode (str);
|
||||||
|
add_extra_xml (*node);
|
||||||
for (i = nlist.begin(); i != nlist.end(); ++i) {
|
|
||||||
if ((*i)->name() == str) {
|
|
||||||
return (*i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Stateful::save_extra_xml (const XMLNode& node)
|
||||||
|
{
|
||||||
|
/* Looks for the child node called "Extra" and makes _extra_xml
|
||||||
|
point to a copy of it. Will delete any existing node pointed
|
||||||
|
to by _extra_xml if a new Extra node is found, but not
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const XMLNode* xtra = node.child ("Extra");
|
||||||
|
|
||||||
|
if (xtra) {
|
||||||
|
delete _extra_xml;
|
||||||
|
_extra_xml = new XMLNode (*xtra);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue