#include "pbd/enumwriter.h"
#include "pbd/memento_command.h"
#include "pbd/unknown_type.h"
-#include "pbd/stacktrace.h"
+#include "pbd/unwind.h"
#include <glibmm/miscutils.h>
#include <gtkmm/image.h>
#include "audio_time_axis.h"
#include "automation_time_axis.h"
#include "bundle_manager.h"
+#include "button_joiner.h"
#include "canvas-noevent-text.h"
#include "canvas_impl.h"
#include "crossfade_edit.h"
N_("Timecode Minutes"),
N_("Seconds"),
N_("Minutes"),
+ N_("Beats/128"),
+ N_("Beats/64"),
N_("Beats/32"),
N_("Beats/28"),
N_("Beats/24"),
layering_order_editor = 0;
no_save_visual = false;
resize_idle_id = -1;
+ within_track_canvas = false;
scrubbing_direction = 0;
set_snap_mode (_snap_mode);
set_mouse_mode (MouseObject, true);
pre_internal_mouse_mode = MouseObject;
+ pre_internal_snap_type = _snap_type;
+ pre_internal_snap_mode = _snap_mode;
+ internal_snap_type = _snap_type;
+ internal_snap_mode = _snap_mode;
set_edit_point_preference (EditAtMouse, true);
_playlist_selector = new PlaylistSelector();
instant_save ();
switch (_snap_type) {
+ case SnapToBeatDiv128:
+ case SnapToBeatDiv64:
case SnapToBeatDiv32:
case SnapToBeatDiv28:
case SnapToBeatDiv24:
}
if ((prop = node.property ("zoom-focus"))) {
- set_zoom_focus ((ZoomFocus) atoi (prop->value()));
+ set_zoom_focus ((ZoomFocus) string_2_enum (prop->value(), zoom_focus));
}
if ((prop = node.property ("zoom"))) {
}
if ((prop = node.property ("snap-to"))) {
- set_snap_to ((SnapType) atoi (prop->value()));
+ set_snap_to ((SnapType) string_2_enum (prop->value(), _snap_type));
}
if ((prop = node.property ("snap-mode"))) {
- set_snap_mode ((SnapMode) atoi (prop->value()));
+ set_snap_mode ((SnapMode) string_2_enum (prop->value(), _snap_mode));
+ }
+
+ if ((prop = node.property ("internal-snap-to"))) {
+ internal_snap_type = (SnapType) string_2_enum (prop->value(), internal_snap_type);
+ }
+
+ if ((prop = node.property ("internal-snap-mode"))) {
+ internal_snap_mode = (SnapMode) string_2_enum (prop->value(), internal_snap_mode);
+ }
+
+ if ((prop = node.property ("pre-internal-snap-to"))) {
+ pre_internal_snap_type = (SnapType) string_2_enum (prop->value(), pre_internal_snap_type);
+ }
+
+ if ((prop = node.property ("pre-internal-snap-mode"))) {
+ pre_internal_snap_mode = (SnapMode) string_2_enum (prop->value(), pre_internal_snap_mode);
}
if ((prop = node.property ("mouse-mode"))) {
maybe_add_mixer_strip_width (*node);
- snprintf (buf, sizeof(buf), "%d", (int) zoom_focus);
- node->add_property ("zoom-focus", buf);
+ node->add_property ("zoom-focus", enum_2_string (zoom_focus));
snprintf (buf, sizeof(buf), "%f", frames_per_unit);
node->add_property ("zoom", buf);
- snprintf (buf, sizeof(buf), "%d", (int) _snap_type);
- node->add_property ("snap-to", buf);
- snprintf (buf, sizeof(buf), "%d", (int) _snap_mode);
- node->add_property ("snap-mode", buf);
-
+ node->add_property ("snap-to", enum_2_string (_snap_type));
+ node->add_property ("snap-mode", enum_2_string (_snap_mode));
+ node->add_property ("internal-snap-to", enum_2_string (internal_snap_type));
+ node->add_property ("internal-snap-mode", enum_2_string (internal_snap_mode));
+ node->add_property ("pre-internal-snap-to", enum_2_string (pre_internal_snap_type));
+ node->add_property ("pre-internal-snap-mode", enum_2_string (pre_internal_snap_mode));
node->add_property ("edit-point", enum_2_string (_edit_point));
snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame);
node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
node->add_property ("mouse-mode", enum2str(mouse_mode));
node->add_property ("internal-edit", _internal_editing ? "yes" : "no");
- node->add_property ("join-object-range", join_object_range_button.get_active () ? "yes" : "no");
+ node->add_property ("join-object-range", smart_mode_action->get_active () ? "yes" : "no");
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-editor-mixer"));
if (act) {
start = _session->tempo_map().round_to_beat (start, direction);
break;
+ case SnapToBeatDiv128:
+ start = _session->tempo_map().round_to_beat_subdivision (start, 128, direction);
+ break;
+ case SnapToBeatDiv64:
+ start = _session->tempo_map().round_to_beat_subdivision (start, 64, direction);
+ break;
case SnapToBeatDiv32:
start = _session->tempo_map().round_to_beat_subdivision (start, 32, direction);
break;
mode_box->set_border_width (2);
mode_box->set_spacing(4);
- /* table containing mode buttons */
-
- HBox* mouse_mode_button_box = manage (new HBox ());
- mouse_mode_button_box->set_spacing (2);
-
- if (Profile->get_sae()) {
- mouse_mode_button_box->pack_start (mouse_move_button);
- } else {
- mouse_mode_button_box->pack_start (mouse_move_button);
- mouse_mode_button_box->pack_start (join_object_range_button);
- mouse_mode_button_box->pack_start (mouse_select_button);
- }
-
- mouse_mode_button_box->pack_start (mouse_zoom_button);
-
- if (!Profile->get_sae()) {
- mouse_mode_button_box->pack_start (mouse_gain_button);
- }
-
- mouse_mode_button_box->pack_start (mouse_timefx_button);
- mouse_mode_button_box->pack_start (mouse_audition_button);
- mouse_mode_button_box->pack_start (mouse_draw_button);
- mouse_mode_button_box->pack_start (internal_edit_button);
+ HBox* mouse_mode_box = manage (new HBox);
+ HBox* mouse_mode_hbox1 = manage (new HBox);
+ HBox* mouse_mode_hbox2 = manage (new HBox);
+ VBox* mouse_mode_vbox1 = manage (new VBox);
+ VBox* mouse_mode_vbox2 = manage (new VBox);
+ Alignment* mouse_mode_align1 = manage (new Alignment);
+ Alignment* mouse_mode_align2 = manage (new Alignment);
+
+ Glib::RefPtr<SizeGroup> mouse_mode_size_group = SizeGroup::create (SIZE_GROUP_BOTH);
+ mouse_mode_size_group->add_widget (mouse_move_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);
+
+ /* make them just a bit bigger */
+ mouse_move_button.set_size_request (-1, 25);
+
+ smart_mode_joiner = manage (new ButtonJoiner ("mouse mode button", mouse_move_button, mouse_select_button));
+ smart_mode_joiner->set_related_action (smart_mode_action);
+
+ mouse_move_button.set_elements (ArdourButton::Element (ArdourButton::Body|ArdourButton::Text));
+ mouse_select_button.set_elements (ArdourButton::Element (ArdourButton::Body|ArdourButton::Text));
+
+ mouse_move_button.set_rounded_corner_mask (0x1); // upper left only
+ mouse_select_button.set_rounded_corner_mask (0x2); // upper right only
+
+ mouse_mode_hbox2->set_spacing (2);
+ mouse_mode_box->set_spacing (2);
+
+ mouse_mode_hbox1->pack_start (*smart_mode_joiner, false, false);
+ mouse_mode_hbox2->pack_start (mouse_zoom_button, false, false);
+ mouse_mode_hbox2->pack_start (mouse_gain_button, false, false);
+ mouse_mode_hbox2->pack_start (mouse_timefx_button, false, false);
+ mouse_mode_hbox2->pack_start (mouse_audition_button, false, false);
+ mouse_mode_hbox2->pack_start (mouse_draw_button, false, false);
+ mouse_mode_hbox2->pack_start (internal_edit_button, false, false);
+
+ mouse_mode_vbox1->pack_start (*mouse_mode_hbox1, false, false);
+ mouse_mode_vbox2->pack_start (*mouse_mode_hbox2, false, false);
+
+ mouse_mode_align1->add (*mouse_mode_vbox1);
+ mouse_mode_align1->set (0.5, 1.0, 0.0, 0.0);
+ mouse_mode_align2->add (*mouse_mode_vbox2);
+ mouse_mode_align2->set (0.5, 1.0, 0.0, 0.0);
+
+ mouse_mode_box->pack_start (*mouse_mode_align1, false, false);
+ mouse_mode_box->pack_start (*mouse_mode_align2, false, false);
edit_mode_strings.push_back (edit_mode_to_string (Slide));
if (!Profile->get_sae()) {
edit_mode_selector.signal_changed().connect (sigc::mem_fun(*this, &Editor::edit_mode_selection_done));
mode_box->pack_start (edit_mode_selector, false, false);
- mode_box->pack_start (*mouse_mode_button_box, false, false);
+ mode_box->pack_start (*mouse_mode_box, false, false);
_mouse_mode_tearoff = manage (new TearOff (*mode_box));
_mouse_mode_tearoff->set_name ("MouseModeBase");
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 (join_object_range_button, _("Select/Move Objects or Ranges"));
+ ARDOUR_UI::instance()->set_tip (smart_mode_joiner, _("Smart Mode (Select/Move Objects + Ranges)"));
ARDOUR_UI::instance()->set_tip (internal_edit_button, _("Edit Region Contents (e.g. notes)"));
ARDOUR_UI::instance()->set_tip (*_group_tabs, _("Groups: click to (de)activate\nContext-click for other operations"));
ARDOUR_UI::instance()->set_tip (nudge_forward_button, _("Nudge Region/Selection Forwards"));
ARDOUR_UI::instance()->set_tip (snap_mode_selector, _("Snap/Grid Mode"));
ARDOUR_UI::instance()->set_tip (edit_point_selector, _("Edit point"));
ARDOUR_UI::instance()->set_tip (edit_mode_selector, _("Edit Mode"));
+ ARDOUR_UI::instance()->set_tip (nudge_clock, _("Nudge Clock\n(controls distance used to nudge regions and selections)"));
}
int
snaptype = SnapToBeatDiv28;
} else if (choice == _("Beats/32")) {
snaptype = SnapToBeatDiv32;
+ } else if (choice == _("Beats/64")) {
+ snaptype = SnapToBeatDiv64;
+ } else if (choice == _("Beats/128")) {
+ snaptype = SnapToBeatDiv128;
} else if (choice == _("Beats")) {
snaptype = SnapToBeat;
} else if (choice == _("Bars")) {
return 1.0;
break;
+ case SnapToBeatDiv128:
+ return 1.0/128.0;
+ break;
+ case SnapToBeatDiv64:
+ return 1.0/64.0;
+ break;
case SnapToBeatDiv32:
return 1.0/32.0;
break;
}
}
-Editor::VisualState::VisualState ()
- : gui_state (new GUIObjectState)
+Editor::VisualState::VisualState (bool with_tracks)
+ : gui_state (with_tracks ? new GUIObjectState : 0)
{
}
Editor::VisualState*
Editor::current_visual_state (bool with_tracks)
{
- VisualState* vs = new VisualState;
+ VisualState* vs = new VisualState (with_tracks);
vs->y_position = vertical_adjustment.get_value();
vs->frames_per_unit = frames_per_unit;
vs->leftmost_frame = leftmost_frame;
vs->zoom_focus = zoom_focus;
if (with_tracks) {
- *(vs->gui_state) = *ARDOUR_UI::instance()->gui_object_state;
+ *vs->gui_state = *ARDOUR_UI::instance()->gui_object_state;
}
return vs;
return;
}
- redo_visual_stack.push_back (current_visual_state());
-
VisualState* vs = undo_visual_stack.back();
undo_visual_stack.pop_back();
+
+
+ redo_visual_stack.push_back (current_visual_state (vs ? vs->gui_state != 0 : false));
+
use_visual_state (*vs);
}
return;
}
- undo_visual_stack.push_back (current_visual_state());
-
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));
+
use_visual_state (*vs);
}
void
Editor::use_visual_state (VisualState& vs)
{
- no_save_visual = true;
+ PBD::Unwinder<bool> nsv (no_save_visual, true);
_routes->suspend_redisplay ();
set_zoom_focus (vs.zoom_focus);
reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
- *ARDOUR_UI::instance()->gui_object_state = *vs.gui_state;
-
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
- (*i)->reset_visual_state ();
+ if (vs.gui_state) {
+ *ARDOUR_UI::instance()->gui_object_state = *vs.gui_state;
+
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ (*i)->reset_visual_state ();
+ }
}
_routes->update_visibility ();
_routes->resume_redisplay ();
-
- no_save_visual = false;
}
void