protected override bool TryCalculateStateName(LayoutState layout, out string stateName)
        {
            // Only continue if there are rules
            if ((Rules != null) && (Rules.Count > 0))
            {
                // Try to find the first matching rule
                var rule = Rules.Where((r) => r.Applies(layout)).FirstOrDefault();

                // If found, make sure state name is valid and set it
                if (rule != null)
                {
                    if (string.IsNullOrEmpty(rule.StateName))
                    {
                        throw new InvalidOperationException("The matching rule did not provide a valid state name.");
                    }

                    // Return the state
                    stateName = rule.StateName;

                    // Success
                    return(true);
                }
            }

            // No matching rule found
            stateName = null;
            return(false);
        }
Example #2
0
        /// <summary>
        /// Updates or creates a sublayer to render a border-like shape.
        /// </summary>
        /// <param name="owner">The parent layer to apply the shape</param>
        /// <param name="area">The rendering area</param>
        /// <param name="background">The background brush</param>
        /// <param name="borderThickness">The border thickness</param>
        /// <param name="borderBrush">The border brush</param>
        /// <param name="cornerRadius">The corner radius</param>
        /// <param name="backgroundImage">The background image in case of a ImageBrush background</param>
        public void UpdateLayer(
            UIView owner,
            Brush background,
            Thickness borderThickness,
            Brush borderBrush,
            CornerRadius cornerRadius,
            UIImage backgroundImage
            )
        {
            // Frame is captured to avoid calling twice calls below.
            var frame = owner.Frame;
            var area  = new CGRect(0, 0, frame.Width, frame.Height);

            var newState            = new LayoutState(area, background, borderThickness, borderBrush, cornerRadius, backgroundImage);
            var previousLayoutState = _currentState;

            if (!newState.Equals(previousLayoutState))
            {
                if (
                    background != null ||
                    (borderThickness != Thickness.Empty && borderBrush != null)
                    )
                {
                    _layerDisposable.Disposable = null;
                    _layerDisposable.Disposable = InnerCreateLayer(owner.Layer, area, background, borderThickness, borderBrush, cornerRadius);
                }
                else
                {
                    _layerDisposable.Disposable = null;
                }

                _currentState = newState;
            }
        }
        private static void ShowButtons(SerializedProperty list, int index, LayoutListOptions options)
        {
            if (GUILayout.Button(moveButtonContent, EditorStyles.miniButtonLeft, miniButtonWidth))
            {
                list.MoveArrayElement(index, index + 1);
            }
            if (GUILayout.Button(duplicateButtonContent, EditorStyles.miniButtonMid, miniButtonWidth))
            {
                list.InsertArrayElementAtIndex(index);
            }
            if (GUILayout.Button(deleteButtonContent, EditorStyles.miniButtonRight, miniButtonWidth))
            {
                list.DeleteArrayElementAtIndex(index);
            }

            GUI.backgroundColor = Color.green;
            if (GUILayout.Button(applyButtonContent, EditorStyles.miniButton, actionButtonWidth))
            {
                LayoutState layoutState = list.serializedObject.targetObject as LayoutState;
                layoutState.layouts[index].Save(layoutState.objectsReference);
            }

            GUI.backgroundColor = Color.yellow;
            if (GUILayout.Button(showButtonContent, EditorStyles.miniButton, actionButtonWidth))
            {
                LayoutState layoutState = list.serializedObject.targetObject as LayoutState;
                layoutState.layouts[index].Load(layoutState.objectsReference);
            }
            GUI.backgroundColor = Color.white;
        }
Example #4
0
        /// <summary>
        /// Updates or creates a sublayer to render a border-like shape.
        /// </summary>
        /// <param name="view">The view to which we should add the layers</param>
        /// <param name="background">The background brush of the border</param>
        /// <param name="borderThickness">The border thickness</param>
        /// <param name="borderBrush">The border brush</param>
        /// <param name="cornerRadius">The corner radius</param>
        /// <param name="padding">The padding to apply on the content</param>
        public void UpdateLayer(
            FrameworkElement view,
            Brush background,
            Thickness borderThickness,
            Brush borderBrush,
            CornerRadius cornerRadius,
            Thickness padding,
            bool willUpdateMeasures = false
            )
        {
            // This is required because android Height and Width are hidden by Control.
            var baseView = view as View;

            var logicalDrawArea = view.LayoutSlot;

            // Set origin to 0, because drawArea should be in the coordinates of the view itself
            logicalDrawArea.X = 0;
            logicalDrawArea.Y = 0;
            var drawArea            = logicalDrawArea.LogicalToPhysicalPixels();
            var newState            = new LayoutState(drawArea, background, borderThickness, borderBrush, cornerRadius, padding);
            var previousLayoutState = _currentState;

            if (!newState.Equals(previousLayoutState))
            {
                bool imageHasChanged      = newState.BackgroundImageSource != previousLayoutState?.BackgroundImageSource;
                bool shouldDisposeEagerly = imageHasChanged || newState.BackgroundImageSource == null;
                if (shouldDisposeEagerly)
                {
                    // Clear previous value anyway in order to make sure the previous values are unset before the new ones.
                    // This prevents the case where a second update would set a new background and then set the background to null when disposing the previous.
                    _layerDisposable.Disposable = null;
                }

                Action onImageSet = null;
                var    disposable = InnerCreateLayers(view, drawArea, background, borderThickness, borderBrush, cornerRadius, () => onImageSet?.Invoke());

                // Most of the time we immediately dispose the previous layer. In the case where we're using an ImageBrush,
                // and the backing image hasn't changed, we dispose the previous layer at the moment the new background is applied,
                // to prevent a visible flicker.
                if (shouldDisposeEagerly)
                {
                    _layerDisposable.Disposable = disposable;
                }
                else
                {
                    onImageSet = () => _layerDisposable.Disposable = disposable;
                }

                if (willUpdateMeasures)
                {
                    view.RequestLayout();
                }
                else
                {
                    view.Invalidate();
                }

                _currentState = newState;
            }
        }
Example #5
0
        /// <summary>
        /// Updates or creates a sublayer to render a border-like shape.
        /// </summary>
        /// <param name="owner">The parent layer to apply the shape</param>
        /// <param name="area">The rendering area</param>
        /// <param name="background">The background brush</param>
        /// <param name="borderThickness">The border thickness</param>
        /// <param name="borderBrush">The border brush</param>
        /// <param name="cornerRadius">The corner radius</param>
        /// <param name="backgroundImage">The background image in case of a ImageBrush background</param>
        public void UpdateLayer(
            FrameworkElement owner,
            Brush background,
            Thickness borderThickness,
            Brush borderBrush,
            CornerRadius cornerRadius,
            object backgroundImage
            )
        {
            // Bounds is captured to avoid calling twice calls below.
            var area = new Rect(0, 0, owner.ActualWidth, owner.ActualHeight);

            var newState            = new LayoutState(area, background, borderThickness, borderBrush, cornerRadius, backgroundImage);
            var previousLayoutState = _currentState;

            if (!newState.Equals(previousLayoutState))
            {
                if (
                    background != null ||
                    cornerRadius != CornerRadius.None ||
                    (borderThickness != Thickness.Empty && borderBrush != null)
                    )
                {
                    _layerDisposable.Disposable = null;
                    _layerDisposable.Disposable = InnerCreateLayer(owner, newState);
                }
                else
                {
                    _layerDisposable.Disposable = null;
                }

                _currentState = newState;
            }
        }
