Пример #1
0
        private static void OnViewLevelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimeLineItemControl ctrl = d as TimeLineItemControl;

            if (ctrl != null)
            {
                ctrl.PlaceOnCanvas();
            }
        }
Пример #2
0
        private static void OnTimeValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimeLineItemControl ctrl = d as TimeLineItemControl;

            if (ctrl != null)
            {
                ctrl.PlaceOnCanvas();
                ctrl.Duration = ctrl.EndTime - ctrl.StartTime;
            }
        }
Пример #3
0
        private TimeLineItemControl CreateTimeLineItemControl(ITimeLineDataItem data)
        {
            Binding startBinding = new Binding("StartTime");
            startBinding.Mode = BindingMode.TwoWay;
            startBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            Binding endBinding = new Binding("EndTime");
            endBinding.Mode = BindingMode.TwoWay;
            endBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            DateTime timelineStart = StartDate;

            Binding expandedBinding = new Binding("TimelineViewExpanded");
            expandedBinding.Mode = BindingMode.TwoWay;
            endBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

            TimeLineItemControl adder = new TimeLineItemControl();
            adder.TimeLineStartTime = timelineStart;
            adder.DataContext = data;
            adder.Content = data;

            adder.SetBinding(TimeLineItemControl.StartTimeProperty, startBinding);
            adder.SetBinding(TimeLineItemControl.EndTimeProperty, endBinding);
            adder.SetBinding(TimeLineItemControl.IsExpandedProperty, expandedBinding);

            if (_template != null)
            {
                adder.ContentTemplate = _template;
            }

            /*adder.PreviewMouseLeftButtonDown += item_PreviewEditButtonDown;
            adder.MouseMove += item_MouseMove;
            adder.PreviewMouseLeftButtonUp += item_PreviewEditButtonUp;*/
            adder.PreviewMouseRightButtonDown += item_PreviewEditButtonDown;
            adder.MouseMove += item_MouseMove;
            adder.PreviewMouseRightButtonUp += item_PreviewEditButtonUp;

            adder.PreviewMouseLeftButtonUp += item_PreviewDragButtonUp;
            adder.PreviewMouseLeftButtonDown += item_PreviewDragButtonDown;
            adder.UnitSize = UnitSize;
            return adder;
        }
Пример #4
0
        private void BringChainIntoView(TimeLineItemControl first, TimeLineItemControl last, int direction)
        {
            Double l1 = 0;
            Double l2 = 0;
            Double w = 0;
            Double w2 = 0;
            Double end = 0;
            first.GetPlacementInfo(ref l1, ref w, ref end);
            last.GetPlacementInfo(ref l2, ref w2, ref end);
            Double chainW = end - l1;
            Double leadBuffer = 4 * UnitSize;
            chainW += leadBuffer;
            if (direction > 0)
            {

                first.BringIntoView(new Rect(new Point(0, 0), new Point(chainW, Height)));
            }
            else
            {
                first.BringIntoView(new Rect(new Point(-leadBuffer, 0), new Point(chainW, Height)));
            }
        }
