예제 #1
0
        /// <summary>
        /// Updates site controls UI position in parent Grid panel based on the
        /// location of data bound widget data object within its parent widget container.
        /// </summary>
        /// <remarks>
        /// Widget data model consists of widget data objects which represent individual widgets
        /// and widget container objects which represent a 2D matrix of widgets. On the UI side
        /// widget containers are bound to source properties of WidgetMatrix controls which in
        /// turn create children WidgetSiteControl controls whose source is then bound to
        /// corresponding widget data objects.
        ///
        /// If parent widget container is resized, locations of widgets in the UI may need to
        /// be updated. The purpose of this method is to perform such an update to ensure the UI
        /// remains consistent with its underlying data model.
        /// </remarks>
        public void UpdateGridPosition()
        {
            MatrixLoc gridPosition = ParentContainer.Source.Bounds.ToIndex(_location);

            SetValue(Grid.RowProperty, gridPosition.Row);
            SetValue(Grid.ColumnProperty, gridPosition.Column);
        }
예제 #2
0
 /// <summary>
 /// Initializing constructor
 /// </summary>
 /// <param name="action">Specifies if a widget was added, removed or replaced</param>
 /// <param name="location">Location of the changed widget</param>
 /// <param name="oldWidget">Reference to the original widget, or null if there wasn't any</param>
 /// <param name="newWidget">Reference to the new widget, or null if there isn't any</param>
 public WidgetContainerChangedEventArgs( NotifyCollectionChangedAction   action,
                                         MatrixLoc                       location,
                                         WidgetData                      oldWidget,
                                         WidgetData                      newWidget )
 {
     _location = location;
     _action = action;
     _oldWidget = oldWidget;
     _newWidget = newWidget;
 }
예제 #3
0
        private void UpdateMatrixUI(MatrixLoc insertLoc, WidgetSiteDragDropData data)
        {
            List <SiteShiftInfo> relocatedSites;

            relocatedSites = CalculateWhichSitesToShift(insertLoc, data);

            var sitesToMove    = relocatedSites.Except(_prevRelocatedSites, SiteShiftInfoComparer.Comparer).ToList();
            var sitesToReverse = _prevRelocatedSites.Except(relocatedSites, SiteShiftInfoComparer.Comparer).ToList();

            foreach (var s in sitesToMove)
            {
                AnimateSiteTranslate(s.site, s.translateX, s.translateY);
            }

            foreach (var s in sitesToReverse)
            {
                AnimateSiteTranslate(s.site, 0.0, 0.0);
            }

            _prevRelocatedSites = relocatedSites;
        }
예제 #4
0
        private WidgetSiteControl CreateWidgetSite(MatrixLoc location, bool withAnimation, ref TimeSpan animationTime)
        {
            var site      = new WidgetSiteControl();
            var transform = new TransformGroup();

            transform.Children.Add(withAnimation ? new ScaleTransform(0, 0) : new ScaleTransform(1, 1));
            transform.Children.Add(new TranslateTransform());

            site.RenderTransform       = transform;
            site.RenderTransformOrigin = new Point(0.5, 0.5);

            if (withAnimation)
            {
                AnimateSiteScaleTransform(site, ref animationTime, 0, 1, null);
            }

            matrixPanel.Children.Add(site);

            site.Location = location;

            return(site);
        }
예제 #5
0
        private bool ProcessDataObject(DragEventArgs eventArgs, ProcessDataObjectDelegate callback)
        {
            WidgetSiteDragDropData data = eventArgs.Data.GetData("Droppy.WidgetSiteDragDropData") as WidgetSiteDragDropData;

            if (data == null)
            {
                eventArgs.Effects = DragDropEffects.None;

                return(false);
            }

            Point pt = eventArgs.GetPosition(this.Target) -
                       new Vector(data.DraggableOffset.X, data.DraggableOffset.Y);
            Rect dragRect = new Rect(pt, new Size(data.Site.ActualWidth + data.Site.Margin.Width(),
                                                  data.Site.ActualHeight + data.Site.Margin.Height()));
            Point dragCenter = new Point(dragRect.X + dragRect.Width / 2,
                                         dragRect.Y + dragRect.Height / 2);

            MatrixLoc insertIndex = new MatrixLoc(
                (int)((dragCenter.Y + dragRect.Height) / dragRect.Height) - 1,
                (int)((dragCenter.X + dragRect.Width) / dragRect.Width) - 1);

            MatrixLoc insertLoc = _controlData.Source.Bounds.ToLocation(insertIndex);

            if (_controlData.Source.Bounds.Contains(insertLoc))
            {
                eventArgs.Effects = DragDropEffects.Move;

                callback(insertLoc, data);
            }
            else
            {
                eventArgs.Effects = DragDropEffects.None;
            }

            return(true);
        }