Example #6
0
        ////////////////////////////////////////////////////////////////////////////////////////////////
        /*--------------------------------------------------------------------------------------------*/
        internal void Build(IHoverboardPanelState pPanelState, LayoutState pLayoutState,
                            IItemVisualSettingsProvider pItemVisualSettProv)
        {
            Vector2 dir    = pLayoutState.ItemLayout.Direction;
            Vector2 pos    = Vector2.zero;
            Vector2 posMin = Vector2.zero;
            Vector2 posMax = Vector2.zero;

            for (int i = 0; i < pLayoutState.FullItems.Length; i++)
            {
                BaseItemState       itemState  = pLayoutState.FullItems[i];
                IItemVisualSettings visualSett = pItemVisualSettProv.GetSettings(itemState.Item);
                GameObject          itemObj    = (GameObject)itemState.Item.DisplayContainer;

                UiItem uiItem = itemObj.AddComponent <UiItem>();
                uiItem.Build(pPanelState, pLayoutState, itemState, visualSett);
                uiItem.transform.localPosition = new Vector3(pos.x, 0, pos.y) * UiItem.Size;

                var itemSize = new Vector2(itemState.Item.Width, itemState.Item.Height);

                posMin = Vector2.Min(posMin, pos);
                posMax = Vector2.Max(posMax, pos + itemSize);
                pos   += Vector2.Scale(itemSize, dir);
            }

            Vector2 size = posMax - posMin;

            Bounds = new Rect(posMin.x, posMin.y, size.x, size.y);

            gameObject.transform.localPosition = Vector3.zero;
            gameObject.transform.localRotation = Quaternion.identity;
            gameObject.transform.localScale    = Vector3.one;
        }
Example #7
0
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PopLink"/>.
 /// </summary>
 private void ProcessPopLinkToken(TextLayoutCommandStream output,
                                  ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     output.WritePopLink();
     state.AdvanceLineToNextCommand();
     index++;
 }
        protected override bool TryCalculateStateName(LayoutState layout, out string stateName)
        {
            // Only continue if there are rules
            if ((Rules != null) && (Rules.Count > 0))
            {
                // Try to find the first matching rule
                var rule = Rules.Where((r) => r.Applies(layout)).FirstOrDefault();

                // If found, make sure state name is valid and set it
                if (rule != null)
                {
                    if (string.IsNullOrEmpty(rule.StateName))
                    {
                        throw new InvalidOperationException("The matching rule did not provide a valid state name.");
                    }

                    // Return the state
                    stateName = rule.StateName;

                    // Success
                    return true;
                }
            }

            // No matching rule found
            stateName = null;
            return false;
        }
Example #9
0
        public void TestLayout()
        {
            var dataSource = new TestDataSource();

            new TestDataGen().GenerateDataItems(dataSource, 10, 0);

            var boxContainer = new BoxContainer(dataSource);

            TestDataGen.GenerateBoxSizes(boxContainer);

            var diagram = new Diagram();

            diagram.Boxes = boxContainer;

            diagram.LayoutSettings.LayoutStrategies.Add("default", new LinearLayoutStrategy());
            diagram.LayoutSettings.DefaultLayoutStrategyId = "default";

            var state = new LayoutState(diagram)
            {
                BoxSizeFunc = dataId => boxContainer.BoxesByDataId[dataId].Size
            };

            LayoutAlgorithm.Apply(state);

            Assert.AreEqual(5, diagram.VisualTree?.Depth);
        }
Example #10
0
 private void Cache(FlexibleView.Recycler recycler, LayoutState layoutState, bool immediate, float scrolled = 0)
 {
     if (layoutState.LayoutDirection == LayoutState.LAYOUT_END)
     {
         // get the first child in the direction we are going
         FlexibleView.ViewHolder child = GetChildClosestToEnd();
         if (child != null)
         {
             if (child.ItemView.Focusable == false || mOrientationHelper.GetViewHolderEnd(child) + scrolled < mOrientationHelper.GetEnd())
             {
                 layoutState.Available       = MAX_SCROLL_FACTOR * mOrientationHelper.GetTotalSpace();
                 layoutState.Extra           = 0;
                 layoutState.ScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN;
                 layoutState.Recycle         = false;
                 Fill(recycler, layoutState, true, immediate);
             }
         }
     }
     else
     {
         FlexibleView.ViewHolder child = GetChildClosestToStart();
         if (child != null)
         {
             if (child.ItemView.Focusable == false || mOrientationHelper.GetViewHolderStart(child) + scrolled > 0)
             {
                 layoutState.Available       = MAX_SCROLL_FACTOR * mOrientationHelper.GetTotalSpace();
                 layoutState.Extra           = 0;
                 layoutState.ScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN;
                 layoutState.Recycle         = false;
                 Fill(recycler, layoutState, true, immediate);
             }
         }
     }
 }
        /// <summary>
        /// Updates or creates a sublayer to render a border-like shape.
        /// </summary>
        /// <param name="owner">The parent layer to apply the shape</param>
        /// <param name="area">The rendering area</param>
        /// <param name="background">The background brush</param>
        /// <param name="borderThickness">The border thickness</param>
        /// <param name="borderBrush">The border brush</param>
        /// <param name="cornerRadius">The corner radius</param>
        /// <param name="backgroundImage">The background image in case of a ImageBrush background</param>
        /// <returns>An updated BoundsPath if the layer has been created or updated; null if there is no change.</returns>
        public CGPath UpdateLayer(
            _View owner,
            Brush background,
            BackgroundSizing backgroundSizing,
            Thickness borderThickness,
            Brush borderBrush,
            CornerRadius cornerRadius,
            _Image backgroundImage)
        {
            // Bounds is captured to avoid calling twice calls below.
            var bounds = owner.Bounds;
            var area   = new CGRect(0, 0, bounds.Width, bounds.Height);

            var newState            = new LayoutState(area, background, backgroundSizing, borderThickness, borderBrush, cornerRadius, backgroundImage);
            var previousLayoutState = _currentState;

            if (!newState.Equals(previousLayoutState))
            {
#if __MACOS__
                owner.WantsLayer = true;
#endif

                _layerDisposable.Disposable = null;
                _layerDisposable.Disposable = InnerCreateLayer(owner as UIElement, owner.Layer, newState);

                _currentState = newState;
            }

            return(newState.BoundsPath);
        }
Example #12
0
        internal virtual void LayoutChunk(FlexibleViewRecycler recycler,
                                          LayoutState layoutState, LayoutChunkResult result)
        {
            FlexibleViewViewHolder holder = layoutState.Next(recycler);

            if (holder == null)
            {
                // if we are laying out views in scrap, this may return null which means there is
                // no more items to layout.
                result.Finished = true;
                return;
            }

            if (mShouldReverseLayout == (layoutState.LayoutDirection == LayoutState.LAYOUT_START))
            {
                AddView(holder);
            }
            else
            {
                AddView(holder, 0);
            }

            result.Consumed = orientationHelper.GetViewHolderMeasurement(holder);

            float left, top, width, height;

            if (Orientation == VERTICAL)
            {
                width  = Width - PaddingLeft - PaddingRight;
                height = result.Consumed;
                left   = PaddingLeft;
                if (layoutState.LayoutDirection == LayoutState.LAYOUT_END)
                {
                    top = layoutState.Offset;
                }
                else
                {
                    top = layoutState.Offset - height;
                }
                LayoutChild(holder, left, top, width, height);
            }
            else
            {
                width  = result.Consumed;
                height = Height - PaddingTop - PaddingBottom;
                top    = PaddingTop;
                if (layoutState.LayoutDirection == LayoutState.LAYOUT_END)
                {
                    left = layoutState.Offset;
                }
                else
                {
                    left = layoutState.Offset - width;
                }
                LayoutChild(holder, left, top, width, height);
            }

            result.Focusable = true;
        }