Пример #5
0
        internal void HandleItemManipulation(TimeLineItemControl ctrl, TimeLineItemChangedEventArgs e)
        {
            Boolean doStretch = false;
            TimeSpan deltaT = e.DeltaTime;
            TimeSpan zeroT = new TimeSpan();
            int direction = deltaT.CompareTo(zeroT);
            if (direction == 0)
                return;//shouldn't happen

            TimeLineItemControl previous = null;
            TimeLineItemControl after = null;
            int afterIndex = -1;
            int previousIndex = -1;
            after = GetTimeLineItemControlStartingAfter(ctrl.StartTime, ref afterIndex);
            previous = GetTimeLineItemControlStartingBefore(ctrl.StartTime, ref previousIndex);
            if (after != null)
                after.ReadyToDraw = false;
            if (ctrl != null)
                ctrl.ReadyToDraw = false;
            Double useDeltaX = e.DeltaX;
            Double cLeft = 0;
            Double cWidth = 0;
            Double cEnd = 0;
            ctrl.GetPlacementInfo(ref cLeft, ref cWidth, ref cEnd);

            switch (e.Action)
            {
                case TimeLineAction.Move:
                    #region move

                    Double chainGap = Double.MaxValue;
                    if (direction > 0)
                    {
                        //find chain connecteds that are after this one
                        //delta each one in that chain that we are pushing
                        List<TimeLineItemControl> afterChain = GetTimeLineForwardChain(ctrl, afterIndex, ref chainGap);

                        if (chainGap < useDeltaX)
                            useDeltaX = chainGap;
                        foreach (var ti in afterChain)
                        {
                            ti.MoveMe(useDeltaX);
                        }

                        //find the size of our chain so we bring it into view
                        var first = afterChain[0];
                        var last = afterChain[afterChain.Count - 1];
                        BringChainIntoView(first, last, direction);

                    }
                    if (direction < 0)
                    {
                        Boolean previousBackToStart = false;
                        List<TimeLineItemControl> previousChain = GetTimeLineBackwardsChain(ctrl, previousIndex, ref previousBackToStart, ref chainGap);
                        if (-chainGap > useDeltaX)
                        {
                            useDeltaX = chainGap;
                        }
                        if (!previousBackToStart)
                        {
                            foreach (var ti in previousChain)
                            {
                                ti.MoveMe(useDeltaX);
                            }
                        }
                        var first = previousChain[0];//previousChain[previousChain.Count - 1];
                        var last = previousChain[previousChain.Count - 1];
                        BringChainIntoView(last, first, direction);
                    }
                    #endregion
                    break;
                case TimeLineAction.StretchStart:
                    switch (e.Mode)
                    {
                        #region stretchstart

                        case TimeLineManipulationMode.Linked:
                            #region linked
                            Double gap = Double.MaxValue;
                            if (previous != null)
                            {
                                Double pLeft = 0;
                                Double pWidth = 0;
                                Double pEnd = 0;
                                previous.GetPlacementInfo(ref pLeft, ref pWidth, ref pEnd);
                                gap = cLeft - pEnd;
                            }
                            if (direction < 0 && Math.Abs(gap) < Math.Abs(useDeltaX) && Math.Abs(gap) > _bumpThreshold)//if we are negative and not linked, but about to bump
                                useDeltaX = -gap;
                            if (Math.Abs(gap) < _bumpThreshold)
                            {//we are linked
                                if (ctrl.CanDelta(0, useDeltaX) && previous.CanDelta(1, useDeltaX))
                                {
                                    ctrl.MoveStartTime(useDeltaX);
                                    previous.MoveEndTime(useDeltaX);
                                }
                            }
                            else if (ctrl.CanDelta(0, useDeltaX))
                            {
                                ctrl.MoveStartTime(useDeltaX);
                            }

                            break;
                            #endregion
                        case TimeLineManipulationMode.Free:
                            #region free
                            gap = Double.MaxValue;
                            doStretch = direction > 0;
                            if (direction < 0)
                            {
                                //disallow us from free stretching into another item

                                if (previous != null)
                                {
                                    Double pLeft = 0;
                                    Double pWidth = 0;
                                    Double pEnd = 0;
                                    previous.GetPlacementInfo(ref pLeft, ref pWidth, ref pEnd);
                                    gap = cLeft - pEnd;

                                }

                                else
                                {
                                    //don't allow us to stretch further than the gap between current and start time
                                    DateTime s = (DateTime)GetValue(StartDateProperty);
                                    gap = cLeft;
                                }
                                doStretch = gap > _bumpThreshold;
                                if (gap < useDeltaX)
                                {
                                    useDeltaX = gap;
                                }
                            }

                            doStretch &= ctrl.CanDelta(0, useDeltaX);

                            if (doStretch)
                            {
                                ctrl.MoveStartTime(useDeltaX);
                            }
                            #endregion
                            break;
                        default:
                            break;
                        #endregion
                    }
                    break;
                case TimeLineAction.StretchEnd:
                    switch (e.Mode)
                    {
                        #region stretchend
                        case TimeLineManipulationMode.Linked:
                            #region linked
                            Double gap = Double.MaxValue;
                            if (after != null)
                            {
                                Double aLeft = 0;
                                Double aWidth = 0;
                                Double aEnd = 0;
                                after.GetPlacementInfo(ref aLeft, ref aWidth, ref aEnd);
                                gap = aLeft - cEnd;
                            }

                            if (direction > 0 && gap > _bumpThreshold && gap < useDeltaX)//if we are positive, not linked but about to bump
                                useDeltaX = -gap;
                            if (gap < _bumpThreshold)
                            {//we are linked
                                if (ctrl.CanDelta(1, useDeltaX) && after.CanDelta(0, useDeltaX))
                                {
                                    ctrl.MoveEndTime(useDeltaX);
                                    after.MoveStartTime(useDeltaX);
                                }
                            }
                            else if (ctrl.CanDelta(0, useDeltaX))
                            {
                                ctrl.MoveEndTime(useDeltaX);
                            }
                            break;
                            #endregion
                        case TimeLineManipulationMode.Free:
                            #region free
                            Double nextGap = Double.MaxValue;
                            doStretch = true;
                            if (direction > 0 && after != null)
                            {
                                //disallow us from free stretching into another item
                                Double nLeft = 0;
                                Double nWidth = 0;
                                Double nEnd = 0;
                                after.GetPlacementInfo(ref nLeft, ref nWidth, ref nEnd);
                                nextGap = nLeft - cEnd;
                                doStretch = nextGap > _bumpThreshold;
                                if (nextGap < useDeltaX)
                                    useDeltaX = nextGap;
                            }

                            doStretch &= ctrl.CanDelta(1, useDeltaX);
                            if (doStretch)
                            {
                                ctrl.MoveEndTime(useDeltaX);
                            }

                            break;
                            #endregion
                        default:
                            break;
                        #endregion
                    }
                    break;
                default:
                    break;
            }
        }
