protected async Task Paint(int limitRight, bool forceRepaint, bool isBecauseOfCursorBlink)
        {
            var gfx = this.NativePlatform.Gfx;

            gfx.DeleteAllPaintJobs();

            if (this.EditorState.RootElement == null)
            {
                gfx.AddJob(new JobClear());
                await gfx.PaintJobs(EditorConfig.ColorBackground);
            }
            else
            {
                var paintMode = XmlElement.PaintModes.OnlyPaintWhenChanged;

                if (forceRepaint)
                {
                    gfx.AddJob(new JobClear());
                    paintMode = XmlElement.PaintModes.ForcePaintNoUnPaintNeeded;
                }

                var paintContext = new PaintContext
                {
                    LimitLeft  = 0,
                    LimitRight = limitRight - 10,
                    PaintPosX  = 10,
                    PaintPosY  = 10,
                    RowStartX  = 10,
                };

                var paintResultContext = await this.EditorState.RootElement.Paint(paintContext.Clone(), EditorState.CursorBlink.PaintCursor, this.EditorState.CursorOptimized, gfx, paintMode, depth : 0);

                await gfx.PaintJobs(EditorConfig.ColorBackground);

                const int margin           = 20;
                var       newVirtualWidth  = ((paintResultContext.FoundMaxX + margin) / margin) * margin;
                var       newVirtualHeight = ((paintResultContext.PaintPosY + margin) / margin) * margin;
                if (this.VirtualWidth != newVirtualWidth || this.VirtualHeight != newVirtualHeight)
                {
                    this.VirtualWidth  = newVirtualWidth;
                    this.VirtualHeight = newVirtualHeight;
                    await this.VirtualSizeChanged.Trigger(EventArgs.Empty);
                }
            }
        }
        /// <summary>
        /// Draws the XML element on the screen
        /// </summary>
        public async Task <PaintContext> Paint(PaintContext paintContext, bool cursorBlinkOn, XmlCursor cursor, IGraphics gfx, PaintModes paintMode, int depth)
        {
            if (this.disposed)
            {
                return(paintContext);
            }
            if (this.XmlNode == null)
            {
                return(paintContext);
            }
            if (this.xmlEditor == null)
            {
                return(paintContext);
            }

            paintContext = await PaintInternal(paintContext, cursorBlinkOn, cursor, gfx, paintMode, depth);

            if (this.cursorPaintPos != null && cursorBlinkOn)
            {
                this.PaintCursor(gfx);
            }
            return(paintContext);
        }
 protected abstract Task <PaintContext> PaintInternal(PaintContext paintContext, bool cursorBlinkOn, XmlCursor cursor, IGraphics gfx, PaintModes paintMode, int depth);
Exemple #4
0
        protected override async Task <PaintContext> PaintInternal(PaintContext paintContext, bool cursorBlinkOn, XmlCursor cursor, IGraphics gfx, PaintModes paintMode, int depth)
        {
            this.nodeDimensions.Update();
            var isSelected = cursor?.StartPos != null && cursor?.EndPos != null && XmlCursorSelectionHelper.IsThisNodeInsideSelection(cursor, this.XmlNode);

            this.CreateChildElementsIfNeeded(gfx);

            Point newCursorPaintPos = null;

            bool alreadyUnpainted = false;

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

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

            case PaintModes.OnlyPaintWhenChanged:
                break;
            }

            // If the cursor is inside the empty node, then draw the cursor there
            if (cursor.StartPos.ActualNode == this.XmlNode)
            {
                if (cursor.StartPos.PosOnNode == XmlCursorPositions.CursorInFrontOfNode)
                {
                    // remember position for cursor line
                    newCursorPaintPos = new Point(paintContext.PaintPosX, paintContext.PaintPosY);
                }
            }

            var cursorIsOnThisNode = cursor.StartPos.ActualNode == this.XmlNode || cursor.EndPos.ActualNode == this.XmlNode;

            paintContext = await this.startTag.Paint(paintContext, cursorIsOnThisNode, cursorBlinkOn, alreadyUnpainted, isSelected, gfx);

            // If the cursor is inside the empty node, then draw the cursor there
            if (cursor.StartPos.ActualNode == this.XmlNode)
            {
                if (cursor.StartPos.PosOnNode == XmlCursorPositions.CursorInsideTheEmptyNode)
                {
                    // set position for cursor line
                    newCursorPaintPos = new Point(paintContext.PaintPosX - 1, paintContext.PaintPosY);
                }
            }

            paintContext = await this.PaintSubNodes(paintContext, cursorBlinkOn, cursor, gfx, paintMode, depth);

            if (this.endTag != null)
            {
                paintContext = await this.endTag.Paint(paintContext, cursorIsOnThisNode, cursorBlinkOn, alreadyUnpainted, isSelected, gfx);
            }

            // If the cursor is behind the node, then also draw the cursor there
            if (cursor.StartPos.ActualNode == this.XmlNode)
            {
                if (cursor.StartPos.PosOnNode == XmlCursorPositions.CursorBehindTheNode)
                {
                    newCursorPaintPos = new Point(paintContext.PaintPosX - 1, paintContext.PaintPosY);
                }
            }

            this.cursorPaintPos = newCursorPaintPos;
            return(paintContext.Clone());
        }
Exemple #5
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);
        }