Example #1
0
        /// <summary>
        /// Draws the vertical cursor line
        /// </summary>
        protected virtual void PaintCursor(IGraphics gfx)
        {
            if (this.cursorPaintPos == null)
            {
                return;
            }
            if (this.EditorState.CursorBlink.PaintCursor == false)
            {
                return;
            }

            var height = (int)(Math.Max(this.editorContext.EditorConfig.FontTextNode.Height, this.editorContext.EditorConfig.FontNodeName.Height) * 1.6);
            var margin = height / 5;

            gfx.AddJob(new JobDrawLine
            {
                Batchable = true,
                Layer     = GfxJob.Layers.Cursor,
                Color     = Color.Black,
                LineWidth = 2,
                X1        = cursorPaintPos.X,
                Y1        = cursorPaintPos.Y + margin,
                X2        = cursorPaintPos.X,
                Y2        = cursorPaintPos.Y + height - margin
            });
        }
 internal static void DrawNodeBodyByCoordinates(GfxJob.Layers layer, int x1, int y1, int x2, int y2, int cornerRadius, Color fillColor, Color borderColor, IGraphics gfx)
 {
     gfx.AddJob(new JobDrawPolygon
     {
         Batchable   = true,
         Layer       = layer,
         FillColor   = fillColor == Color.Transparent ? null : fillColor,
         BorderColor = borderColor == Color.Transparent ? null : borderColor,
         BorderWidth = 1,
         Points      = new[] {
             new Point(x1 + cornerRadius, y1),
             new Point(x2 - cornerRadius, y1),
             new Point(x2, y1 + cornerRadius),
             new Point(x2, y2 - cornerRadius),
             new Point(x2 - cornerRadius, y2),
             new Point(x1 + cornerRadius, y2),
             new Point(x1, y2 - cornerRadius),
             new Point(x1, y1 + cornerRadius)
         }
     });
 }
        /// <summary>
        /// Draws the attributes
        /// </summary>
        private async Task <PaintContext> PaintAttributes(PaintContext paintContext, string attributesString, bool isSelected, IGraphics gfx)
        {
            paintContext = paintContext.Clone();

            if (string.IsNullOrWhiteSpace(attributesString))
            {
                return(paintContext);
            }

            var attributeWidth = await this.GetAttributeTextWidth(attributesString, gfx);

            // draw a frame around the attributes
            StandardNodeTagPaint.DrawNodeBodyBySize(GfxJob.Layers.AttributeBackground,
                                                    paintContext.PaintPosX, paintContext.PaintPosY + this.dimensions.AttributeMarginY,
                                                    attributeWidth, this.dimensions.AttributeHeight, 2,
                                                    isSelected ? this.config.ColorNodeAttributeBackground.InvertedColor : this.config.ColorNodeAttributeBackground,
                                                    isSelected ? this.config.ColorNodeTagBorder.InvertedColor : this.config.ColorNodeTagBorder,
                                                    gfx);

            // Draw attributes
            gfx.AddJob(new JobDrawString
            {
                Batchable = false,
                Layer     = GfxJob.Layers.Text,
                Text      = attributesString.ToString(),
                Color     = isSelected ? this.config.ColorText.InvertedColor : this.config.ColorText,
                X         = paintContext.PaintPosX,
                Y         = paintContext.PaintPosY + this.dimensions.AttributeMarginY + this.dimensions.AttributeInnerMarginY + 1,
                Font      = config.FontNodeAttribute
            });

            // Set character cursor behind the attributes
            paintContext.PaintPosX += attributeWidth + this.dimensions.InnerMarginX;

            return(paintContext);
        }
        protected override async Task <PaintContext> PaintInternal(PaintContext paintContext, string attributesString, bool isSelected, IGraphics gfx)
        {
            var esteemedWidth = this.nodeNameTextWidth + this.dimensions.InnerMarginX * 3;

            if (paintContext.PaintPosX + esteemedWidth > paintContext.LimitRight)
            {
                paintContext.HeightActualRow = Math.Max(paintContext.HeightActualRow, config.MinLineHeight);
                paintContext.PaintPosX       = paintContext.LimitLeft + this.config.ChildIndentX;
                paintContext.PaintPosY      += paintContext.HeightActualRow;
                paintContext.HeightActualRow = config.MinLineHeight;
            }

            var startX = paintContext.PaintPosX;
            var startY = paintContext.PaintPosY;

            paintContext.PaintPosX += this.dimensions.InnerMarginX;  // margin to left border

            // draw node name
            gfx.AddJob(new JobDrawString
            {
                Batchable = false,
                Layer     = GfxJob.Layers.Text,
                Text      = this.node.Name,
                Color     = isSelected ? this.config.ColorText.InvertedColor : this.config.ColorText,
                X         = paintContext.PaintPosX,
                Y         = paintContext.PaintPosY + this.config.InnerMarginY,
                Font      = this.config.FontNodeName
            });

            paintContext.PaintPosX += nodeNameTextWidth + this.dimensions.InnerMarginX;

            // draw the attributes
            paintContext = await this.PaintAttributes(paintContext, attributesString, isSelected, gfx);

            // standard distance + one pixel to the right, otherwise we draw on the frame line
            paintContext.PaintPosX += 1;

            var borderWidth = paintContext.PaintPosX - startX;

            StandardNodeTagPaint.DrawNodeBodyBySize(
                GfxJob.Layers.TagBackground,
                startX, paintContext.PaintPosY,
                borderWidth, this.config.TagHeight,
                this.dimensions.CornerRadius,
                isSelected ? this.dimensions.BackgroundColor.InvertedColor : this.dimensions.BackgroundColor,
                isSelected ? this.config.ColorNodeTagBorder.InvertedColor : this.config.ColorNodeTagBorder,
                gfx);

            // if necessary draw the continuing arrow at the end of the frame
            if (this.isClosingTagVisible)
            {
                var point1 = new Point(paintContext.PaintPosX, paintContext.PaintPosY + this.config.InnerMarginY);
                var point2 = new Point(paintContext.PaintPosX + this.dimensions.InnerMarginX, paintContext.PaintPosY + this.config.TagHeight / 2);
                var point3 = new Point(paintContext.PaintPosX, paintContext.PaintPosY + this.config.TagHeight - this.config.InnerMarginY);
                gfx.AddJob(new JobDrawPolygon
                {
                    Batchable = true,
                    Layer     = GfxJob.Layers.TagBorder,
                    FillColor = isSelected ? this.config.ColorNodeTagBorder.InvertedColor : this.config.ColorNodeTagBorder,
                    Points    = new[] { point1, point2, point3 }
                });

                // Remember the right arrow area
                this.AreaArrow          = new Rectangle(paintContext.PaintPosX, paintContext.PaintPosY, this.dimensions.InnerMarginX, this.config.TagHeight);
                paintContext.PaintPosX += this.dimensions.InnerMarginX;
            }
            else
            {
                this.AreaArrow = null;
            }

            paintContext.HeightActualRow = System.Math.Max(paintContext.HeightActualRow, this.config.MinLineHeight); // See how high the current line is

            // Remember where the mouse areas are
            this.AreaTag = new Rectangle(startX - 2, startY, paintContext.PaintPosX + 2 - (startX), this.config.TagHeight);

            paintContext.FoundMaxX = System.Math.Max(paintContext.FoundMaxX, paintContext.PaintPosX);

            this.lastPaintContextResult = paintContext.Clone();
            return(paintContext.Clone());
        }
