steps to an ecology of editing

This commit is contained in:
Paul Davis 2023-10-16 22:34:30 -06:00
parent 744b491162
commit 089a9521d5
17 changed files with 1343 additions and 1166 deletions

View file

@ -18,44 +18,44 @@
#include <pbd/error.h>
#include "editor.h"
#include "editing_context.h"
#include "cursor_context.h"
CursorContext::CursorContext(Editor& editor, Gdk::Cursor* cursor)
: _editor(editor)
, _index(editor.push_canvas_cursor(cursor))
CursorContext::CursorContext(EditingContext& ec, Gdk::Cursor* cursor)
: editing_context(ec)
, _index (editing_context.push_canvas_cursor(cursor))
{}
CursorContext::~CursorContext()
{
if (_index == _editor._cursor_stack.size() - 1) {
_editor.pop_canvas_cursor();
if (_index == editing_context._cursor_stack.size() - 1) {
editing_context.pop_canvas_cursor();
} else {
_editor._cursor_stack[_index] = NULL;
editing_context._cursor_stack[_index] = NULL;
}
}
CursorContext::Handle
CursorContext::create(Editor& editor, Gdk::Cursor* cursor)
CursorContext::create(EditingContext& ec, Gdk::Cursor* cursor)
{
return CursorContext::Handle(new CursorContext(editor, cursor));
return CursorContext::Handle(new CursorContext(ec, cursor));
}
void
CursorContext::change(Gdk::Cursor* cursor)
{
_editor._cursor_stack[_index] = cursor;
if (_index == _editor._cursor_stack.size() - 1) {
_editor.set_canvas_cursor(cursor);
editing_context._cursor_stack[_index] = cursor;
if (_index == editing_context._cursor_stack.size() - 1) {
editing_context.set_canvas_cursor(cursor);
}
}
void
CursorContext::set(Handle* handle, Editor& editor, Gdk::Cursor* cursor)
CursorContext::set(Handle* handle, EditingContext& ec, Gdk::Cursor* cursor)
{
if (*handle) {
(*handle)->change(cursor);
} else {
*handle = CursorContext::create(editor, cursor);
*handle = CursorContext::create(ec, cursor);
}
}

View file

@ -23,7 +23,7 @@
#include <gdkmm/cursor.h>
class Editor;
class EditingContext;
/**
A scoped handle for changing the editor mouse cursor.
@ -53,7 +53,7 @@ public:
* When the returned handle goes out of scope, the cursor will be reset to
* the previous value.
*/
static Handle create(Editor& editor, Gdk::Cursor* cursor);
static Handle create(EditingContext&, Gdk::Cursor* cursor);
/** Change the editor cursor of an existing cursor context. */
void change(Gdk::Cursor* cursor);
@ -63,13 +63,13 @@ public:
* If the handle points to an existing context, it will first be reset
* before the new context is created.
*/
static void set(Handle* handle, Editor& editor, Gdk::Cursor* cursor);
static void set(Handle* handle, EditingContext&, Gdk::Cursor* cursor);
private:
Editor& _editor;
EditingContext& editing_context;
size_t _index;
CursorContext(Editor& editor, Gdk::Cursor* cursor);
CursorContext(EditingContext&, Gdk::Cursor* cursor);
};
#endif /* __ardour_gtk_cursor_context_h__ */

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,10 @@
#include "ardour/session_handle.h"
#include "ardour/types.h"
#include "widgets/ardour_dropdown.h"
#include "editing.h"
#include "editor_items.h"
#include "selection.h"
using ARDOUR::samplepos_t;
@ -48,15 +51,42 @@ using ARDOUR::samplecnt_t;
class VerboseCursor;
class MouseCursors;
class MidiRegionView;
class CursorContext;
class MidiEditingContext : public ARDOUR::SessionHandlePtr
class EditingContext : public ARDOUR::SessionHandlePtr
{
public:
MidiEditingContext ();
~MidiEditingContext ();
/** Context for mouse entry (stored in a stack). */
struct EnterContext {
ItemType item_type;
std::shared_ptr<CursorContext> cursor_ctx;
};
EditingContext ();
~EditingContext ();
void set_session (ARDOUR::Session*);
virtual void instant_save() = 0;
virtual void redisplay_grid (bool immediate_redraw) = 0;
virtual Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) = 0;
/** Get the topmost enter context for the given item type.
*
* This is used to change the cursor associated with a given enter context,
* which may not be on the top of the stack.
*/
virtual EnterContext* get_enter_context(ItemType type) = 0;
virtual void begin_reversible_selection_op (std::string cmd_name) = 0;
virtual void commit_reversible_selection_op () = 0;
virtual void begin_reversible_command (std::string cmd_name) = 0;
virtual void begin_reversible_command (GQuark) = 0;
virtual void abort_reversible_command () = 0;
virtual void commit_reversible_command () = 0;
virtual void set_selected_midi_region_view (MidiRegionView&);
virtual samplepos_t pixel_to_sample_from_event (double pixel) const = 0;
virtual samplepos_t pixel_to_sample (double pixel) const = 0;
virtual double sample_to_pixel (samplepos_t sample) const = 0;
@ -72,18 +102,25 @@ public:
virtual int32_t get_grid_beat_divisions (Editing::GridType gt) = 0;
virtual int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) = 0;
/** Set the snap type.
* @param t Snap type (defined in editing_syms.h)
*/
virtual void set_grid_to (Editing::GridType t) = 0;
Editing::GridType grid_type () const;
bool grid_type_is_musical (Editing::GridType) const;
bool grid_musical () const;
virtual Editing::GridType grid_type () const = 0;
virtual Editing::SnapMode snap_mode () const = 0;
void cycle_snap_mode ();
void next_grid_choice ();
void prev_grid_choice ();
void set_grid_to (Editing::GridType);
void set_snap_mode (Editing::SnapMode);
/** Set the snap mode.
* @param m Snap mode (defined in editing_syms.h)
*/
virtual void set_snap_mode (Editing::SnapMode m) = 0;
void set_draw_length_to (Editing::GridType);
void set_draw_velocity_to (int);
void set_draw_channel_to (int);
Editing::GridType draw_length () const;
int draw_velocity () const;
int draw_channel () const;
Editing::SnapMode snap_mode () const;
virtual void snap_to (Temporal::timepos_t & first,
Temporal::RoundMode direction = Temporal::RoundNearest,
@ -111,6 +148,7 @@ public:
virtual void reposition_and_zoom (samplepos_t, double) = 0;
virtual Selection& get_selection() const = 0;
virtual Selection& get_cut_buffer () const = 0;
/** Set the mouse mode (gain, object, range, timefx etc.)
* @param m Mouse mode (defined in editing_syms.h)
@ -132,6 +170,72 @@ public:
virtual Gdk::Cursor* get_canvas_cursor () const = 0;
virtual MouseCursors const* cursors () const = 0;
virtual VerboseCursor* verbose_cursor () const = 0;
virtual void set_snapped_cursor_position (Temporal::timepos_t const & pos) = 0;
static sigc::signal<void> DropDownKeys;
PBD::Signal0<void> SnapChanged;
PBD::Signal0<void> MouseModeChanged;
/* MIDI actions, proxied to selected MidiRegionView(s) */
void midi_action (void (MidiRegionView::*method)());
virtual std::vector<MidiRegionView*> filter_to_unique_midi_region_views (RegionSelection const & ms) const = 0;
void register_midi_actions (Gtkmm2ext::Bindings*);
Glib::RefPtr<Gtk::ActionGroup> _midi_actions;
/* Cursor stuff. Do not use directly, use via CursorContext. */
friend class CursorContext;
std::vector<Gdk::Cursor*> _cursor_stack;
virtual void set_canvas_cursor (Gdk::Cursor*) = 0;
virtual size_t push_canvas_cursor (Gdk::Cursor*) = 0;
virtual void pop_canvas_cursor () = 0;
Editing::GridType pre_internal_grid_type;
Editing::SnapMode pre_internal_snap_mode;
Editing::GridType internal_grid_type;
Editing::SnapMode internal_snap_mode;
std::vector<std::string> grid_type_strings;
Glib::RefPtr<Gtk::RadioAction> grid_type_action (Editing::GridType);
Glib::RefPtr<Gtk::RadioAction> snap_mode_action (Editing::SnapMode);
Glib::RefPtr<Gtk::RadioAction> draw_length_action (Editing::GridType);
Glib::RefPtr<Gtk::RadioAction> draw_velocity_action (int);
Glib::RefPtr<Gtk::RadioAction> draw_channel_action (int);
Editing::GridType _grid_type;
Editing::SnapMode _snap_mode;
Editing::GridType _draw_length;
int _draw_velocity;
int _draw_channel;
ArdourWidgets::ArdourDropdown grid_type_selector;
void build_grid_type_menu ();
ArdourWidgets::ArdourDropdown draw_length_selector;
ArdourWidgets::ArdourDropdown draw_velocity_selector;
ArdourWidgets::ArdourDropdown draw_channel_selector;
void build_draw_midi_menus ();
void grid_type_selection_done (Editing::GridType);
void snap_mode_selection_done (Editing::SnapMode);
void snap_mode_chosen (Editing::SnapMode);
void grid_type_chosen (Editing::GridType);
void draw_length_selection_done (Editing::GridType);
void draw_length_chosen (Editing::GridType);
void draw_velocity_selection_done (int);
void draw_velocity_chosen (int);
void draw_channel_selection_done (int);
void draw_channel_chosen (int);
};
#endif /* __ardour_midi_editing_context_h__ */

View file

