Exemplo n.º 1
0
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            var renderRequest = new RenderRequest
            {
                IsHitTest   = true,
                CursorPoint = e.Location
            };

            Render(renderRequest);

            switch (e.Button)
            {
            case MouseButtons.XButton1:
            case MouseButtons.XButton2:

                // TODO: Redo this so that the paragraph selected in the text is the selected one
                // TODO: Mouse4 changes start, mouse5 changes end
                // TODO: The note should not have to be visible; remake the NoteMoved so the note is not required


                // Middle mouse button should resize the note according to the most closely clicked location, in relevance to the location that the user is in the text
                var    clickedByteIndex = ClientXToByteIndex(e.X);
                var    clickedInterval  = new Interval(clickedByteIndex, clickedByteIndex);
                long[] closestDistances = null;
                var    closestDistance  = long.MaxValue;
                Note   closestNote      = null;
                foreach (var note in renderRequest.Notes)
                {
                    if (note.IsFocused)
                    {
                        closestNote      = note;
                        closestDistances = note.Interval.GetDistanceFromOverlap(clickedByteIndex);
                        break;
                    }
                }

                if (closestNote == null)
                {
                    foreach (var note in renderRequest.Notes)
                    {
                        var distance = note.Interval.GetDistanceFromOverlap(clickedByteIndex);
                        if (note.IsFocused || note.Interval.IsOverlapping(clickedInterval))
                        {
                            closestNote      = note;
                            closestDistances = distance;
                            break;
                        }

                        var actualDistance = Math.Min(Math.Abs(distance[0]), Math.Abs(distance[1]));
                        if (actualDistance < closestDistance)
                        {
                            closestNote      = note;
                            closestDistances = distance;
                            closestDistance  = actualDistance;
                        }
                    }
                }

                if (closestNote != null)
                {
                    var isStart = Math.Abs(closestDistances[0]) < Math.Abs(closestDistances[1]);

                    if (NoteMoved != null)
                    {
                        var args = new NoteMovedEventArgs
                        {
                            Area      = isStart ? HitTestArea.NoteLeft : HitTestArea.NoteRight,
                            ByteIndex = clickedByteIndex,
                            Note      = closestNote
                        };

                        NoteMoved(this, args);
                    }
                }

                break;

            case MouseButtons.Middle:
                break;

                #region old zoom code

                /*
                 * if (this._mouseDraggingZoom)
                 * {
                 * // Let's set the time zoom!
                 * var low = Math.Max(0, Math.Min(this._mouseDragStartX, this._mouseDragEndX));
                 * var high = Math.Min(this.ClientRectangle.Width, Math.Max(this._mouseDragStartX, this._mouseDragEndX));
                 *
                 * // Set as approximative as we can.
                 * var timeStart = this.ClientXToByteIndex(low);
                 * var timeEnd = this.ClientXToByteIndex(high);
                 *
                 * this._zoomStack.Push((timeEnd - timeStart) / (double)this._bytesTotal);
                 *
                 * // Restart the processing, since we've now zoomed in.
                 * this.ClearWork();
                 * this.QueueWork(new Work(this.GetCurrentViewPortStart(), this.GetCurrentViewPortEnd()));
                 * }
                 * else
                 * {
                 * // The user clicked Middle Mouse, but had not selected anything. Let's zoom out.
                 * // Zoom out to the previous zoom level.
                 * if (this._zoomStack.Count > 0)
                 * {
                 *  this._zoomStack.Pop();
                 *  this.ClearWork();
                 *  this.QueueWork(new Work(this.GetCurrentViewPortStart(), this.GetCurrentViewPortEnd()));
                 * }
                 * }
                 */

                #endregion

            case MouseButtons.Left:
                if (_mouseDraggingPan == false)
                {
                    var note = renderRequest.FocusedObject as Note;
                    if (note != null)
                    {
                        if (NoteClicked != null)
                        {
                            NoteClicked(this, new NoteClickedEventArgs
                            {
                                Note = note,
                                Area = renderRequest.HitTestArea
                            });
                        }
                    }
                }

                break;
            }

            if (_mouseDraggingPan)
            {
                if (_mouseDraggingObject == null && IsCaretInsideViewPort)
                {
                    var distanceIntoViewPort = GetCurrentBytePosition() - GetCurrentViewPortStart();
                    _caretOffset = distanceIntoViewPort / (double)GetCurrentViewPortDistance();
                }
                else
                {
                    // Since we stopped panning outside of the currently playing viewport, we'll set the caret offset to NaN.
                    // This means that the viewport will stay where it is, while the track is playing.
                    switch (Bass.ChannelIsActive(_playChannel))
                    {
                    case PlaybackState.Playing:
                        _caretOffset = double.NaN;
                        break;
                    }
                }

                // Let's get the new area that should be rendered, and queue the work.
                // We'll add the whole visible viewport, and it will automatically be split and merged properly.
                var work = new Work(GetCurrentViewPortStart(), GetCurrentViewPortEnd());
                QueueWork(work);
            }

            Cursor               = Cursors.Default;
            _mouseDraggingZoom   = false;
            _mouseDraggingPan    = false;
            _mouseDown           = false;
            _mouseDraggingObject = null;
            _mouseDraggingArea   = HitTestArea.None;

            Invalidate();
        }