Example #13
0
        public LinearLayoutManager(int orientation)
        {
            mOrientation       = orientation;
            mOrientationHelper = OrientationHelper.CreateOrientationHelper(this, mOrientation);

            mLayoutState        = new LayoutState();
            mLayoutState.Offset = mOrientationHelper.GetStartAfterPadding();
        }
Example #14
0
 public LayoutManagerState()
 {
     this.agvsToDispatch = new StringList();
     this.agvsToRoute    = new StringList();
     this.blockedAgvs    = new StringList();
     this.congestedNodes = new StringList();
     this.layout         = new LayoutState();
 }
Example #15
0
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.ToggleBold"/>.
 /// </summary>
 private void ProcessToggleBoldToken(TextLayoutCommandStream output, ref Boolean bold,
                                     ref LayoutState state, ref Int32 index)
 {
     output.WriteToggleBold();
     state.AdvanceLineToNextCommand();
     bold = !bold;
     index++;
 }
Example #16
0
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.ToggleItalic"/>.
 /// </summary>
 private void ProcessToggleItalicToken(TextLayoutCommandStream output, ref Boolean italic,
                                       ref LayoutState state, ref Int32 index)
 {
     output.WriteToggleItalic();
     state.AdvanceLineToNextCommand();
     italic = !italic;
     index++;
 }
Example #17
0
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PopStyle"/>.
 /// </summary>
 private void ProcessPopStyleToken(TextLayoutCommandStream output, ref Boolean bold, ref Boolean italic,
                                   ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     output.WritePopStyle();
     state.AdvanceLineToNextCommand();
     PopStyle(ref bold, ref italic);
     index++;
 }
Example #18
0
        public virtual void UpdateLayout()
        {
            if (_layoutState == LayoutState.Normal)
            {
                return;
            }

            if (_layoutState == LayoutState.Invalid)
            {
                // Full rearrange
                Point size;
                if (HorizontalAlignment != HorizontalAlignment.Stretch ||
                    VerticalAlignment != VerticalAlignment.Stretch)
                {
                    size = Measure(_containerBounds.Size());
                }
                else
                {
                    size = _containerBounds.Size();
                }

                if (size.X > _containerBounds.Width)
                {
                    size.X = _containerBounds.Width;
                }

                if (size.Y > _containerBounds.Height)
                {
                    size.Y = _containerBounds.Height;
                }

                // Align
                var controlBounds = LayoutUtils.Align(_containerBounds.Size(), size, HorizontalAlignment, VerticalAlignment);
                controlBounds.Offset(_containerBounds.Location);

                controlBounds.Offset(Left, Top);

                _bounds       = controlBounds;
                _actualBounds = CalculateClientBounds(controlBounds);

                Arrange();
            }
            else
            {
                // Only location
                MoveChildren(new Point(Left - _lastLocationHint.X, Top - _lastLocationHint.Y));
            }

            _lastLocationHint = new Point(Left, Top);
            _layoutState      = LayoutState.Normal;

            var ev = LayoutUpdated;

            if (ev != null)
            {
                ev(this, EventArgs.Empty);
            }
        }
Example #19
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.PushColor"/>.
        /// </summary>
        private void ProcessPushColorToken(TextLayoutCommandStream output,
                                           ref TextParserToken token, ref LayoutState state, ref Int32 index)
        {
            var pushedColor = ParseColor(token.Text);

            output.WritePushColor(new TextLayoutColorCommand(pushedColor));
            state.AdvanceLineToNextCommand();
            index++;
        }
Example #20
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.PushLink"/>.
        /// </summary>
        private void ProcessPushLinkToken(TextLayoutCommandStream output,
                                          ref TextParserToken token, ref LayoutState state, ref Int32 index)
        {
            var pushedLinkTargetIndex = RegisterLinkTargetWithCommandStream(output, token.Text);

            output.WritePushLink(new TextLayoutLinkCommand(pushedLinkTargetIndex));
            state.AdvanceLineToNextCommand();
            index++;
        }
Example #21
0
        /**
         * Tells the node that the current values in {@link #layout} have been seen. Subsequent calls
         * to {@link #hasNewLayout()} will return false until this node is laid out with new parameters.
         * You must call this each time the layout is generated if the node has a new layout.
         */

        public void MarkLayoutSeen()
        {
            if (!HasNewLayout)
            {
                throw new InvalidOperationException("Expected node to have a new layout to be seen!");
            }

            mLayoutState = LayoutState.UP_TO_DATE;
        }
Example #22
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.PushGlyphShader"/>.
        /// </summary>
        private void ProcessPushGlyphShaderToken(TextLayoutCommandStream output,
                                                 ref TextParserToken token, ref LayoutState state, ref Int32 index)
        {
            var pushedGlyphShader      = default(GlyphShader);
            var pushedGlyphShaderIndex = RegisterGlyphShaderWithCommandStream(output, token.Text, out pushedGlyphShader);

            output.WritePushGlyphShader(new TextLayoutGlyphShaderCommand(pushedGlyphShaderIndex));
            state.AdvanceLineToNextCommand();
            index++;
        }
Example #23
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.Custom"/>.
        /// </summary>
        private void ProcessCustomCommandToken(TextLayoutCommandStream output,
                                               ref TextParserToken token, ref LayoutState state, ref Int32 index)
        {
            var commandID    = (token.TokenType - TextParserTokenType.Custom);
            var commandValue = token.Text.IsEmpty ? default(Int32) : StringSegmentConversion.ParseInt32(token.Text);

            output.WriteCustomCommand(new TextLayoutCustomCommand(commandID, commandValue));
            state.AdvanceLineToNextCommand();
            index++;
        }
Example #24
0
        private void QuickLayout()
        {
            var state = new LayoutState(m_diagram);

            state.BoxSizeFunc         = dataId => m_diagram.Boxes.BoxesByDataId[dataId].Size;
            state.LayoutOptimizerFunc = LayoutOptimizer;

            LayoutAlgorithm.Apply(state);

            RenderBoxes(m_diagram.VisualTree, DrawCanvas);
        }
Example #25
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.PushFont"/>.
        /// </summary>
        private void ProcessPushFontToken(TextLayoutCommandStream output,
                                          ref TextParserToken token, ref LayoutState state, ref Int32 index)
        {
            var pushedFont      = default(SpriteFont);
            var pushedFontIndex = RegisterFontWithCommandStream(output, token.Text, out pushedFont);

            output.WritePushFont(new TextLayoutFontCommand(pushedFontIndex));
            state.AdvanceLineToNextCommand();
            PushFont(pushedFont);
            index++;
        }
