*/
#include <utility>
-#include <ardour/route.h>
-#include <ardour/automation_control.h>
-#include <pbd/memento_command.h>
#include <gtkmm2ext/barcontroller.h>
+#include <pbd/memento_command.h>
+#include <ardour/automation_control.h>
+#include <ardour/event_type_map.h>
+#include <ardour/route.h>
#include "ardour_ui.h"
#include "automation_time_axis.h"
ignore_state_request = false;
first_call_to_set_height = true;
- _base_rect = new SimpleRect(*canvas_display);
+ _base_rect = new SimpleRect(*_canvas_display);
_base_rect->property_x1() = 0.0;
_base_rect->property_y1() = 0.0;
_base_rect->property_x2() = LONG_MAX - 2;
_base_rect->set_data ("trackview", this);
- _base_rect->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_automation_track_event),
- _base_rect, this));
+ _base_rect->signal_event().connect (bind (
+ mem_fun (_editor, &PublicEditor::canvas_automation_track_event),
+ _base_rect, this));
_base_rect->lower_to_bottom();
/* no regions, just a single line for the entire track (e.g. bus gain) */
} else {
-
boost::shared_ptr<AutomationLine> line(new AutomationLine (
ARDOUR::EventTypeMap::instance().to_symbol(_control->parameter()),
*this,
- *canvas_display,
+ *_canvas_display,
_control->alist()));
line->set_line_color (ARDOUR_UI::config()->canvasvar_ProcessorAutomationLine.get());
}
}
- if (_line)
+ if (_line) {
_line->set_interpolation(style);
+ }
}
void
AutomationTimeAxisView::set_interpolation (AutomationList::InterpolationStyle style)
{
_control->list()->set_interpolation(style);
- if (_line)
+ if (_line) {
_line->set_interpolation(style);
+ }
}
void
AutomationTimeAxisView::clear_clicked ()
{
_session.begin_reversible_command (_("clear automation"));
- if (_line)
+ if (_line) {
_line->clear ();
+ }
_session.commit_reversible_command ();
}
AutomationTimeAxisView::set_height (uint32_t h)
{
bool changed = (height != (uint32_t) h) || first_call_to_set_height;
- bool changed_between_small_and_normal = ( (height < hNormal && h >= hNormal) || (height >= hNormal || h < hNormal) );
+ bool changed_between_small_and_normal = (
+ (height < hNormal && h >= hNormal)
+ || (height >= hNormal || h < hNormal) );
TimeAxisView* state_parent = get_parent_with_state ();
assert(state_parent);
auto_state_menu->set_name ("ArdourContextMenu");
MenuList& as_items = auto_state_menu->items();
- as_items.push_back (CheckMenuElem (_("Manual"),
- bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Off)));
+ as_items.push_back (CheckMenuElem (_("Manual"), bind (
+ mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
+ (AutoState) Off)));
auto_off_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
- as_items.push_back (CheckMenuElem (_("Play"),
- bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Play)));
+ as_items.push_back (CheckMenuElem (_("Play"), bind (
+ mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
+ (AutoState) Play)));
auto_play_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
- as_items.push_back (CheckMenuElem (_("Write"),
- bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Write)));
+ as_items.push_back (CheckMenuElem (_("Write"), bind (
+ mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
+ (AutoState) Write)));
auto_write_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
- as_items.push_back (CheckMenuElem (_("Touch"),
- bind (mem_fun(*this, &AutomationTimeAxisView::set_automation_state), (AutoState) Touch)));
+ as_items.push_back (CheckMenuElem (_("Touch"), bind (
+ mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
+ (AutoState) Touch)));
auto_touch_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
items.push_back (MenuElem (_("State"), *auto_state_menu));
/* mode menu */
-
- if (_control->parameter().type() == MidiCCAutomation) {
+
+ if ( EventTypeMap::instance().is_midi_parameter(_control->parameter()) ) {
+
Menu* auto_mode_menu = manage (new Menu);
auto_mode_menu->set_name ("ArdourContextMenu");
MenuList& am_items = auto_mode_menu->items();
RadioMenuItem::Group group;
-
+
am_items.push_back (RadioMenuElem (group, _("Discrete"), bind (
mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
AutomationList::Discrete)));
mode_discrete_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
- //mode_discrete_item->set_active(_control->list()->interpolation() == AutomationList::Discrete);
-
- am_items.push_back (RadioMenuElem (group, _("Line"), bind (
- mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
- AutomationList::Linear)));
- mode_line_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
- //mode_line_item->set_active(_control->list()->interpolation() == AutomationList::Linear);
+ mode_discrete_item->set_active(_control->list()->interpolation() == AutomationList::Discrete);
+
+ // For discrete types we dont allow the linear option since it makes no sense for those Controls
+ if (EventTypeMap::instance().interpolation_of(_control->parameter()) == Evoral::ControlList::Linear) {
+ am_items.push_back (RadioMenuElem (group, _("Line"), bind (
+ mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
+ AutomationList::Linear)));
+ mode_line_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
+ mode_line_item->set_active(_control->list()->interpolation() == AutomationList::Linear);
+ }
items.push_back (MenuElem (_("Mode"), *auto_mode_menu));
}
double x = 0;
- canvas_display->w2i (x, y);
+ _canvas_display->w2i (x, y);
/* compute vertical fractional position */
/* map using line */
- _line->view_to_model_y (y);
+ _line->view_to_model_coord (x, y);
_session.begin_reversible_command (_("add automation event"));
XMLNode& before = _control->alist()->get_state();
switch (op) {
case Cut:
if ((what_we_got = alist->cut (selection.time.front().start, selection.time.front().end)) != 0) {
- editor.get_cut_buffer().add (what_we_got);
+ _editor.get_cut_buffer().add (what_we_got);
_session.add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &alist->get_state()));
ret = true;
}
break;
case Copy:
if ((what_we_got = alist->copy (selection.time.front().start, selection.time.front().end)) != 0) {
- editor.get_cut_buffer().add (what_we_got);
+ _editor.get_cut_buffer().add (what_we_got);
}
break;
if (what_we_got) {
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
- double foo = (*x)->value;
- line.model_to_view_y (foo);
- (*x)->value = foo;
+ double when = (*x)->when;
+ double val = (*x)->value;
+ line.model_to_view_coord (when, val);
+ (*x)->when = when;
+ (*x)->value = val;
}
}
switch (op) {
case Cut:
if ((what_we_got = alist->cut ((*i).start, (*i).end)) != 0) {
- editor.get_cut_buffer().add (what_we_got);
+ _editor.get_cut_buffer().add (what_we_got);
_session.add_command (new MementoCommand<AutomationList>(*alist.get(), new XMLNode (before), &alist->get_state()));
ret = true;
}
break;
case Copy:
if ((what_we_got = alist->copy ((*i).start, (*i).end)) != 0) {
- editor.get_cut_buffer().add (what_we_got);
+ _editor.get_cut_buffer().add (what_we_got);
}
break;
if (what_we_got) {
for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
- double foo = (*x)->value;
- line.model_to_view_y (foo);
- (*x)->value = foo;
+ double when = (*x)->when;
+ double val = (*x)->value;
+ line.model_to_view_coord (when, val);
+ (*x)->when = when;
+ (*x)->value = val;
}
}
AutomationList copy (**p);
for (AutomationList::iterator x = copy.begin(); x != copy.end(); ++x) {
- double foo = (*x)->value;
- line.view_to_model_y (foo);
- (*x)->value = foo;
+ double when = (*x)->when;
+ double val = (*x)->value;
+ line.view_to_model_coord (when, val);
+ (*x)->when = when;
+ (*x)->value = val;
}
XMLNode &before = alist->get_state();
double botfrac;
/* remember: this is X Window - coordinate space starts in upper left and moves down.
- y_position is the "origin" or "top" of the track.
+ _y_position is the "origin" or "top" of the track.
*/
- double mybot = y_position + height;
+ double mybot = _y_position + height;
- if (y_position >= top && mybot <= bot) {
+ if (_y_position >= top && mybot <= bot) {
- /* y_position is below top, mybot is above bot, so we're fully
+ /* _y_position is below top, mybot is above bot, so we're fully
covered vertically.
*/
} else {
- /* top and bot are within y_position .. mybot */
+ /* top and bot are within _y_position .. mybot */
- topfrac = 1.0 - ((top - y_position) / height);
- botfrac = 1.0 - ((bot - y_position) / height);
+ topfrac = 1.0 - ((top - _y_position) / height);
+ botfrac = 1.0 - ((bot - _y_position) / height);
}
if (_line)
_line->track_exited();
}
-/*void
-AutomationTimeAxisView::set_colors ()
-{
- for (list<GhostRegion*>::iterator i=ghosts.begin(); i != ghosts.end(); i++ ) {
- (*i)->set_colors();
- }
-
- if (_line)
- _line->set_colors();
- }*/
-
void
AutomationTimeAxisView::color_handler ()
{
XMLProperty const * shown = node.property ("shown");
if (shown && shown->value () == "yes") {
set_marked_for_display (true);
- canvas_display->show (); /* FIXME: necessary? show_at? */
+ _canvas_display->show (); /* FIXME: necessary? show_at? */
}
}