Beispiel #1
0
        /// <summary>
        /// Handles the <see cref="UIElement.PreviewDragEnter"/> routed event for the <see cref="tracksListBox"/>.
        /// </summary>
        /// <remarks>Begins a dragging operation for a <see cref="VideoTimelineSegment"/>.</remarks>
        /// <inheritdoc cref="DragEventHandler"/>
        private void OnTracksListBoxPreviewDragEnter(object sender, DragEventArgs e)
        {
            if (_segmentDragAdorner == null)
            {
                Size?adornerRectangleSize = null;
                if (e.Data.GetDataPresent(typeof(SegmentViewModelWeakReference)) && e.Data.GetDataPresent(typeof(Size)))
                {
                    adornerRectangleSize = (Size)e.Data.GetData(typeof(Size));
                    _isDraggingSegment   = true;
                }
                else if (e.Data.GetDataPresent(typeof(WeakReference <AddTrackSegmentCommandParameters>)))
                {
                    if (!(e.Data.GetData(typeof(WeakReference <AddTrackSegmentCommandParameters>)) is WeakReference <AddTrackSegmentCommandParameters> addTrackSegmentActionDataRef) ||
                        !addTrackSegmentActionDataRef.TryGetTarget(out AddTrackSegmentCommandParameters addTrackSegmentActionData))
                    {
                        throw new InvalidOperationException($"Invalid reference to a {nameof(AddTrackSegmentCommandParameters)} object.");
                    }

                    Debug.Assert(tracksListBox.HasItems);

                    ListBoxItem listBoxItem = tracksListBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;
                    Debug.Assert(listBoxItem != null);

                    VideoTimelineTrack trackElement = listBoxItem.FindVisualChild <VideoTimelineTrack>();
                    Debug.Assert(trackElement != null);

                    double trackPixelsPerFrame = trackElement.PixelsPerFrame;
                    adornerRectangleSize = new Size(trackPixelsPerFrame * addTrackSegmentActionData.FrameDuration, trackElement.ActualHeight);
                    _segmentDragOrigin   = trackElement.TranslatePoint(new Point((addTrackSegmentActionData.FrameDuration / 2) * trackPixelsPerFrame, 0d), tracksListBox);

                    _isDraggingSegment = true;
                }
                else
                {
                    _isDraggingSegment = false;
                }

                if (_isDraggingSegment && adornerRectangleSize.HasValue)
                {
                    _segmentDragAdorner = new TrackSegmentDragAdorner(adornedElement: tracksListBox,
                                                                      segmentElementSize: adornerRectangleSize.Value);
                    _segmentDragAdorner.Attach();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Handles the <see cref="VideoTimelineSegment.HorizontalResizeDragCompletedEvent"/> attached event
        /// for a <see cref="VideoTimelineSegment"/> element.
        /// </summary>
        /// <inheritdoc cref="HorizontalResizeDragCompletedEventHandler"/>
        private void OnTrackSegmentHorizontalResizeDragCompleted(object sender, HorizontalResizeDragCompletedEventArgs e)
        {
            if (_isResizingSegment)
            {
                VideoTimelineSegment segmentElement = e.OriginalSource as VideoTimelineSegment;
                Debug.Assert(segmentElement != null);

                VideoTimelineTrack trackElement = segmentElement.ParentTrackElement;

                SegmentViewModelBase segmentViewModel = segmentElement.DataContext as SegmentViewModelBase;
                Debug.Assert(segmentViewModel != null);

                int frameDiff = (int)Math.Round(_segmentResizeAdorner.HorizontalOffset / trackElement.PixelsPerFrame);
                if (frameDiff != 0)
                {
                    if (e.HorizontalSide == HorizontalSide.Left)
                    {
                        int newStartFrame = segmentViewModel.StartFrame + frameDiff;
                        ViewModel.ChangeTrackSegmentStartFrame(segmentViewModel, newStartFrame);
                    }
                    else // e.HorizontalSide == HorizontalSide.Right
                    {
                        int newEndFrame = segmentViewModel.EndFrame + frameDiff;
                        ViewModel.ChangeTrackSegmentEndFrame(segmentViewModel, newEndFrame);
                    }
                }

                segmentElement.Clip = null;

                _segmentResizeAdorner?.Detach();
                _segmentResizeAdorner = null;

                _isResizingSegment = false;
            }

            e.Handled = true;
        }
Beispiel #3
0
        /// <summary>
        /// Tries to find the <see cref="VideoTimelineTrack"/> element and closest frame number
        /// to the current drag location.
        /// </summary>
        /// <param name="dragEventArgs">(In) The <see cref="DragEventArgs"/> for the drag operation.</param>
        /// <param name="draggedItemStartFrame">(In) The Start Frame of the <see cref="VideoTimelineSegment"/> being dragged.</param>
        /// <param name="timelineTrackElement">(Out) If successful, the <see cref="VideoTimelineTrack"/> element.</param>
        /// <param name="closestFrameNumber">(Out) If successful, the closest frame number.</param>
        /// <returns>A <see cref="bool"/> value indicating success or failure.</returns>
        private bool TryFindTrackElementAndClosestFrameNumber(DragEventArgs dragEventArgs, int draggedItemStartFrame, out VideoTimelineTrack timelineTrackElement, out int closestFrameNumber)
        {
            closestFrameNumber = -1;

            timelineTrackElement = dragEventArgs.OriginalSource as VideoTimelineTrack;
            if (timelineTrackElement == null)
            {
                if (!(tracksListBox.ContainerFromElement((DependencyObject)dragEventArgs.OriginalSource) is ListBoxItem listBoxItem) ||
                    (timelineTrackElement = listBoxItem.FindVisualChild <VideoTimelineTrack>()) == null)
                {
                    return(false);
                }
            }

            Point  mousePositionInListBox = dragEventArgs.GetPosition(tracksListBox);
            Vector dragPositionOffset     = mousePositionInListBox - _segmentDragOrigin.Value;

            double trackPixelsPerFrame      = timelineTrackElement.PixelsPerFrame;
            double segmentPixelLeftPosition = trackPixelsPerFrame * draggedItemStartFrame;

            closestFrameNumber = (int)Math.Round((segmentPixelLeftPosition + dragPositionOffset.X) / trackPixelsPerFrame);

            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Handles the <see cref="VideoTimelineSegment.HorizontalResizeDraggingEvent"/> attached event
        /// for a <see cref="VideoTimelineSegment"/> element.
        /// </summary>
        /// <inheritdoc cref="HorizontalResizeDraggingEventHandler"/>
        private void OnTrackSegmentHorizontalResizeDragging(object sender, HorizontalResizeDragEventArgs e)
        {
            e.Handled = true;

            VideoTimelineSegment segmentElement = e.OriginalSource as VideoTimelineSegment;

            Debug.Assert(segmentElement != null);

            VideoTimelineTrack trackElement = segmentElement.ParentTrackElement;

            SegmentViewModelBase segmentViewModel = segmentElement.DataContext as SegmentViewModelBase;

            Debug.Assert(segmentViewModel != null);

            int frameDiff = (int)Math.Round(e.HorizontalChange / trackElement.PixelsPerFrame);

            if (frameDiff == 0)
            {
                return;
            }

            int    proposedStartFrame = segmentViewModel.StartFrame;
            int    proposedEndFrame   = segmentViewModel.EndFrame;
            double framePixelOffset   = trackElement.PixelsPerFrame * frameDiff;
            bool   isContracting      = false;
            Rect   segmentElementClipRect;

            if (e.HorizontalSide == HorizontalSide.Left)
            {
                proposedStartFrame += frameDiff;
                if (!ViewModel.CanChangeTrackSegmentStartFrame(segmentViewModel, proposedStartFrame))
                {
                    return;
                }

                if (frameDiff > 0)
                {
                    isContracting          = true;
                    segmentElementClipRect = new Rect(framePixelOffset, 0d, segmentElement.ActualWidth - framePixelOffset, segmentElement.ActualHeight);
                }
            }
            else // e.HorizontalSide == HorizontalSide.Right
            {
                proposedEndFrame += frameDiff;
                if (!ViewModel.CanChangeTrackSegmentEndFrame(segmentViewModel, proposedEndFrame))
                {
                    return;
                }

                if (frameDiff < 0)
                {
                    isContracting = true;

                    segmentElementClipRect = new Rect(
                        new Size(segmentElement.ActualWidth + framePixelOffset, segmentElement.ActualHeight)
                        );
                }
            }

            if (isContracting)
            {
                if (segmentElement.Clip is RectangleGeometry rectangleGeometry)
                {
                    rectangleGeometry.Rect = segmentElementClipRect;
                }
                else
                {
                    segmentElement.Clip = new RectangleGeometry(segmentElementClipRect);
                }
            }
            else
            {
                segmentElement.Clip = null;
            }

            if (_segmentResizeAdorner == null)
            {
                UIElement segmentElementContainer = segmentElement.TemplatedParent as UIElement;
                Debug.Assert(segmentElementContainer != null);

                _segmentResizeAdorner = new TrackSegmentResizeAdorner(adornedElement: trackElement, segmentElement,
                                                                      segmentElementLeftCoordinate: Canvas.GetLeft(segmentElementContainer),
                                                                      attachPosition: e.HorizontalSide);
                _segmentResizeAdorner.Attach();

                _isResizingSegment = true;
            }

            _segmentResizeAdorner.HorizontalOffset       = framePixelOffset;
            _segmentResizeAdorner.ToolTipData.StartFrame = proposedStartFrame;
            _segmentResizeAdorner.ToolTipData.EndFrame   = proposedEndFrame;
        }