Example #26
0
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.PushStyle"/>.
        /// </summary>
        private void ProcessPushStyleToken(TextLayoutCommandStream output, ref Boolean bold, ref Boolean italic,
                                           ref TextParserToken token, ref LayoutState state, ref Int32 index)
        {
            var pushedStyle      = default(TextStyle);
            var pushedStyleIndex = RegisterStyleWithCommandStream(output, token.Text, out pushedStyle);

            output.WritePushStyle(new TextLayoutStyleCommand(pushedStyleIndex));
            state.AdvanceLineToNextCommand();
            PushStyle(pushedStyle, ref bold, ref italic);
            index++;
        }
        /// <summary>
        /// Updates or creates a sublayer to render a border-like shape.
        /// </summary>
        /// <param name="view">The view to which we should add the layers</param>
        /// <param name="background">The background brush of the border</param>
        /// <param name="borderThickness">The border thickness</param>
        /// <param name="borderBrush">The border brush</param>
        /// <param name="cornerRadius">The corner radius</param>
        /// <param name="padding">The padding to apply on the content</param>
        public void UpdateLayers(
            FrameworkElement view,
            Brush background,
            Thickness borderThickness,
            Brush borderBrush,
            CornerRadius cornerRadius,
            Thickness padding
            )
        {
            // This is required because android Height and Width are hidden by Control.
            var baseView = view as View;

            Size targetSize          = new Size(baseView.Width, baseView.Height);
            var  drawArea            = new Windows.Foundation.Rect(0, 0, targetSize.Width, targetSize.Height);
            var  newState            = new LayoutState(drawArea, background, borderThickness, borderBrush, cornerRadius, padding);
            var  previousLayoutState = _currentState;

            if (!newState.Equals(previousLayoutState))
            {
                bool imageHasChanged      = newState.BackgroundImageSource != previousLayoutState?.BackgroundImageSource;
                bool shouldDisposeEagerly = imageHasChanged || newState.BackgroundImageSource == null;
                if (shouldDisposeEagerly)
                {
                    // Clear previous value anyway in order to make sure the previous values are unset before the new ones.
                    // This prevents the case where a second update would set a new background and then set the background to null when disposing the previous.
                    _layerDisposable.Disposable = null;
                }

                if (
                    background != null ||
                    (borderThickness != Thickness.Empty && borderBrush != null)
                    )
                {
                    Action onImageSet = null;
                    var    disposable = InnerCreateLayers(view, drawArea, background, borderThickness, borderBrush, cornerRadius, () => onImageSet?.Invoke());

                    // Most of the time we immediately dispose the previous layer. In the case where we're using an ImageBrush,
                    // and the backing image hasn't changed, we dispose the previous layer at the moment the new background is applied,
                    // to prevent a visible flicker.
                    if (shouldDisposeEagerly)
                    {
                        _layerDisposable.Disposable = disposable;
                    }
                    else
                    {
                        onImageSet = () => _layerDisposable.Disposable = disposable;
                    }
                }

                view.Invalidate();

                _currentState = newState;
            }
        }
 private static void OnCurrentStateChanged(BindableObject bindable, LayoutState oldValue, LayoutState newValue)
 {
     if (newValue == LayoutState.None)
     {
         Current.IsVisible = false;
     }
     else
     {
         Current.IsVisible = true;
     }
 }
Example #29
0
    public void CreateStateScaffold()
    {
        layoutState = new LayoutState();
        List <StationState> stations = new List <StationState>();

        foreach (var item in layout.Stations)
        {
            stations.Add(new StationState(item.Name));
        }
        layoutState.StationStates = stations.ToArray();
        layoutState.Seed          = layout.InitialSeed;
    }
Example #30
0
 public override bool Applies(LayoutState layout)
 {
     if ((MinHeight > -1) && (layout.ActualHeight < MinHeight))
     {
         return(false);
     }
     if ((MinWidth > -1) && (layout.ActualWidth < MinWidth))
     {
         return(false);
     }
     return(true);
 }
Example #31
0
        private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            e.Handled = true;

            if (!((sender as Hyperlink)?.DataContext is SearchInstance instance))
            {
                return;
            }

            CurrentSearchInstance = instance;

            current_layout = LayoutState.Three;
            ApplyTranslate();
        }
Example #32
0
        public override bool Applies(LayoutState layout)
        {
            // If there are no child rules the answer is no
            if ((Rules == null) || (Rules.Count < 1)) { return false; }

            // At least one child must match
            foreach (var child in Rules)
            {
                // If child matches, success
                if (child.Applies(layout)) return true;
            }

            // No match
            return false;
        }
Example #33
0
        public override bool Applies(LayoutState layout)
        {
            // If there are no child rules the answer is no
            if ((Rules == null) || (Rules.Count < 1)) { return false; }

            // All children must match
            foreach (var child in Rules)
            {
                // Child doesn't match. Fail.
                if (!child.Applies(layout)) return false;
            }

            // Success
            return true;
        }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PushColor"/>.
 /// </summary>
 private void ProcessPushColorToken(TextLayoutCommandStream output,
     ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     var pushedColor = ParseColor(token.Text);
     output.WritePushColor(new TextLayoutColorCommand(pushedColor));
     state.AdvanceLineToNextCommand();
     index++;
 }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PopStyle"/>.
 /// </summary>
 private void ProcessPopStyleToken(TextLayoutCommandStream output, ref Boolean bold, ref Boolean italic,
     ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     output.WritePopStyle();
     state.AdvanceLineToNextCommand();
     PopStyle(ref bold, ref italic);
     index++;
 }
Example #36
0
        //*************************************************************************
        //  Method: AsyncLayout_LayOutGraphCompleted()
        //
        /// <summary>
        /// Handles the LayOutGraphCompleted event on the m_oAsyncLayout object.
        /// </summary>
        ///
        /// <param name="oSender">
        /// Standard event argument.
        /// </param>
        ///
        /// <param name="oAsyncCompletedEventArgs">
        /// Standard event argument.
        /// </param>
        //*************************************************************************
        protected void AsyncLayout_LayOutGraphCompleted(
            Object oSender,
            AsyncCompletedEventArgs oAsyncCompletedEventArgs
            )
        {
            AssertValid();

            #if TRACE_LAYOUT_AND_DRAW
            Debug.WriteLine("NodeXLControl: AsyncLayout_LayOutGraphCompleted()");
            #endif

            if (oAsyncCompletedEventArgs.Error == null)
            {
            // The asynchronous layout has completed and now the graph needs to
            // be drawn.

            m_eLayoutState = LayoutState.LayoutCompleted;
            LayOutOrDrawGraph();
            }
            else
            {
            m_eLayoutState = LayoutState.Stable;
            }

            FireGraphLaidOut(oAsyncCompletedEventArgs);
        }
Example #37
0
        protected void Dirty()
        {
            if (layoutState == LayoutState.DIRTY) {
                return;
            } else if (layoutState == LayoutState.HAS_NEW_LAYOUT) {
                throw new InvalidOperationException ("Previous layout was ignored! MarkLayoutSeen() was never called.");
            }

            layoutState = LayoutState.DIRTY;

            if (parent != null) {
                parent.Dirty ();
            }
        }
Example #38
0
 public override bool Applies(LayoutState layout)
 {
     if ((MinHeight > -1) && (layout.ActualHeight < MinHeight)) { return false; }
     if ((MinWidth > -1) && (layout.ActualWidth < MinWidth)) { return false; }
     return true;
 }
