private void timeline_MouseUp(object sender, MouseButtonEventArgs e) { selectionDragStart = null; if (selectionIsDragging) { selectionIsDragging = false; dragSelectionRect.Visibility = Visibility.Hidden; if (selectionCompositionMode != CompositionMode.None) { sequencer.ConfirmSelectionDelta(); selectionCompositionMode = CompositionMode.None; } timeline.ReleaseMouseCapture(); } else { // If it was a non-dragging click on empty space, move the cursor. var originalDataContext = ((FrameworkElement)e.OriginalSource).DataContext; if ((e.ChangedButton == MouseButton.Left || e.ChangedButton == MouseButton.Right) && !(originalDataContext is BlockViewModel)) { sequencer.CursorPosition = SnapValue((float)e.GetPosition(timeline).X / sequencer.TimePixelScale); } } }
// ===== Commands ===== public void SelectBlock(BlockViewModel block, CompositionMode compositionMode) { Debug.WriteLine("single select (mode: {0}, block: {1})", compositionMode, block); switch (compositionMode) { case CompositionMode.None: SelectedBlocks.Clear(); if (block != null && !SelectedBlocks.Contains(block)) { SelectedBlocks.Add(block); } break; case CompositionMode.Additive: if (block != null && !SelectedBlocks.Contains(block)) { SelectedBlocks.Add(block); } break; case CompositionMode.Subtractive: if (block != null) { SelectedBlocks.Remove(block); } break; } }
private void timeline_MouseMove(object sender, MouseEventArgs e) { if (selectionDragStart == null) { return; // TODO why? } if (selectionIsDragging) { Point p1 = e.GetPosition(timeline); Point p2 = selectionDragStart.Value; Rect r = new Rect(p1, p2); dragSelectionRect.Visibility = Visibility.Visible; Canvas.SetLeft(dragSelectionRect, r.Left); Canvas.SetTop(dragSelectionRect, r.Top); dragSelectionRect.Width = r.Width; dragSelectionRect.Height = r.Height; MultiSelectBlocks(r); e.Handled = true; } else if (selectionDragStart != null) { Vector delta = e.GetPosition(timeline) - selectionDragStart.Value; if (delta.LengthSquared >= SELECTION_DRAG_INITIAL_THRESHOLD * SELECTION_DRAG_INITIAL_THRESHOLD) { selectionIsDragging = true; selectionCompositionMode = CompositionModeFromKeyboard(); timeline.CaptureMouse(); e.Handled = true; } } }
public void SelectBlocksDelta(IEnumerable <BlockViewModel> collection, CompositionMode compositionMode) { Debug.WriteLine("multiselect (mode: {0}, blocks: {1})", compositionMode, collection.Count()); var sel = SelectedBlocks; switch (compositionMode) { case CompositionMode.None: ISet <BlockViewModel> newBlocks = new HashSet <BlockViewModel>(collection); if (newBlocks.Count == 0) { sel.Clear(); } else { // make sel equal to newBlocks for (int i = sel.Count - 1; i >= 0; i--) { if (!newBlocks.Contains(sel[i])) { sel.RemoveAt(i); } } foreach (BlockViewModel b in newBlocks) { if (!sel.Contains(b)) { sel.Add(b); } } } break; case CompositionMode.Additive: { // delta set contains all blocks that are part of the additive selection // calculate necessary changes var toDeselect = temporaryDeltaSelectedBlocks.Except(collection).ToList(); var toSelect = collection.Except(temporaryDeltaSelectedBlocks).Except(sel).ToList(); foreach (BlockViewModel b in toDeselect) { sel.Remove(b); temporaryDeltaSelectedBlocks.Remove(b); } foreach (BlockViewModel b in toSelect) { sel.Add(b); temporaryDeltaSelectedBlocks.Add(b); } } break; case CompositionMode.Subtractive: { // delta set contains all blocks that are part of the subtractive selection // calculate necessary changes var toDeselect = collection.Except(temporaryDeltaSelectedBlocks).Intersect(sel).ToList(); var toSelect = temporaryDeltaSelectedBlocks.Except(collection).ToList(); foreach (BlockViewModel b in toDeselect) { sel.Remove(b); temporaryDeltaSelectedBlocks.Add(b); } foreach (BlockViewModel b in toSelect) { if (!sel.Contains(b)) { sel.Add(b); } temporaryDeltaSelectedBlocks.Remove(b); } } break; } }
// select multiple blocks, but as an atomic operation (not over time) public void SelectBlocks(IEnumerable <BlockViewModel> collection, CompositionMode compositionMode) { SelectBlocksDelta(collection, compositionMode); ConfirmSelectionDelta(); }