Exemplo n.º 2
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            var renderRequest = new RenderRequest
            {
                IsHitTest   = true,
                CursorPoint = e.Location
            };

            Render(renderRequest);

            if (_mouseDown)
            {
                _mouseDragEndX = e.Location.X;
                var distance = Math.Max(_mouseDragStartX, _mouseDragEndX) - Math.Min(_mouseDragStartX, _mouseDragEndX);

                // If we've dragged more than a few pixels, so we'll count it as a drag/zoom action
                var isDragging = distance > 3;
                switch (e.Button)
                {
                case MouseButtons.Middle:
                    _mouseDraggingZoom = isDragging;
                    break;

                case MouseButtons.Left:
                    var previous = _mouseDraggingPan;
                    _mouseDraggingPan = isDragging;
                    if (previous != _mouseDraggingPan && _mouseDraggingObject == null)
                    {
                        Cursor = _mouseDraggingPan ? Cursors.Hand : Cursors.Default;
                    }
                    break;
                }
            }

            if (_mouseDraggingPan)
            {
                var startByteIndex   = ClientXToByteIndex(_mouseDragStartX);
                var currentByteIndex = ClientXToByteIndex(e.Location.X);
                var byteDistance     = startByteIndex - currentByteIndex;

                if (_mouseDraggingObject is Note)
                {
                    var note = (Note)_mouseDraggingObject;

                    var capStart = 0L;
                    var capEnd   = _bytesTotal;
                    if (renderRequest.Notes != null)
                    {
                        var foundIndex = -1;
                        for (var i = 0; i < renderRequest.Notes.Count; i++)
                        {
                            var otherNote = renderRequest.Notes[i];
                            if (otherNote.Equals(note) == false)
                            {
                                continue;
                            }

                            switch (_mouseDraggingArea)
                            {
                            case HitTestArea.NoteLeft:
                                capEnd = otherNote.Interval.End -
                                         (long)Math.Round(GetBytesPerPixel() * GetZoomRatio() * 2);
                                break;

                            case HitTestArea.NoteRight:
                                capStart = otherNote.Interval.Start +
                                           (long)Math.Round(GetBytesPerPixel() * GetZoomRatio() * 2);
                                break;
                            }

                            foundIndex = i;
                            break;
                        }

                        if (foundIndex != -1)
                        {
                            long previousEnd;
                            long nextStart;
                            if (renderRequest.HitTestArea == HitTestArea.NoteCenter)
                            {
                                previousEnd = foundIndex > 0
                                    ? renderRequest.Notes[foundIndex - 1].Interval.End
                                    : capStart;
                                nextStart = foundIndex < renderRequest.Notes.Count - 1
                                    ? renderRequest.Notes[foundIndex + 1].Interval.Start -
                                            renderRequest.Notes[foundIndex + 1].Interval.Length
                                    : capEnd;
                            }
                            else
                            {
                                previousEnd = foundIndex > 0
                                    ? renderRequest.Notes[foundIndex - 1].Interval.End
                                    : capStart;
                                nextStart = foundIndex < renderRequest.Notes.Count - 1
                                    ? renderRequest.Notes[foundIndex + 1].Interval.Start
                                    : capEnd;
                            }

                            capStart = Math.Max(capStart, previousEnd);
                            capEnd   = Math.Min(capEnd, nextStart);
                        }
                    }

                    var args = new NoteMovedEventArgs
                    {
                        Note      = note,
                        Area      = _mouseDraggingArea,
                        ByteIndex = Math.Max(capStart, Math.Min(capEnd, _mouseDragByteIndexStart - byteDistance))
                    };

                    NoteMoved(this, args);
                }
                else
                {
                    _viewPortStart = Math.Max(0, _mouseDragByteIndexStart + byteDistance);
                }
            }
            else
            {
                if (_mouseDown == false)
                {
                    Cursor = renderRequest.CursorResult ?? Cursors.Default;
                }
            }

            Invalidate();
        }