Example #39
0
        //*************************************************************************
        //  Method: LayOutOrDrawGraph()
        //
        /// <summary>
        /// Lays out or draws the graph, depending on the current layout state.
        /// </summary>
        //*************************************************************************
        protected void LayOutOrDrawGraph()
        {
            AssertValid();

            #if TRACE_LAYOUT_AND_DRAW
            Debug.WriteLine("NodeXLControl: LayOutOrDrawGraph(), m_eLayoutState = "
            + m_eLayoutState);
            #endif

            Rect oGraphRectangle = this.GraphRectangle;

            #if TRACE_LAYOUT_AND_DRAW
            Debug.WriteLine("NodeXLControl: LayOutOrDrawGraph(), size = " +
            oGraphRectangle.Width + " , " + oGraphRectangle.Height);
            #endif

            System.Drawing.Rectangle oGraphRectangle2 =
            WpfGraphicsUtil.RectToRectangle(oGraphRectangle);

            switch (m_eLayoutState)
            {
            case LayoutState.Stable:

                break;

            case LayoutState.LayoutRequired:

                Debug.Assert(!m_oAsyncLayout.IsBusy);

                FireLayingOutGraph();

                m_oLastLayoutContext = new LayoutContext(oGraphRectangle2);

                m_eLayoutState = LayoutState.LayingOut;

                if (m_oAsyncLayout is SortableLayoutBase)
                {
                    // If the vertex layout order has been set, tell the layout
                    // object to sort the vertices before laying them out.

                    ( (SortableLayoutBase)m_oAsyncLayout ).VertexSorter =

                        m_oGraph.ContainsKey(
                            ReservedMetadataKeys.SortableLayoutOrderSet) ?

                        new ByMetadataVertexSorter<Single>(
                            ReservedMetadataKeys.SortableLayoutOrder)
                        :
                        null;
                }

                // Start an asynchronous layout.  The m_oAsyncLayout object
                // will fire LayOutGraphIterationCompleted and
                // LayOutGraphCompleted events as it does its work.

                m_oAsyncLayout.LayOutGraphAsync(
                    m_oGraph, m_oLastLayoutContext);

                break;

            case LayoutState.LayingOut:

                break;

            case LayoutState.LayoutIterationCompleted:

                // An iteration of the asynchronous layout has completed and
                // now the graph needs to be drawn.

                m_eLayoutState = LayoutState.LayingOut;

                DrawGraph(oGraphRectangle);

                break;

            case LayoutState.LayoutCompleted:

                // The asynchronous layout has completed and now the graph
                // needs to be drawn.

                m_eLayoutState = LayoutState.Stable;

                // Has the size of the control changed since the layout was
                // started?

                System.Drawing.Rectangle oLastGraphRectangle =
                    m_oLastLayoutContext.GraphRectangle;

                if (
                    oLastGraphRectangle.Width != oGraphRectangle2.Width
                    ||
                    oLastGraphRectangle.Height != oGraphRectangle2.Height
                    )
                {
                    // Yes.  Transform the layout to the new size.

                    #if TRACE_LAYOUT_AND_DRAW
                    Debug.WriteLine("NodeXLControl: Transforming layout.");
                    #endif

                    m_oLastLayoutContext = TransformLayout(oGraphRectangle);
                }

                DrawGraph(oGraphRectangle);

                break;

            case LayoutState.TransformRequired:

                // The control has been resized and now the graph's layout
                // needs to be transformed to the new size.

                m_oLastLayoutContext = TransformLayout(oGraphRectangle);

                m_eLayoutState = LayoutState.Stable;

                DrawGraph(oGraphRectangle);

                break;

            default:

                Debug.Assert(false);
                break;
            }
        }
        /// <summary>
        /// Initializes a new <see cref="LayoutStateCalculatingEventArgs"/> instance.
        /// </summary>
        public LayoutStateCalculatingEventArgs(LayoutState layout)
        {
            // Validate
            if (layout == null) throw new ArgumentNullException("layout");

            // Store
            this.Layout = layout;

            // Default values
            StateName = string.Empty;
        }
 /// <summary>
 /// Attempts to calculate the state name for the associated object.
 /// </summary>
 /// <param name="layout">
 /// A <see cref="LayoutState"/> instance that provides information about the layout 
 /// of the application.
 /// </param>
 /// <param name="stateName">
 /// If successful, the calculated state name; otherwise <see langword="null"/>.
 /// </param>
 /// <returns>
 /// <c>true</c> if the state name could be calculated; otherwise <c>false</c>.
 /// </returns>
 protected abstract bool TryCalculateStateName(LayoutState layout, out string stateName);
        protected override bool TryCalculateStateName(LayoutState layout, out string stateName)
        {
            // Figure out difference between width and height
            var diff = Math.Abs(layout.ActualWidth - layout.ActualHeight);

            // If it's within the square threshold, call it square
            if (diff <= SquareThreshold)
            {
                stateName = SquareStateName;
            }
            // Wider than tall?
            else if (layout.ActualWidth > layout.ActualHeight)
            {
                stateName = LandscapeStateName;
            }
            else
            {
                stateName = PortraitStateName;
            }

            // Success
            return true;
        }
        /// <summary>
        /// Given a string and an available space, returns the largest substring which will fit within that space.
        /// </summary>
        private Boolean GetFittedSubstring(SpriteFontFace font, Int32 maxLineWidth, ref StringSegment tokenText, ref Size2 tokenSize, ref LayoutState state, Boolean hyphenate)
        {
            var substringAvailableWidth = maxLineWidth - state.PositionX;
            var substringWidth = 0;
            var substringLength = 0;

            for (int glyphIndex = 0; glyphIndex < tokenText.Length - 1; glyphIndex++)
            {
                var glyph1 = tokenText[glyphIndex];
                var glyph2 = tokenText[glyphIndex + 1];
                var glyphWidth = 0;

                if (hyphenate)
                {
                    glyphWidth = font.MeasureGlyph(glyph1, '-').Width + font.MeasureGlyph('-').Width;
                }
                else
                {
                    glyphWidth = font.MeasureGlyph(glyph1).Width;
                }

                if (substringAvailableWidth - glyphWidth < 0)
                    break;

                var glyphSize = font.MeasureGlyph(glyph1, glyph2);
                substringAvailableWidth -= glyphSize.Width;
                substringWidth += glyphSize.Width;
                substringLength++;
            }

            tokenText = substringLength > 0 ? tokenText.Substring(0, substringLength) : StringSegment.Empty;
            tokenSize = new Size2(substringWidth, tokenSize.Height);

            return substringLength > 0;
        }
        /// <summary>
        /// Adds a <see cref="TextLayoutCommandType.Text"/> command to the output stream if the specified span of text has a non-zero length.
        /// </summary>
        private Boolean EmitTextIfNecessary(TextLayoutCommandStream output, Int32 start, Int32 length, ref Rectangle bounds, ref LayoutState state)
        {
            if (length == 0)
                return false;

            output.WriteText(new TextLayoutTextCommand(start, length, 
                bounds.X, bounds.Y, (Int16)bounds.Width, (Int16)bounds.Height));

            state.LineLengthInCommands++;

            return true;
        }
        /// <summary>
        /// Accumulates sequential text tokens into a single text command.
        /// </summary>
        private Boolean AccumulateText(TextParserTokenStream input, TextLayoutCommandStream output, SpriteFontFace font, ref Int32 index, ref LayoutState state, ref TextLayoutSettings settings)
        {
            var hyphenate = (settings.Options & TextLayoutOptions.Hyphenate) == TextLayoutOptions.Hyphenate;

            var availableWidth = (settings.Width ?? Int32.MaxValue);
            var x = state.PositionX;
            var y = state.PositionY;
            var width = 0;
            var height = 0;

            var accumulatedStart = input[index].Text.Start + (state.ParserTokenOffset ?? 0);
            var accumulatedLength = 0;
            var accumulatedCount = 0;

            var lineOverflow = false;
            var lineBreakPossible = false;

            var tokenText = default(StringSegment);
            var tokenNext = default(TextParserToken?);
            var tokenSize = default(Size2);

            while (index < input.Count)
            {
                var token = input[index];
                if (token.TokenType != TextParserTokenType.Text || token.IsNewLine)
                    break;

                if (!IsSegmentForCurrentSource(token.Text))
                {
                    if (accumulatedCount > 0)
                        break;

                    EmitChangeSourceIfNecessary(input, output, ref token);
                }

                tokenText = token.Text.Substring(state.ParserTokenOffset ?? 0);
                tokenNext = GetNextTextToken(input, index);
                tokenSize = MeasureToken(font, token.TokenType, tokenText, tokenNext);

                // NOTE: We assume in a couple of places that tokens sizes don't exceed Int16.MaxValue, so try to
                // avoid accumulating tokens larger than that just in case somebody is doing something dumb
                if (width + tokenSize.Width > Int16.MaxValue)
                    break;

                var overflowsLine = state.PositionX + tokenSize.Width > availableWidth;
                if (overflowsLine)
                {
                    lineOverflow = true;
                    break;
                }

                if (tokenText.Start != accumulatedStart + accumulatedLength)
                    break;

                if (token.IsWhiteSpace && (state.LineBreakCommand == null || !token.IsNonBreakingSpace))
                {
                    lineBreakPossible = true;
                    state.LineBreakCommand = output.Count;
                    state.LineBreakOffset = accumulatedLength + token.Text.Length - 1;
                }

                width = width + tokenSize.Width;
                height = Math.Max(height, tokenSize.Height);
                accumulatedLength = accumulatedLength + tokenText.Length;
                accumulatedCount++;

                state.AdvanceLineToNextCommand(tokenSize.Width, tokenSize.Height, 1, tokenText.Length);
                state.ParserTokenOffset = 0;
                state.LineLengthInCommands--;

                index++;
            }

            if (lineBreakPossible)
            {
                var preLineBreakTextStart = accumulatedStart;
                var preLineBreakTextLength = state.LineBreakOffset.Value;
                var preLineBreakText = CreateStringSegmentFromCurrentSource(preLineBreakTextStart, preLineBreakTextLength);
                var preLineBreakSize = (preLineBreakText.Length == 0) ? Size2.Zero :
                    MeasureToken(font, TextParserTokenType.Text, preLineBreakText);
                state.BrokenTextSizeBeforeBreak = preLineBreakSize;

                var postLineBreakStart = accumulatedStart + (state.LineBreakOffset.Value + 1);
                var postLineBreakLength = accumulatedLength - (state.LineBreakOffset.Value + 1);
                var postLineBreakText = CreateStringSegmentFromCurrentSource(postLineBreakStart, postLineBreakLength);
                var postLineBreakSize = (postLineBreakText.Length == 0) ? Size2.Zero :
                    MeasureToken(font, TextParserTokenType.Text, postLineBreakText, GetNextTextToken(input, index - 1));
                state.BrokenTextSizeAfterBreak = postLineBreakSize;
            }

            var bounds = new Rectangle(x, y, width, height);
            EmitTextIfNecessary(output, accumulatedStart, accumulatedLength, ref bounds, ref state);

            if (lineOverflow && !state.ReplaceLastBreakingSpaceWithLineBreak(output, ref settings))
            {
                var overflowingToken = input[index];
                if (overflowingToken.IsWhiteSpace && !overflowingToken.IsNonBreakingSpace)
                {
                    output.WriteLineBreak(new TextLayoutLineBreakCommand(1));
                    state.AdvanceLineToNextCommand(0, 0, 1, 1, isLineBreak: true);
                    state.AdvanceLayoutToNextLine(output, ref settings);

                    if (overflowingToken.Text.Length > 1)
                    {
                        state.ParserTokenOffset = 1;
                    }
                    else
                    {
                        index++;
                    }
                    return true;
                }

                if (!GetFittedSubstring(font, availableWidth, ref tokenText, ref tokenSize, ref state, hyphenate) && state.LineWidth == 0)
                    return false;

                var overflowingTokenBounds = (tokenText.Length == 0) ? Rectangle.Empty :
                    new Rectangle(state.PositionX, state.PositionY, tokenSize.Width, tokenSize.Height);

                var overflowingTextEmitted = EmitTextIfNecessary(output, tokenText.Start, tokenText.Length, ref overflowingTokenBounds, ref state);
                if (overflowingTextEmitted)
                {
                    state.AdvanceLineToNextCommand(tokenSize.Width, tokenSize.Height, 0, tokenText.Length);
                    if (hyphenate)
                    {
                        output.WriteHyphen();
                        state.AdvanceLineToNextCommand(0, 0, 1, 0);
                    }
                }

                state.ParserTokenOffset = (state.ParserTokenOffset ?? 0) + tokenText.Length;
                state.AdvanceLayoutToNextLine(output, ref settings);
            }

            return true;
        }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PopGlyphShader"/>.
 /// </summary>
 private void ProcessPopGlyphShaderToken(TextLayoutCommandStream output,
     ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     output.WritePopGlyphShader();
     state.AdvanceLineToNextCommand();
     index++;
 }
        protected override bool TryCalculateStateName(out string stateName)
        {
            try
            {
                // TODO: Get args
                var view = ApplicationView.GetForCurrentView();
                var bounds = (Window.Current != null ? Window.Current.Bounds : Rect.Empty);
                LayoutState layout = new LayoutState();

                // See if we have event subscribers first
                if (LayoutStateCalculating != null)
                {
                    // Wrap in event args
                    var e = new LayoutStateCalculatingEventArgs(layout);

                    // Raise the event
                    LayoutStateCalculating(this, e);

                    // If the calculation was canceled, bail
                    if (e.IsCanceled)
                    {
                        stateName = null;
                        return false;
                    }

                    // If the calculation was handled, process
                    if (e.IsHandled)
                    {
                        stateName = e.StateName;
                        return true;
                    }
                }

                // No subscribers or none handled it. Pass to override.
                return TryCalculateStateName(layout, out stateName);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Could not calculate state name. {0}", ex.Message);
                stateName = null;
                return false;
            }
        }
