};
#endif
+#define COMBO_TRIANGLE_WIDTH 25 // ArdourButton _diameter (11) + 2 * arrow-padding (2*2) + 2 * text-padding (2*5)
+
static void
pane_size_watcher (Paned* pane)
{
clicked_control_point = 0;
last_update_frame = 0;
pre_press_cursor = 0;
+ last_paste_pos = 0;
+ paste_count = 0;
_drags = new DragManager (this);
lock_dialog = 0;
ruler_dialog = 0;
sfbrowser = 0;
- location_marker_color = ARDOUR_UI::config()->get_canvasvar_LocationMarker();
- location_range_color = ARDOUR_UI::config()->get_canvasvar_LocationRange();
- location_cd_marker_color = ARDOUR_UI::config()->get_canvasvar_LocationCDMarker();
- location_loop_color = ARDOUR_UI::config()->get_canvasvar_LocationLoop();
- location_punch_color = ARDOUR_UI::config()->get_canvasvar_LocationPunch();
+ location_marker_color = ARDOUR_UI::config()->get_LocationMarker();
+ location_range_color = ARDOUR_UI::config()->get_LocationRange();
+ location_cd_marker_color = ARDOUR_UI::config()->get_LocationCDMarker();
+ location_loop_color = ARDOUR_UI::config()->get_LocationLoop();
+ location_punch_color = ARDOUR_UI::config()->get_LocationPunch();
zoom_focus = ZoomFocusLeft;
_edit_point = EditAtMouse;
_internal_editing = false;
current_canvas_cursor = 0;
- _visible_track_count = 16;
+ _visible_track_count = -1;
samples_per_pixel = 2048; /* too early to use reset_zoom () */
initialize_canvas ();
+ CairoWidget::set_focus_handler (sigc::mem_fun (*this, &Editor::reset_focus));
+
_summary = new EditorSummary (this);
selection->TimeChanged.connect (sigc::mem_fun(*this, &Editor::time_selection_changed));
_snapshots = new EditorSnapshots (this);
_locations = new EditorLocations (this);
+ /* these are static location signals */
+
+ Location::start_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
+ Location::end_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
+ Location::changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
+
add_notebook_page (_("Regions"), _regions->widget ());
add_notebook_page (_("Tracks & Busses"), _routes->widget ());
add_notebook_page (_("Snapshots"), _snapshots->widget ());
/* nudge stuff */
nudge_forward_button.set_name ("nudge button");
-// nudge_forward_button.add_elements (ArdourButton::Inset);
nudge_forward_button.set_image(::get_icon("nudge_right"));
nudge_backward_button.set_name ("nudge button");
-// nudge_backward_button.add_elements (ArdourButton::Inset);
nudge_backward_button.set_image(::get_icon("nudge_left"));
fade_context_menu.set_name ("ArdourContextMenu");
delete _route_groups;
delete _track_canvas_viewport;
delete _drags;
+ delete nudge_clock;
}
XMLNode*
Editor::show_window ()
{
if (!is_visible ()) {
+ DisplaySuspender ds;
show_all ();
/* XXX: this is a bit unfortunate; it would probably
_dragging_playhead = true;
}
- if ((fraction < 0.0f) && (*_control_scroll_target < (framepos_t) fabs(step))) {
+ if ((fraction < 0.0f) && (*_control_scroll_target <= (framepos_t) fabs(step))) {
*_control_scroll_target = 0;
} else if ((fraction > 0.0f) && (max_framepos - *_control_scroll_target < step)) {
*_control_scroll_target = max_framepos - (current_page_samples()*2); // allow room for slop in where the PH is on the screen
} else {
- *_control_scroll_target += (framepos_t) floor (step);
+ *_control_scroll_target += (framepos_t) trunc (step);
}
/* move visuals, we'll catch up with it later */
case GDK_KEY_RELEASE:
gettimeofday (&last_event_time, 0);
break;
+
+ case GDK_LEAVE_NOTIFY:
+ switch (ev->crossing.detail) {
+ case GDK_NOTIFY_UNKNOWN:
+ case GDK_NOTIFY_INFERIOR:
+ case GDK_NOTIFY_ANCESTOR:
+ break;
+ case GDK_NOTIFY_VIRTUAL:
+ case GDK_NOTIFY_NONLINEAR:
+ case GDK_NOTIFY_NONLINEAR_VIRTUAL:
+ /* leaving window, so reset focus, thus ending any and
+ all text entry operations.
+ */
+ reset_focus();
+ break;
+ }
+ break;
+
default:
break;
}
+
return false;
}
timersub (&now, &last_event_time, &delta);
- if (delta.tv_sec > ARDOUR_UI::config()->get_lock_gui_after_seconds()) {
+ if (delta.tv_sec > (time_t) ARDOUR_UI::config()->get_lock_gui_after_seconds()) {
lock ();
/* don't call again. Returning false will effectively
disconnect us from the timer callback.
_session->locations()->added.connect (_session_connections, invalidator (*this), boost::bind (&Editor::add_new_location, this, _1), gui_context());
_session->locations()->removed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::location_gone, this, _1), gui_context());
_session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::refresh_location_display, this), gui_context());
- _session->locations()->StateChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::refresh_location_display, this), gui_context());
_session->history().Changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::history_changed, this), gui_context());
playhead_cursor->show ();
bool changed = (_edit_point != ep);
_edit_point = ep;
- string str = edit_point_strings[(int)ep];
-
if (Profile->get_mixbus())
if (ep == EditAtSelectedMarker)
ep = EditAtPlayhead;
-
+
+ string str = edit_point_strings[(int)ep];
if (str != edit_point_selector.get_text ()) {
edit_point_selector.set_text (str);
}
if (_session && (prop = node.property ("playhead"))) {
framepos_t pos;
sscanf (prop->value().c_str(), "%" PRIi64, &pos);
- playhead_cursor->set_position (pos);
+ if (pos >= 0) {
+ playhead_cursor->set_position (pos);
+ } else {
+ warning << _("Playhead position stored with a negative value - ignored (use zero instead)") << endmsg;
+ playhead_cursor->set_position (0);
+ }
} else {
playhead_cursor->set_position (0);
}
* @param event Event to get current key modifier information from, or 0.
*/
void
-Editor::snap_to_with_modifier (framepos_t& start, GdkEvent const * event, int32_t direction, bool for_mark)
+Editor::snap_to_with_modifier (framepos_t& start, GdkEvent const * event, RoundMode direction, bool for_mark)
{
if (!_session || !event) {
return;
}
void
-Editor::snap_to (framepos_t& start, int32_t direction, bool for_mark)
+Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark)
{
if (!_session || _snap_mode == SnapOff) {
return;
}
void
-Editor::timecode_snap_to_internal (framepos_t& start, int32_t direction, bool /*for_mark*/)
+Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool /*for_mark*/)
{
const framepos_t one_timecode_second = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->frames_per_timecode_frame());
framepos_t one_timecode_minute = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->frames_per_timecode_frame() * 60);
switch (_snap_type) {
case SnapToTimecodeFrame:
- if (((direction == 0) && (fmod((double)start, (double)_session->frames_per_timecode_frame()) > (_session->frames_per_timecode_frame() / 2))) || (direction > 0)) {
+ if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
+ fmod((double)start, (double)_session->frames_per_timecode_frame()) == 0) {
+ /* start is already on a whole timecode frame, do nothing */
+ } else if (((direction == 0) && (fmod((double)start, (double)_session->frames_per_timecode_frame()) > (_session->frames_per_timecode_frame() / 2))) || (direction > 0)) {
start = (framepos_t) (ceil ((double) start / _session->frames_per_timecode_frame()) * _session->frames_per_timecode_frame());
} else {
start = (framepos_t) (floor ((double) start / _session->frames_per_timecode_frame()) * _session->frames_per_timecode_frame());
} else {
start -= _session->config.get_timecode_offset ();
}
- if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) {
+ if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
+ (start % one_timecode_second == 0)) {
+ /* start is already on a whole second, do nothing */
+ } else if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) {
start = (framepos_t) ceil ((double) start / one_timecode_second) * one_timecode_second;
} else {
start = (framepos_t) floor ((double) start / one_timecode_second) * one_timecode_second;
} else {
start -= _session->config.get_timecode_offset ();
}
- if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) {
+ if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
+ (start % one_timecode_minute == 0)) {
+ /* start is already on a whole minute, do nothing */
+ } else if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) {
start = (framepos_t) ceil ((double) start / one_timecode_minute) * one_timecode_minute;
} else {
start = (framepos_t) floor ((double) start / one_timecode_minute) * one_timecode_minute;
break;
default:
fatal << "Editor::smpte_snap_to_internal() called with non-timecode snap type!" << endmsg;
- /*NOTREACHED*/
+ abort(); /*NOTREACHED*/
}
}
void
-Editor::snap_to_internal (framepos_t& start, int32_t direction, bool for_mark)
+Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark)
{
const framepos_t one_second = _session->frame_rate();
const framepos_t one_minute = _session->frame_rate() * 60;
return timecode_snap_to_internal (start, direction, for_mark);
case SnapToCDFrame:
- if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
+ if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
+ start % (one_second/75) == 0) {
+ /* start is already on a whole CD frame, do nothing */
+ } else if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
start = (framepos_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
} else {
start = (framepos_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
break;
case SnapToSeconds:
- if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) {
+ if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
+ start % one_second == 0) {
+ /* start is already on a whole second, do nothing */
+ } else if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) {
start = (framepos_t) ceil ((double) start / one_second) * one_second;
} else {
start = (framepos_t) floor ((double) start / one_second) * one_second;
break;
case SnapToMinutes:
- if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) {
+ if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
+ start % one_minute == 0) {
+ /* start is already on a whole minute, do nothing */
+ } else if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) {
start = (framepos_t) ceil ((double) start / one_minute) * one_minute;
} else {
start = (framepos_t) floor ((double) start / one_minute) * one_minute;
VBox* mouse_mode_vbox = manage (new VBox);
Alignment* mouse_mode_align = manage (new Alignment);
- Glib::RefPtr<SizeGroup> mouse_mode_size_group = SizeGroup::create (SIZE_GROUP_BOTH);
- //mouse_mode_size_group->add_widget (smart_mode_button);
+ Glib::RefPtr<SizeGroup> mouse_mode_size_group = SizeGroup::create (SIZE_GROUP_VERTICAL);
+ mouse_mode_size_group->add_widget (smart_mode_button);
mouse_mode_size_group->add_widget (mouse_move_button);
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_zoom_button);
mouse_mode_size_group->add_widget (mouse_gain_button);
mouse_mode_size_group->add_widget (mouse_timefx_button);
mouse_mode_size_group->add_widget (mouse_audition_button);
mouse_mode_size_group->add_widget (mouse_draw_button);
mouse_mode_size_group->add_widget (internal_edit_button);
- if (!ARDOUR::Profile->get_small_screen()) {
- /* make them just a bit bigger */
- mouse_move_button.set_size_request (24, 30);
- } else {
- /* make them just a bit taller */
- mouse_move_button.set_size_request (-1, 30);
- }
+ mouse_mode_size_group->add_widget (zoom_in_button);
+ mouse_mode_size_group->add_widget (zoom_out_button);
+ mouse_mode_size_group->add_widget (zoom_preset_selector);
+ mouse_mode_size_group->add_widget (zoom_out_full_button);
+ mouse_mode_size_group->add_widget (zoom_focus_selector);
+
+ mouse_mode_size_group->add_widget (tav_shrink_button);
+ mouse_mode_size_group->add_widget (tav_expand_button);
+ mouse_mode_size_group->add_widget (visible_tracks_selector);
+
+ mouse_mode_size_group->add_widget (snap_type_selector);
+ mouse_mode_size_group->add_widget (snap_mode_selector);
+
+ mouse_mode_size_group->add_widget (edit_point_selector);
+ mouse_mode_size_group->add_widget (edit_mode_selector);
+
+ mouse_mode_size_group->add_widget (*nudge_clock);
+ mouse_mode_size_group->add_widget (nudge_forward_button);
+ mouse_mode_size_group->add_widget (nudge_backward_button);
+
mouse_mode_hbox->set_spacing (2);
if (!ARDOUR::Profile->get_trx()) {
if (!ARDOUR::Profile->get_mixbus()) {
mouse_mode_hbox->pack_start (mouse_cut_button, false, false);
- mouse_mode_hbox->pack_start (mouse_zoom_button, false, false);
}
if (!ARDOUR::Profile->get_trx()) {
mouse_mode_hbox->pack_start (mouse_timefx_button, false, false);
mouse_mode_hbox->pack_start (mouse_audition_button, false, false);
mouse_mode_hbox->pack_start (mouse_draw_button, false, false);
- mouse_mode_hbox->pack_start (internal_edit_button, false, false, 4);
+ mouse_mode_hbox->pack_start (internal_edit_button, false, false, 0);
}
mouse_mode_vbox->pack_start (*mouse_mode_hbox);
zoom_preset_selector.set_size_request (42, -1);
zoom_in_button.set_name ("zoom button");
-// zoom_in_button.add_elements ( ArdourButton::Inset );
- zoom_in_button.set_tweaks ((ArdourButton::Tweaks) (ArdourButton::ShowClick) );
zoom_in_button.set_image(::get_icon ("zoom_in"));
act = ActionManager::get_action (X_("Editor"), X_("temporal-zoom-in"));
zoom_in_button.set_related_action (act);
zoom_out_button.set_name ("zoom button");
-// zoom_out_button.add_elements ( ArdourButton::Inset );
- zoom_out_button.set_tweaks ((ArdourButton::Tweaks) (ArdourButton::ShowClick) );
zoom_out_button.set_image(::get_icon ("zoom_out"));
act = ActionManager::get_action (X_("Editor"), X_("temporal-zoom-out"));
zoom_out_button.set_related_action (act);
zoom_out_full_button.set_name ("zoom button");
-// zoom_out_full_button.add_elements ( ArdourButton::Inset );
- zoom_out_full_button.set_tweaks ((ArdourButton::Tweaks) (ArdourButton::ShowClick) );
zoom_out_full_button.set_image(::get_icon ("zoom_full"));
act = ActionManager::get_action (X_("Editor"), X_("zoom-to-session"));
zoom_out_full_button.set_related_action (act);
zoom_focus_selector.set_name ("zoom button");
-// zoom_focus_selector.add_elements (ArdourButton::Inset);
if (ARDOUR::Profile->get_mixbus()) {
_zoom_box.pack_start (zoom_preset_selector, false, false);
/* Track zoom buttons */
visible_tracks_selector.set_name ("zoom button");
-// visible_tracks_selector.add_elements ( ArdourButton::Inset );
if (Profile->get_mixbus()) {
visible_tracks_selector.set_image(::get_icon ("tav_exp"));
visible_tracks_selector.set_size_request (42, -1);
}
tav_expand_button.set_name ("zoom button");
-// tav_expand_button.add_elements ( ArdourButton::FlatFace );
- tav_expand_button.set_tweaks ((ArdourButton::Tweaks) (ArdourButton::ShowClick) );
- tav_expand_button.set_size_request (-1, 20);
tav_expand_button.set_image(::get_icon ("tav_exp"));
act = ActionManager::get_action (X_("Editor"), X_("expand-tracks"));
tav_expand_button.set_related_action (act);
tav_shrink_button.set_name ("zoom button");
-// tav_shrink_button.add_elements ( ArdourButton::FlatFace );
- tav_shrink_button.set_tweaks ((ArdourButton::Tweaks) (ArdourButton::ShowClick) );
- tav_shrink_button.set_size_request (-1, 20);
tav_shrink_button.set_image(::get_icon ("tav_shrink"));
act = ActionManager::get_action (X_("Editor"), X_("shrink-tracks"));
tav_shrink_button.set_related_action (act);
nudge_forward_button.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::nudge_forward_release), false);
nudge_backward_button.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::nudge_backward_release), false);
- nudge_forward_button.set_tweaks ((ArdourButton::Tweaks) (ArdourButton::ShowClick) );
- nudge_backward_button.set_tweaks ((ArdourButton::Tweaks) (ArdourButton::ShowClick) );
-
nudge_box->pack_start (nudge_backward_button, false, false);
nudge_box->pack_start (nudge_forward_button, false, false);
nudge_box->pack_start (*nudge_clock, false, false);
edit_point_selector.AddMenuElem (MenuElem ( edit_point_strings[(int)EditAtSelectedMarker], sigc::bind (sigc::mem_fun(*this, &Editor::edit_point_selection_done), (EditPoint) EditAtSelectedMarker)));
edit_point_selector.AddMenuElem (MenuElem ( edit_point_strings[(int)EditAtMouse], sigc::bind (sigc::mem_fun(*this, &Editor::edit_point_selection_done), (EditPoint) EditAtMouse)));
- set_size_request_to_display_given_text (edit_point_selector, edit_point_strings, 30, 2);
+ set_size_request_to_display_given_text (edit_point_selector, edit_point_strings, COMBO_TRIANGLE_WIDTH, 2);
}
void
edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Ripple], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Ripple)));
edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Lock], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Lock)));
- set_size_request_to_display_given_text (edit_mode_selector, edit_mode_strings, 30, 2);
+ set_size_request_to_display_given_text (edit_mode_selector, edit_mode_strings, COMBO_TRIANGLE_WIDTH, 2);
}
void
snap_mode_selector.AddMenuElem (MenuElem ( snap_mode_strings[(int)SnapNormal], sigc::bind (sigc::mem_fun(*this, &Editor::snap_mode_selection_done), (SnapMode) SnapNormal)));
snap_mode_selector.AddMenuElem (MenuElem ( snap_mode_strings[(int)SnapMagnetic], sigc::bind (sigc::mem_fun(*this, &Editor::snap_mode_selection_done), (SnapMode) SnapMagnetic)));
- set_size_request_to_display_given_text (snap_mode_selector, snap_mode_strings, 30, 2);
+ set_size_request_to_display_given_text (snap_mode_selector, snap_mode_strings, COMBO_TRIANGLE_WIDTH, 2);
}
void
snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToRegionSync], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToRegionSync)));
snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToRegionBoundary], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToRegionBoundary)));
- set_size_request_to_display_given_text (snap_type_selector, snap_type_strings, 30, 2);
+ set_size_request_to_display_given_text (snap_type_selector, snap_type_strings, COMBO_TRIANGLE_WIDTH, 2);
}
ARDOUR_UI::instance()->set_tip (mouse_select_button, _("Range Mode (select/move Ranges)"));
ARDOUR_UI::instance()->set_tip (mouse_draw_button, _("Draw/Edit MIDI Notes"));
ARDOUR_UI::instance()->set_tip (mouse_gain_button, _("Draw Region Gain"));
- ARDOUR_UI::instance()->set_tip (mouse_zoom_button, _("Select Zoom Range"));
ARDOUR_UI::instance()->set_tip (mouse_timefx_button, _("Stretch/Shrink Regions and MIDI Notes"));
ARDOUR_UI::instance()->set_tip (mouse_audition_button, _("Listen to Specific Regions"));
ARDOUR_UI::instance()->set_tip (internal_edit_button, _("Note Level Editing"));
zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusMouse], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusMouse)));
zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusEdit], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusEdit)));
- set_size_request_to_display_given_text (zoom_focus_selector, longest (zoom_focus_strings), 30, 2);
+ set_size_request_to_display_given_text (zoom_focus_selector, zoom_focus_strings, COMBO_TRIANGLE_WIDTH, 2);
}
void
void
Editor::override_visible_track_count ()
{
- _visible_track_count = -_visible_track_count;
+ _visible_track_count = -1;
visible_tracks_selector.set_text ( _("*") );
}
return *_playlist_selector;
}
+framecnt_t
+Editor::get_paste_offset (framepos_t pos, unsigned paste_count, framecnt_t duration)
+{
+ if (paste_count == 0) {
+ /* don't bother calculating an offset that will be zero anyway */
+ return 0;
+ }
+
+ /* calculate basic unsnapped multi-paste offset */
+ framecnt_t offset = paste_count * duration;
+
+ /* snap offset so pos + offset is aligned to the grid */
+ framepos_t offset_pos = pos + offset;
+ snap_to(offset_pos, RoundUpMaybe);
+ offset = offset_pos - pos;
+
+ return offset;
+}
+
Evoral::MusicalTime
Editor::get_grid_type_as_beats (bool& success, framepos_t position)
{
switch (_snap_type) {
case SnapToBeat:
- return 1.0;
+ return Evoral::MusicalTime(1.0);
break;
case SnapToBeatDiv128:
- return 1.0/128.0;
+ return Evoral::MusicalTime(1.0/128.0);
break;
case SnapToBeatDiv64:
- return 1.0/64.0;
+ return Evoral::MusicalTime(1.0/64.0);
break;
case SnapToBeatDiv32:
- return 1.0/32.0;
+ return Evoral::MusicalTime(1.0/32.0);
break;
case SnapToBeatDiv28:
- return 1.0/28.0;
+ return Evoral::MusicalTime(1.0/28.0);
break;
case SnapToBeatDiv24:
- return 1.0/24.0;
+ return Evoral::MusicalTime(1.0/24.0);
break;
case SnapToBeatDiv20:
- return 1.0/20.0;
+ return Evoral::MusicalTime(1.0/20.0);
break;
case SnapToBeatDiv16:
- return 1.0/16.0;
+ return Evoral::MusicalTime(1.0/16.0);
break;
case SnapToBeatDiv14:
- return 1.0/14.0;
+ return Evoral::MusicalTime(1.0/14.0);
break;
case SnapToBeatDiv12:
- return 1.0/12.0;
+ return Evoral::MusicalTime(1.0/12.0);
break;
case SnapToBeatDiv10:
- return 1.0/10.0;
+ return Evoral::MusicalTime(1.0/10.0);
break;
case SnapToBeatDiv8:
- return 1.0/8.0;
+ return Evoral::MusicalTime(1.0/8.0);
break;
case SnapToBeatDiv7:
- return 1.0/7.0;
+ return Evoral::MusicalTime(1.0/7.0);
break;
case SnapToBeatDiv6:
- return 1.0/6.0;
+ return Evoral::MusicalTime(1.0/6.0);
break;
case SnapToBeatDiv5:
- return 1.0/5.0;
+ return Evoral::MusicalTime(1.0/5.0);
break;
case SnapToBeatDiv4:
- return 1.0/4.0;
+ return Evoral::MusicalTime(1.0/4.0);
break;
case SnapToBeatDiv3:
- return 1.0/3.0;
+ return Evoral::MusicalTime(1.0/3.0);
break;
case SnapToBeatDiv2:
- return 1.0/2.0;
+ return Evoral::MusicalTime(1.0/2.0);
break;
case SnapToBar:
if (_session) {
- return _session->tempo_map().meter_at (position).divisions_per_bar();
+ return Evoral::MusicalTime(_session->tempo_map().meter_at (position).divisions_per_bar());
}
break;
break;
}
- return 0.0;
+ return Evoral::MusicalTime();
}
framecnt_t
}
}
+void
+Editor::reattach_all_tearoffs ()
+{
+ if (_mouse_mode_tearoff) _mouse_mode_tearoff->put_it_back ();
+ if (_tools_tearoff) _tools_tearoff->put_it_back ();
+ if (_zoom_tearoff) _zoom_tearoff->put_it_back ();
+}
+
void
Editor::maximise_editing_space ()
{
redo_visual_stack.push_back (current_visual_state (vs ? vs->gui_state != 0 : false));
- use_visual_state (*vs);
+ if (vs) {
+ use_visual_state (*vs);
+ }
}
void
VisualState* vs = redo_visual_stack.back();
redo_visual_stack.pop_back();
- undo_visual_stack.push_back (current_visual_state (vs ? vs->gui_state != 0 : false));
+ // can 'vs' really be 0? Is there a place that puts NULL pointers onto the stack?
+ // why do we check here?
+ undo_visual_stack.push_back (current_visual_state (vs ? (vs->gui_state != 0) : false));
- use_visual_state (*vs);
+ if (vs) {
+ use_visual_state (*vs);
+ }
}
void
Editor::ensure_visual_change_idle_handler ()
{
if (pending_visual_change.idle_handler_id < 0) {
- pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this);
+ // see comment in add_to_idle_resize above.
+ pending_visual_change.idle_handler_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, _idle_visual_changer, this, NULL);
pending_visual_change.being_handled = false;
}
}
Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
{
if (resize_idle_id < 0) {
- resize_idle_id = g_idle_add (_idle_resize, this);
+ /* https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#G-PRIORITY-HIGH-IDLE:CAPS
+ * GTK+ uses G_PRIORITY_HIGH_IDLE + 10 for resizing operations, and G_PRIORITY_HIGH_IDLE + 20 for redrawing operations.
+ * (This is done to ensure that any pending resizes are processed before any pending redraws, so that widgets are not redrawn twice unnecessarily.)
+ */
+ resize_idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, _idle_resize, this, NULL);
_pending_resize_amount = 0;
}