@ -181,31 +181,6 @@ using Gtkmm2ext::Keyboard;
double Editor::timebar_height = 15.0;
static const gchar *_grid_type_strings[] = {
N_("No Grid"),
N_("Bar"),
N_("1/4 Note"),
N_("1/8 Note"),
N_("1/16 Note"),
N_("1/32 Note"),
N_("1/64 Note"),
N_("1/128 Note"),
N_("1/3 (8th triplet)"), // or "1/12" ?
N_("1/6 (16th triplet)"),
N_("1/12 (32nd triplet)"),
N_("1/24 (64th triplet)"),
N_("1/5 (8th quintuplet)"),
N_("1/10 (16th quintuplet)"),
N_("1/20 (32nd quintuplet)"),
N_("1/7 (8th septuplet)"),
N_("1/14 (16th septuplet)"),
N_("1/28 (32nd septuplet)"),
N_("Timecode"),
N_("MinSec"),
N_("CD Frames"),
0
};
static const gchar *_edit_point_strings[] = {
N_("Playhead"),
N_("Marker"),
@ -263,10 +238,6 @@ Editor::Editor ()
, samples_per_pixel (2048)
, zoom_focus (ZoomFocusPlayhead)
, mouse_mode (MouseObject)
, pre_internal_grid_type (GridTypeBeat)
, pre_internal_snap_mode (SnapOff)
, internal_grid_type (GridTypeBeat)
, internal_snap_mode (SnapOff)
, marker_click_behavior (MarkerClickSelectOnly)
, _join_object_range_state (JOIN_OBJECT_RANGE_NONE)
, _notebook_shrunk (false)
@ -366,11 +337,6 @@ Editor::Editor ()
, select_new_marker (false)
, have_pending_keyboard_selection (false)
, pending_keyboard_selection_start (0)
, _grid_type (GridTypeBeat)
, _snap_mode (SnapOff)
, _draw_length (GridTypeNone)
, _draw_velocity (DRAW_VEL_AUTO)
, _draw_channel (DRAW_CHAN_AUTO)
, ignore_gui_changes (false)
, _drags (new DragManager (this))
, lock_dialog (0)
@ -475,7 +441,6 @@ Editor::Editor ()
selection_op_history.clear();
before.clear();
grid_type_strings = I18N (_grid_type_strings);
zoom_focus_strings = I18N (_zoom_focus_strings);
edit_mode_strings = I18N (_edit_mode_strings);
ripple_mode_strings = I18N (_ripple_mode_strings);
@ -2155,73 +2120,6 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
edit_items.push_back (MenuElem (_("Nudge"), *nudge_menu));
}
GridType
Editor::grid_type() const
{
return _grid_type;
}
GridType
Editor::draw_length() const
{
return _draw_length;
}
int
Editor::draw_velocity() const
{
return _draw_velocity;
}
int
Editor::draw_channel() const
{
return _draw_channel;
}
bool
Editor::grid_musical() const
{
return grid_type_is_musical (_grid_type);
}
bool
Editor::grid_type_is_musical(GridType gt) const
{
switch (gt) {
case GridTypeBeatDiv32:
case GridTypeBeatDiv28:
case GridTypeBeatDiv24:
case GridTypeBeatDiv20:
case GridTypeBeatDiv16:
case GridTypeBeatDiv14:
case GridTypeBeatDiv12:
case GridTypeBeatDiv10:
case GridTypeBeatDiv8:
case GridTypeBeatDiv7:
case GridTypeBeatDiv6:
case GridTypeBeatDiv5:
case GridTypeBeatDiv4:
case GridTypeBeatDiv3:
case GridTypeBeatDiv2:
case GridTypeBeat:
case GridTypeBar:
return true;
case GridTypeNone:
case GridTypeTimecode:
case GridTypeMinSec:
case GridTypeCDFrame:
return false;
}
return false;
}
SnapMode
Editor::snap_mode() const
{
return _snap_mode;
}
void
Editor::show_rulers_for_grid ()
{
@ -2269,144 +2167,6 @@ Editor::show_rulers_for_grid ()
}
}
void
Editor::set_draw_length_to (GridType gt)
{
if ( !grid_type_is_musical(gt) ) { //range-check
gt = DRAW_LEN_AUTO;
}
_draw_length = gt;
if (DRAW_LEN_AUTO==gt) {
draw_length_selector.set_text (_("Auto"));
return;
}
unsigned int grid_index = (unsigned int)gt;
string str = grid_type_strings[grid_index];
if (str != draw_length_selector.get_text()) {
draw_length_selector.set_text (str);
}
instant_save ();
}
void
Editor::set_draw_velocity_to (int v)
{
if ( v<0 || v>127 ) { //range-check midi channel
v = DRAW_VEL_AUTO;
}
_draw_velocity = v;
if (DRAW_VEL_AUTO==v) {
draw_velocity_selector.set_text (_("Auto"));
return;
}
char buf[64];
sprintf(buf, "%d", v );
draw_velocity_selector.set_text (buf);
instant_save ();
}
void
Editor::set_draw_channel_to (int c)
{
if ( c<0 || c>15 ) { //range-check midi channel
c = DRAW_CHAN_AUTO;
}
_draw_channel = c;
if (DRAW_CHAN_AUTO==c) {
draw_channel_selector.set_text (_("Auto"));
return;
}
char buf[64];
sprintf(buf, "%d", c+1 );
draw_channel_selector.set_text (buf);
instant_save ();
}
void
Editor::set_grid_to (GridType gt)
{
unsigned int grid_ind = (unsigned int)gt;
if (internal_editing() && UIConfiguration::instance().get_grid_follows_internal()) {
internal_grid_type = gt;
} else {
pre_internal_grid_type = gt;
}
bool grid_type_changed = true;
if ( grid_type_is_musical(_grid_type) && grid_type_is_musical(gt))
grid_type_changed = false;
_grid_type = gt;
if (grid_ind > grid_type_strings.size() - 1) {
grid_ind = 0;
_grid_type = (GridType)grid_ind;
}
string str = grid_type_strings[grid_ind];
if (str != grid_type_selector.get_text()) {
grid_type_selector.set_text (str);
}
if (grid_type_changed && UIConfiguration::instance().get_show_grids_ruler()) {
show_rulers_for_grid ();
}
instant_save ();
const bool grid_is_musical = grid_musical ();
if (grid_is_musical) {
compute_bbt_ruler_scale (_leftmost_sample, _leftmost_sample + current_page_samples());
update_tempo_based_rulers ();
} else if (current_mouse_mode () == Editing::MouseGrid) {
Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (X_("MouseMode"), X_("set-mouse-mode-object"));
ract->set_active (true);
}
ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-grid"))->set_sensitive (grid_is_musical);
mark_region_boundary_cache_dirty ();
redisplay_grid (false);
SnapChanged (); /* EMIT SIGNAL */
}
void
Editor::set_snap_mode (SnapMode mode)
{
if (internal_editing()) {
internal_snap_mode = mode;
} else {
pre_internal_snap_mode = mode;
}
_snap_mode = mode;
if (_snap_mode == SnapOff) {
snap_mode_button.set_active_state (Gtkmm2ext::Off);
} else {
snap_mode_button.set_active_state (Gtkmm2ext::ExplicitActive);
}
instant_save ();
}
void
Editor::set_edit_point_preference (EditPoint ep, bool force)
{

View file

@ -182,27 +182,8 @@ public:
}
double trackviews_height () const;
void cycle_snap_mode ();
void next_grid_choice ();
void prev_grid_choice ();
void set_grid_to (Editing::GridType);
void set_snap_mode (Editing::SnapMode);
void set_draw_length_to (Editing::GridType);
void set_draw_velocity_to (int);
void set_draw_channel_to (int);
Editing::SnapMode snap_mode () const;
Editing::GridType grid_type () const;
bool grid_type_is_musical (Editing::GridType) const;
bool grid_musical () const;
bool on_velocity_scroll_event (GdkEventScroll*);
Editing::GridType draw_length () const;
int draw_velocity () const;
int draw_channel () const;
void undo (uint32_t n = 1);
void redo (uint32_t n = 1);
@ -288,7 +269,6 @@ public:
void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&);
void set_selection (std::list<Selectable*>, ARDOUR::SelectionOperation);
void set_selected_midi_region_view (MidiRegionView&);
std::shared_ptr<ARDOUR::Route> current_mixer_stripable () const;
@ -557,12 +537,6 @@ public:
void get_pointer_position (double &, double &) const;
/** Context for mouse entry (stored in a stack). */
struct EnterContext {
ItemType item_type;
std::shared_ptr<CursorContext> cursor_ctx;
};
/** Get the topmost enter context for the given item type.
*
* This is used to change the cursor associated with a given enter context,
@ -681,10 +655,6 @@ private:
void on_samples_per_pixel_changed ();
Editing::MouseMode mouse_mode;
Editing::GridType pre_internal_grid_type;
Editing::SnapMode pre_internal_snap_mode;
Editing::GridType internal_grid_type;
Editing::SnapMode internal_snap_mode;
Editing::MouseMode effective_mouse_mode () const;
Editing::MarkerClickBehavior marker_click_behavior;
@ -892,10 +862,7 @@ private:
Gtk::HBox global_hpacker;
Gtk::VBox global_vpacker;
/* Cursor stuff. Do not use directly, use via CursorContext. */
friend class CursorContext;
std::vector<Gdk::Cursor*> _cursor_stack;
void set_canvas_cursor (Gdk::Cursor*);
void set_canvas_cursor (Gdk::Cursor* cursor);
size_t push_canvas_cursor (Gdk::Cursor*);
void pop_canvas_cursor ();
@ -1314,7 +1281,6 @@ private:
void register_actions ();
void register_region_actions ();
void register_midi_actions (Gtkmm2ext::Bindings*);
void load_bindings ();
@ -1664,13 +1630,6 @@ private:
void move_range_selection_start_or_end_to_region_boundary (bool, bool);
Editing::GridType _grid_type;
Editing::SnapMode _snap_mode;
Editing::GridType _draw_length;
int _draw_velocity;
int _draw_channel;
bool ignore_gui_changes;
DragManager* _drags;
@ -2028,13 +1987,6 @@ private:
void set_edit_mode (ARDOUR::EditMode);
void cycle_edit_mode ();
ArdourWidgets::ArdourDropdown grid_type_selector;
void build_grid_type_menu ();
ArdourWidgets::ArdourDropdown draw_length_selector;
ArdourWidgets::ArdourDropdown draw_velocity_selector;
ArdourWidgets::ArdourDropdown draw_channel_selector;
void build_draw_midi_menus ();
Gtk::CheckButton stretch_marker_cb;
@ -2057,30 +2009,6 @@ private:
Gtk::HBox _box;
std::vector<std::string> grid_type_strings;
std::vector<std::string> snap_mode_strings;
void grid_type_selection_done (Editing::GridType);
void snap_mode_selection_done (Editing::SnapMode);
void snap_mode_chosen (Editing::SnapMode);
void grid_type_chosen (Editing::GridType);
void draw_length_selection_done (Editing::GridType);
void draw_length_chosen (Editing::GridType);
void draw_velocity_selection_done (int);
void draw_velocity_chosen (int);
void draw_channel_selection_done (int);
void draw_channel_chosen (int);
Glib::RefPtr<Gtk::RadioAction> grid_type_action (Editing::GridType);
Glib::RefPtr<Gtk::RadioAction> snap_mode_action (Editing::SnapMode);
Glib::RefPtr<Gtk::RadioAction> draw_length_action (Editing::GridType);
Glib::RefPtr<Gtk::RadioAction> draw_velocity_action (int);
Glib::RefPtr<Gtk::RadioAction> draw_channel_action (int);
//zoom focus menu stuff
ArdourWidgets::ArdourDropdown zoom_focus_selector;
void zoom_focus_selection_done (Editing::ZoomFocus);
@ -2577,8 +2505,6 @@ private:
QuantizeDialog* quantize_dialog;
MainMenuDisabler* _main_menu_disabler;
/* MIDI actions, proxied to selected MidiRegionView(s) */
void midi_action (void (MidiRegionView::*method)());
std::vector<MidiRegionView*> filter_to_unique_midi_region_views (RegionSelection const & ms) const;
/* private helper functions to help with registering region actions */

View file