Example #48
0
 /// <summary>
 /// Determines if the rule applies to the specified layout.
 /// </summary>
 /// <param name="layout">
 /// The <see cref="LayoutState"/> instance to test.
 /// </param>
 /// <returns>
 /// <c>true</c> if the rule applies to the specified layout; otherwise <c>false</c>.
 /// </returns>
 public abstract bool Applies(LayoutState layout);
Example #49
0
        //*************************************************************************
        //  Constructor: NodeXLControl()
        //
        /// <summary>
        /// Initializes a new instance of the <see cref="NodeXLControl" /> class.
        /// </summary>
        //*************************************************************************
        public NodeXLControl()
        {
            m_oGraph = new Graph();
            m_oGraphDrawer = new GraphDrawer(this);

            m_oAsyncLayout = new FruchtermanReingoldLayout();
            OnNewLayout(m_oAsyncLayout);

            m_oLastLayoutContext =
            new LayoutContext(System.Drawing.Rectangle.Empty);

            m_oLastGraphDrawingContext = null;

            m_eLayoutState = LayoutState.Stable;

            m_eMouseMode = MouseMode.Select;
            m_bMouseAlsoSelectsIncidentEdges = true;
            m_bAllowVertexDrag = true;

            m_oVerticesBeingDragged = null;
            m_oMarqueeBeingDragged = null;
            m_oTranslationBeingDragged = null;

            m_oSelectedVertices = new HashSet<IVertex>();
            m_oSelectedEdges = new HashSet<IEdge>();
            m_oCollapsedGroups = new Dictionary<String, IVertex>();
            m_oDoubleClickedVertexInfo = null;

            m_bShowVertexToolTips = false;
            m_oLastMouseMoveLocation = new Point(-1, -1);

            // Create a helper object for displaying vertex tooltips.

            CreateVertexToolTipTracker();
            m_oVertexToolTip = null;

            m_bGraphZoomCentered = false;

            this.AddLogicalChild(m_oGraphDrawer.VisualCollection);

            CreateTransforms();

            // Prevent a focus rectangle from being drawn around the control when
            // it captures keyboard focus.  The focus rectangle does not behave
            // properly when the layout and render transforms are applied --
            // sometimes the rectangle disappears, and sometimes it gets magnified
            // by the render layout.

            this.FocusVisualStyle = null;

            // AssertValid();
        }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PushFont"/>.
 /// </summary>
 private void ProcessPushFontToken(TextLayoutCommandStream output,
     ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     var pushedFont = default(SpriteFont);
     var pushedFontIndex = RegisterFontWithCommandStream(output, token.Text, out pushedFont);
     output.WritePushFont(new TextLayoutFontCommand(pushedFontIndex));
     state.AdvanceLineToNextCommand();
     PushFont(pushedFont);
     index++;
 }
