void
Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
{
- // if dragging with button2, the motion is x constrained, with Alt-button2 it is y constrained
/* we set up x/y dragging constraints on first move */
_x_constrained = false;
/* just changed */
if (fabs (current_pointer_y() - _grab_y) > fabs (current_pointer_x() - _grab_x)) {
- if ((event->motion.state & Gdk::BUTTON2_MASK) && Config->get_edit_mode() != Lock) {
- _x_constrained = true;
- _y_constrained = false;
- }
_initially_vertical = true;
} else {
- if ((event->motion.state & Gdk::BUTTON2_MASK) && Config->get_edit_mode() != Lock) {
- _x_constrained = false;
- _y_constrained = true;
- }
_initially_vertical = false;
}
-
- if (Config->get_edit_mode() == Lock) {
+ if (Config->get_edit_mode() != Lock) {
+ if (event->motion.state & Gdk::BUTTON2_MASK) {
+ // if dragging with button2, the motion is x constrained, with constraint modifier it is y constrained
+ if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::constraint_modifier ())) {
+ _x_constrained = false;
+ _y_constrained = true;
+ } else {
+ _x_constrained = true;
+ _y_constrained = false;
+ }
+ } else if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::constraint_modifier ())) {
+ // if dragging normally, the motion is constrained to the first direction of movement.
+ if (_initially_vertical) {
+ _x_constrained = true;
+ _y_constrained = false;
+ } else {
+ _x_constrained = false;
+ _y_constrained = true;
+ }
+ }
+ } else {
if (event->button.state & Gdk::BUTTON2_MASK) {
_x_constrained = false;
} else {
me->ui.setup_tooltips ();
}
+guint ArdourKeyboard::constraint_mod = Keyboard::SecondaryModifier;
guint ArdourKeyboard::trim_contents_mod = Keyboard::PrimaryModifier;
guint ArdourKeyboard::trim_overlap_mod = Keyboard::TertiaryModifier;
guint ArdourKeyboard::trim_anchored_mod = Keyboard::TertiaryModifier;
XMLNode* node = &Keyboard::get_state ();
char buf[32];
+ snprintf (buf, sizeof (buf), "%d", constraint_mod);
+ node->add_property ("constraint-modifier", buf);
snprintf (buf, sizeof (buf), "%d", trim_contents_mod);
node->add_property ("trim-contents-modifier", buf);
snprintf (buf, sizeof (buf), "%d", trim_overlap_mod);
{
const XMLProperty* prop;
+ if ((prop = node.property ("constraint-modifier")) != 0) {
+ sscanf (prop->value().c_str(), "%d", &constraint_mod);
+ }
+
if ((prop = node.property ("trim-contents-modifier")) != 0) {
sscanf (prop->value().c_str(), "%d", &trim_contents_mod);
}
return (contains_d && ((contains_s && !equals_s) || !contains_s));
}
+void
+ArdourKeyboard::set_constraint_modifier (guint mod)
+{
+ RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~constraint_mod);
+ constraint_mod = mod;
+ RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | constraint_mod);
+}
+
void
ArdourKeyboard::set_trim_contents_modifier (guint mod)
{
static bool indicates_snap (guint state);
static bool indicates_snap_delta (guint state);
+ static void set_constraint_modifier (guint);
+ /** @return Modifier mask to constrain drags in a particular direction;
+ */
+ static ModifierMask constraint_modifier () { return ModifierMask (constraint_mod); }
+
static void set_trim_contents_modifier (guint);
/** @return Modifier mask to move contents rather than region bounds during trim;
*/
*/
static ModifierMask note_size_relative_modifier () { return ModifierMask (note_size_relative_mod); }
private:
+ static guint constraint_mod;
static guint trim_contents_mod;
static guint trim_overlap_mod;
static guint trim_anchored_mod;
}
if (!cursor_set) {
- /* snap delta is in pixels (sigh) */
- framepos_t delta_samps = trackview.editor().pixel_to_sample (snap_delta);
- double delta_beats;
+ /* Convert snap delta from pixels to beats. */
+ framepos_t snap_delta_samps = trackview.editor().pixel_to_sample (snap_delta);
+ double snap_delta_beats;
int sign = 1;
+
/* negative beat offsets aren't allowed */
- if (delta_samps > 0) {
- delta_beats = region_frames_to_region_beats_double (delta_samps);
- } else if (delta_samps < 0) {
- delta_beats = region_frames_to_region_beats_double ( - delta_samps);
+ if (snap_delta_samps > 0) {
+ snap_delta_beats = region_frames_to_region_beats_double (snap_delta_samps);
+ } else if (snap_delta_samps < 0) {
+ snap_delta_beats = region_frames_to_region_beats_double ( - snap_delta_samps);
sign = -1;
}
if (at_front) {
if (beats < canvas_note->note()->end_time()) {
- len = canvas_note->note()->time() - beats + (sign * delta_beats);
+ len = canvas_note->note()->time() - beats + (sign * snap_delta_beats);
len += canvas_note->note()->length();
}
} else {
if (beats >= canvas_note->note()->time()) {
- len = beats - canvas_note->note()->time() - (sign * delta_beats);
+ len = beats - canvas_note->note()->time() - (sign * snap_delta_beats);
}
}
if (current_x > trackview.editor().sample_to_pixel(_region->length())) {
current_x = trackview.editor().sample_to_pixel(_region->length());
}
+
+ /* Convert snap delta from pixels to beats with sign. */
framepos_t snap_delta_samps = trackview.editor().pixel_to_sample (snap_delta);
double snap_delta_beats;
int sign = 1;
+
if (snap_delta_samps > 0) {
snap_delta_beats = region_frames_to_region_beats_double (snap_delta_samps);
} else if (snap_delta_samps < 0) {
sign = -1;
}
- /* Convert that to a frame within the source */
+ /* Convert the new x position to a frame within the source */
const framepos_t current_fr = snap_pixel_to_sample (current_x, with_snap) + _region->start ();
/* and then to beats */
t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
+ ++row;
+ col = 1;
+
+ /* constraint modifier */
+ set_popdown_strings (_constraint_modifier_combo, dumb);
+ _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
+
+ for (int x = 0; modifiers[x].name; ++x) {
+ if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
+ _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
+ break;
+ }
+ }
+
+ l = manage (left_aligned_label (_("Constrain drag using:")));
+ l->set_name ("OptionsLabel");
+
+ t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
+ t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
+
++row;
l = manage (left_aligned_label (_("When Beginning a Trim:")));
}
}
+ void constraint_modifier_chosen ()
+ {
+ string const txt = _constraint_modifier_combo.get_active_text();
+
+ for (int i = 0; modifiers[i].name; ++i) {
+ if (txt == _(modifiers[i].name)) {
+ ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
+ break;
+ }
+ }
+ }
+
void trim_contents_modifier_chosen ()
{
string const txt = _trim_contents_combo.get_active_text();
ComboBoxText _insert_note_modifier_combo;
ComboBoxText _snap_modifier_combo;
ComboBoxText _snap_delta_combo;
+ ComboBoxText _constraint_modifier_combo;
ComboBoxText _trim_contents_combo;
ComboBoxText _trim_overlap_combo;
ComboBoxText _trim_anchored_combo;