Пример #6
0
        public TimeLineDragAdorner(TimeLineItemControl uiElement, DataTemplate template)
            : base(uiElement)
        {
            _adorningContentPresenter = new ContentPresenter();
            _adorningContentPresenter.Content = uiElement.DataContext;
            _adorningContentPresenter.ContentTemplate = template;
            _adorningContentPresenter.Opacity = 0.5;
            _layer = AdornerLayer.GetAdornerLayer(uiElement);

            _layer.Add(this);
            IsHitTestVisible = false;
        }
Пример #7
0
        void TimeLineControl_Drop(object sender, DragEventArgs e)
        {
            DragAdorner = null;

            TimeLineItemControl dropper = e.Data.GetData(typeof(TimeLineItemControl)) as TimeLineItemControl;
            ITimeLineDataItem dropData = null;
            if (dropper == null)
            {
                //dropData = e.Data.GetData(typeof(ITimeLineDataItem)) as ITimeLineDataItem;
                dropData = e.Data.GetData("GongSolutions.Wpf.DragDrop") as ITimeLineDataItem;
                if (dropData != null)
                {
                    //I haven't figured out why but
                    //sometimes when dropping from an external source
                    //the drop event hits twice.
                    //that results in ugly duplicates ending up in the timeline
                    //and it is a mess.
                    if (Items.Contains(dropData))
                        return;
                    //create a new timeline item control from this data
                    dropper = CreateTimeLineItemControl(dropData);
                    dropper.StartTime = StartDate;
                    dropper.InitializeDefaultLength();
                    Children.Remove(_tmpDraggAdornerControl);
                    _tmpDraggAdornerControl = null;

                }
            }
            var dropX = e.GetPosition(this).X;
            int newIndex = GetDroppedNewIndex(dropX);
            var curData = dropper.DataContext as ITimeLineDataItem;
            var curIndex = Items.IndexOf(curData);
            if ((curIndex == newIndex || curIndex + 1 == newIndex) && dropData == null && dropper.Parent == this)//dropdata null is to make sure we aren't failing on adding a new data item into the timeline
            //dropper.parent==this makes it so that we allow a dropper control from another timeline to be inserted in at the start.
            {
                return;//our drag did nothing meaningful so we do nothing.
            }

            if (dropper != null)
            {
                DateTime start = (DateTime)GetValue(StartDateProperty);
                if (newIndex == 0)
                {
                    if (dropData == null)
                    {
                        RemoveTimeLineItemControl(dropper);
                    }
                    if (dropper.Parent != this && dropper.Parent is TimeLineControl)
                    {
                        var tlCtrl = dropper.Parent as TimeLineControl;
                        tlCtrl.RemoveTimeLineItemControl(dropper);
                    }
                    InsertTimeLineItemControlAt(newIndex, dropper);
                    dropper.MoveToNewStartTime(start);
                    MakeRoom(newIndex, dropper.Width);

                }
                else//we are moving this after something.
                {

                    //find out if we are moving the existing one back or forward.
                    var placeAfter = GetTimeLineItemControlAt(newIndex - 1);
                    if (placeAfter != null)
                    {
                        start = placeAfter.EndTime;
                        RemoveTimeLineItemControl(dropper);
                        if (curIndex < newIndex && curIndex >= 0)//-1 is on an insert in which case we definitely don't want to take off on our new index value
                        {
                            //we are moving forward.
                            newIndex--;//when we removed our item, we shifted our insert index back 1
                        }
                        if (dropper.Parent != null && dropper.Parent != this)
                        {
                            var ptl = dropper.Parent as TimeLineControl;
                            ptl.RemoveTimeLineItemControl(dropper);
                        }

                        InsertTimeLineItemControlAt(newIndex, dropper);
                        dropper.MoveToNewStartTime(start);
                        MakeRoom(newIndex, dropper.Width);
                    }
                }
            }
            //ReDrawChildren();
            DrawBackGround();
            e.Handled = true;
        }