예제 #6
0
        private void CommitMove(MatrixLoc insertLoc, WidgetSiteDragDropData data)
        {
            List <SiteShiftInfo> relocatedSites;

            relocatedSites = CalculateWhichSitesToShift(insertLoc, data);

            if (relocatedSites.Count > 0)
            {
                foreach (var s in relocatedSites)
                {
                    _controlData.Source[s.newLocation] = s.widget;

                    AnimateTranslate(s.site, TranslateTransform.XProperty, null);
                    AnimateTranslate(s.site, TranslateTransform.YProperty, null);
                }

                _controlData.Source[insertLoc] = data.Widget;
            }

            // If there are any controls left out of original position, return them now.
            _prevRelocatedSites = _prevRelocatedSites.Except(relocatedSites, SiteShiftInfoComparer.Comparer).ToList();

            CancelMove();
        }
예제 #7
0
파일: WidgetData.cs 프로젝트: dxm007/Droppy
 /// <summary>
 /// Sets parent container information on the current widget
 /// </summary>
 /// <param name="parent">Reference to the parent widget container</param>
 /// <param name="location">Location of the widget within the parent container</param>
 public void SetOwner( WidgetContainerData parent, MatrixLoc location )
 {
     _location = location;
     _parent = parent;
 }
예제 #8
0
파일: WidgetData.cs 프로젝트: dxm007/Droppy
 /// <summary>
 /// Removes any association between the widget and its parent
 /// </summary>
 public void ClearOwner()
 {
     _parent = null;
     _location = new MatrixLoc();
 }
예제 #9
0
        private void SetWidget( MatrixLoc location, WidgetData widget )
        {
            WidgetData  removedWidget = null;

            Validate();

            // the same widget is being inserted at the same spot where it is already located,
            // let not do anything and just exit
            if( widget != null && widget.Parent == this && widget.Location == location ) return;

            MatrixRect neededBounds = _containerBounds.GrowTo( location );

            // If the cell being modified within the bounds of the current array, let's make sure
            // the existing cell is empty.  Otherwise, we need to reallocate the array before
            // we can assign the widget to it.
            if( neededBounds.Size == _containerBounds.Size )
            {
                removedWidget = ClearWidget( location );
            }
            else if( widget != null )
            {
                WidgetContainerResizeJustify resizeJustify =
                    ( _containerBounds.Row == neededBounds.Row ?
                            WidgetContainerResizeJustify.Top : WidgetContainerResizeJustify.Bottom ) |
                    ( _containerBounds.Column == neededBounds.Column ?
                            WidgetContainerResizeJustify.Left : WidgetContainerResizeJustify.Right );

                Resize( neededBounds.Size, resizeJustify );
            }

            Validate();

            if( widget != null )
            {
                if( widget.HasOwner )
                {
                    widget.Parent.Remove( widget );
                }

                _widgetArray[ _containerBounds.ToIndex( location ) ] = widget;

                widget.SetOwner( this, location );
                widget.IsDirtyChanged += OnChildIsDirtyChanged;

                if( removedWidget != null )
                {
                    OnWidgetReplaced( location, removedWidget, widget );
                    removedWidget = null;
                }
                else
                {
                    OnWidgetAdded( location, widget );
                }
            }

            if( removedWidget != null )
            {
                OnWidgetRemoved( location, removedWidget );
            }

            Validate();

            IsDirty = true;
        }
예제 #10
0
        private WidgetData ClearWidget( MatrixLoc loc )
        {
            MatrixLoc   arrayIndex = _containerBounds.ToIndex( loc );
            WidgetData  widget = _widgetArray[ arrayIndex ];

            _widgetArray[ arrayIndex ] = null;

            if( widget != null )
            {
                widget.ClearOwner();
                widget.IsDirtyChanged -= OnChildIsDirtyChanged;
            }

            return widget;
        }
예제 #11
0
 /// <summary>
 /// This method is invoked whenever a widget is replaced
 /// </summary>
 /// <param name="location">Location where a widget was replaced</param>
 /// <param name="oldWidget">Reference to an old widget that was replaced</param>
 /// <param name="newWidget">Reference to a new widget that is being inserted</param>
 protected virtual void OnWidgetReplaced( MatrixLoc location, WidgetData oldWidget, WidgetData newWidget )
 {
     if( _containerChangedEvent != null )
     {
         _containerChangedEvent( this, new WidgetContainerChangedEventArgs(
                                 NotifyCollectionChangedAction.Replace, location, oldWidget, newWidget ) );
     }
 }
예제 #12
0
 /// <summary>
 /// This method is invoked whenever a widget is added
 /// </summary>
 /// <param name="location">Location where new widget was added</param>
 /// <param name="widget">Reference to a widget that was added</param>
 protected virtual void OnWidgetAdded( MatrixLoc location, WidgetData widget )
 {
     if( _containerChangedEvent != null )
     {
         _containerChangedEvent( this, new WidgetContainerChangedEventArgs(
                                 NotifyCollectionChangedAction.Add, location, null, widget ) );
     }
 }
예제 #13
0
 /// <summary>
 /// Gets/sets a widget at a specified location in the container
 /// </summary>
 /// <param name="location">Location to access/modify</param>
 public WidgetData this[MatrixLoc location]
 {
     get { return _widgetArray[ _containerBounds.ToIndex( location ) ]; }
     set { SetWidget( location, value ); }
 }