Example #5
0
        protected override async Task <PaintContext> PaintInternal(PaintContext paintContext, bool cursorBlinkOn, XmlCursor cursor, IGraphics gfx, PaintModes paintMode, int depth)
        {
            paintContext.PaintPosX += 3;

            var actualText      = ToolboxXml.TextFromNodeCleaned(XmlNode);
            var selection       = this.CalculateStartAndEndOfSelection(actualText, cursor);
            var actualPaintData = LastPaintingDataText.CalculateActualPaintData(paintContext, cursorBlinkOn, this.XmlNode, actualText, this.Config.FontTextNode.Height, cursor, selection.Start, selection.Length);

            var alreadyUnpainted = false;

            switch (paintMode)
            {
            case PaintModes.ForcePaintNoUnPaintNeeded:
                alreadyUnpainted   = true;
                this.lastPaintData = null;
                break;

            case PaintModes.ForcePaintAndUnpaintBefore:
                alreadyUnpainted   = true;
                this.lastPaintData = null;
                this.UnPaint(gfx);
                break;

            case PaintModes.OnlyPaintWhenChanged:
                if (!actualPaintData.Equals(lastPaintData))
                {
                    this.lastPaintData = null;
                }
                break;
            }

            if (this.lastPaintData != null && this.lastPaintContextResult != null)
            {
                return(lastPaintContextResult.Clone());
            }

            this.lastPaintData  = actualPaintData;
            this.cursorPaintPos = null;

            if (lastFontHeight != this.Config.FontTextNode.Height)
            {
                lastFontHeight          = this.Config.FontTextNode.Height;
                lastCalculatedFontWidth = await this.xmlEditor.NativePlatform.Gfx.MeasureDisplayStringWidthAsync("W", this.Config.FontTextNode);
            }

            paintContext.HeightActualRow = Math.Max(paintContext.HeightActualRow, this.Config.MinLineHeight);

            int marginY = (paintContext.HeightActualRow - this.Config.FontTextNode.Height) / 2;

            const int charMarginRight = 2;

            var textPartsRaw = TextSplitHelper.SplitText(
                text: actualText,
                invertStart: selection.Start,
                invertLength: selection.Length,
                maxLength: (int)((paintContext.LimitRight - paintContext.LimitLeft) / lastCalculatedFontWidth) - charMarginRight,
                maxLengthFirstLine: (int)((paintContext.LimitRight - paintContext.PaintPosX) / lastCalculatedFontWidth) - charMarginRight)
                               .ToArray();

            var newTextParts = this.GetTextLinesFromTextParts(textPartsRaw, paintContext, cursorBlinkOn, cursor, lastCalculatedFontWidth).ToArray();

            // Now draw the content, if necessary wrap to several text parts and lines
            for (int i = 0; i < newTextParts.Length; i++)
            {
                var newPart = newTextParts[i];
                var oldPart = (this.textParts != null && i < this.textParts.Length) ? this.textParts[i] : null;
                if (alreadyUnpainted == false && newPart.Equals(oldPart))
                {
                    // no need to paint the text part again
                }
                else
                {
                    // draw the inverted background
                    if (!alreadyUnpainted && oldPart != null)
                    {
                        gfx.UnPaintRectangle(oldPart.Rectangle);
                    }

                    if (newPart.Inverted || this.colorBackground != this.Config.ColorBackground)
                    {
                        gfx.AddJob(new JobDrawRectangle
                        {
                            Batchable = true,
                            Layer     = GfxJob.Layers.TagBackground,
                            Rectangle = newPart.Rectangle,
                            FillColor = newPart.Inverted ? this.colorBackground.InvertedColor : this.colorBackground,
                        });
                    }

                    // draw the text
                    gfx.AddJob(new JobDrawString
                    {
                        Batchable = false,
                        Layer     = GfxJob.Layers.Text,
                        Text      = newPart.Text,
                        Color     = newPart.Inverted ? this.colorText.InvertedColor : this.colorText,
                        X         = newPart.Rectangle.X,
                        Y         = newPart.Rectangle.Y + marginY,
                        Font      = Config.FontTextNode
                    });;
                }
                paintContext.PaintPosY = newPart.Rectangle.Y;
                paintContext.PaintPosX = newPart.Rectangle.X + newPart.Rectangle.Width;
                paintContext.FoundMaxX = Math.Max(paintContext.FoundMaxX, paintContext.PaintPosX);
            }

            if (this.textParts != null) // unpaint old text parts out of new parts range
            {
                for (int i = newTextParts.Length; i < this.textParts.Length; i++)
                {
                    gfx.UnPaintRectangle(this.textParts[i].Rectangle);
                }
            }

            this.textParts = newTextParts;

            paintContext.PaintPosX += 2;

            this.lastPaintContextResult = paintContext.Clone();
            return(paintContext.Clone());
        }
        protected override async Task <PaintContext> PaintInternal(PaintContext paintContext, string attributesString, bool isSelected, IGraphics gfx)
        {
            var startX = paintContext.PaintPosX;

            var esteemedWidth = this.nodeNameTextWidth + this.dimensions.InnerMarginX * 3;

            if (paintContext.PaintPosX + esteemedWidth > paintContext.LimitRight)
            {
                paintContext.HeightActualRow = Math.Max(paintContext.HeightActualRow, config.MinLineHeight);
                paintContext.PaintPosX       = paintContext.LimitLeft + this.config.ChildIndentX;
                paintContext.PaintPosY      += paintContext.HeightActualRow;
                paintContext.HeightActualRow = config.MinLineHeight;
            }

            // draw an arrow to the left in front of the node frame
            // arrow to left
            Point point1 = new Point(paintContext.PaintPosX + this.dimensions.InnerMarginX, paintContext.PaintPosY + this.config.InnerMarginY);
            Point point2 = new Point(paintContext.PaintPosX + this.dimensions.InnerMarginX, paintContext.PaintPosY + this.config.TagHeight - this.config.InnerMarginY);
            Point point3 = new Point(paintContext.PaintPosX, paintContext.PaintPosY + this.config.TagHeight / 2);

            gfx.AddJob(new JobDrawPolygon
            {
                Batchable = true,
                Layer     = GfxJob.Layers.TagBorder,
                FillColor = isSelected ? this.config.ColorNodeTagBorder.InvertedColor : this.config.ColorNodeTagBorder,
                Points    = new[] { point1, point2, point3 }
            });

            // Remember the right arrow area
            this.AreaArrow          = new Rectangle(paintContext.PaintPosX, paintContext.PaintPosY, this.dimensions.InnerMarginX, this.config.TagHeight);
            paintContext.PaintPosX += this.dimensions.InnerMarginX + 1; // Place drawing cursor behind the arrow

            // ## Draw frame for closing node ###
            StandardNodeTagPaint.DrawNodeBodyBySize(GfxJob.Layers.TagBackground,
                                                    paintContext.PaintPosX, paintContext.PaintPosY,
                                                    this.nodeNameTextWidth + this.dimensions.InnerMarginX * 2, this.config.TagHeight, this.dimensions.CornerRadius,
                                                    isSelected ? this.dimensions.BackgroundColor.InvertedColor : this.dimensions.BackgroundColor,
                                                    isSelected ? this.config.ColorNodeTagBorder.InvertedColor : this.config.ColorNodeTagBorder,
                                                    gfx);

            paintContext.PaintPosX += this.dimensions.InnerMarginX; // Distance between frame and font

            //  ## Draw name for closing node ###
            gfx.AddJob(new JobDrawString
            {
                Batchable = false,
                Layer     = GfxJob.Layers.Text,
                Text      = this.node.Name,
                Color     = isSelected ? this.config.ColorText.InvertedColor : this.config.ColorText,
                X         = paintContext.PaintPosX,
                Y         = paintContext.PaintPosY + this.config.InnerMarginY,
                Font      = this.config.FontNodeName
            });

            paintContext.PaintPosX += this.nodeNameTextWidth + this.dimensions.InnerMarginX; // Distance between font and frame

            // One pixel to the right, because otherwise we draw on the frame line and the cursor flashes on the frame
            paintContext.PaintPosX++;

            // Remember where the mouse areas are
            this.AreaTag = new Rectangle(startX, paintContext.PaintPosY, paintContext.PaintPosX - startX, this.config.TagHeight);

            paintContext.FoundMaxX = System.Math.Max(paintContext.FoundMaxX, paintContext.PaintPosX);

            this.lastPaintContextResult = paintContext.Clone();
            await Task.CompletedTask;

            return(paintContext);
        }