Пример #8
0
        void TimeLineControl_DragOver(object sender, DragEventArgs e)
        {
            //throw new NotImplementedException();
            TimeLineItemControl d = e.Data.GetData(typeof(TimeLineItemControl)) as TimeLineItemControl;
            if (d != null)
            {
                if (Manager != null)
                {
                    if (!Manager.CanAddToTimeLine(d.DataContext as ITimeLineDataItem))
                    {
                        e.Effects = DragDropEffects.None;
                        return;
                    }
                }
                e.Effects = DragDropEffects.Move;
                //this is an internal drag or a drag from another time line control
                if (DragAdorner == null)
                {
                    _dragAdorner = new TimeLineDragAdorner(d, ItemTemplate);

                }
                DragAdorner.MousePosition = e.GetPosition(d);
                DragAdorner.InvalidateVisual();

            }
            else
            {//GongSolutions.Wpf.DragDrop

                var d2 = e.Data.GetData("GongSolutions.Wpf.DragDrop");
                if (d2 != null)
                {
                    if (Manager != null)
                    {
                        if (!Manager.CanAddToTimeLine(d2 as ITimeLineDataItem))
                        {
                            e.Effects = DragDropEffects.None;
                            return;
                        }
                    }

                    e.Effects = DragDropEffects.Move;
                    if (DragAdorner == null)
                    {
                        //we are dragging from an external source and we don't have a timeline item control of any sort
                        Children.Remove(_tmpDraggAdornerControl);
                        //in order to get an adornment layer the control has to be somewhere
                        _tmpDraggAdornerControl = new TimeLineItemControl();
                        _tmpDraggAdornerControl.UnitSize = UnitSize;
                        Children.Add(_tmpDraggAdornerControl);
                        Canvas.SetLeft(_tmpDraggAdornerControl, -1000000);
                        _tmpDraggAdornerControl.DataContext = d2;
                        _tmpDraggAdornerControl.StartTime = StartDate;
                        _tmpDraggAdornerControl.InitializeDefaultLength();
                        _tmpDraggAdornerControl.ContentTemplate = ItemTemplate;

                        _dragAdorner = new TimeLineDragAdorner(_tmpDraggAdornerControl, ItemTemplate);
                    }
                    DragAdorner.MousePosition = e.GetPosition(_tmpDraggAdornerControl);
                    DragAdorner.InvalidateVisual();
                }
            }
            DragScroll(e);
        }
Пример #9
0
 void TimeLineControL_DragLeave(object sender, DragEventArgs e)
 {
     DragAdorner = null;
     Children.Remove(_tmpDraggAdornerControl);
     _tmpDraggAdornerControl = null;
 }
Пример #10
0
        private void RemoveTimeLineItemControl(TimeLineItemControl remover)
        {
            var curData = remover.DataContext as ITimeLineDataItem;
            remover.PreviewMouseRightButtonDown -= item_PreviewEditButtonDown;
            remover.MouseMove -= item_MouseMove;
            remover.PreviewMouseRightButtonUp -= item_PreviewEditButtonUp;

            remover.PreviewMouseLeftButtonUp -= item_PreviewDragButtonUp;
            remover.PreviewMouseLeftButtonDown -= item_PreviewDragButtonDown;
            Items.Remove(curData);
            Children.Remove(remover);
        }
Пример #11
0
 void item_PreviewDragButtonUp(object sender, MouseButtonEventArgs e)
 {
     _dragStartPosition.X = double.MinValue;
     _dragStartPosition.Y = double.MinValue;
     _dragObject = null;
 }
Пример #12
0
 void item_PreviewDragButtonDown(object sender, MouseButtonEventArgs e)
 {
     _dragStartPosition = Mouse.GetPosition(null);
     _dragObject = sender as TimeLineItemControl;
 }