예제 #14
0
        private List <SiteShiftInfo> CalculateWhichSitesToShift(MatrixLoc insertLoc, WidgetSiteDragDropData data)
        {
            MatrixLoc            sourceLoc = data.Site.Location;
            List <SiteShiftInfo> relocatedSites;
            int    i, step;
            double translateBy;

            // preallocate enough so we don't need to worry about reallocations
            relocatedSites = new List <SiteShiftInfo>(_controlData.Source.Bounds.RowCount +
                                                      _controlData.Source.Bounds.ColumnCount + 10);

            if (insertLoc.Column != sourceLoc.Column)
            {
                translateBy = data.Site.ActualWidth + data.Site.Margin.Width();

                if (insertLoc.Column < sourceLoc.Column)
                {
                    step = 1;
                }
                else
                {
                    step        = -1;
                    translateBy = -translateBy;
                }

                for (i = insertLoc.Column; i != sourceLoc.Column; i += step)
                {
                    MatrixLoc arrayIndex = _controlData.Source.Bounds.ToIndex(new MatrixLoc(sourceLoc.Row, i));

                    WidgetSiteControl ctrl = _controlData.SiteGrid[arrayIndex];

                    relocatedSites.Add(new SiteShiftInfo()
                    {
                        site        = ctrl, widget = (Data.WidgetData)ctrl.Content,
                        translateX  = translateBy, translateY = 0.0,
                        newLocation = new MatrixLoc(sourceLoc.Row, i + step)
                    });
                }
            }

            if (insertLoc.Row != sourceLoc.Row)
            {
                translateBy = data.Site.ActualHeight + data.Site.Margin.Height();

                if (insertLoc.Row < sourceLoc.Row)
                {
                    step = 1;
                }
                else
                {
                    step        = -1;
                    translateBy = -translateBy;
                }

                for (i = insertLoc.Row; i != sourceLoc.Row; i += step)
                {
                    MatrixLoc arrayIndex = _controlData.Source.Bounds.ToIndex(new MatrixLoc(i, insertLoc.Column));

                    WidgetSiteControl ctrl = _controlData.SiteGrid[arrayIndex];

                    relocatedSites.Add(new SiteShiftInfo()
                    {
                        site        = ctrl, widget = (Data.WidgetData)ctrl.Content,
                        translateY  = translateBy, translateX = 0.0,
                        newLocation = new MatrixLoc(i + step, insertLoc.Column)
                    });
                }
            }

            return(relocatedSites);
        }
예제 #15
0
        private void UpdateGrid(bool withAnimation)
        {
            TimeSpan animationTime = new TimeSpan();
            List <WidgetSiteControl> sitesToRemove = new List <WidgetSiteControl>(256);

            int rowCount    = _controlData.Source.Bounds.RowCount;
            int columnCount = _controlData.Source.Bounds.ColumnCount;

            ResizeRowOrColumn(matrixPanel.RowDefinitions, rowCount);
            ResizeRowOrColumn(matrixPanel.ColumnDefinitions, columnCount);

            _controlData.SiteGrid = new Array2D <WidgetSiteControl>(rowCount, columnCount);

            foreach (var child in matrixPanel.Children)
            {
                WidgetSiteControl site = child as WidgetSiteControl;

                if (site == null)
                {
                    continue;
                }

                if (!_controlData.Source.Bounds.Contains(site.Location))
                {
                    if (withAnimation)
                    {
                        MatrixSize siteDistance = _controlData.Source.Bounds.Distance(site.Location);

                        TranslateTransform transform = (TranslateTransform)((TransformGroup)site.RenderTransform).Children[1];

                        transform.Y = site.HeightWithMargin * siteDistance.RowCount;
                        transform.X = site.WidthWithMargin * siteDistance.ColumnCount;

                        AnimateSiteScaleTransform(site, ref animationTime, 1, 0,
                                                  new EventHandler((o, e) => {
                            matrixPanel.Children.Remove(site);
                        }));
                    }
                    else
                    {
                        sitesToRemove.Add(site);
                    }
                }
                else
                {
                    MatrixLoc arrayIndex = _controlData.Source.Bounds.ToIndex(site.Location);

                    _controlData.SiteGrid[arrayIndex] = site;

                    site.UpdateGridPosition();
                }
            }

            foreach (var site in sitesToRemove)
            {
                matrixPanel.Children.Remove(site);
            }

            foreach (MatrixLoc loc in _controlData.Source.Bounds)
            {
                MatrixLoc arrayIndex = _controlData.Source.Bounds.ToIndex(loc);

                if (_controlData.SiteGrid[arrayIndex] == null)
                {
                    var site = CreateWidgetSite(loc, withAnimation, ref animationTime);

                    _controlData.SiteGrid[arrayIndex] = site;
                }

                _controlData.SiteGrid[arrayIndex].Content = _controlData.Source[loc];
            }
        }