@ -798,134 +798,6 @@ Editor::register_actions ()
reg_sens (editor_actions, "quantize", _("Quantize"), sigc::mem_fun (*this, &Editor::quantize_region));
}
void
Editor::register_midi_actions (Bindings* midi_bindings)
{
_midi_actions = ActionManager::create_action_group (midi_bindings, X_("Notes"));
/* two versions to allow same action for Delete and Backspace */
ActionManager::register_action (_midi_actions, X_("clear-selection"), _("Clear Note Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::clear_note_selection));
ActionManager::register_action (_midi_actions, X_("invert-selection"), _("Invert Note Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::invert_selection));
ActionManager::register_action (_midi_actions, X_("extend-selection"), _("Extend Note Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::extend_selection));
ActionManager::register_action (_midi_actions, X_("duplicate-selection"), _("Duplicate Note Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::duplicate_selection));
/* Lengthen */
ActionManager::register_action (_midi_actions, X_("move-starts-earlier-fine"), _("Move Note Start Earlier (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_starts_earlier_fine));
ActionManager::register_action (_midi_actions, X_("move-starts-earlier"), _("Move Note Start Earlier"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_starts_earlier));
ActionManager::register_action (_midi_actions, X_("move-ends-later-fine"), _("Move Note Ends Later (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_ends_later_fine));
ActionManager::register_action (_midi_actions, X_("move-ends-later"), _("Move Note Ends Later"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_ends_later));
/* Shorten */
ActionManager::register_action (_midi_actions, X_("move-starts-later-fine"), _("Move Note Start Later (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_starts_later_fine));
ActionManager::register_action (_midi_actions, X_("move-starts-later"), _("Move Note Start Later"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_starts_later));
ActionManager::register_action (_midi_actions, X_("move-ends-earlier-fine"), _("Move Note Ends Earlier (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_ends_earlier_fine));
ActionManager::register_action (_midi_actions, X_("move-ends-earlier"), _("Move Note Ends Earlier"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_ends_earlier));
/* Alt versions allow bindings for both Tab and ISO_Left_Tab, if desired */
ActionManager::register_action (_midi_actions, X_("select-next"), _("Select Next"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::select_next_note));
ActionManager::register_action (_midi_actions, X_("alt-select-next"), _("Select Next (alternate)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::select_next_note));
ActionManager::register_action (_midi_actions, X_("select-previous"), _("Select Previous"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::select_previous_note));
ActionManager::register_action (_midi_actions, X_("alt-select-previous"), _("Select Previous (alternate)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::select_previous_note));
ActionManager::register_action (_midi_actions, X_("add-select-next"), _("Add Next to Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::add_select_next_note));
ActionManager::register_action (_midi_actions, X_("alt-add-select-next"), _("Add Next to Selection (alternate)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::add_select_next_note));
ActionManager::register_action (_midi_actions, X_("add-select-previous"), _("Add Previous to Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::add_select_previous_note));
ActionManager::register_action (_midi_actions, X_("alt-add-select-previous"), _("Add Previous to Selection (alternate)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::add_select_previous_note));
ActionManager::register_action (_midi_actions, X_("increase-velocity"), _("Increase Velocity"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity));
ActionManager::register_action (_midi_actions, X_("increase-velocity-fine"), _("Increase Velocity (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity_fine));
ActionManager::register_action (_midi_actions, X_("increase-velocity-smush"), _("Increase Velocity (allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity_smush));
ActionManager::register_action (_midi_actions, X_("increase-velocity-together"), _("Increase Velocity (non-relative)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity_together));
ActionManager::register_action (_midi_actions, X_("increase-velocity-fine-smush"), _("Increase Velocity (fine, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity_fine_smush));
ActionManager::register_action (_midi_actions, X_("increase-velocity-fine-together"), _("Increase Velocity (fine, non-relative)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity_fine_together));
ActionManager::register_action (_midi_actions, X_("increase-velocity-smush-together"), _("Increase Velocity (maintain ratios, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity_smush_together));
ActionManager::register_action (_midi_actions, X_("increase-velocity-fine-smush-together"), _("Increase Velocity (fine, allow mush, non-relative)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::increase_note_velocity_fine_smush_together));
ActionManager::register_action (_midi_actions, X_("decrease-velocity"), _("Decrease Velocity"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity));
ActionManager::register_action (_midi_actions, X_("decrease-velocity-fine"), _("Decrease Velocity (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity_fine));
ActionManager::register_action (_midi_actions, X_("decrease-velocity-smush"), _("Decrease Velocity (allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity_smush));
ActionManager::register_action (_midi_actions, X_("decrease-velocity-together"), _("Decrease Velocity (non-relative)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity_together));
ActionManager::register_action (_midi_actions, X_("decrease-velocity-fine-smush"), _("Decrease Velocity (fine, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity_fine_smush));
ActionManager::register_action (_midi_actions, X_("decrease-velocity-fine-together"), _("Decrease Velocity (fine, non-relative)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity_fine_together));
ActionManager::register_action (_midi_actions, X_("decrease-velocity-smush-together"), _("Decrease Velocity (maintain ratios, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity_smush_together));
ActionManager::register_action (_midi_actions, X_("decrease-velocity-fine-smush-together"), _("Decrease Velocity (fine, allow mush, non-relative)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::decrease_note_velocity_fine_smush_together));
ActionManager::register_action (_midi_actions, X_("transpose-up-octave"), _("Transpose Up (octave)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_up_octave));
ActionManager::register_action (_midi_actions, X_("transpose-up-octave-smush"), _("Transpose Up (octave, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_up_octave_smush));
ActionManager::register_action (_midi_actions, X_("transpose-up-semitone"), _("Transpose Up (semitone)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_up_tone));
ActionManager::register_action (_midi_actions, X_("transpose-up-semitone-smush"), _("Transpose Up (semitone, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_up_octave_smush));
ActionManager::register_action (_midi_actions, X_("transpose-down-octave"), _("Transpose Down (octave)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_down_octave));
ActionManager::register_action (_midi_actions, X_("transpose-down-octave-smush"), _("Transpose Down (octave, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_down_octave_smush));
ActionManager::register_action (_midi_actions, X_("transpose-down-semitone"), _("Transpose Down (semitone)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_down_tone));
ActionManager::register_action (_midi_actions, X_("transpose-down-semitone-smush"), _("Transpose Down (semitone, allow mush)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::transpose_down_octave_smush));
ActionManager::register_action (_midi_actions, X_("nudge-later"), _("Nudge Notes Later (grid)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::nudge_notes_later));
ActionManager::register_action (_midi_actions, X_("nudge-later-fine"), _("Nudge Notes Later (1/4 grid)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::nudge_notes_later_fine));
ActionManager::register_action (_midi_actions, X_("nudge-earlier"), _("Nudge Notes Earlier (grid)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::nudge_notes_earlier));
ActionManager::register_action (_midi_actions, X_("nudge-earlier-fine"), _("Nudge Notes Earlier (1/4 grid)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::nudge_notes_earlier_fine));
ActionManager::register_action (_midi_actions, X_("edit-channels"), _("Edit Note Channels"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::channel_edit));
ActionManager::register_action (_midi_actions, X_("edit-velocities"), _("Edit Note Velocities"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::velocity_edit));
ActionManager::register_action (_midi_actions, X_("quantize-selected-notes"), _("Quantize Selected Notes"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::quantize_selected_notes));
ActionManager::register_action (_midi_actions, X_("split-notes-grid"), _("Split Selected Notes on grid boundaries"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::split_notes_grid));
ActionManager::register_action (_midi_actions, X_("split-notes-more"), _("Split Selected Notes into more pieces"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::split_notes_more));
ActionManager::register_action (_midi_actions, X_("split-notes-less"), _("Split Selected Notes into less pieces"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::split_notes_less));
ActionManager::register_action (_midi_actions, X_("join-notes"), _("Join Selected Notes"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::join_notes));
Glib::RefPtr<ActionGroup> length_actions = ActionManager::create_action_group (midi_bindings, X_("DrawLength"));
RadioAction::Group draw_length_group;
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-thirtyseconds"), grid_type_strings[(int)GridTypeBeatDiv32].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv32)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-twentyeighths"), grid_type_strings[(int)GridTypeBeatDiv28].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv28)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-twentyfourths"), grid_type_strings[(int)GridTypeBeatDiv24].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv24)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-twentieths"), grid_type_strings[(int)GridTypeBeatDiv20].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv20)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-asixteenthbeat"), grid_type_strings[(int)GridTypeBeatDiv16].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv16)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-fourteenths"), grid_type_strings[(int)GridTypeBeatDiv14].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv14)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-twelfths"), grid_type_strings[(int)GridTypeBeatDiv12].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv12)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-tenths"), grid_type_strings[(int)GridTypeBeatDiv10].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv10)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-eighths"), grid_type_strings[(int)GridTypeBeatDiv8].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv8)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-sevenths"), grid_type_strings[(int)GridTypeBeatDiv7].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv7)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-sixths"), grid_type_strings[(int)GridTypeBeatDiv6].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv6)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-fifths"), grid_type_strings[(int)GridTypeBeatDiv5].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv5)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-quarters"), grid_type_strings[(int)GridTypeBeatDiv4].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv4)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-thirds"), grid_type_strings[(int)GridTypeBeatDiv3].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv3)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-halves"), grid_type_strings[(int)GridTypeBeatDiv2].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeatDiv2)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-beat"), grid_type_strings[(int)GridTypeBeat].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBeat)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-bar"), grid_type_strings[(int)GridTypeBar].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBar)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-auto"), _("Auto"), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), DRAW_LEN_AUTO)));
Glib::RefPtr<ActionGroup> velocity_actions = ActionManager::create_action_group (midi_bindings, X_("DrawVelocity"));
RadioAction::Group draw_velocity_group;
ActionManager::register_radio_action (velocity_actions, draw_velocity_group, X_("draw-velocity-auto"), _("Auto"), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_velocity_chosen), DRAW_VEL_AUTO)));
for (int i = 1; i <= 127; i++) {
char buf[64];
sprintf(buf, X_("draw-velocity-%d"), i);
char vel[64];
sprintf(vel, _("Velocity %d"), i);
ActionManager::register_radio_action (velocity_actions, draw_velocity_group, buf, vel, (sigc::bind (sigc::mem_fun(*this, &Editor::draw_velocity_chosen), i)));
}
Glib::RefPtr<ActionGroup> channel_actions = ActionManager::create_action_group (midi_bindings, X_("DrawChannel"));
RadioAction::Group draw_channel_group;
ActionManager::register_radio_action (channel_actions, draw_channel_group, X_("draw-channel-auto"), _("Auto"), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_channel_chosen), DRAW_CHAN_AUTO)));
for (int i = 0; i <= 15; i++) {
char buf[64];
sprintf(buf, X_("draw-channel-%d"), i+1);
char ch[64];
sprintf(ch, X_("Channel %d"), i+1);
ActionManager::register_radio_action (channel_actions, draw_channel_group, buf, ch, (sigc::bind (sigc::mem_fun(*this, &Editor::draw_channel_chosen), i)));
}
ActionManager::set_sensitive (_midi_actions, false);
}
static void _lua_print (std::string s) {
#ifndef NDEBUG
std::cout << "LuaInstance: " << s << "\n";
@ -1181,438 +1053,6 @@ Editor::edit_current_tempo ()
edit_tempo_section (Temporal::TempoMap::use()->metric_at (ARDOUR_UI::instance()->primary_clock->last_when()).get_editable_tempo());
}
RefPtr<RadioAction>
Editor::draw_velocity_action (int v)
{
char buf[64];
const char* action = 0;
RefPtr<Action> act;
if (v==DRAW_VEL_AUTO) {
action = "draw-velocity-auto";
} else if (v>=1 && v<=127) {
sprintf(buf, X_("draw-velocity-%d"), v); //we don't allow drawing a velocity 0; some synths use that as note-off
action = buf;
}
act = ActionManager::get_action (X_("DrawVelocity"), action);
if (act) {
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
return ract;
} else {
error << string_compose (_("programming error: %1"), "Editor::draw_velocity_action could not find action to match velocity.") << endmsg;
return RefPtr<RadioAction>();
}
}
RefPtr<RadioAction>
Editor::draw_channel_action (int c)
{
char buf[64];
const char* action = 0;
RefPtr<Action> act;
if (c==DRAW_CHAN_AUTO) {
action = "draw-channel-auto";
} else if (c>=0 && c<=15) {
sprintf(buf, X_("draw-channel-%d"), c+1);
action = buf;
}
act = ActionManager::get_action (X_("DrawChannel"), action);
if (act) {
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
return ract;
} else {
error << string_compose (_("programming error: %1"), "Editor::draw_channel_action could not find action to match channel.") << endmsg;
return RefPtr<RadioAction>();
}
}
RefPtr<RadioAction>
Editor::draw_length_action (GridType type)
{
const char* action = 0;
RefPtr<Action> act;
switch (type) {
case Editing::GridTypeBeatDiv32:
action = "draw-length-thirtyseconds";
break;
case Editing::GridTypeBeatDiv28:
action = "draw-length-twentyeighths";
break;
case Editing::GridTypeBeatDiv24:
action = "draw-length-twentyfourths";
break;
case Editing::GridTypeBeatDiv20:
action = "draw-length-twentieths";
break;
case Editing::GridTypeBeatDiv16:
action = "draw-length-asixteenthbeat";
break;
case Editing::GridTypeBeatDiv14:
action = "draw-length-fourteenths";
break;
case Editing::GridTypeBeatDiv12:
action = "draw-length-twelfths";
break;
case Editing::GridTypeBeatDiv10:
action = "draw-length-tenths";
break;
case Editing::GridTypeBeatDiv8:
action = "draw-length-eighths";
break;
case Editing::GridTypeBeatDiv7:
action = "draw-length-sevenths";
break;
case Editing::GridTypeBeatDiv6:
action = "draw-length-sixths";
break;
case Editing::GridTypeBeatDiv5:
action = "draw-length-fifths";
break;
case Editing::GridTypeBeatDiv4:
action = "draw-length-quarters";
break;
case Editing::GridTypeBeatDiv3:
action = "draw-length-thirds";
break;
case Editing::GridTypeBeatDiv2:
action = "draw-length-halves";
break;
case Editing::GridTypeBeat:
action = "draw-length-beat";
break;
case Editing::GridTypeBar:
action = "draw-length-bar";
break;
case Editing::GridTypeNone:
action = "draw-length-auto";
break;
case Editing::GridTypeTimecode:
case Editing::GridTypeCDFrame:
case Editing::GridTypeMinSec:
default:
fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible grid length type", (int) type) << endmsg;
abort(); /*NOTREACHED*/
}
act = ActionManager::get_action (X_("DrawLength"), action);
if (act) {
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
return ract;
} else {
error << string_compose (_("programming error: %1"), "Editor::draw_length_chosen could not find action to match type.") << endmsg;
return RefPtr<RadioAction>();
}
}
RefPtr<RadioAction>
Editor::grid_type_action (GridType type)
{
const char* action = 0;
RefPtr<Action> act;
switch (type) {
case Editing::GridTypeBeatDiv32:
action = "grid-type-thirtyseconds";
break;
case Editing::GridTypeBeatDiv28:
action = "grid-type-twentyeighths";
break;
case Editing::GridTypeBeatDiv24:
action = "grid-type-twentyfourths";
break;
case Editing::GridTypeBeatDiv20:
action = "grid-type-twentieths";
break;
case Editing::GridTypeBeatDiv16:
action = "grid-type-asixteenthbeat";
break;
case Editing::GridTypeBeatDiv14:
action = "grid-type-fourteenths";
break;
case Editing::GridTypeBeatDiv12:
action = "grid-type-twelfths";
break;
case Editing::GridTypeBeatDiv10:
action = "grid-type-tenths";
break;
case Editing::GridTypeBeatDiv8:
action = "grid-type-eighths";
break;
case Editing::GridTypeBeatDiv7:
action = "grid-type-sevenths";
break;
case Editing::GridTypeBeatDiv6:
action = "grid-type-sixths";
break;
case Editing::GridTypeBeatDiv5:
action = "grid-type-fifths";
break;
case Editing::GridTypeBeatDiv4:
action = "grid-type-quarters";
break;
case Editing::GridTypeBeatDiv3:
action = "grid-type-thirds";
break;
case Editing::GridTypeBeatDiv2:
action = "grid-type-halves";
break;
case Editing::GridTypeBeat:
action = "grid-type-beat";
break;
case Editing::GridTypeBar:
action = "grid-type-bar";
break;
case Editing::GridTypeNone:
action = "grid-type-none";
break;
case Editing::GridTypeTimecode:
action = "grid-type-timecode";
break;
case Editing::GridTypeCDFrame:
action = "grid-type-cdframe";
break;
case Editing::GridTypeMinSec:
action = "grid-type-minsec";
break;
default:
fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible snap-to type", (int) type) << endmsg;
abort(); /*NOTREACHED*/
}
act = ActionManager::get_action (X_("Snap"), action);
if (act) {
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
return ract;
} else {
error << string_compose (_("programming error: %1"), "Editor::grid_type_chosen could not find action to match type.") << endmsg;
return RefPtr<RadioAction>();
}
}
void
Editor::next_grid_choice ()
{
switch (_grid_type) {
case Editing::GridTypeBeatDiv32:
set_grid_to (Editing::GridTypeNone);
break;
case Editing::GridTypeBeatDiv16:
set_grid_to (Editing::GridTypeBeatDiv32);
break;
case Editing::GridTypeBeatDiv8:
set_grid_to (Editing::GridTypeBeatDiv16);
break;
case Editing::GridTypeBeatDiv4:
set_grid_to (Editing::GridTypeBeatDiv8);
break;
case Editing::GridTypeBeatDiv2:
set_grid_to (Editing::GridTypeBeatDiv4);
break;
case Editing::GridTypeBeat:
set_grid_to (Editing::GridTypeBeatDiv2);
break;
case Editing::GridTypeBar:
set_grid_to (Editing::GridTypeBeat);
break;
case Editing::GridTypeNone:
set_grid_to (Editing::GridTypeBar);
break;
case Editing::GridTypeBeatDiv3:
case Editing::GridTypeBeatDiv6:
case Editing::GridTypeBeatDiv12:
case Editing::GridTypeBeatDiv24:
case Editing::GridTypeBeatDiv5:
case Editing::GridTypeBeatDiv10:
case Editing::GridTypeBeatDiv20:
case Editing::GridTypeBeatDiv7:
case Editing::GridTypeBeatDiv14:
case Editing::GridTypeBeatDiv28:
case Editing::GridTypeTimecode:
case Editing::GridTypeMinSec:
case Editing::GridTypeCDFrame:
break; //do nothing
}
}
void
Editor::prev_grid_choice ()
{
switch (_grid_type) {
case Editing::GridTypeBeatDiv32:
set_grid_to (Editing::GridTypeBeatDiv16);
break;
case Editing::GridTypeBeatDiv16:
set_grid_to (Editing::GridTypeBeatDiv8);
break;
case Editing::GridTypeBeatDiv8:
set_grid_to (Editing::GridTypeBeatDiv4);
break;
case Editing::GridTypeBeatDiv4:
set_grid_to (Editing::GridTypeBeatDiv2);
break;
case Editing::GridTypeBeatDiv2:
set_grid_to (Editing::GridTypeBeat);
break;
case Editing::GridTypeBeat:
set_grid_to (Editing::GridTypeBar);
break;
case Editing::GridTypeBar:
set_grid_to (Editing::GridTypeNone);
break;
case Editing::GridTypeNone:
set_grid_to (Editing::GridTypeBeatDiv32);
break;
case Editing::GridTypeBeatDiv3:
case Editing::GridTypeBeatDiv6:
case Editing::GridTypeBeatDiv12:
case Editing::GridTypeBeatDiv24:
case Editing::GridTypeBeatDiv5:
case Editing::GridTypeBeatDiv10:
case Editing::GridTypeBeatDiv20:
case Editing::GridTypeBeatDiv7:
case Editing::GridTypeBeatDiv14:
case Editing::GridTypeBeatDiv28:
case Editing::GridTypeTimecode:
case Editing::GridTypeMinSec:
case Editing::GridTypeCDFrame:
break; //do nothing
}
}
void
Editor::grid_type_chosen (GridType type)
{
/* this is driven by a toggle on a radio group, and so is invoked twice,
once for the item that became inactive and once for the one that became
active.
*/
RefPtr<RadioAction> ract = grid_type_action (type);
if (ract && ract->get_active()) {
set_grid_to (type);
}
}
void
Editor::draw_length_chosen (GridType type)
{
/* this is driven by a toggle on a radio group, and so is invoked twice,
once for the item that became inactive and once for the one that became
active.
*/
RefPtr<RadioAction> ract = draw_length_action (type);
if (ract && ract->get_active()) {
set_draw_length_to (type);
}
}
void
Editor::draw_velocity_chosen (int v)
{
/* this is driven by a toggle on a radio group, and so is invoked twice,
once for the item that became inactive and once for the one that became
active.
*/
RefPtr<RadioAction> ract = draw_velocity_action (v);
if (ract && ract->get_active()) {
set_draw_velocity_to (v);
}
}
void
Editor::draw_channel_chosen (int c)
{
/* this is driven by a toggle on a radio group, and so is invoked twice,
once for the item that became inactive and once for the one that became
active.
*/
RefPtr<RadioAction> ract = draw_channel_action (c);
if (ract && ract->get_active()) {
set_draw_channel_to (c);
}
}
RefPtr<RadioAction>
Editor::snap_mode_action (SnapMode mode)
{
const char* action = 0;
RefPtr<Action> act;
switch (mode) {
case Editing::SnapOff:
action = X_("snap-off");
break;
case Editing::SnapNormal:
action = X_("snap-normal");
break;
case Editing::SnapMagnetic:
action = X_("snap-magnetic");
break;
default:
fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible snap mode type", (int) mode) << endmsg;
abort(); /*NOTREACHED*/
}
act = ActionManager::get_action (X_("Editor"), action);
if (act) {
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
return ract;
} else {
error << string_compose (_("programming error: %1: %2"), "Editor::snap_mode_chosen could not find action to match mode.", action) << endmsg;
return RefPtr<RadioAction> ();
}
}
void
Editor::cycle_snap_mode ()
{
switch (_snap_mode) {
case SnapOff:
case SnapNormal:
set_snap_mode (SnapMagnetic);
break;
case SnapMagnetic:
set_snap_mode (SnapOff);
break;
}
}
void
Editor::snap_mode_chosen (SnapMode mode)
{
/* this is driven by a toggle on a radio group, and so is invoked twice,
once for the item that became inactive and once for the one that became
active.
*/
if (mode == SnapNormal) {
mode = SnapMagnetic;
}
RefPtr<RadioAction> ract = snap_mode_action (mode);
if (ract && ract->get_active()) {
set_snap_mode (mode);
}
}
RefPtr<RadioAction>
Editor::edit_point_action (EditPoint ep)
{

View file

@ -893,7 +893,7 @@ Editor::stop_canvas_autoscroll ()
autoscroll_cnt = 0;
}
Editor::EnterContext*
EditingContext::EnterContext*
Editor::get_enter_context(ItemType type)
{
for (ssize_t i = _enter_stack.size() - 1; i >= 0; --i) {

View file

@ -9422,34 +9422,6 @@ Editor::filter_to_unique_midi_region_views (RegionSelection const & ms) const
return views;
}
void
Editor::midi_action (void (MidiRegionView::*method)())
{
MidiRegionSelection ms = selection->midi_regions();
if (ms.empty()) {
return;
}
if (ms.size() > 1) {
vector<MidiRegionView*> views = filter_to_unique_midi_region_views (ms);
for (vector<MidiRegionView*>::iterator mrv = views.begin(); mrv != views.end(); ++mrv) {
((*mrv)->*method) ();
}
} else {
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(ms.front());
if (mrv) {
(mrv->*method)();
}
}
}
void
Editor::add_region_marker ()
{

View file

@ -978,20 +978,6 @@ out:
return commit;
}
void
Editor::set_selected_midi_region_view (MidiRegionView& mrv)
{
/* clear note selection in all currently selected MidiRegionViews */
if (get_selection().regions.contains (&mrv) && get_selection().regions.size() == 1) {
/* Nothing to do */
return;
}
midi_action (&MidiRegionView::clear_note_selection);
get_selection().set (&mrv);
}
void
Editor::set_selection (std::list<Selectable*> s, SelectionOperation op)
{

View file

@ -1,33 +0,0 @@
/*
* Copyright (C) 2023 Paul Davis <paul@linuxaudiosystems.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "midi_editing_context.h"
MidiEditingContext::MidiEditingContext ()
{
}
MidiEditingContext::~MidiEditingContext()
{
}
void
MidiEditingContext::set_session (ARDOUR::Session* s)
{
SessionHandlePtr::set_session (s);
}

View file

@ -103,11 +103,13 @@ using Gtkmm2ext::Keyboard;
#define MIDI_BP_ZERO ((Config->get_first_midi_bank_is_zero())?0:1)
MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
EditingContext& ec,
RouteTimeAxisView& tv,
std::shared_ptr<MidiRegion> r,
double spu,
uint32_t basic_color)
: RegionView (parent, tv, r, spu, basic_color)
, editing_context (ec)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
@ -138,7 +140,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
_patch_change_fill = UIConfiguration::instance().color_mod ("midi patch change fill", "midi patch change fill");
_note_group->raise_to_top();
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
EditingContext::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
@ -146,6 +148,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
}
MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
EditingContext& ec,
RouteTimeAxisView& tv,
std::shared_ptr<MidiRegion> r,
double spu,
@ -153,6 +156,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
bool recording,
TimeAxisViewItem::Visibility visibility)
: RegionView (parent, tv, r, spu, basic_color, recording, visibility)
, editing_context (ec)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
@ -182,7 +186,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Container* parent,
_note_group->raise_to_top();
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
EditingContext::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
connect_to_diskstream ();
}
@ -205,6 +209,7 @@ MidiRegionView::parameter_changed (std::string const & p)
MidiRegionView::MidiRegionView (const MidiRegionView& other)
: sigc::trackable(other)
, RegionView (other)
, editing_context (other.editing_context)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
@ -231,6 +236,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
MidiRegionView::MidiRegionView (const MidiRegionView& other, std::shared_ptr<MidiRegion> region)
: RegionView (other, std::shared_ptr<Region> (region))
, editing_context (other.editing_context)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
@ -260,7 +266,7 @@ MidiRegionView::init (bool /*wfd*/)
{
DisplaySuspender ds (*this, true);
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
EditingContext::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
_model = midi_region()->midi_source(0)->model();
assert (_model);
@ -286,11 +292,11 @@ MidiRegionView::init (bool /*wfd*/)
instrument_info().Changed.connect (_instrument_changed_connection, invalidator (*this),
boost::bind (&MidiRegionView::instrument_settings_changed, this), gui_context());
trackview.editor().SnapChanged.connect(snap_changed_connection, invalidator(*this),
editing_context.SnapChanged.connect(snap_changed_connection, invalidator(*this),
boost::bind (&MidiRegionView::snap_changed, this),
gui_context());
trackview.editor().MouseModeChanged.connect(_mouse_mode_connection, invalidator (*this),
editing_context.MouseModeChanged.connect(_mouse_mode_connection, invalidator (*this),
boost::bind (&MidiRegionView::mouse_mode_changed, this),
gui_context ());
@ -327,13 +333,13 @@ MidiRegionView::canvas_group_event(GdkEvent* ev)
return false;
}
if (!trackview.editor().internal_editing()) {
if (!editing_context.internal_editing()) {
// not in internal edit mode, so just act like a normal region
return RegionView::canvas_group_event (ev);
}
//For now, move the snapped cursor aside so it doesn't bother you during internal editing
//trackview.editor().set_snapped_cursor_position(_region->position());
//editing_context.set_snapped_cursor_position(_region->position());
bool r;
@ -407,7 +413,7 @@ MidiRegionView::mouse_mode_changed ()
// Adjust frame colour (become more transparent for internal tools)
set_frame_color();
if (!trackview.editor().internal_editing()) {
if (!editing_context.internal_editing()) {
/* Switched out of internal editing mode while entered.
Only necessary for leave as a mouse_mode_change over a region
@ -420,7 +426,7 @@ MidiRegionView::mouse_mode_changed ()
it->second->set_hide_selection (true);
}
} else if (trackview.editor().current_mouse_mode() == MouseContent) {
} else if (editing_context.current_mouse_mode() == MouseContent) {
// hide cursor and ghost note after changing to internal edit mode
@ -447,7 +453,7 @@ MidiRegionView::mouse_mode_changed ()
void
MidiRegionView::enter_internal (uint32_t state)
{
if (trackview.editor().current_mouse_mode() == MouseDraw && _mouse_state != AddDragging) {
if (editing_context.current_mouse_mode() == MouseDraw && _mouse_state != AddDragging) {
// Show ghost note under pencil
create_ghost_note(_last_event_x, _last_event_y, state);
}
@ -486,11 +492,10 @@ MidiRegionView::button_press (GdkEventButton* ev)
return false;
}
Editor* editor = dynamic_cast<Editor *> (&trackview.editor());
MouseMode m = editor->current_mouse_mode();
MouseMode m = editing_context.current_mouse_mode();
if (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
_press_cursor_ctx = CursorContext::create(*editor, editor->cursors()->midi_pencil);
_press_cursor_ctx = CursorContext::create(editing_context, editing_context.cursors()->midi_pencil);
}
if (_mouse_state != SelectTouchDragging) {
@ -500,9 +505,9 @@ MidiRegionView::button_press (GdkEventButton* ev)
if (m == MouseDraw || (m == MouseContent && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier()))) {
if (midi_view()->note_mode() == Percussive) {
editor->drags()->set (new HitCreateDrag (dynamic_cast<Editor *> (editor), group, this), (GdkEvent *) ev);
// editor->drags()->set (new HitCreateDrag (dynamic_cast<Editor *> (editor), group, this), (GdkEvent *) ev);
} else {
editor->drags()->set (new NoteCreateDrag (dynamic_cast<Editor *> (editor), group, this), (GdkEvent *) ev);
// editor->drags()->set (new NoteCreateDrag (dynamic_cast<Editor *> (editor), group, this), (GdkEvent *) ev);
}
_mouse_state = AddDragging;
@ -536,14 +541,12 @@ MidiRegionView::button_release (GdkEventButton* ev)
group->canvas_to_item (event_x, event_y);
group->ungrab ();
PublicEditor& editor = trackview.editor ();
_press_cursor_ctx.reset();
switch (_mouse_state) {
case Pressed: // Clicked
switch (editor.current_mouse_mode()) {
switch (editing_context.current_mouse_mode()) {
case MouseRange:
/* no motion occurred - simple click */
clear_selection_internal ();
@ -551,14 +554,14 @@ MidiRegionView::button_release (GdkEventButton* ev)
break;
case MouseContent:
editor.get_selection().set (this);
editing_context.get_selection().set (this);
/* fallthru */
case MouseTimeFX:
_mouse_changed_selection = true;
clear_selection_internal ();
break;
case MouseDraw:
editor.get_selection().set (this);
editing_context.get_selection().set (this);
break;
default:
@ -572,7 +575,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
/* Don't a ghost note when we added a note - wait until motion to avoid visual confusion.
we don't want one when we were drag-selecting either. */
case SelectRectDragging:
editor.drags()->end_grab ((GdkEvent *) ev);
// editor.drags()->end_grab ((GdkEvent *) ev);
_mouse_state = None;
break;
@ -582,8 +585,8 @@ MidiRegionView::button_release (GdkEventButton* ev)
}
if (_mouse_changed_selection) {
trackview.editor().begin_reversible_selection_op (X_("Mouse Selection Change"));
trackview.editor().commit_reversible_selection_op ();
editing_context.begin_reversible_selection_op (X_("Mouse Selection Change"));
editing_context.commit_reversible_selection_op ();
}
return false;
@ -592,8 +595,6 @@ MidiRegionView::button_release (GdkEventButton* ev)
bool
MidiRegionView::motion (GdkEventMotion* ev)
{
PublicEditor& editor = trackview.editor ();
if (!_entered_note) {
if (_mouse_state == AddDragging) {
@ -601,23 +602,23 @@ MidiRegionView::motion (GdkEventMotion* ev)
remove_ghost_note ();
}
} else if (!_ghost_note && editor.current_mouse_mode() == MouseContent &&
} else if (!_ghost_note && editing_context.current_mouse_mode() == MouseContent &&
Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier()) &&
_mouse_state != AddDragging) {
create_ghost_note (ev->x, ev->y, ev->state);
} else if (_ghost_note && editor.current_mouse_mode() == MouseContent &&
} else if (_ghost_note && editing_context.current_mouse_mode() == MouseContent &&
Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
update_ghost_note (ev->x, ev->y, ev->state);
} else if (_ghost_note && editor.current_mouse_mode() == MouseContent) {
} else if (_ghost_note && editing_context.current_mouse_mode() == MouseContent) {
remove_ghost_note ();
hide_verbose_cursor ();
} else if (editor.current_mouse_mode() == MouseDraw) {
} else if (editing_context.current_mouse_mode() == MouseDraw) {
if (_ghost_note) {
update_ghost_note (ev->x, ev->y, ev->state);
@ -638,10 +639,10 @@ MidiRegionView::motion (GdkEventMotion* ev)
if (_pressed_button == 1) {
MouseMode m = editor.current_mouse_mode();
MouseMode m = editing_context.current_mouse_mode();
if (m == MouseContent && !Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
editor.drags()->set (new MidiRubberbandSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
// editing_context.drags()->set (new MidiRubberbandSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
if (!Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
clear_selection_internal ();
_mouse_changed_selection = true;
@ -649,7 +650,7 @@ MidiRegionView::motion (GdkEventMotion* ev)
_mouse_state = SelectRectDragging;
return true;
} else if (m == MouseRange) {
editor.drags()->set (new MidiVerticalSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
// editing_context.drags()->set (new MidiVerticalSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
_mouse_state = SelectVerticalDragging;
return true;
}
@ -660,7 +661,7 @@ MidiRegionView::motion (GdkEventMotion* ev)
case SelectRectDragging:
case SelectVerticalDragging:
case AddDragging:
editor.drags()->motion_handler ((GdkEvent *) ev, false);
// editing_context.drags()->motion_handler ((GdkEvent *) ev, false);
break;
case SelectTouchDragging:
@ -679,11 +680,11 @@ MidiRegionView::motion (GdkEventMotion* ev)
bool
MidiRegionView::scroll (GdkEventScroll* ev)
{
if (trackview.editor().drags()->active()) {
return false;
}
// if (editing_context.drags()->active()) {
// return false;
// }
if (!trackview.editor().get_selection().selected (this)) {
if (!editing_context.get_selection().selected (this)) {
return false;
}
@ -909,7 +910,10 @@ MidiRegionView::create_note_at (timepos_t const & t, double y, Temporal::Beats l
note_diff_add_note (new_note, true, false);
apply_note_diff();
trackview.editor().set_selected_midi_region_view (*this);
editing_context.set_selected_midi_region_view (*this);
list<Evoral::event_id_t> to_be_selected;
to_be_selected.push_back (new_note->id());
select_notes (to_be_selected, true);
/* apply_note_diff above selects and plays the newly created note */
}
@ -950,7 +954,7 @@ void
MidiRegionView::start_note_diff_command (string name)
{
if (!_note_diff_command) {
trackview.editor().begin_reversible_command (name);
editing_context.begin_reversible_command (name);
_note_diff_command = _model->new_note_diff_command (name);
} else {
std::cerr << "ERROR: start_note_diff_command command called, but a note_diff_command was already underway" << std::endl;
@ -1022,7 +1026,7 @@ MidiRegionView::apply_note_diff (bool as_subcommand, bool was_copy)
}
if (!as_subcommand) {
trackview.editor().commit_reversible_command (); /*instead, we can explicitly commit the command in progress */
editing_context.commit_reversible_command (); /*instead, we can explicitly commit the command in progress */
}
_note_diff_command = nullptr;
@ -1039,7 +1043,7 @@ MidiRegionView::abort_note_diff()
{
delete _note_diff_command;
_note_diff_command = 0;
trackview.editor().abort_reversible_command();
editing_context.abort_reversible_command();
clear_selection_internal ();
}
@ -1148,7 +1152,7 @@ MidiRegionView::model_changed()
if (_active_notes) {
// Currently recording
const samplecnt_t zoom = trackview.editor().get_current_zoom();
const samplecnt_t zoom = editing_context.get_current_zoom();
if (zoom != _last_display_zoom) {
/* Update resolved canvas notes to reflect changes in zoom without
touching model. Leave active notes (with length max) alone since
@ -1291,7 +1295,7 @@ MidiRegionView::view_changed()
if (_active_notes) {
// Currently recording
const samplecnt_t zoom = trackview.editor().get_current_zoom();
const samplecnt_t zoom = editing_context.get_current_zoom();
if (zoom != _last_display_zoom) {
/* Update resolved canvas notes to reflect changes in zoom without
touching model. Leave active notes (with length max) alone since
@ -1388,9 +1392,9 @@ MidiRegionView::display_patch_changes_on_channel (uint8_t channel, bool active_c
p->hide();
} else {
const timepos_t flag_time = _region->source_beats_to_absolute_time ((*i)->time());
const double flag_x = trackview.editor().time_to_pixel (flag_time);
const double flag_x = editing_context.time_to_pixel (flag_time);
const double region_x = trackview.editor().time_to_pixel (_region->position());
const double region_x = editing_context.time_to_pixel (_region->position());
p->canvas_item()->set_position (ArdourCanvas::Duple (flag_x-region_x, 1.0));
p->update_name ();
@ -1419,9 +1423,9 @@ MidiRegionView::update_patch_changes ()
pc->hide();
} else {
const timepos_t flag_time = _region->source_beats_to_absolute_time (p->first->time());
const double flag_x = trackview.editor().time_to_pixel (flag_time);
const double flag_x = editing_context.time_to_pixel (flag_time);
const double region_x = trackview.editor().time_to_pixel (_region->position());
const double region_x = editing_context.time_to_pixel (_region->position());
pc->canvas_item()->set_position (ArdourCanvas::Duple (flag_x-region_x, 1.0));
pc->update_name ();
@ -1446,7 +1450,7 @@ MidiRegionView::display_sysexes()
}
if (have_periodic_system_messages) {
double zoom = trackview.editor().get_current_zoom (); // samples per pixel
double zoom = editing_context.get_current_zoom (); // samples per pixel
/* get an approximate value for the number of samples per video frame */
@ -1489,7 +1493,7 @@ MidiRegionView::display_sysexes()
}
string text = str.str();
const double x = trackview.editor().time_to_pixel (_region->source_beats_to_region_time (time.beats()));
const double x = editing_context.time_to_pixel (_region->source_beats_to_region_time (time.beats()));
double height = midi_stream_view()->contents_height();
@ -1538,7 +1542,7 @@ MidiRegionView::update_sysexes ()
sysex->show();
}
const double x = trackview.editor().time_to_pixel (_region->source_beats_to_region_time (time.beats()));
const double x = editing_context.time_to_pixel (_region->source_beats_to_region_time (time.beats()));
sysex->set_height (height);
sysex->item().set_position (ArdourCanvas::Duple (x, 1.0));
@ -1638,7 +1642,7 @@ MidiRegionView::apply_note_range (uint8_t min, uint8_t max, bool force)
GhostRegion*
MidiRegionView::add_ghost (TimeAxisView& tv)
{
double unit_position = trackview.editor().time_to_pixel (_region->position ());
double unit_position = editing_context.time_to_pixel (_region->position ());
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(&tv);
MidiGhostRegion* ghost;
@ -1703,7 +1707,7 @@ MidiRegionView::extend_active_notes()
for (unsigned i = 0; i < 128; ++i) {
if (_active_notes[i]) {
_active_notes[i]->set_x1 (trackview.editor().duration_to_pixels (_region->length()));
_active_notes[i]->set_x1 (editing_context.duration_to_pixels (_region->length()));
}
}
}
@ -1817,7 +1821,7 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
const samplepos_t note_start_samples = _region->position().distance ((note_start + session_source_start)).samples();
const double x0 = trackview.editor().sample_to_pixel (note_start_samples);
const double x0 = editing_context.sample_to_pixel (note_start_samples);
double x1;
const double y0 = 1 + floor(note_to_y(note->note()));
@ -1841,13 +1845,13 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
const samplepos_t note_end_samples = _region->position().distance ((note_end + session_source_start)).samples();
x1 = std::max(1., trackview.editor().sample_to_pixel (note_end_samples));
x1 = std::max(1., editing_context.sample_to_pixel (note_end_samples));
} else {
/* nascent note currently being recorded, noteOff has not yet arrived */
x1 = std::max(1., trackview.editor().duration_to_pixels (_region->length()));
x1 = std::max(1., editing_context.duration_to_pixels (_region->length()));
}
y1 = y0 + std::max(1., floor(note_height()) - 1);
@ -1888,7 +1892,7 @@ MidiRegionView::update_hit (Hit* ev, bool update_ghost_regions)
std::shared_ptr<NoteType> note = ev->note();
const timepos_t note_time = _region->source_beats_to_absolute_time (note->time());
const double x = trackview.editor().time_to_pixel(note_time) - trackview.editor().time_to_pixel (_region->position());
const double x = editing_context.time_to_pixel(note_time) - editing_context.time_to_pixel (_region->position());
const double diamond_size = std::max(1., floor(note_height()) - 2.);
const double y = 1.5 + floor(note_to_y(note->note())) + diamond_size * .5;
@ -2026,7 +2030,7 @@ void
MidiRegionView::add_canvas_patch_change (MidiModel::PatchChangePtr patch)
{
timecnt_t off (_region->source_beats_to_region_time (patch->time()), _region->position());
const double x = trackview.editor().duration_to_pixels (off);
const double x = editing_context.duration_to_pixels (off);
double const height = midi_stream_view()->contents_height();
// CAIROCANVAS: active_channel info removed from PatcChange constructor
@ -2211,9 +2215,9 @@ MidiRegionView::delete_selection()
return;
}
if (trackview.editor().drags()->active()) {
return;
}
// if (editing_context.drags()->active()) {
// return;
// }
start_note_diff_command (_("delete selection"));
@ -2265,8 +2269,7 @@ void
MidiRegionView::clear_note_selection ()
{
clear_selection_internal ();
PublicEditor& editor(trackview.editor());
editor.get_selection().remove (this);
editing_context.get_selection().remove (this);
}
void
@ -2515,12 +2518,10 @@ MidiRegionView::note_deselected(NoteBase* ev)
void
MidiRegionView::update_drag_selection(timepos_t const & start, timepos_t const & end, double gy0, double gy1, bool extend)
{
PublicEditor& editor = trackview.editor();
// Convert to local coordinates
const double y = midi_view()->y_position();
const double x0 = editor.sample_to_pixel_unrounded (max<samplepos_t>(0, _region->region_relative_position (start).samples()));
const double x1 = editor.sample_to_pixel_unrounded (max<samplepos_t>(0, _region->region_relative_position (end).samples()));
const double x0 = editing_context.sample_to_pixel_unrounded (max<samplepos_t>(0, _region->region_relative_position (start).samples()));
const double x1 = editing_context.sample_to_pixel_unrounded (max<samplepos_t>(0, _region->region_relative_position (end).samples()));
const double y0 = max(0.0, gy0 - y);
const double y1 = max(0.0, gy1 - y);
@ -2545,7 +2546,8 @@ MidiRegionView::update_drag_selection(timepos_t const & start, timepos_t const &
/* Add control points to selection. */
const ATracks& atracks = midi_view()->automation_tracks();
editor.get_selection().clear_points();
Selectables selectables;
editing_context.get_selection().clear_points();
timepos_t st (start);
timepos_t et (end);
@ -2556,10 +2558,10 @@ MidiRegionView::update_drag_selection(timepos_t const & start, timepos_t const &
for (Selectables::const_iterator s = selectables.begin(); s != selectables.end(); ++s) {
ControlPoint* cp = dynamic_cast<ControlPoint*>(*s);
if (cp) {
editor.get_selection().add(cp);
editing_context.get_selection().add(cp);
}
}
a->second->set_selected_points(editor.get_selection().points);
a->second->set_selected_points(editing_context.get_selection().points);
}
}
@ -2601,8 +2603,7 @@ MidiRegionView::remove_from_selection (NoteBase* ev)
sync_ghost_selection (ev);
if (_selection.empty()) {
PublicEditor& editor (trackview.editor());
editor.get_selection().remove (this);
editing_context.get_selection().remove (this);
}
}
@ -2625,7 +2626,7 @@ MidiRegionView::add_to_selection (NoteBase* ev)
* 1 thing can be selected by clearing any current selection
*/
trackview.editor().get_selection().clear ();
editing_context.get_selection().clear ();
/* first note selected in this region, force Editor region
* selection to this region.
@ -2637,7 +2638,7 @@ MidiRegionView::add_to_selection (NoteBase* ev)
* only apply to notes anyway, not regions.
*/
trackview.editor().set_selected_midi_region_view (*this);
editing_context.set_selected_midi_region_view (*this);
}
if (_selection.insert (ev).second == true) {
@ -2678,7 +2679,6 @@ void
MidiRegionView::move_selection(timecnt_t const & dx_qn, double dy, double cumulative_dy)
{
typedef vector<std::shared_ptr<NoteType> > PossibleChord;
Editor* editor = dynamic_cast<Editor*> (&trackview.editor());
PossibleChord to_play;
Temporal::Beats earliest = earliest_in_selection();
@ -2691,13 +2691,13 @@ MidiRegionView::move_selection(timecnt_t const & dx_qn, double dy, double cumula
double dx = 0.0;
if (midi_view()->note_mode() == Sustained) {
dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
dx = editing_context.time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
- n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
} else {
/* Hit::x0() is offset by _position.x, unlike Note::x0() */
Hit* hit = dynamic_cast<Hit*>(n);
if (hit) {
dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
dx = editing_context.time_to_pixel_unrounded (timepos_t (note_time_qn + dx_qn.beats()))
- n->item()->item_to_canvas (ArdourCanvas::Duple (((hit->x0() + hit->x1()) / 2.0) - hit->position().x, 0)).x;
}
}
@ -2707,7 +2707,7 @@ MidiRegionView::move_selection(timecnt_t const & dx_qn, double dy, double cumula
/* update length */
if (midi_view()->note_mode() == Sustained) {
Note* sus = dynamic_cast<Note*> (*i);
double const len_dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
double const len_dx = editing_context.time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
sus->set_x1 (n->item()->canvas_to_item (ArdourCanvas::Duple (len_dx, 0)).x);
}
@ -2774,7 +2774,6 @@ void
MidiRegionView::move_copies (timecnt_t const & dx_qn, double dy, double cumulative_dy)
{
typedef vector<std::shared_ptr<NoteType> > PossibleChord;
Editor* editor = dynamic_cast<Editor*> (&trackview.editor());
PossibleChord to_play;
Temporal::Beats earliest = earliest_in_selection();
@ -2788,12 +2787,12 @@ MidiRegionView::move_copies (timecnt_t const & dx_qn, double dy, double cumulati
double_t dx = 0;
if (midi_view()->note_mode() == Sustained) {
dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn)
dx = editing_context.time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn)
- n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
} else {
Hit* hit = dynamic_cast<Hit*>(n);
if (hit) {
dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn)
dx = editing_context.time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn)
- n->item()->item_to_canvas (ArdourCanvas::Duple (((hit->x0() + hit->x1()) / 2.0) - hit->position().x, 0)).x;
}
}
@ -2802,7 +2801,7 @@ MidiRegionView::move_copies (timecnt_t const & dx_qn, double dy, double cumulati
if (midi_view()->note_mode() == Sustained) {
Note* sus = dynamic_cast<Note*> (*i);
double const len_dx = editor->time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
double const len_dx = editing_context.time_to_pixel_unrounded (timepos_t (note_time_qn) + dx_qn + timecnt_t (n->note()->length()));
sus->set_x1 (n->item()->canvas_to_item (ArdourCanvas::Duple (len_dx, 0)).x);
}
@ -2935,7 +2934,7 @@ MidiRegionView::note_dropped(NoteBase *, timecnt_t const & d_qn, int8_t dnote, b
}
apply_note_diff (true /*subcommand, we don't want this to start a new commit*/, copy);
trackview.editor().commit_reversible_command ();
editing_context.commit_reversible_command ();
// care about notes being moved beyond the upper/lower bounds on the canvas
if (lowest_note_in_selection < midi_stream_view()->lowest_note() ||
@ -2952,8 +2951,7 @@ MidiRegionView::note_dropped(NoteBase *, timecnt_t const & d_qn, int8_t dnote, b
timecnt_t
MidiRegionView::snap_pixel_to_time (double x, bool ensure_snap)
{
PublicEditor& editor (trackview.editor());
return snap_region_time_to_region_time (timecnt_t (editor.pixel_to_sample (x)), ensure_snap);
return snap_region_time_to_region_time (timecnt_t (editing_context.pixel_to_sample (x)), ensure_snap);
}
/** @param x Pixel relative to the region position.
@ -2963,20 +2961,20 @@ MidiRegionView::snap_pixel_to_time (double x, bool ensure_snap)
double
MidiRegionView::snap_to_pixel(double x, bool ensure_snap)
{
return (double) trackview.editor().sample_to_pixel (snap_pixel_to_time(x, ensure_snap).samples());
return (double) editing_context.sample_to_pixel (snap_pixel_to_time(x, ensure_snap).samples());
}
double
MidiRegionView::get_position_pixels()
{
return trackview.editor().time_to_pixel(get_position());
return editing_context.time_to_pixel(get_position());
}
double
MidiRegionView::get_end_position_pixels()
{
const timepos_t end = get_position() + get_duration ();
return trackview.editor().time_to_pixel (end);
return editing_context.time_to_pixel (end);
}
void
@ -3032,7 +3030,7 @@ void
MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_x, bool relative, double snap_delta, bool with_snap)
{
bool cursor_set = false;
bool const ensure_snap = trackview.editor().snap_mode () != SnapMagnetic;
bool const ensure_snap = editing_context.snap_mode () != SnapMagnetic;
for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
ArdourCanvas::Rectangle* resize_rect = (*i)->resize_rect;
@ -3059,8 +3057,8 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
*/
current_x = 0;
}
if (current_x > trackview.editor().duration_to_pixels (_region->length())) {
current_x = trackview.editor().duration_to_pixels (_region->length());
if (current_x > editing_context.duration_to_pixels (_region->length())) {
current_x = editing_context.duration_to_pixels (_region->length());
}
if (at_front) {
@ -3082,7 +3080,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
if (!cursor_set) {
/* Convert snap delta from pixels to beats. */
timepos_t snap_delta_time = timepos_t (trackview.editor().pixel_to_sample (snap_delta));
timepos_t snap_delta_time = timepos_t (editing_context.pixel_to_sample (snap_delta));
Beats snap_delta_beats;
int sign = 1;
@ -3100,7 +3098,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
if (with_snap) {
snapped_x = snap_pixel_to_time (current_x, ensure_snap); /* units depend on snap settings */
} else {
snapped_x = timepos_t (trackview.editor ().pixel_to_sample (current_x)); /* probably samples */
snapped_x = timepos_t (editing_context.pixel_to_sample (current_x)); /* probably samples */
}
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
@ -3133,7 +3131,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
cursor_set = true;
trackview.editor().set_snapped_cursor_position (snapped_x + midi_region()->position());
editing_context.set_snapped_cursor_position (snapped_x + midi_region()->position());
}
}
@ -3149,7 +3147,7 @@ MidiRegionView::finish_resizing (NoteBase* primary, bool at_front, double delta_
_note_diff_command = _model->new_note_diff_command (_("resize notes")); /* we are a subcommand, so we don't want to use start_note_diff() which begins a new command */
/* XX why doesn't snap_pixel_to_sample() handle this properly? */
bool const ensure_snap = trackview.editor().snap_mode () != SnapMagnetic;
bool const ensure_snap = editing_context.snap_mode () != SnapMagnetic;
for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
Note* canvas_note = (*i)->note;
@ -3179,12 +3177,12 @@ MidiRegionView::finish_resizing (NoteBase* primary, bool at_front, double delta_
current_x = 0;
}
if (current_x > trackview.editor().duration_to_pixels (_region->length())) {
current_x = trackview.editor().duration_to_pixels (_region->length());
if (current_x > editing_context.duration_to_pixels (_region->length())) {
current_x = editing_context.duration_to_pixels (_region->length());
}
/* Convert snap delta from pixels to beats with sign. */
timepos_t snap_delta_time (trackview.editor().pixel_to_sample (snap_delta));
timepos_t snap_delta_time (editing_context.pixel_to_sample (snap_delta));
Temporal::Beats snap_delta_beats;
int sign = 1;
@ -3200,7 +3198,7 @@ MidiRegionView::finish_resizing (NoteBase* primary, bool at_front, double delta_
if (with_snap) {
current_time = snap_pixel_to_time (current_x, ensure_snap);
} else {
current_time = timecnt_t (trackview.editor().pixel_to_sample (current_x));
current_time = timecnt_t (editing_context.pixel_to_sample (current_x));
}
/* and then to beats */
@ -3399,9 +3397,8 @@ MidiRegionView::change_note_length (NoteBase* event, Temporal::Beats t)
void
MidiRegionView::begin_drag_edit (std::string const & why)
{
if (!_selected) {
trackview.editor().get_selection().set (this, true);
}
editing_context.get_selection().set (this, true);
start_note_diff_command (why);
}
void
@ -3441,9 +3438,22 @@ MidiRegionView::set_velocities_for_notes (std::vector<NoteBase*>& notes, std::ve
delete _note_diff_command;
_note_diff_command = nullptr;
return changed;
}
void
MidiRegionView::end_drag_edit (bool apply)
{
if (apply) {
drag_apply ();
editing_context.commit_reversible_command ();
_note_diff_command = nullptr;
} else {
abort_note_diff ();
}
}
bool
MidiRegionView::set_velocity_for_notes (std::vector<NoteBase*>& notes, int velocity)
{
@ -3660,9 +3670,9 @@ MidiRegionView::nudge_notes (bool forward, bool fine)
Temporal::Beats delta;
timecnt_t unused;
const timecnt_t distance = trackview.editor().get_nudge_distance (ref_point, unused);
const timecnt_t distance = editing_context.get_nudge_distance (ref_point, unused);
if (!distance.is_zero() || trackview.editor().snap_mode() == Editing::SnapOff) {
if (!distance.is_zero() || editing_context.snap_mode() == Editing::SnapOff) {
/* grid is off - use nudge distance */
@ -3674,7 +3684,7 @@ MidiRegionView::nudge_notes (bool forward, bool fine)
bool success;
delta = trackview.editor().get_grid_type_as_beats (success, ref_point);
delta = editing_context.get_grid_type_as_beats (success, ref_point);
if (!success) {
delta = Temporal::Beats (1, 0);
@ -3722,18 +3732,16 @@ MidiRegionView::note_entered(NoteBase* ev)
{
_entered_note = ev;
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
if (_mouse_state == SelectTouchDragging) {
note_selected (ev, true);
} else if (editor->current_mouse_mode() == MouseContent) {
} else if (editing_context.current_mouse_mode() == MouseContent) {
remove_ghost_note ();
show_verbose_cursor (ev->note ());
} else if (editor->current_mouse_mode() == MouseDraw) {
} else if (editing_context.current_mouse_mode() == MouseDraw) {
remove_ghost_note ();
show_verbose_cursor (ev->note ());
@ -3795,18 +3803,17 @@ MidiRegionView::sysex_left (SysEx *)
void
MidiRegionView::note_mouse_position (float x_fraction, float /*y_fraction*/, bool can_set_cursor)
{
Editor* editor = dynamic_cast<Editor*>(&trackview.editor());
Editing::MouseMode mm = editor->current_mouse_mode();
Editing::MouseMode mm = editing_context.current_mouse_mode();
bool trimmable = (mm == MouseContent || mm == MouseTimeFX || mm == MouseDraw);
Editor::EnterContext* ctx = editor->get_enter_context(NoteItem);
Editor::EnterContext* ctx = editing_context.get_enter_context(NoteItem);
if (can_set_cursor && ctx) {
if (trimmable && x_fraction > 0.0 && x_fraction < 0.2) {
ctx->cursor_ctx->change(editor->cursors()->left_side_trim);
ctx->cursor_ctx->change(editing_context.cursors()->left_side_trim);
} else if (trimmable && x_fraction >= 0.8 && x_fraction < 1.0) {
ctx->cursor_ctx->change(editor->cursors()->right_side_trim);
ctx->cursor_ctx->change(editing_context.cursors()->right_side_trim);
} else {
ctx->cursor_ctx->change(editor->cursors()->grabber_note);
ctx->cursor_ctx->change(editing_context.cursors()->grabber_note);
}
}
}
@ -3820,7 +3827,7 @@ MidiRegionView::get_fill_color() const
if (_dragging) {
mod_name = "dragging region";
} else if (trackview.editor().internal_editing()) {
} else if (editing_context.internal_editing()) {
if (!opaque || _region->muted ()) {
mod_name = "editable region";
}
@ -3881,15 +3888,13 @@ MidiRegionView::cut_copy_clear (Editing::CutCopyOp op)
return;
}
PublicEditor& editor (trackview.editor());
switch (op) {
case Delete:
/* XXX what to do ? */
break;
case Cut:
case Copy:
editor.get_cut_buffer().add (selection_as_cut_buffer());
editing_context.get_cut_buffer().add (selection_as_cut_buffer());
break;
default:
break;
@ -3934,7 +3939,7 @@ MidiRegionView::selection_as_cut_buffer () const
void
MidiRegionView::duplicate_selection ()
{
trackview.editor().begin_reversible_command (_("duplicate notes"));
editing_context.begin_reversible_command (_("duplicate notes"));
if (_selection.empty()) {
return;
@ -3947,14 +3952,12 @@ MidiRegionView::duplicate_selection ()
dup_pos = std::max (dup_pos, _region->source_beats_to_absolute_time ((*s)->note()->end_time()));
}
PublicEditor& editor (trackview.editor());
/* Use a local Selection object that will not affect the global
* selection. Possible ::paste() should accept a different kind of
* object but that would conflict with the Editor API.
*/
::Selection local_selection (&editor, false);
::Selection local_selection (dynamic_cast<PublicEditor*> (&editing_context), false);
MidiNoteSelection note_selection;
note_selection.push_back (selection_as_cut_buffer());
@ -3964,9 +3967,9 @@ MidiRegionView::duplicate_selection ()
PasteContext ctxt (0, 1, ItemCounts(), false);
bool commit = paste (dup_pos, local_selection, ctxt);
if (commit) {
trackview.editor().commit_reversible_command ();
editing_context.commit_reversible_command ();
} else {
trackview.editor().abort_reversible_command ();
editing_context.abort_reversible_command ();
}
}
@ -4088,7 +4091,7 @@ MidiRegionView::goto_next_note (bool add_to_selection)
return;
}
trackview.editor().begin_reversible_selection_op (X_("Select Adjacent Note"));
editing_context.begin_reversible_selection_op (X_("Select Adjacent Note"));
for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) {
NoteBase* cne = 0;
@ -4122,7 +4125,7 @@ MidiRegionView::goto_next_note (bool add_to_selection)
}
trackview.editor().commit_reversible_selection_op();
editing_context.commit_reversible_selection_op();
}
void
@ -4141,7 +4144,7 @@ MidiRegionView::goto_previous_note (bool add_to_selection)
return;
}
trackview.editor().begin_reversible_selection_op (X_("Select Adjacent Note"));
editing_context.begin_reversible_selection_op (X_("Select Adjacent Note"));
for (MidiModel::Notes::reverse_iterator n = notes.rbegin(); n != notes.rend(); ++n) {
NoteBase* cne = 0;
@ -4175,7 +4178,7 @@ MidiRegionView::goto_previous_note (bool add_to_selection)
unique_select (last_note);
}
trackview.editor().commit_reversible_selection_op();
editing_context.commit_reversible_selection_op();
}
void
@ -4215,12 +4218,9 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state)
/* we need the y value only */
_note_group->canvas_to_item (x, y);
PublicEditor& editor = trackview.editor ();
samplepos_t const unsnapped_sample = editor.pixel_to_sample (global_x);
samplepos_t const unsnapped_sample = editing_context.pixel_to_sample (global_x);
Temporal::timepos_t snapped_pos = timepos_t (unsnapped_sample);
editor.snap_to (snapped_pos, RoundNearest, SnapToGrid_Scaled);
editing_context.snap_to (snapped_pos, RoundNearest, SnapToGrid_Scaled);
const Temporal::Beats snapped_beats = _region->absolute_time_to_region_beats(snapped_pos);
@ -4283,7 +4283,7 @@ MidiRegionView::remove_ghost_note ()
void
MidiRegionView::hide_verbose_cursor ()
{
trackview.editor().verbose_cursor()->hide ();
editing_context.verbose_cursor()->hide ();
MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
if (mtv) {
mtv->set_note_highlight (NO_MIDI_NOTE);
@ -4339,8 +4339,7 @@ MidiRegionView::maybe_select_by_position (GdkEventButton* ev, double /*x*/, doub
}
if (add_mrv_selection) {
PublicEditor& editor (trackview.editor());
editor.get_selection().add (this);
editing_context.get_selection().add (this);
}
}
@ -4383,7 +4382,7 @@ MidiRegionView::move_step_edit_cursor (Temporal::Beats pos)
_step_edit_cursor_position = pos;
if (_step_edit_cursor) {
double pixel = trackview.editor().time_to_pixel (_region->region_beats_to_region_time (pos));
double pixel = editing_context.time_to_pixel (_region->region_beats_to_region_time (pos));
_step_edit_cursor->set_x0 (pixel);
set_step_edit_cursor_width (_step_edit_cursor_width);
}
@ -4403,7 +4402,7 @@ MidiRegionView::set_step_edit_cursor_width (Temporal::Beats beats)
_step_edit_cursor_width = beats;
if (_step_edit_cursor) {
_step_edit_cursor->set_x1 (_step_edit_cursor->x0() + trackview.editor().duration_to_pixels (
_step_edit_cursor->set_x1 (_step_edit_cursor->x0() + editing_context.duration_to_pixels (
_region->region_beats_to_region_time (_step_edit_cursor_position).distance
(_region->region_beats_to_region_time (_step_edit_cursor_position + beats))));
}
@ -4487,7 +4486,7 @@ MidiRegionView::data_recorded (std::weak_ptr<MidiSource> w)
// - and then take the samples() value of that and convert it to pixels
//
// Much simpler to just use ev.time() which is already the absolute position (in sample-time)
_active_notes[note]->set_x1 (trackview.editor().sample_to_pixel ((src->time_since_capture_start (timepos_t (ev.time ()))).samples()));
_active_notes[note]->set_x1 (editing_context.sample_to_pixel ((src->time_since_capture_start (timepos_t (ev.time ()))).samples()));
_active_notes[note]->set_outline_all ();
_active_notes[note] = 0;
}
@ -4591,9 +4590,9 @@ MidiRegionView::show_verbose_cursor (std::shared_ptr<NoteType> n) const
void
MidiRegionView::show_verbose_cursor (string const & text, double xoffset, double yoffset) const
{
trackview.editor().verbose_cursor()->set (text);
trackview.editor().verbose_cursor()->show ();
trackview.editor().verbose_cursor()->set_offset (ArdourCanvas::Duple (xoffset, yoffset));
editing_context.verbose_cursor()->set (text);
editing_context.verbose_cursor()->show ();
editing_context.verbose_cursor()->set_offset (ArdourCanvas::Duple (xoffset, yoffset));
}
@ -4601,9 +4600,8 @@ uint8_t
MidiRegionView::get_channel_for_add (MidiModel::TimeType time) const
{
/* first, use the user-specified channel in the editor */
PublicEditor& editor = trackview.editor();
if (editor.draw_channel() != Editing::DRAW_CHAN_AUTO) {
return editor.draw_channel();
if (editing_context.draw_channel() != Editing::DRAW_CHAN_AUTO) {
return editing_context.draw_channel();
}
/* second, use the nearest note in the region-view (consistent with get_velocity_for_add behavior) */
@ -4633,9 +4631,8 @@ MidiRegionView::get_channel_for_add (MidiModel::TimeType time) const
uint8_t
MidiRegionView::get_velocity_for_add (MidiModel::TimeType time) const
{
PublicEditor& editor = trackview.editor();
if (editor.draw_velocity() != Editing::DRAW_VEL_AUTO) {
return editor.draw_velocity();
if (editing_context.draw_velocity() != Editing::DRAW_VEL_AUTO) {
return editing_context.draw_velocity();
}
if (_model->notes().size() < 2) {
@ -4691,9 +4688,8 @@ MidiRegionView::get_selected_channels () const
Temporal::Beats
MidiRegionView::get_grid_beats (timepos_t const & pos) const
{
PublicEditor& editor = trackview.editor();
bool success = false;
Temporal::Beats beats = editor.get_grid_type_as_beats (success, pos);
Temporal::Beats beats = editing_context.get_grid_type_as_beats (success, pos);
if (!success) {
beats = Temporal::Beats (1, 0);

View file

@ -68,6 +68,7 @@ class PatchChange;
class ItemCounts;
class CursorContext;
class VelocityGhostRegion;
class EditingContext;
class MidiRegionView : public RegionView
{
@ -76,12 +77,14 @@ public:
typedef Evoral::Sequence<Temporal::Beats>::Notes Notes;
MidiRegionView (ArdourCanvas::Container* parent,
EditingContext&,
RouteTimeAxisView& tv,
std::shared_ptr<ARDOUR::MidiRegion> r,
double samples_per_pixel,
uint32_t basic_color);
MidiRegionView (ArdourCanvas::Container* parent,
EditingContext&,
RouteTimeAxisView& tv,
std::shared_ptr<ARDOUR::MidiRegion> r,
double samples_per_pixel,
@ -348,7 +351,8 @@ public:
void _redisplay (bool view_only);
protected:
friend class Editor;
friend class EditingContext;
friend class Editor; // grr, C++ does not allow inheritance of friendship
void invert_note_selection ();
void extend_note_selection ();
@ -456,6 +460,8 @@ public:
uint8_t get_velocity_for_add (ARDOUR::MidiModel::TimeType time) const;
uint8_t get_channel_for_add (ARDOUR::MidiModel::TimeType time) const;
EditingContext& editing_context;
uint8_t _current_range_min;
uint8_t _current_range_max;

View file

@ -129,11 +129,11 @@ MidiStreamView::create_region_view (std::shared_ptr<Region> r, bool /*wfd*/, boo
RegionView* region_view = NULL;
if (recording) {
region_view = new MidiRegionView (
_region_group, _trackview, region,
_region_group, _trackview.editor(), _trackview, region,
_samples_per_pixel, region_color, recording,
TimeAxisViewItem::Visibility(TimeAxisViewItem::ShowFrame));
} else {
region_view = new MidiRegionView (_region_group, _trackview, region,
region_view = new MidiRegionView (_region_group, _trackview.editor(), _trackview, region,
_samples_per_pixel, region_color);
}

View file

@ -29,8 +29,6 @@ const int PublicEditor::container_border_width = 12;
const int PublicEditor::vertical_spacing = 6;
const int PublicEditor::horizontal_spacing = 6;
sigc::signal<void> PublicEditor::DropDownKeys;
ARDOUR::DataType PublicEditor::pbdid_dragged_dt = ARDOUR::DataType::NIL;
PublicEditor::PublicEditor (Gtk::Widget& content)

View file

@ -62,7 +62,7 @@
#include "axis_provider.h"
#include "editing.h"
#include "midi_editing_context.h"
#include "editing_context.h"
#include "selection.h"
namespace Temporal {
@ -124,7 +124,7 @@ using ARDOUR::samplecnt_t;
* of PublicEditor need not be recompiled if private methods or member variables
* change.
*/
class PublicEditor : public ArdourWidgets::Tabbable, public MidiEditingContext, public AxisViewProvider
class PublicEditor : public ArdourWidgets::Tabbable, public EditingContext, public AxisViewProvider
{
public:
PublicEditor (Gtk::Widget& content);
@ -189,10 +189,8 @@ public:
virtual void transition_to_rolling (bool fwd) = 0;
virtual bool get_selection_extents (Temporal::timepos_t &start, Temporal::timepos_t &end) const = 0;
virtual Selection& get_cut_buffer () const = 0;
virtual void set_selection (std::list<Selectable*>, ARDOUR::SelectionOperation) = 0;
virtual void set_selected_midi_region_view (MidiRegionView&) = 0;
virtual std::shared_ptr<ARDOUR::Route> current_mixer_stripable () const = 0;
@ -347,15 +345,11 @@ public:
virtual void split_region_at_points (std::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false) = 0;
virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0;
virtual void add_to_idle_resize (TimeAxisView*, int32_t) = 0;
virtual Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next) = 0;
virtual Temporal::timecnt_t get_paste_offset (Temporal::timepos_t const & pos, unsigned paste_count, Temporal::timecnt_t const & duration) = 0;
virtual Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position) = 0;
virtual Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position) = 0;
virtual int draw_velocity () const = 0;
virtual int draw_channel () const = 0;
virtual void edit_notes (MidiRegionView*) = 0;
virtual void queue_visual_videotimeline_update () = 0;
@ -387,8 +381,6 @@ public:
virtual bool pending_locate_request() const = 0;
static sigc::signal<void> DropDownKeys;
struct RegionAction {
Glib::RefPtr<Gtk::Action> action;
Editing::RegionActionTarget target;
@ -405,7 +397,6 @@ public:
Glib::RefPtr<Gtk::ActionGroup> editor_actions;
Glib::RefPtr<Gtk::ActionGroup> editor_menu_actions;
Glib::RefPtr<Gtk::ActionGroup> _region_actions;
Glib::RefPtr<Gtk::ActionGroup> _midi_actions;
virtual bool canvas_scroll_event (GdkEventScroll* event, bool from_canvas) = 0;
virtual bool canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item*, ControlPoint*) = 0;
@ -469,13 +460,6 @@ public:
virtual void stop_canvas_autoscroll () = 0;
virtual bool autoscroll_active() const = 0;
virtual void begin_reversible_selection_op (std::string cmd_name) = 0;
virtual void commit_reversible_selection_op () = 0;
virtual void begin_reversible_command (std::string cmd_name) = 0;
virtual void begin_reversible_command (GQuark) = 0;
virtual void abort_reversible_command () = 0;
virtual void commit_reversible_command () = 0;
virtual Temporal::TempoMap::WritableSharedPtr begin_tempo_map_edit () = 0;
virtual void abort_tempo_map_edit () = 0;
void commit_tempo_map_edit (Temporal::TempoMap::WritableSharedPtr& map, bool with_update = false) {
@ -510,8 +494,6 @@ public:
bool ensure_snap = false) = 0;
virtual Temporal::timepos_t snap_to_bbt (Temporal::timepos_t const & pos, Temporal::RoundMode, ARDOUR::SnapPref) = 0;
virtual void set_snapped_cursor_position (Temporal::timepos_t const & pos) = 0;
virtual void get_regions_at (RegionSelection &, Temporal::timepos_t const & where, TrackViewList const &) const = 0;
virtual void get_regions_after (RegionSelection&, Temporal::timepos_t const & where, const TrackViewList& ts) const = 0;
virtual RegionSelection get_regions_from_selection_and_mouse (Temporal::timepos_t const &) = 0;
@ -547,9 +529,6 @@ public:
friend bool ARDOUR_UI_UTILS::relay_key_press (GdkEventKey*, Gtk::Window*);
friend bool ARDOUR_UI_UTILS::forward_key_press (GdkEventKey*);
PBD::Signal0<void> SnapChanged;
PBD::Signal0<void> MouseModeChanged;
Gtkmm2ext::Bindings* bindings;
protected:

View file

@ -73,6 +73,7 @@ gtk2_ardour_sources = [
'duplicate_routes_dialog.cc',
'edit_note_dialog.cc',
'editing.cc',
'editing_context.cc',
'editor.cc',
'editor_actions.cc',
'editor_audio_import.cc',
@ -158,7 +159,6 @@ gtk2_ardour_sources = [
'midi_channel_selector.cc',
'midi_clip_editor.cc',
'midi_cut_buffer.cc',
'midi_editing_context.cc',
'midi_export_dialog.cc',
'midi_list_editor.cc',
'midi_region_view.cc',