diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 4180fe4331..8268d035af 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -369,6 +369,7 @@ Editor::Editor () , have_pending_keyboard_selection (false) , pending_keyboard_selection_start (0) , _grid_type (GridTypeBeat) + , _draw_length (GridTypeNone) , _snap_mode (SnapOff) , ignore_gui_changes (false) , _drags (new DragManager (this)) @@ -855,6 +856,7 @@ Editor::Editor () setup_fade_images (); set_grid_to (GridTypeNone); + set_draw_length_to (GridTypeBeat); } Editor::~Editor() @@ -2095,6 +2097,12 @@ Editor::grid_type() const return _grid_type; } +GridType +Editor::draw_length() const +{ + return _draw_length; +} + bool Editor::grid_musical() const { @@ -2186,6 +2194,26 @@ Editor::show_rulers_for_grid () } } +void +Editor::set_draw_length_to (GridType gt) +{ + if ( !grid_type_is_musical(gt) ) { //range-check + gt = GridTypeBeat; + } + + if (_draw_length == gt) { // already set + return; + } + + _draw_length = gt; + + 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); + } +} + void Editor::set_grid_to (GridType gt) { @@ -2355,6 +2383,12 @@ Editor::set_state (const XMLNode& node, int version) } set_grid_to (grid_type); + GridType draw_length; + if (!node.get_property ("draw-length", draw_length)) { + draw_length = GridTypeBeat; + } + set_draw_length_to (draw_length); + SnapMode sm; if (node.get_property ("snap-mode", sm)) { snap_mode_selection_done(sm); @@ -2523,6 +2557,7 @@ Editor::get_state () node->set_property ("zoom", samples_per_pixel); node->set_property ("grid-type", _grid_type); + node->set_property ("draw-length", _draw_length); node->set_property ("snap-mode", _snap_mode); node->set_property ("internal-grid-type", internal_grid_type); node->set_property ("internal-snap-mode", internal_snap_mode); @@ -2866,7 +2901,7 @@ Editor::snap_to_bbt (timepos_t const & presnap, Temporal::RoundMode direction, S break; } } else { - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (get_grid_beat_divisions(), direction)); + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (get_grid_beat_divisions(_grid_type), direction)); } return ret; @@ -3043,6 +3078,7 @@ Editor::setup_toolbar () } mouse_mode_size_group->add_widget (grid_type_selector); + mouse_mode_size_group->add_widget (draw_length_selector); mouse_mode_size_group->add_widget (snap_mode_button); mouse_mode_size_group->add_widget (edit_point_selector); @@ -3153,6 +3189,7 @@ Editor::setup_toolbar () snap_box.set_border_width (2); grid_type_selector.set_name ("mouse mode button"); + draw_length_selector.set_name ("mouse mode button"); snap_mode_button.set_name ("mouse mode button"); @@ -3174,6 +3211,10 @@ Editor::setup_toolbar () nudge_box->pack_start (nudge_forward_button, false, false); nudge_box->pack_start (*nudge_clock, false, false); + /* Draw - these MIDI tools are only visible when in Draw mode */ + draw_box.set_spacing (2); + draw_box.set_border_width (2); + draw_box.pack_start (draw_length_selector, false, false); /* Pack everything in... */ @@ -3201,6 +3242,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 (*(manage (new ArdourVSpacer ())), false, false, 3); + toolbar_hbox.pack_start (draw_box, false, false); toolbar_hbox.pack_end (_zoom_box, false, false, 2); toolbar_hbox.pack_end (*(manage (new ArdourVSpacer ())), false, false, 3); toolbar_hbox.pack_end (_track_box, false, false); @@ -3286,6 +3329,17 @@ Editor::build_grid_type_menu () grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeTimecode], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeTimecode))); grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeMinSec], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeMinSec))); grid_type_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeCDFrame], sigc::bind (sigc::mem_fun(*this, &Editor::grid_type_selection_done), (GridType) GridTypeCDFrame))); + + + /* main grid: bars, quarter-notes, etc */ + draw_length_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeBar], sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_selection_done), (GridType) GridTypeBar))); + draw_length_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeBeat], sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_selection_done), (GridType) GridTypeBeat))); + draw_length_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeBeatDiv2], sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_selection_done), (GridType) GridTypeBeatDiv2))); + draw_length_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeBeatDiv4], sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_selection_done), (GridType) GridTypeBeatDiv4))); + draw_length_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeBeatDiv8], sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_selection_done), (GridType) GridTypeBeatDiv8))); + draw_length_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeBeatDiv16], sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_selection_done), (GridType) GridTypeBeatDiv16))); + draw_length_selector.AddMenuElem (MenuElem (grid_type_strings[(int)GridTypeBeatDiv32], sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_selection_done), (GridType) GridTypeBeatDiv32))); + } void @@ -3310,6 +3364,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 (draw_length_selector, _("Note Length to Draw")); set_tooltip (grid_type_selector, _("Grid Mode")); set_tooltip (snap_mode_button, _("Snap Mode\n\nRight-click to visit Snap preferences.")); set_tooltip (edit_point_selector, _("Edit Point")); @@ -3715,6 +3770,15 @@ Editor::grid_type_selection_done (GridType gridtype) } } +void +Editor::draw_length_selection_done (GridType gridtype) +{ + RefPtr ract = draw_length_action (gridtype); + if (ract) { + ract->set_active (); + } +} + void Editor::snap_mode_selection_done (SnapMode mode) { @@ -4075,9 +4139,9 @@ Editor::get_paste_offset (Temporal::timepos_t const & pos, unsigned paste_count, } unsigned -Editor::get_grid_beat_divisions () +Editor::get_grid_beat_divisions (GridType gt) { - switch (_grid_type) { + switch (gt) { case GridTypeBeatDiv32: return 32; case GridTypeBeatDiv28: return 28; case GridTypeBeatDiv24: return 24; @@ -4111,7 +4175,7 @@ Editor::get_grid_beat_divisions () @param event_state the current keyboard modifier mask. */ int32_t -Editor::get_grid_music_divisions (uint32_t event_state) +Editor::get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) { if (snap_mode() == SnapOff && !ArdourKeyboard::indicates_snap (event_state)) { return 0; @@ -4121,7 +4185,7 @@ Editor::get_grid_music_divisions (uint32_t event_state) return 0; } - switch (_grid_type) { + switch (gt) { case GridTypeBeatDiv32: return 32; case GridTypeBeatDiv28: return 28; case GridTypeBeatDiv24: return 24; @@ -4153,9 +4217,9 @@ Editor::get_grid_type_as_beats (bool& success, timepos_t const & position) { success = true; - const unsigned divisions = get_grid_beat_divisions (); + const unsigned divisions = get_grid_beat_divisions (_grid_type); if (divisions) { - return Temporal::Beats::from_double (1.0 / (double) get_grid_beat_divisions ()); + return Temporal::Beats::from_double (1.0 / (double) divisions); } TempoMap::SharedPtr tmap (TempoMap::use()); @@ -4178,6 +4242,20 @@ Editor::get_grid_type_as_beats (bool& success, timepos_t const & position) return Temporal::Beats(); } +Temporal::Beats +Editor::get_draw_length_as_beats (bool& success, timepos_t const & position) +{ + success = true; + + const unsigned divisions = get_grid_beat_divisions (_draw_length); + if (divisions) { + return Temporal::Beats::from_double (1.0 / (double) divisions); + } + + success = false; + return Temporal::Beats(); +} + timecnt_t Editor::get_nudge_distance (timepos_t const & pos, timecnt_t& next) { diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 3a63926c6f..95123cf381 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -185,10 +185,12 @@ public: void next_grid_choice (); void prev_grid_choice (); void set_grid_to (Editing::GridType); + void set_draw_length_to (Editing::GridType); void set_snap_mode (Editing::SnapMode); Editing::SnapMode snap_mode () const; Editing::GridType grid_type () const; + Editing::GridType draw_length () const; bool grid_type_is_musical (Editing::GridType) const; bool grid_musical () const; @@ -360,10 +362,12 @@ public: Temporal::timecnt_t get_nudge_distance (Temporal::timepos_t const & pos, Temporal::timecnt_t& next); Temporal::timecnt_t get_paste_offset (Temporal::timepos_t const & pos, unsigned paste_count, Temporal::timecnt_t const & duration); - unsigned get_grid_beat_divisions (); - Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position); - int32_t get_grid_music_divisions (uint32_t event_state); + Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position); + Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position); + + unsigned get_grid_beat_divisions (Editing::GridType gt); + int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state); void nudge_forward (bool next, bool force_playhead); void nudge_backward (bool next, bool force_playhead); @@ -1587,6 +1591,7 @@ private: void move_range_selection_start_or_end_to_region_boundary (bool, bool); Editing::GridType _grid_type; + Editing::GridType _draw_length; Editing::SnapMode _snap_mode; bool ignore_gui_changes; @@ -1878,12 +1883,14 @@ private: void cycle_edit_mode (); ArdourWidgets::ArdourDropdown grid_type_selector; + ArdourWidgets::ArdourDropdown draw_length_selector; void build_grid_type_menu (); ArdourWidgets::ArdourButton snap_mode_button; bool snap_mode_button_clicked (GdkEventButton*); Gtk::HBox snap_box; + Gtk::HBox draw_box; Gtk::HBox ebox_hpacker; Gtk::VBox ebox_vpacker; @@ -1894,11 +1901,14 @@ private: std::vector snap_mode_strings; void grid_type_selection_done (Editing::GridType); + void draw_length_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_chosen (Editing::GridType); Glib::RefPtr grid_type_action (Editing::GridType); + Glib::RefPtr draw_length_action (Editing::GridType); Glib::RefPtr snap_mode_action (Editing::SnapMode); //zoom focus meu stuff diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index dadddcbeb2..13062eacd2 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -601,6 +601,27 @@ Editor::register_actions () ActionManager::register_action (editor_actions, X_("next-grid-choice"), _("Next Quantize Grid Choice"), sigc::mem_fun (*this, &Editor::next_grid_choice)); ActionManager::register_action (editor_actions, X_("prev-grid-choice"), _("Previous Quantize Grid Choice"), sigc::mem_fun (*this, &Editor::prev_grid_choice)); + Glib::RefPtr length_actions = ActionManager::create_action_group (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))); + Glib::RefPtr snap_actions = ActionManager::create_action_group (bindings, X_("Snap")); RadioAction::Group grid_choice_group; @@ -1062,6 +1083,85 @@ Editor::edit_current_tempo () edit_tempo_section (Temporal::TempoMap::use()->metric_at (ARDOUR_UI::instance()->primary_clock->absolute_time()).get_editable_tempo()); } +RefPtr +Editor::draw_length_action (GridType type) +{ + const char* action = 0; + RefPtr 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: + 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 ract = RefPtr::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(); + } +} + RefPtr Editor::grid_type_action (GridType type) { @@ -1253,6 +1353,20 @@ Editor::grid_type_chosen (GridType type) 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 ract = draw_length_action (type); + + if (ract && ract->get_active()) { + set_draw_length_to (type); + } +} RefPtr Editor::snap_mode_action (SnapMode mode) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 8d5f7a010c..0335956fcf 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3786,7 +3786,7 @@ BBTRulerDrag::setup_pointer_offset () _grab_qn = max (Beats(), raw_grab_time().beats()); - uint32_t divisions = _editor->get_grid_beat_divisions (); + uint32_t divisions = _editor->get_grid_beat_divisions (_editor->grid_type()); if (divisions == 0) { divisions = 4; @@ -6976,7 +6976,7 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) const timepos_t pos = _drags->current_pointer_time (); Temporal::Beats aligned_beats (round_down_to_grid (pos, event)); - const Temporal::Beats grid_beats (_region_view->get_grid_beats (pos)); + const Temporal::Beats grid_beats (_region_view->get_draw_length_beats (pos)); _note[0] = timepos_t (aligned_beats); /* minimum initial length is grid beats */ @@ -7027,7 +7027,7 @@ NoteCreateDrag::finished (GdkEvent* ev, bool had_movement) Beats const start = _region_view->region()->absolute_time_to_region_beats (min (_note[0], _note[1])); Beats length = max (Beats (0, 1), (_note[0].distance (_note[1]).abs().beats())); - int32_t div = _editor->get_grid_music_divisions (ev->button.state); + int32_t div = _editor->get_grid_music_divisions (_editor->draw_length(), ev->button.state); if (div > 0) { length = length.round_to_subdivision (div, RoundUpMaybe); @@ -7072,7 +7072,6 @@ HitCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) _y = _region_view->note_to_y (_region_view->y_to_note (y_to_region (event->button.y))); const timepos_t pos = _drags->current_pointer_time (); - const int32_t divisions = _editor->get_grid_music_divisions (event->button.state); const Beats beats = pos.beats (); @@ -7083,7 +7082,7 @@ HitCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) } const Temporal::Beats start = beats - _region_view->region()->position().beats (); - Temporal::Beats length = _region_view->get_grid_beats (pos); + Temporal::Beats length = _region_view->get_draw_length_beats (pos); _editor->begin_reversible_command (_("Create Hit")); _region_view->clear_note_selection(); @@ -7096,9 +7095,9 @@ void HitCreateDrag::motion (GdkEvent* event, bool) { const timepos_t pos = _drags->current_pointer_time (); - const int32_t divisions = _editor->get_grid_music_divisions (event->button.state); - if (divisions == 0) { + const int32_t divisions = _editor->get_grid_music_divisions (_editor->draw_length(), event->button.state); + if (divisions <= 0) { return; } @@ -7109,7 +7108,7 @@ HitCreateDrag::motion (GdkEvent* event, bool) return; } - Temporal::Beats length = _region_view->get_grid_beats (pos); + Temporal::Beats length = _region_view->get_draw_length_beats (pos); boost::shared_ptr mr = _region_view->midi_region(); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index e1ed2f7541..fa720cfdab 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -337,6 +337,10 @@ Editor::mouse_mode_toggled (MouseMode m) mouse_mode = m; + /* Ben ToDo: once we have a dedicated 'region edit panel', we can store + * one snap mode in the editor canvas and another one in the editor, + * relieving the complexity here */ + /* Switch snap type/mode if we're moving to/from an internal tool. Note this must toggle the actions and not call set_snap_*() directly, otherwise things get out of sync and the combo box stops working. */ @@ -365,6 +369,13 @@ Editor::mouse_mode_toggled (MouseMode m) update_time_selection_display (); + if (mouse_mode == MouseDraw) { + draw_length_selector.set_sensitive(true); + } else { + draw_length_selector.set_sensitive(false); + } + + if (internal_editing()) { /* reinstate any existing MIDI note (and by extension, MIDI diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index 7d3a73d53a..c53f2bf3db 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -1045,7 +1045,7 @@ Editor::compute_bbt_ruler_scale (samplepos_t lower, samplepos_t upper) /* Now that we know how fine a grid (Ruler) is allowable on this screen, limit it to the coarseness selected by the user */ /* note: GridType and RulerScale are not the same enums, so it's not a simple mathematical operation */ int suggested_scale = (int) bbt_ruler_scale; - int divs = get_grid_music_divisions(_grid_type); + int divs = get_grid_music_divisions(_grid_type, 0); if (_grid_type == GridTypeBar) { suggested_scale = std::min(suggested_scale, (int) bbt_show_1); } else if (_grid_type == GridTypeBeat) { diff --git a/gtk2_ardour/luainstance.cc b/gtk2_ardour/luainstance.cc index e2e66adefe..7d32e53d09 100644 --- a/gtk2_ardour/luainstance.cc +++ b/gtk2_ardour/luainstance.cc @@ -1000,6 +1000,7 @@ LuaInstance::register_classes (lua_State* L) .addFunction ("get_paste_offset", &PublicEditor::get_paste_offset) .addFunction ("get_grid_beat_divisions", &PublicEditor::get_grid_beat_divisions) .addRefFunction ("get_grid_type_as_beats", &PublicEditor::get_grid_type_as_beats) + .addRefFunction ("get_draw_length_as_beats", &PublicEditor::get_draw_length_as_beats) .addFunction ("toggle_ruler_video", &PublicEditor::toggle_ruler_video) .addFunction ("toggle_xjadeo_proc", &PublicEditor::toggle_xjadeo_proc) diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 3f3bd9c626..ade5d20bd9 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -3350,7 +3350,7 @@ MidiRegionView::change_note_lengths (bool fine, bool shorter, Temporal::Beats de delta = Temporal::Beats::ticks (Temporal::ticks_per_beat / 128); } else { /* grab the current grid distance */ - delta = get_grid_beats (_region->position()); + delta = get_draw_length_beats (_region->position()); } } @@ -3912,7 +3912,7 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state) _ghost_note->show(); /* calculate time in of a single grid units worth of beats, at the start of source */ - const Temporal::Beats length = get_grid_beats (_region->source_position() + timepos_t (snapped_beats)); + const Temporal::Beats length = get_draw_length_beats (_region->source_position() + timepos_t (snapped_beats)); _ghost_note->note()->set_time (snapped_beats); _ghost_note->note()->set_length (length); @@ -4307,6 +4307,21 @@ MidiRegionView::get_grid_beats (timepos_t const & pos) const return beats; } + +Temporal::Beats +MidiRegionView::get_draw_length_beats (timepos_t const & pos) const +{ + PublicEditor& editor = trackview.editor(); + bool success = false; + Temporal::Beats beats = editor.get_draw_length_as_beats (success, pos); + + if (!success) { + beats = Temporal::Beats (1, 0); + } + + return beats; +} + uint8_t MidiRegionView::y_to_note (double y) const { diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 42e6544ee5..f464fae878 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -531,6 +531,8 @@ public: /** Get grid type as beats, or default to 1 if not snapped to beats. */ Temporal::Beats get_grid_beats(Temporal::timepos_t const & pos) const; + Temporal::Beats get_draw_length_beats(Temporal::timepos_t const & pos) const; + void remove_ghost_note (); void mouse_mode_changed (); void enter_internal (uint32_t state); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 7961d64e38..aa5b347090 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -368,9 +368,13 @@ public: 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 unsigned get_grid_beat_divisions () = 0; + virtual Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position) = 0; - virtual int32_t get_grid_music_divisions (uint32_t event_state) = 0; + virtual Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position) = 0; + + virtual unsigned get_grid_beat_divisions (Editing::GridType gt) = 0; + virtual int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) = 0; + virtual void edit_notes (MidiRegionView*) = 0; virtual void queue_visual_videotimeline_update () = 0; diff --git a/gtk2_ardour/step_editor.cc b/gtk2_ardour/step_editor.cc index 2f6b28033c..927a46daf6 100644 --- a/gtk2_ardour/step_editor.cc +++ b/gtk2_ardour/step_editor.cc @@ -272,7 +272,7 @@ StepEditor::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Tem beat_duration = StepEntry::instance().note_length(); } else if (beat_duration == 0.0) { bool success; - beat_duration = _editor.get_grid_type_as_beats (success, step_edit_insert_position); + beat_duration = _editor.get_draw_length_as_beats (success, step_edit_insert_position); if (!success) { return -1; @@ -387,7 +387,7 @@ StepEditor::step_edit_rest (Temporal::Beats beats) bool success; if (beats == 0.0) { - beats = _editor.get_grid_type_as_beats (success, step_edit_insert_position); + beats = _editor.get_draw_length_as_beats (success, step_edit_insert_position); } else { success = true; }