private void trackCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
 {
     _movePartElement = false;
     _resizePartElement = false;
     _hitPartElement = null;
     DocManager.Inst.EndUndoGroup();
     // End selection
     selectionStart = null;
     if (selectionBox != null)
     {
         Canvas.SetZIndex(selectionBox, -100);
         selectionBox.Visibility = System.Windows.Visibility.Hidden;
     }
     trackVM.DoneTempSelect();
     trackVM.UpdateViewSize();
     ((UIElement)sender).ReleaseMouseCapture();
     Mouse.OverrideCursor = null;
 }
        private void trackCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Point mousePos = e.GetPosition((UIElement)sender);

            var hit = VisualTreeHelper.HitTest(trackCanvas, mousePos).VisualHit;
            System.Diagnostics.Debug.WriteLine("Mouse hit " + hit.ToString());

            if (Keyboard.Modifiers == ModifierKeys.Control || Keyboard.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift))
            {
                selectionStart = new Point(trackVM.CanvasToQuarter(mousePos.X), trackVM.CanvasToTrack(mousePos.Y));

                if (Keyboard.IsKeyUp(Key.LeftShift) && Keyboard.IsKeyUp(Key.RightShift)) trackVM.DeselectAll();
                
                if (selectionBox == null)
                {
                    selectionBox = new Rectangle()
                    {
                        Stroke = Brushes.Black,
                        StrokeThickness = 2,
                        Fill = ThemeManager.BarNumberBrush,
                        Width = 0,
                        Height = 0,
                        Opacity = 0.5,
                        RadiusX = 8,
                        RadiusY = 8,
                        IsHitTestVisible = false
                    };
                    trackCanvas.Children.Add(selectionBox);
                    Canvas.SetZIndex(selectionBox, 1000);
                    selectionBox.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    selectionBox.Width = 0;
                    selectionBox.Height = 0;
                    Canvas.SetZIndex(selectionBox, 1000);
                    selectionBox.Visibility = System.Windows.Visibility.Visible;
                }
                Mouse.OverrideCursor = Cursors.Cross;
            }
            else if (hit is DrawingVisual)
            {
                PartElement partEl = ((DrawingVisual)hit).Parent as PartElement;
                _hitPartElement = partEl;

                if (!trackVM.SelectedParts.Contains(_hitPartElement.Part)) trackVM.DeselectAll();

                if (e.ClickCount == 2)
                {
                    if (partEl is VoicePartElement) // load part into midi window
                    {
                        if (midiWindow == null) midiWindow = new MidiWindow();
                        DocManager.Inst.ExecuteCmd(new LoadPartNotification(partEl.Part, trackVM.Project));
                        midiWindow.Show();
                        midiWindow.Focus();
                    }
                }
                else if (mousePos.X > partEl.X + partEl.VisualWidth - UIConstants.ResizeMargin && partEl is VoicePartElement) // resize
                {
                    _resizePartElement = true;
                    _resizeMinDurTick = trackVM.GetPartMinDurTick(_hitPartElement.Part);
                    Mouse.OverrideCursor = Cursors.SizeWE;
                    if (trackVM.SelectedParts.Count > 0)
                    {
                        _partResizeShortest = _hitPartElement.Part;
                        foreach (UPart part in trackVM.SelectedParts)
                        {
                            if (part.DurTick - part.GetMinDurTick(trackVM.Project) <
                                _partResizeShortest.DurTick - _partResizeShortest.GetMinDurTick(trackVM.Project))
                                _partResizeShortest = part;
                        }
                        _resizeMinDurTick = _partResizeShortest.GetMinDurTick(trackVM.Project);
                    }
                    DocManager.Inst.StartUndoGroup();
                }
                else // move
                {
                    _movePartElement = true;
                    _partMoveRelativeTick = trackVM.CanvasToSnappedTick(mousePos.X) - _hitPartElement.Part.PosTick;
                    _partMoveStartTick = partEl.Part.PosTick;
                    Mouse.OverrideCursor = Cursors.SizeAll;
                    if (trackVM.SelectedParts.Count > 0)
                    {
                        _partMovePartLeft = _partMovePartMin = _partMovePartMax = _hitPartElement.Part;
                        foreach (UPart part in trackVM.SelectedParts)
                        {
                            if (part.PosTick < _partMovePartLeft.PosTick) _partMovePartLeft = part;
                            if (part.TrackNo < _partMovePartMin.TrackNo) _partMovePartMin = part;
                            if (part.TrackNo > _partMovePartMax.TrackNo) _partMovePartMax = part;
                        }
                    }
                    DocManager.Inst.StartUndoGroup();
                }
            }
            else
            {
                if (trackVM.CanvasToTrack(mousePos.Y) > trackVM.Project.Tracks.Count - 1) return;
                UVoicePart part = new UVoicePart()
                {
                    PosTick = trackVM.CanvasToSnappedTick(mousePos.X),
                    TrackNo = trackVM.CanvasToTrack(mousePos.Y),
                    DurTick = trackVM.Project.Resolution * 4 / trackVM.Project.BeatUnit * trackVM.Project.BeatPerBar
                };
                DocManager.Inst.StartUndoGroup();
                DocManager.Inst.ExecuteCmd(new AddPartCommand(trackVM.Project, part));
                DocManager.Inst.EndUndoGroup();
                // Enable drag
                trackVM.DeselectAll();
                _movePartElement = true;
                _hitPartElement = trackVM.GetPartElement(part);
                _partMoveRelativeTick = 0;
                _partMoveStartTick = part.PosTick;
            }
            ((UIElement)sender).CaptureMouse();
        }