Example #51
0
        //*************************************************************************
        //  Method: OnRenderSizeChanged()
        //
        /// <summary>
        /// Raises the SizeChanged event, using the specified information as part
        /// of the eventual event data.
        /// </summary>
        ///
        /// <param name="sizeInfo">
        /// Details of the old and new size involved in the change.
        /// </param>
        //*************************************************************************
        protected override void OnRenderSizeChanged(
            SizeChangedInfo sizeInfo
            )
        {
            AssertValid();

            // Note that this method gets called when the layout transform is
            // modified, not just when the control is resized.

            #if TRACE_LAYOUT_AND_DRAW
            Debug.WriteLine("NodeXLControl: OnRenderSizeChanged(),"
            + " sizeInfo.NewSize = " + sizeInfo.NewSize);
            #endif

            base.OnRenderSizeChanged(sizeInfo);

            // The next block is an ugly workaround for the following problem.
            //
            // The center of the graph zoom should initially be placed at the
            // center of the control, so that if the zoom is first increased via
            // the GraphZoom property, the control will zoom from the center.  (If
            // the zoom is first increased via the mouse wheel, the zoom center
            // will be placed at the mouse location.)  This can't be done until the
            // final control size is known.
            //
            // A Loaded handler would be a logical place to do this, but the final
            // control size is not always available during the Loaded event,
            // depending on how the control is anchored or docked within its
            // parent.
            //
            // A workaround would be to set this control's RenderTransformOrigin to
            // (0.5, 0.5) when the transforms are first created, but the control's
            // transforms are designed to work with this property left at its
            // default value of the origin.
            //
            // TODO: Fix this!

            if (!m_bGraphZoomCentered && this.IsLoaded)
            {
            m_bGraphZoomCentered = true;
            CenterGraphZoom();
            }

            if (m_eLayoutState != LayoutState.Stable)
            {
            // The new size will be detected by the LayoutState.LayoutCompleted
            // case in OnRender().

            return;
            }

            // Make sure the size has actually changed.  This event fires once at
            // startup and should be ignored then.

            System.Drawing.Rectangle oLastGraphRectangle =
            m_oLastLayoutContext.GraphRectangle;

            System.Drawing.Rectangle oNewGraphRectangle =
            WpfGraphicsUtil.RectToRectangle( new Rect(sizeInfo.NewSize) );

            if (
            oLastGraphRectangle.Width != oNewGraphRectangle.Width
            ||
            oLastGraphRectangle.Height != oNewGraphRectangle.Height
            )
            {
            m_eLayoutState = LayoutState.TransformRequired;
            LayOutOrDrawGraph();

            // For the case where this method was called because the layout
            // transform was modified, make sure the graph wasn't moved too
            // far by the transform.

            LimitTranslation();
            }
        }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.ToggleItalic"/>.
 /// </summary>
 private void ProcessToggleItalicToken(TextLayoutCommandStream output, ref Boolean italic,
     ref LayoutState state, ref Int32 index)
 {
     output.WriteToggleItalic();
     state.AdvanceLineToNextCommand();
     italic = !italic;
     index++;
 }
Example #53
0
        //*************************************************************************
        //  Method: AsyncLayout_LayOutGraphIterationCompleted()
        //
        /// <summary>
        /// Handles the LayOutGraphIterationCompleted event on the m_oAsyncLayout
        /// object.
        /// </summary>
        ///
        /// <param name="oSender">
        /// Standard event argument.
        /// </param>
        ///
        /// <param name="oEventArgs">
        /// Standard event argument.
        /// </param>
        //*************************************************************************
        protected void AsyncLayout_LayOutGraphIterationCompleted(
            Object oSender,
            EventArgs oEventArgs
            )
        {
            AssertValid();

            #if TRACE_LAYOUT_AND_DRAW
            Debug.WriteLine("NodeXLControl:"
            + " AsyncLayout_LayOutGraphIterationCompleted()");
            #endif

            // Note that the worker thread on which the layout is occurring blocks
            // until this event handler returns.  Therefore, it is okay for
            // LayOutOrDrawGraph() to use the graph's vertex locations and
            // metadata, even though the worker thread modifies that same data
            // while the worker thread is running.

            m_eLayoutState = LayoutState.LayoutIterationCompleted;
            LayOutOrDrawGraph();
        }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.ToggleBold"/>.
 /// </summary>
 private void ProcessToggleBoldToken(TextLayoutCommandStream output, ref Boolean bold,
     ref LayoutState state, ref Int32 index)
 {
     output.WriteToggleBold();
     state.AdvanceLineToNextCommand();
     bold = !bold;
     index++;
 }
