Add the tool for Grid, and accompanying buttons and event-handling
This commit is contained in:
parent
268d1d33c7
commit
784d2ecce4
@ -66,6 +66,7 @@ MOUSEMODE(MouseObject)
|
||||
MOUSEMODE(MouseRange)
|
||||
MOUSEMODE(MouseCut)
|
||||
MOUSEMODE(MouseTimeFX)
|
||||
MOUSEMODE(MouseGrid)
|
||||
MOUSEMODE(MouseAudition)
|
||||
MOUSEMODE(MouseDraw)
|
||||
MOUSEMODE(MouseContent)
|
||||
|
@ -924,6 +924,7 @@ Editor::~Editor()
|
||||
delete _snapshots;
|
||||
delete _sections;
|
||||
delete _locations;
|
||||
delete _canvas_grid_zone;
|
||||
delete _properties_box;
|
||||
delete selection;
|
||||
delete cut_buffer;
|
||||
@ -3259,6 +3260,7 @@ Editor::setup_toolbar ()
|
||||
mouse_mode_size_group->add_widget (mouse_cut_button);
|
||||
mouse_mode_size_group->add_widget (mouse_select_button);
|
||||
mouse_mode_size_group->add_widget (mouse_timefx_button);
|
||||
mouse_mode_size_group->add_widget (mouse_grid_button);
|
||||
if (!Profile->get_mixbus()) {
|
||||
mouse_mode_size_group->add_widget (mouse_audition_button);
|
||||
}
|
||||
@ -3277,6 +3279,8 @@ Editor::setup_toolbar ()
|
||||
mouse_mode_size_group->add_widget (visible_tracks_selector);
|
||||
}
|
||||
|
||||
mouse_mode_size_group->add_widget (stretch_midi_cb);
|
||||
|
||||
mouse_mode_size_group->add_widget (grid_type_selector);
|
||||
mouse_mode_size_group->add_widget (draw_length_selector);
|
||||
mouse_mode_size_group->add_widget (draw_velocity_selector);
|
||||
@ -3304,6 +3308,7 @@ Editor::setup_toolbar ()
|
||||
}
|
||||
|
||||
mouse_mode_hbox->pack_start (mouse_timefx_button, false, false);
|
||||
mouse_mode_hbox->pack_start (mouse_grid_button, false, false);
|
||||
mouse_mode_hbox->pack_start (mouse_draw_button, false, false);
|
||||
mouse_mode_hbox->pack_start (mouse_content_button, false, false);
|
||||
|
||||
@ -3393,6 +3398,8 @@ Editor::setup_toolbar ()
|
||||
snap_box.set_spacing (2);
|
||||
snap_box.set_border_width (2);
|
||||
|
||||
stretch_midi_cb.set_name ("mouse mode button");
|
||||
|
||||
grid_type_selector.set_name ("mouse mode button");
|
||||
draw_length_selector.set_name ("mouse mode button");
|
||||
draw_velocity_selector.set_name ("mouse mode button");
|
||||
@ -3424,6 +3431,13 @@ Editor::setup_toolbar ()
|
||||
nudge_box->pack_start (nudge_forward_button, false, false);
|
||||
nudge_box->pack_start (*nudge_clock, false, false);
|
||||
|
||||
stretch_midi_cb.set_label(_("Stretch MIDI"));
|
||||
|
||||
/* Grid - these tools are only visible when in Grid mode */
|
||||
grid_box.set_spacing (2);
|
||||
grid_box.set_border_width (2);
|
||||
grid_box.pack_start (stretch_midi_cb, false, false, 4);
|
||||
|
||||
/* Draw - these MIDI tools are only visible when in Draw mode */
|
||||
draw_box.set_spacing (2);
|
||||
draw_box.set_border_width (2);
|
||||
@ -3462,6 +3476,8 @@ Editor::setup_toolbar ()
|
||||
toolbar_hbox.pack_start (snap_box, false, false);
|
||||
toolbar_hbox.pack_start (*(manage (new ArdourVSpacer ())), false, false, 3);
|
||||
toolbar_hbox.pack_start (*nudge_box, false, false);
|
||||
toolbar_hbox.pack_start (_grid_box_spacer, false, false, 3);
|
||||
toolbar_hbox.pack_start (grid_box, false, false);
|
||||
toolbar_hbox.pack_start (_draw_box_spacer, false, false, 3);
|
||||
toolbar_hbox.pack_start (draw_box, false, false);
|
||||
toolbar_hbox.pack_end (_zoom_box, false, false, 2);
|
||||
@ -3621,6 +3637,7 @@ Editor::setup_tooltips ()
|
||||
set_tooltip (mouse_move_button, _("Grab Mode (select/move objects)"));
|
||||
set_tooltip (mouse_cut_button, _("Cut Mode (split regions)"));
|
||||
set_tooltip (mouse_select_button, _("Range Mode (select time ranges)"));
|
||||
set_tooltip (mouse_grid_button, _("Grid Mode (edit tempo-map, drag/drop music-time grid)"));
|
||||
set_tooltip (mouse_draw_button, _("Draw Mode (draw and edit gain/notes/automation)"));
|
||||
set_tooltip (mouse_timefx_button, _("Stretch Mode (time-stretch audio and midi regions, preserving pitch)"));
|
||||
set_tooltip (mouse_audition_button, _("Audition Mode (listen to regions)"));
|
||||
@ -3636,6 +3653,7 @@ Editor::setup_tooltips ()
|
||||
set_tooltip (tav_expand_button, _("Expand Tracks"));
|
||||
set_tooltip (tav_shrink_button, _("Shrink Tracks"));
|
||||
set_tooltip (visible_tracks_selector, _("Number of visible tracks"));
|
||||
set_tooltip (stretch_midi_cb, _("Enable to move MIDI events when stretching the Grid"));
|
||||
set_tooltip (draw_length_selector, _("Note Length to Draw (AUTO uses the current Grid setting)"));
|
||||
set_tooltip (draw_velocity_selector, _("Note Velocity to Draw (AUTO uses the nearest note's velocity)"));
|
||||
set_tooltip (draw_channel_selector, _("Note Channel to Draw (AUTO uses the nearest note's channel)"));
|
||||
|
@ -1966,6 +1966,7 @@ private:
|
||||
ArdourWidgets::ArdourButton mouse_draw_button;
|
||||
ArdourWidgets::ArdourButton mouse_move_button;
|
||||
ArdourWidgets::ArdourButton mouse_timefx_button;
|
||||
ArdourWidgets::ArdourButton mouse_grid_button;
|
||||
ArdourWidgets::ArdourButton mouse_content_button;
|
||||
ArdourWidgets::ArdourButton mouse_audition_button;
|
||||
ArdourWidgets::ArdourButton mouse_cut_button;
|
||||
@ -2005,12 +2006,16 @@ private:
|
||||
ArdourWidgets::ArdourDropdown draw_channel_selector;
|
||||
void build_draw_midi_menus ();
|
||||
|
||||
Gtk::CheckButton stretch_midi_cb;
|
||||
|
||||
ArdourWidgets::ArdourButton snap_mode_button;
|
||||
bool snap_mode_button_clicked (GdkEventButton*);
|
||||
|
||||
Gtk::HBox snap_box;
|
||||
Gtk::HBox grid_box;
|
||||
Gtk::HBox draw_box;
|
||||
|
||||
ArdourWidgets::ArdourVSpacer _grid_box_spacer;
|
||||
ArdourWidgets::ArdourVSpacer _draw_box_spacer;
|
||||
|
||||
Gtk::HBox ebox_hpacker;
|
||||
@ -2550,6 +2555,7 @@ private:
|
||||
|
||||
void remove_gap_marker_callback (Temporal::timepos_t at, Temporal::timecnt_t distance);
|
||||
|
||||
Editing::GridType determine_mapping_grid_snap (Temporal::timepos_t t);
|
||||
void choose_mapping_drag (ArdourCanvas::Item*, GdkEvent*);
|
||||
|
||||
Editing::TempoEditBehavior _tempo_edit_behavior;
|
||||
|
@ -597,6 +597,11 @@ Editor::register_actions ()
|
||||
mouse_timefx_button.set_icon (ArdourWidgets::ArdourIcon::ToolStretch);
|
||||
mouse_timefx_button.set_name ("mouse mode button");
|
||||
|
||||
act = ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-grid", _("Grid Tool"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseGrid));
|
||||
mouse_grid_button.set_related_action (act);
|
||||
mouse_grid_button.set_icon (ArdourWidgets::ArdourIcon::ToolGrid);
|
||||
mouse_grid_button.set_name ("mouse mode button");
|
||||
|
||||
act = ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-content", _("Internal Edit (Content Tool)"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseContent));
|
||||
mouse_content_button.set_related_action (act);
|
||||
mouse_content_button.set_icon (ArdourWidgets::ArdourIcon::ToolContent);
|
||||
|
@ -270,6 +270,8 @@ Editor::get_mouse_mode_action(MouseMode m) const
|
||||
return ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-draw"));
|
||||
case MouseTimeFX:
|
||||
return ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-timefx"));
|
||||
case MouseGrid:
|
||||
return ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-grid"));
|
||||
case MouseContent:
|
||||
return ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-content"));
|
||||
case MouseAudition:
|
||||
@ -376,6 +378,15 @@ Editor::mouse_mode_toggled (MouseMode m)
|
||||
_draw_box_spacer.hide();
|
||||
}
|
||||
|
||||
if (mouse_mode == MouseGrid) {
|
||||
grid_box.show();
|
||||
_grid_box_spacer.show();
|
||||
_canvas_grid_zone->set_ignore_events (false); // woohoo
|
||||
} else {
|
||||
grid_box.hide();
|
||||
_grid_box_spacer.hide();
|
||||
_canvas_grid_zone->set_ignore_events (true); // important !!!
|
||||
}
|
||||
|
||||
if (internal_editing()) {
|
||||
|
||||
@ -478,6 +489,7 @@ Editor::update_time_selection_display ()
|
||||
selection->clear_tracks ();
|
||||
break;
|
||||
|
||||
case MouseGrid:
|
||||
default:
|
||||
/*Clear everything */
|
||||
selection->clear_objects();
|
||||
@ -1237,6 +1249,12 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
return true;
|
||||
break;
|
||||
|
||||
case MouseGrid:
|
||||
/* MouseGrid clicks are handled by _canvas_grid_zone */
|
||||
assert (0);
|
||||
abort(); /*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case MouseDraw:
|
||||
switch (item_type) {
|
||||
case GainLineItem:
|
||||
@ -1917,6 +1935,12 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
}
|
||||
break;
|
||||
|
||||
case MouseGrid:
|
||||
/* MouseGrid clicks are handled by _canvas_grid_zone */
|
||||
assert (0);
|
||||
abort(); /*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case MouseAudition:
|
||||
if (scrubbing_direction == 0) {
|
||||
/* no drag, just a click */
|
||||
@ -2321,6 +2345,27 @@ Editor::scrub (samplepos_t sample, double current_x)
|
||||
last_scrub_x = current_x;
|
||||
}
|
||||
|
||||
GridType
|
||||
Editor::determine_mapping_grid_snap(timepos_t t)
|
||||
{
|
||||
timepos_t snapped = _snap_to_bbt (t, RoundNearest, SnapToGrid_Unscaled, GridTypeBeat);
|
||||
timepos_t snapped_to_bar = _snap_to_bbt (t, RoundNearest, SnapToGrid_Unscaled, GridTypeBar);
|
||||
const double unsnapped_pos = time_to_pixel_unrounded (t);
|
||||
const double snapped_pos = time_to_pixel_unrounded (snapped);
|
||||
|
||||
double ruler_line_granularity = UIConfiguration::instance().get_ruler_granularity () * UIConfiguration::instance().get_ui_scale(); // in pixels
|
||||
|
||||
if (std::abs (snapped_pos - unsnapped_pos) < ruler_line_granularity) {
|
||||
if (snapped == snapped_to_bar) {
|
||||
return GridTypeBar;
|
||||
} else {
|
||||
return GridTypeBeat;
|
||||
}
|
||||
} else {
|
||||
return GridTypeNone;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, bool from_autoscroll)
|
||||
{
|
||||
@ -2377,44 +2422,22 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, bool from_aut
|
||||
|
||||
timepos_t t (where);
|
||||
bool move_snapped_cursor = true;
|
||||
|
||||
if (item == mapping_bar) {
|
||||
|
||||
/* Snap to the nearest beat, and figure out how
|
||||
* many pixels from the pointer cursor that is.
|
||||
*/
|
||||
|
||||
Editor::EnterContext* ctx = get_enter_context (MappingBarItem);
|
||||
|
||||
if (ctx) {
|
||||
timepos_t snapped = _snap_to_bbt (t, RoundNearest, SnapToGrid_Unscaled, GridTypeBeat);
|
||||
timepos_t snapped_to_bar = _snap_to_bbt (t, RoundNearest, SnapToGrid_Unscaled, GridTypeBar);
|
||||
const double unsnapped_pos = time_to_pixel_unrounded (t);
|
||||
const double snapped_pos = time_to_pixel_unrounded (snapped);
|
||||
|
||||
if (std::abs (snapped_pos - unsnapped_pos) < 10 * UIConfiguration::instance().get_ui_scale()) {
|
||||
|
||||
/* Close to a beat, so snap the mapping
|
||||
* cursor *and* the snapped cursor to
|
||||
* the beat.
|
||||
*/
|
||||
|
||||
if (snapped == snapped_to_bar) {
|
||||
ctx->cursor_ctx->change (cursors()->time_fx);
|
||||
} else {
|
||||
/* snapped to a beat, not a bar .... we'll implement a TWIST here */
|
||||
ctx->cursor_ctx->change (cursors()->expand_left_right);
|
||||
}
|
||||
} else {
|
||||
ctx->cursor_ctx->change (cursors()->grabber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (move_snapped_cursor) {
|
||||
snap_to_with_modifier (t, event);
|
||||
set_snapped_cursor_position (t);
|
||||
}
|
||||
|
||||
/* if tempo-mapping, set a cursor to indicate whether we are close to a bar line, beat line, or neither */
|
||||
if (mouse_mode == MouseGrid && item == _canvas_grid_zone) {
|
||||
GridType gt = determine_mapping_grid_snap (t);
|
||||
if (gt == GridTypeBar) {
|
||||
set_canvas_cursor (cursors()->time_fx);
|
||||
} else if (gt == GridTypeBeat) {
|
||||
set_canvas_cursor (cursors()->expand_left_right);
|
||||
} else {
|
||||
set_canvas_cursor (cursors()->grabber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!peaks_visible) {
|
||||
@ -2996,29 +3019,29 @@ Editor::choose_mapping_drag (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
/* In a departure from convention, this event is not handled by a widget
|
||||
* 'on' the ruler-bar, like a tempo marker, but is instead handled by the
|
||||
* mapping-bar widget itself. The intent is for the user to feel that they
|
||||
* whole canvas. The intent is for the user to feel that they
|
||||
* are manipulating the 'beat and bar grid' which may or may not have tempo
|
||||
* markers already assigned at the point under the mouse.
|
||||
*/
|
||||
|
||||
if (item != mapping_bar) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cursor_stack.empty()) {
|
||||
bool ignored;
|
||||
samplepos_t where;
|
||||
|
||||
if (!mouse_sample (where, ignored)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if tempo-mapping, set a cursor to indicate whether we are close to a bar line, beat line, or neither */
|
||||
bool ramped = false;
|
||||
if (_cursor_stack.back() == cursors()->time_fx) {
|
||||
/* We are on a BAR line ... the user can drag the line exactly where it's needed */
|
||||
if (mouse_mode == MouseGrid && item ==_canvas_grid_zone) {
|
||||
GridType gt = determine_mapping_grid_snap (timepos_t (where));
|
||||
if (gt == GridTypeBar) {
|
||||
ramped = false;
|
||||
} else if (_cursor_stack.back() == cursors()->expand_left_right) {
|
||||
/* We are on a BEAT line ... we will nudge the beat line via ramping, without moving any tempo markers */
|
||||
} else if (gt == GridTypeBeat) {
|
||||
ramped = true;
|
||||
} else {
|
||||
/* Not close enough to a beat line to start any mapping drag */
|
||||
return;
|
||||
return; // neither a bar nor a beat; don't start a drag
|
||||
}
|
||||
}
|
||||
|
||||
/* The reversible command starts here, must be ended/aborted in drag */
|
||||
|
@ -192,6 +192,7 @@ setup_gtk_ardour_enums ()
|
||||
REGISTER_ENUM(MouseRange);
|
||||
REGISTER_ENUM(MouseDraw);
|
||||
REGISTER_ENUM(MouseTimeFX);
|
||||
REGISTER_ENUM(MouseGrid);
|
||||
REGISTER_ENUM(MouseAudition);
|
||||
REGISTER_ENUM(MouseCut);
|
||||
REGISTER_ENUM(MouseContent);
|
||||
|
Loading…
Reference in New Issue
Block a user