Exemplo n.º 1
0
        /// <summary>
        /// Called when a ItemProxy should be displayed in the river. The method will attempt to get data for the item either from the
        /// river's data source or the history. If no data is available, the item will not be shown and no attempt will be made to show it
        /// until the next loop around the grid.
        /// </summary>
        /// <param name="proxy">The ItemProxy which should be added.</param>
        /// <param name="maintainOrientation">if set to <c>true</c> [maintain orientation].</param>
        /// <param name="maintainUnblockedData">if set to <c>true</c> [maintain unblocked data].</param>
        private void AttemptToAddToRiver(ItemProxy proxy, bool maintainOrientation, bool maintainUnblockedData)
        {
            RiverItemState state = GetState(proxy);
            if (state == null)
            {
                return;
            }

            if (state.DidAttemptToAddToRiver)
            {
                return;
            }

            RiverItemBase riverItem = proxy.FindVisualChild<RiverItemBase>();
            double orientation = 0;

            bool isPortrait = state.RowSpan > state.ColumnSpan;

            if (riverItem == null)
            {
                orientation = isPortrait ? 90 : 0;
            }
            else
            {
                int page = (int)Math.Ceiling(_cumulativeScrollChange / (_totalColumns * GridCellSize.Width));
                if (GetItemVisibilityInfo(state).IsLooping)
                {
                    page++;
                }

                RiverItemHistoryInfo history = _history.Where(h => h.State == state && h.Grid == page).FirstOrDefault();

                object data = null;

                if (history != null)
                {
                    // Use the historical data and orientation if it exists.
                    data = history.Data;
                    orientation = history.Orientation;
                }
                else
                {
                    data = riverItem.GetData(state, maintainUnblockedData);

                    if (InteractiveSurface.PrimarySurfaceDevice.Tilt == Tilt.Horizontal)
                    {
                        // If running on a tabletop, randomly rotate the item.
                        orientation = _random.NextDouble() > .5 ? 0 : 180;

                        if (isPortrait)
                        {
                            // Rotate vertical items.
                            orientation += 90 * (_random.NextDouble() > .5 ? 1 : -1);
                        }

                        if (state.RowSpan == state.ColumnSpan && _random.NextDouble() > .5)
                        {
                            // Maybe rotate square items.
                            orientation += 90 * (_random.NextDouble() > .5 ? 1 : -1);
                        }
                    }
                    else if (isPortrait)
                    {
                        // If running vertically, portrait items still get rotated to portrait.
                        orientation = _random.NextDouble() > .5 ? 90 : -90;
                    }
                    else
                    {
                        // If running vertically and not portrait, always render right-side-up.
                        orientation = 0;
                    }

                    history = new RiverItemHistoryInfo { State = state, Grid = page, Orientation = orientation };
                    _history.Add(history);
                }

                history.Data = riverItem.RenderData(state, data);

                if (history.Data == null)
                {
                    // The item rejected this data and didn't provide new data.
                    _history.Remove(history);
                }

                if (data == null)
                {
                    // The item rejected the attempt to add, so don't try again until it's looped around.
                    state.DidAttemptToAddToRiver = true;
                    proxy.Visibility = Visibility.Collapsed;
                }
            }

            if (maintainOrientation)
            {
                // Don't apply the orientation if this was a user-requested refresh.
                return;
            }

            proxy.Orientation = state.OriginalOrientation = orientation;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Contains the main logic for creating, destroying, and positioning items. This is called whenever the HorizontalOffset changes.
        /// </summary>
        /// <param name="proxy">The proxy to update.</param>
        /// <param name="state">The state of the proxy.</param>
        private void UpdateScrollPosition(ItemProxy proxy, RiverItemState state)
        {
            if (GridCellSize == Size.Empty || ActualWidth == 0 || ActualHeight == 0 || _totalColumns == 0 || _totalRows == 0)
            {
                // Not initialized yet.
                return;
            }

            if (state.IsRemovedFromRiver)
            {
                // This item is pulled from the river, so don't do anything with it.
                return;
            }

            // Get the pool for items of this style.
            Style proxyStyle = state.ProxyStyle;
            Queue<ItemProxy> pool = null;

            if (proxyStyle == null)
            {
                // There's no style, so use the default pool.
                pool = _defaultRiverItemPool;
            }
            else
            {
                // There is a style, so create a pool if needed, and use that.
                if (!_styledRiverItemPool.ContainsKey(proxyStyle))
                {
                    _styledRiverItemPool[proxyStyle] = new Queue<ItemProxy>();
                }

                pool = _styledRiverItemPool[proxyStyle];
            }

            RiverItemVisibilityInfo visibilityInfo = GetItemVisibilityInfo(state);
            if (!visibilityInfo.IsVisible)
            {
                if (proxy != null)
                {
                    RiverItemBase riverItem = proxy.FindVisualChild<RiverItemBase>();

                    // This definition should not be visible, so hide it.
                    state.IsAnimatingBackToRiver = false;
                    state.IsAnimatingToContactOrientation = false;
                    state.IsAnimatingToRemovedSize = false;
                    state.DidAttemptToAddToRiver = false;
                    state.IsRemovedFromRiver = false;
                    _stateToProxyMap[state] = null;
                    _sviToProxyMap.Remove(proxy);
                    proxy.Visibility = Visibility.Hidden;
                    if (riverItem != null)
                    {
                        riverItem.Cleanup();
                    }

                    pool.Enqueue(proxy);
                }

                return;
            }

            // The definition should be visible, but it's not paired with any ItemProxy yet, so build or recycle one.
            if (proxy == null)
            {
                if (pool.Count > 0)
                {
                    // Use an SVI from the queue.
                    proxy = pool.Dequeue();
                    proxy.Visibility = Visibility.Visible;
                }
                else
                {
                    // Set up a new proxy.
                    proxy = AddNewItemProxy();
                    proxy.Style = proxyStyle;
                }

                // Size the ScatterView item when it's first added to the river.
                bool isPortrait = state.RowSpan > state.ColumnSpan;
                double itemWidth = state.ColumnSpan * GridCellSize.Width;
                double itemHeight = state.RowSpan * GridCellSize.Height;
                itemWidth += Plane.GetPlaneFrontPadding(proxy).Left + Plane.GetPlaneFrontPadding(proxy).Right;
                itemHeight += Plane.GetPlaneFrontPadding(proxy).Top + Plane.GetPlaneFrontPadding(proxy).Bottom;
                proxy.Width = isPortrait ? itemHeight : itemWidth;
                proxy.Height = isPortrait ? itemWidth : itemHeight;
                proxy.Visibility = Visibility.Visible;

                // More setup of added items.
                _stateToProxyMap[state] = proxy;
                _sviToProxyMap[proxy] = state;
                AttemptToAddToRiver(proxy, false, false);
            }

            if (state.DidAttemptToAddToRiver)
            {
                // We already tried to add this one and it rejected the add, so wait until it's looped around.
                return;
            }

            // Update the position of the item.
            proxy.Center = GetItemCenter(state);
        }