Example #7
0
        protected async Task <PaintContext> PaintSubNodes(PaintContext paintContext, bool cursorBlinkOn, XmlCursor cursor, IGraphics gfx, PaintModes paintMode, int depth)
        {
            if (this.XmlNode == null)
            {
                throw new ApplicationException("PaintSubNodes:xmlNode is null");
            }

            var childPaintContext = paintContext.Clone();

            childPaintContext.LimitLeft = paintContext.LimitLeft + this.Config.ChildIndentX;

            for (int childLauf = 0; childLauf < this.XmlNode.ChildNodes.Count; childLauf++)
            {
                // At this point, the ChildControl object should contain the corresponding instance of the XMLElement control for the current XMLChildNode
                var childElement = (XmlElement)childElements[childLauf];
                var displayType  = this.XmlRules.DisplayType(childElement.XmlNode);
                switch (displayType)
                {
                case DisplayTypes.OwnRow:

                    // This child element starts a new row and is then drawn in this row

                    // start new row
                    childPaintContext.LimitLeft       = paintContext.LimitLeft + this.Config.ChildIndentX;
                    childPaintContext.PaintPosX       = childPaintContext.LimitLeft;
                    childPaintContext.PaintPosY      += this.Config.SpaceYBetweenLines + paintContext.HeightActualRow; // line break
                    childPaintContext.HeightActualRow = 0;                                                             // no element in this line yet, therefore Height 0
                                                                                                                       // Set X-cursor to the start of the new line
                                                                                                                       // line down and then right into the ChildElement
                                                                                                                       // Line down
                    bool paintLines = false;
                    if (paintLines)
                    {
                        gfx.AddJob(new JobDrawLine
                        {
                            Layer     = GfxJob.Layers.TagBorder,
                            Batchable = true,
                            Color     = Color.LightGray,
                            X1        = paintContext.LimitLeft,
                            Y1        = paintContext.PaintPosY + this.Config.MinLineHeight / 2,
                            X2        = paintContext.LimitLeft,
                            Y2        = childPaintContext.PaintPosY + this.Config.MinLineHeight / 2
                        });

                        // Line to the right with arrow on ChildElement
                        gfx.AddJob(new JobDrawLine
                        {
                            Layer     = GfxJob.Layers.TagBorder,
                            Batchable = true,
                            Color     = Color.LightGray,
                            X1        = paintContext.LimitLeft,
                            Y1        = childPaintContext.PaintPosY + this.Config.MinLineHeight / 2,
                            X2        = childPaintContext.LimitLeft,
                            Y2        = childPaintContext.PaintPosY + this.Config.MinLineHeight / 2
                        });
                    }

                    childPaintContext = await childElement.Paint(childPaintContext, cursorBlinkOn, cursor, gfx, paintMode, depth + 1);

                    break;

                case DisplayTypes.FloatingElement:
                    // This child is a floating element; it inserts itself into the same line as the previous element and does not start a new line unless the current line is already too long
                    if (childPaintContext.PaintPosX > paintContext.LimitRight)     //  If the row is already too long
                    {
                        // to next row
                        paintContext.PaintPosY      += paintContext.HeightActualRow + this.Config.SpaceYBetweenLines;
                        paintContext.HeightActualRow = 0;
                        paintContext.PaintPosX       = paintContext.RowStartX;
                    }
                    else     // fits into this line
                    {
                        // set the child to the right of it
                    }
                    childPaintContext = await childElement.Paint(childPaintContext, cursorBlinkOn, cursor, gfx, paintMode, depth + 1);

                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(displayType) + ":" + displayType.ToString());
                }
                paintContext.FoundMaxX = childPaintContext.FoundMaxX;
                paintContext.PaintPosX = childPaintContext.PaintPosX;
                paintContext.PaintPosY = childPaintContext.PaintPosY;
            }

            // If we have more ChildControls than XMLChildNodes, then delete them at the end of the ChildControl list
            while (this.XmlNode.ChildNodes.Count < childElements.Count)
            {
                var deleteChildElement = childElements[childElements.Count - 1];
                deleteChildElement.UnPaint(gfx);
                childElements.Remove(childElements[childElements.Count - 1]);
                deleteChildElement.Dispose();
            }
            return(paintContext);
        }