Example #55
0
        //*************************************************************************
        //  Method: DrawGraph()
        //
        /// <summary>
        /// Draws the graph after optionally laying it out.
        /// </summary>
        ///
        /// <param name="layOutGraphFirst">
        /// If true, the graph is laid out again before it is drawn.  If false, the
        /// graph is drawn using the current vertex locations.
        /// </param>
        ///
        /// <remarks>
        /// Graph layout occurs asynchronously after this method is called with a
        /// <paramref name="layOutGraphFirst" /> argument of true.  See the <see
        /// cref="IsLayingOutGraph" /> property for details.
        ///
        /// <para>
        /// If the graph is currently being laid out, this method does nothing.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        public void DrawGraph(
            Boolean layOutGraphFirst
            )
        {
            AssertValid();

            if (this.IsLayingOutGraph)
            {
            return;
            }

            if (layOutGraphFirst)
            {
            m_eLayoutState = LayoutState.LayoutRequired;

            // Don't just call LayOutOrDrawGraph() here, as is done in the else
            // clause.  Assuming that this method is being called at
            // application startup time, the control has not yet gone through
            // its measure cycle.  If LayOutOrDrawGraph() were called instead
            // of InvalidateVisual(), the actual width and height of this
            // control would be zero when the layout begins, and the graph
            // wouldn't get laid out properly.

            this.InvalidateVisual();
            }
            else
            {
            m_eLayoutState = LayoutState.LayoutCompleted;
            LayOutOrDrawGraph();
            }
        }
        /// <summary>
        /// Processes a parser token with type <see cref="TextParserTokenType.Icon"/>.
        /// </summary>
        private Boolean ProcessIconToken(TextLayoutCommandStream output,
            ref TextParserToken token, ref LayoutState state, ref TextLayoutSettings settings, ref Int32 index)
        {
            var icon = default(TextIconInfo);
            var iconIndex = RegisterIconWithCommandStream(output, token.Text, out icon);
            var iconSize = MeasureToken(null, token.TokenType, token.Text);

            if (state.PositionX + iconSize.Width > (settings.Width ?? Int32.MaxValue))
                state.AdvanceLayoutToNextLine(output, ref settings);

            if (state.PositionY + iconSize.Height > (settings.Height ?? Int32.MaxValue))
                return false;

            output.WriteIcon(new TextLayoutIconCommand(iconIndex, state.PositionX, state.PositionY, (Int16)iconSize.Width, (Int16)iconSize.Height));
            state.AdvanceLineToNextCommand(iconSize.Width, iconSize.Height, 1, 1);
            index++;

            return true;
        }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.Text"/>.
 /// </summary>
 private Boolean ProcessTextToken(TextParserTokenStream input, TextLayoutCommandStream output, SpriteFontFace currentFontFace,
     ref TextParserToken token, ref LayoutState state, ref TextLayoutSettings settings, ref Int32 index)
 {
     if (token.IsNewLine)
     {
         state.AdvanceLayoutToNextLineWithBreak(output, token.SourceLength, ref settings);
         index++;
     }
     else
     {
         if (!AccumulateText(input, output, currentFontFace, ref index, ref state, ref settings))
             return false;
     }
     return true;
 }
        /// <summary>
        /// Calculates a layout for the specified text.
        /// </summary>
        /// <param name="input">The parsed text which will be laid out according to the specified settings.</param>
        /// <param name="output">The layout command stream which will be populated with commands by this operation.</param>
        /// <param name="settings">A <see cref="TextLayoutSettings"/> structure which contains the settings for this operation.</param>
        public void CalculateLayout(TextParserTokenStream input, TextLayoutCommandStream output, TextLayoutSettings settings)
        {
            Contract.Require(input, "input");
            Contract.Require(output, "output");

            if (settings.Font == null)
                throw new ArgumentException(UltravioletStrings.InvalidLayoutSettings);

            var state = new LayoutState() { LineInfoCommandIndex = 1 };

            output.Clear();
            output.SourceText = input.SourceText;
            output.ParserOptions = input.ParserOptions;

            var acquiredPointers = !output.HasAcquiredPointers;
            if (acquiredPointers)
                output.AcquirePointers();

            output.WriteBlockInfo();
            output.WriteLineInfo();

            var bold = (settings.Style == SpriteFontStyle.Bold || settings.Style == SpriteFontStyle.BoldItalic);
            var italic = (settings.Style == SpriteFontStyle.Italic || settings.Style == SpriteFontStyle.BoldItalic);

            if (settings.InitialLayoutStyle != null)
                PrepareInitialStyle(output, ref bold, ref italic, ref settings);

            var currentFont = settings.Font;
            var currentFontFace = settings.Font.GetFace(SpriteFontStyle.Regular);

            var index = 0;
            var processing = true;

            while (index < input.Count && processing)
            {
                if (state.PositionY >= (settings.Height ?? Int32.MaxValue))
                    break;

                var token = input[index];

                currentFontFace = default(SpriteFontFace);
                currentFont = GetCurrentFont(ref settings, bold, italic, out currentFontFace);

                switch (token.TokenType)
                {
                    case TextParserTokenType.Text:
                        processing = ProcessTextToken(input, output, currentFontFace, ref token, ref state, ref settings, ref index);
                        break;

                    case TextParserTokenType.Icon:
                        processing = ProcessIconToken(output, ref token, ref state, ref settings, ref index);
                        break;

                    case TextParserTokenType.ToggleBold:
                        ProcessToggleBoldToken(output, ref bold, ref state, ref index);
                        break;

                    case TextParserTokenType.ToggleItalic:
                        ProcessToggleItalicToken(output, ref italic, ref state, ref index);
                        break;

                    case TextParserTokenType.PushFont:
                        ProcessPushFontToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PushColor:
                        ProcessPushColorToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PushStyle:
                        ProcessPushStyleToken(output, ref bold, ref italic, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PushGlyphShader:
                        ProcessPushGlyphShaderToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopFont:
                        ProcessPopFontToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopColor:
                        ProcessPopColorToken(output, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopStyle:
                        ProcessPopStyleToken(output, ref bold, ref italic, ref token, ref state, ref index);
                        break;

                    case TextParserTokenType.PopGlyphShader:
                        ProcessPopGlyphShaderToken(output, ref token, ref state, ref index);
                        break;

                    default:
                        throw new InvalidOperationException(UltravioletStrings.UnrecognizedLayoutCommand.Format(token.TokenType));
                }
            }

            state.FinalizeLayout(output, ref settings);

            if (acquiredPointers)
                output.ReleasePointers();

            ClearLayoutStacks();
        }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PushGlyphShader"/>.
 /// </summary>
 private void ProcessPushGlyphShaderToken(TextLayoutCommandStream output,
     ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     var pushedGlyphShader = default(GlyphShader);
     var pushedGlyphShaderIndex = RegisterGlyphShaderWithCommandStream(output, token.Text, out pushedGlyphShader);
     output.WritePushGlyphShader(new TextLayoutGlyphShaderCommand(pushedGlyphShaderIndex));
     state.AdvanceLineToNextCommand();
     index++;
 }
 /// <summary>
 /// Processes a parser token with type <see cref="TextParserTokenType.PushStyle"/>.
 /// </summary>
 private void ProcessPushStyleToken(TextLayoutCommandStream output, ref Boolean bold, ref Boolean italic,
     ref TextParserToken token, ref LayoutState state, ref Int32 index)
 {
     var pushedStyle = default(TextStyle);
     var pushedStyleIndex = RegisterStyleWithCommandStream(output, token.Text, out pushedStyle);
     output.WritePushStyle(new TextLayoutStyleCommand(pushedStyleIndex));
     state.AdvanceLineToNextCommand();
     PushStyle(pushedStyle, ref bold, ref italic);
     index++;
 }