Пример #13
0
        private void InsertTimeLineItemControlAt(int index, TimeLineItemControl adder)
        {
            var Data = adder.DataContext as ITimeLineDataItem;
            if (Items.Contains(Data))
                return;

            adder.PreviewMouseRightButtonDown -= item_PreviewEditButtonDown;
            adder.MouseMove -= item_MouseMove;
            adder.PreviewMouseRightButtonUp -= item_PreviewEditButtonUp;

            adder.PreviewMouseLeftButtonUp -= item_PreviewDragButtonUp;
            adder.PreviewMouseLeftButtonDown -= item_PreviewDragButtonDown;

            adder.PreviewMouseRightButtonDown += item_PreviewEditButtonDown;
            adder.MouseMove += item_MouseMove;
            adder.PreviewMouseRightButtonUp += item_PreviewEditButtonUp;

            adder.PreviewMouseLeftButtonUp += item_PreviewDragButtonUp;
            adder.PreviewMouseLeftButtonDown += item_PreviewDragButtonDown;
            //child 0 is our grid and we want to keep that there.
            Children.Insert(index + 1, adder);
            Items.Insert(index, Data);
        }
Пример #14
0
        /// <summary>
        /// Returns a list of all timeline controls starting with the current one and moving forward
        /// so long as they are contiguous.
        /// </summary>
        /// <param name="current"></param>
        /// <returns></returns>
        private List<TimeLineItemControl> GetTimeLineForwardChain(TimeLineItemControl current, int afterIndex, ref Double chainGap)
        {
            List<TimeLineItemControl> returner = new List<TimeLineItemControl>() { current };
            Double left = 0, width = 0, end = 0;
            current.GetPlacementInfo(ref left, ref width, ref end);
            if (afterIndex < 0)
            {
                //we are on the end of the list so there is no limit.
                chainGap = Double.MaxValue;
                return returner;
            }
            Double bumpThreshold = _bumpThreshold;
            Double lastAddedEnd = end;
            while (afterIndex < Items.Count)
            {
                left = width = end = 0;
                var checker = GetTimeLineItemControlAt(afterIndex++);
                if (checker != null)
                {
                    checker.GetPlacementInfo(ref left, ref width, ref end);
                    Double gap = left - lastAddedEnd;
                    if (gap > bumpThreshold)
                    {
                        chainGap = gap;
                        return returner;
                    }
                    returner.Add(checker);
                    lastAddedEnd = end;
                }

            }
            //we have chained off to the end and thus have no need to worry about our gap
            chainGap = Double.MaxValue;
            return returner;
        }
Пример #15
0
        /// <summary>
        /// Returns a list of all timeline controls starting with the current one and moving backwoards
        /// so long as they are contiguous.  If the chain reaches back to the start time of the timeline then the
        /// ChainsBackToStart boolean is modified to reflect that.
        /// </summary>
        /// <param name="current"></param>
        /// <returns></returns>
        private List<TimeLineItemControl> GetTimeLineBackwardsChain(TimeLineItemControl current, int prevIndex, ref Boolean ChainsBackToStart, ref Double chainGap)
        {
            List<TimeLineItemControl> returner = new List<TimeLineItemControl>() { current };
            Double left = 0, width = 0, end = 0;
            current.GetPlacementInfo(ref left, ref width, ref end);
            if (prevIndex < 0)
            {
                chainGap = Double.MaxValue;
                ChainsBackToStart = left == 0;
                return returner;
            }

            Double lastAddedLeft = left;
            while (prevIndex >= 0)
            {
                left = width = end = 0;

                var checker = GetTimeLineItemControlAt(prevIndex--);
                if (checker != null)
                {
                    checker.GetPlacementInfo(ref left, ref width, ref end);
                    if (lastAddedLeft - end > _bumpThreshold)
                    {
                        //our chain just broke;
                        chainGap = lastAddedLeft - end;
                        ChainsBackToStart = lastAddedLeft == 0;
                        return returner;
                    }
                    returner.Add(checker);
                    lastAddedLeft = left;
                }

            }
            ChainsBackToStart = lastAddedLeft == 0;
            chainGap = lastAddedLeft;//gap between us and zero;
            return returner;
        }
Пример #16
0
 private static void OnEditThresholdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
 {
     TimeLineItemControl ctrl = d as TimeLineItemControl;
 }