示例#1
0
 /// <summary>
 /// Add a rectangle. Note 1 px sized rectangles won't be rendered properly.
 /// </summary>
 /// <param name="a">upper-left point</param>
 /// <param name="b">lower-right point</param>
 /// <param name="color">color</param>
 /// <param name="rounding">radius of rounded corners</param>
 /// <param name="roundingCorners">which corner(s) will be rounded</param> TODO finish this documentation on how to use roundingCorners
 /// <param name="thickness">thickness</param>
 public void AddRect(Point a, Point b, Color color, float rounding = 0.0f, int roundingCorners = 0x0F, float thickness = 1.0f)
 {
     if (MathEx.AmostZero(color.A))
     {
         return;
     }
     PathRect(a + new Vector(0.5f, 0.5f), b - new Vector(0.5f, 0.5f), rounding, roundingCorners);
     PathStroke(color, true, thickness);
 }
示例#2
0
        public void AddRectFilledGradientTopLeftToBottomRight(Point a, Point b, Color topLeftColor, Color bottomRightColor)
        {
            if (MathEx.AmostZero(topLeftColor.A) && MathEx.AmostZero(bottomRightColor.A))
            {
                return;
            }

            this.ShapeMesh.PrimReserve(6, 4);
            PrimRectGradientTopLeftToBottomRight(a, b, topLeftColor, bottomRightColor);
        }
示例#3
0
 /// <summary>
 /// Add a line segment.
 /// </summary>
 /// <param name="start">start point</param>
 /// <param name="end">end point</param>
 /// <param name="color">color</param>
 /// <param name="thickness">thickness</param>
 public void AddLine(Point start, Point end, Color color, double thickness = 1.0)
 {
     if (MathEx.AmostZero(color.A))
     {
         return;
     }
     PathLineTo(start + new Vector(0.5, 0.5));
     PathLineTo(end + new Vector(0.5, 0.5));
     PathStroke(color, false, thickness);
 }
示例#4
0
        /// <summary>
        /// Add a filled triangle. Make sure the points a->b->c is clockwise.
        /// </summary>
        /// <param name="a">point A</param>
        /// <param name="b">point B</param>
        /// <param name="c">point C</param>
        /// <param name="color"></param>
        public void AddTriangleFilled(Point a, Point b, Point c, Color color)
        {
            if (MathEx.AmostZero(color.A))
            {
                return;
            }

            PathLineTo(a);
            PathLineTo(b);
            PathLineTo(c);
            PathFill(color);
        }
示例#5
0
        public void AddCircleFilled(Point center, double radius, Color col, int num_segments)
        {
            if (MathEx.AmostZero(col.A))
            {
                return;
            }

            float a_max = (float)Math.PI * 2.0f * (num_segments - 1.0f) / num_segments;

            PathArcTo(center, (float)radius, 0.0f, a_max, num_segments);
            PathFill(col);
        }
示例#6
0
        public void AddCircle(Point center, float radius, Color col, int num_segments, float thickness)
        {
            if (MathEx.AmostZero(col.A))
            {
                return;
            }

            float a_max = (float)Math.PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;

            PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments);
            PathStroke(col, true, thickness);
        }
示例#7
0
 /// <summary>
 /// Add an image.
 /// </summary>
 /// <param name="texture">the texture that are used</param>
 /// <param name="a">top-left point</param>
 /// <param name="b">bottom-right point</param>
 /// <param name="uvA">texture coordinate of point a</param>
 /// <param name="uvB">texture coordinate of point b</param>
 /// <param name="color">tint color</param>
 public void AddImage(ITexture texture, Point a, Point b, Point uvA, Point uvB, Color color)
 {
     if (GetCurrentClipRect().IsEmpty)
     {
         return;
     }
     if (MathEx.AmostZero(color.A))
     {
         return;
     }
     AddImageDrawCommand(texture);
     this.ImageMesh.PrimReserve(6, 4);
     AddImageRect(a, b, uvA, uvB, color);
 }
示例#8
0
 /// <summary>
 /// Add a filled rectangle. Note 1 px sized rectangles won't be rendered properly.
 /// </summary>
 /// <param name="a">top-left point</param>
 /// <param name="b">bottom-right point</param>
 /// <param name="color">color</param>
 /// <param name="rounding">radius of rounded corners</param>
 /// <param name="roundingCorners">which corner(s) will be rounded</param> TODO finish this documentation on how to use roundingCorners
 public void AddRectFilled(Point a, Point b, Color color, float rounding = 0.0f, int roundingCorners = 0x0F)
 {
     if (MathEx.AmostZero(color.A))
     {
         return;
     }
     if (rounding > 0.0f)
     {
         PathRect(a, b, rounding, roundingCorners);
         PathFill(color);
     }
     else
     {
         this.ShapeMesh.PrimReserve(6, 4);
         PrimRect(a, b, color);
     }
 }
示例#9
0
 /// <summary>
 /// (Fast) adds an arc from angle1 to angle2 to the current path.
 /// </summary>
 /// <param name="center">the center of the arc</param>
 /// <param name="radius">the radius of the arc</param>
 /// <param name="amin">angle1 = amin * π * 1/12</param>
 /// <param name="amax">angle1 = amax * π * 1/12</param>
 public void PathArcToFast(Point center, double radius, int amin, int amax)
 {
     if (amin > amax)
     {
         return;
     }
     if (MathEx.AmostZero(radius))
     {
         Path.Add(center);
     }
     else
     {
         Path.Capacity = Path.Count + amax - amin + 1;
         for (int a = amin; a <= amax; a++)
         {
             Point c = CirclePoints[a % CirclePoints.Length];
             Path.Add(new Point(center.X + c.X * radius, center.Y + c.Y * radius));
         }
     }
 }
示例#10
0
        /// <summary>
        /// Draw a box model
        /// </summary>
        /// <param name="drawList"></param>
        /// <param name="rect">the rect (of the border-box) to draw this box model </param>
        /// <param name="text">text of the box model</param>
        /// <param name="style">style of the box model</param>
        /// <param name="state"></param>
        public static void DrawBoxModel(this DrawList drawList, Rect rect, string text, GUIStyle style, GUIState state = GUIState.Normal)
        {
            if (rect == Layout.StackLayout.DummyRect)
            {
                return;
            }

            //Widths of border
            var bt = style.Get <double>(GUIStyleName.BorderTop, state);
            var br = style.Get <double>(GUIStyleName.BorderRight, state);
            var bb = style.Get <double>(GUIStyleName.BorderBottom, state);
            var bl = style.Get <double>(GUIStyleName.BorderLeft, state);

            //Widths of padding
            var pt = style.Get <double>(GUIStyleName.PaddingTop, state);
            var pr = style.Get <double>(GUIStyleName.PaddingRight, state);
            var pb = style.Get <double>(GUIStyleName.PaddingBottom, state);
            var pl = style.Get <double>(GUIStyleName.PaddingLeft, state);

            //4 corner of the border-box
            var btl           = new Point(rect.Left, rect.Top);
            var btr           = new Point(rect.Right, rect.Top);
            var bbr           = new Point(rect.Right, rect.Bottom);
            var bbl           = new Point(rect.Left, rect.Bottom);
            var borderBoxRect = new Rect(btl, bbr);

            //4 corner of the padding-box
            var ptl = new Point(btl.X + bl, btl.Y + bt);
            var ptr = new Point(btr.X - br, btr.Y + bt);
            var pbr = new Point(bbr.X - br, bbr.Y - bb);
            var pbl = new Point(bbl.X + bl, bbl.Y - bb);
            //if (ptl.X > ptr.X) return;//TODO what if (ptl.X > ptr.X) happens?
            var paddingBoxRect = new Rect(ptl, pbr);

            //4 corner of the content-box
            var ctl            = new Point(ptl.X + pl, ptl.Y + pt);
            var ctr            = new Point(ptr.X - pr, ptr.Y + pr);
            var cbr            = new Point(pbr.X - pr, pbr.Y - pb);
            var cbl            = new Point(pbl.X + pl, pbl.Y - pb);
            var contentBoxRect = new Rect(ctl, cbr);

            // draw background in padding-box
            var gradient = (Gradient)style.Get <int>(GUIStyleName.BackgroundGradient, state);

            if (gradient == Gradient.None)
            {
                var bgColor        = style.Get <Color>(GUIStyleName.BackgroundColor, state);
                var borderRounding = style.BorderRadius.topLeft;                        //FIXME
                drawList.AddRectFilled(paddingBoxRect, bgColor, (float)borderRounding); //TODO drawing method needed: rect with custom rounding at each corner
            }
            else if (gradient == Gradient.TopBottom)
            {
                var topColor    = style.Get <Color>(GUIStyleName.GradientTopColor, state);
                var bottomColor = style.Get <Color>(GUIStyleName.GradientBottomColor, state);
                drawList.AddRectFilledGradient(paddingBoxRect, topColor, bottomColor);
            }
            else
            {
                throw new InvalidOperationException();
            }

            //Content
            //Content-box
            if (text != null && ctl.X < ctr.X)//content should not be visible when ctl.X > ctr.X
            {
                //var textSize = style.CalcSize(text, state);
                /*HACK Don't check text size because the size calculated by Typography is not accurate. */
                /*if (textSize.Height < contentBoxRect.Height && textSize.Width < contentBoxRect.Width)*/
                {
                    drawList.DrawText(contentBoxRect, text, style, state);
                }
            }

            //Border
            //  Top
            if (!MathEx.AmostZero(bt))
            {
                var borderTopColor = style.Get <Color>(GUIStyleName.BorderTopColor, state);
                if (!MathEx.AmostZero(borderTopColor.A))
                {
                    drawList.PathLineTo(ptl);
                    drawList.PathLineTo(btl);
                    drawList.PathLineTo(btr);
                    drawList.PathLineTo(ptr);
                    drawList.PathFill(borderTopColor);
                }
            }
            //  Right
            if (!MathEx.AmostZero(br))
            {
                var borderRightColor = style.Get <Color>(GUIStyleName.BorderRightColor, state);
                if (!MathEx.AmostZero(borderRightColor.A))
                {
                    drawList.PathLineTo(ptr);
                    drawList.PathLineTo(btr);
                    drawList.PathLineTo(bbr);
                    drawList.PathLineTo(pbr);
                    drawList.PathFill(borderRightColor);
                }
            }
            //  Bottom
            if (!MathEx.AmostZero(bb))
            {
                var borderBottomColor = style.Get <Color>(GUIStyleName.BorderBottomColor, state);
                if (!MathEx.AmostZero(borderBottomColor.A))
                {
                    drawList.PathLineTo(pbr);
                    drawList.PathLineTo(bbr);
                    drawList.PathLineTo(bbl);
                    drawList.PathLineTo(pbl);
                    drawList.PathFill(borderBottomColor);
                }
            }
            //  Left
            if (!MathEx.AmostZero(bl))
            {
                var borderLeftColor = style.Get <Color>(GUIStyleName.BorderLeftColor, state);
                if (!MathEx.AmostZero(borderLeftColor.A))
                {
                    drawList.PathLineTo(pbl);
                    drawList.PathLineTo(bbl);
                    drawList.PathLineTo(btl);
                    drawList.PathLineTo(ptl);
                    drawList.PathFill(borderLeftColor);
                }
            }

            //Outline
            var outlineWidth = style.Get <double>(GUIStyleName.OutlineWidth, state);

            if (!MathEx.AmostZero(outlineWidth))
            {
                var outlineColor = style.Get <Color>(GUIStyleName.OutlineColor, state);
                if (!MathEx.AmostZero(outlineColor.A))
                {
                    drawList.PathRect(btl, bbr);
                    drawList.PathStroke(outlineColor, true, outlineWidth);
                }
            }

#if DrawPaddingBox
            drawList.PathRect(ptl, pbr);
            drawList.PathStroke(Color.ColorRgb(0, 100, 100), true, 1);
#endif

#if DrawContentBox
            drawList.PathRect(ctl, cbr);
            drawList.PathStroke(Color.ColorRgb(100, 0, 100), true, 1);
#endif
        }
示例#11
0
        public void NewFrame(GUIContext g)
        {
            // Handle user moving window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows.
            if (MovingWindow != null)
            {
                g.KeepAliveID(g.ActiveId);
                Debug.Assert(MovingWindow?.RootWindow != null);
                var movingWindow = MovingWindow.RootWindow;
                if (Mouse.Instance.LeftButtonState == KeyState.Down)
                {
                    var delta = Mouse.Instance.MouseDelta;
                    if (!MathEx.AmostZero(delta.X) && !MathEx.AmostZero(delta.Y))
                    {
                        movingWindow.Position += Mouse.Instance.MouseDelta;
                        movingWindow.Layout();
                    }
                    this.FocusWindow(MovingWindow);
                }
                else
                {
                    g.SetActiveID(0, null);
                    this.MovingWindow = null;
                }
            }
            else
            {
                if (ActiveIdWindow != null && ActiveIdWindow.MoveId == g.ActiveId)
                {
                    g.KeepAliveID(g.ActiveId);
                    if (Mouse.Instance.LeftButtonState != KeyState.Down)
                    {
                        g.SetActiveID(0, null);
                    }
                }
            }

            // Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow
            this.HoveredWindow = this.MovingWindow ?? this.FindHoveredWindow(Mouse.Instance.Position, false);
            if (this.HoveredWindow != null && (this.HoveredWindow.Flags.HaveFlag(WindowFlags.ChildWindow)))
            {
                this.HoveredRootWindow = this.HoveredWindow.RootWindow;
            }
            else
            {
                this.HoveredRootWindow = (this.MovingWindow != null) ? this.MovingWindow.RootWindow : this.FindHoveredWindow(Mouse.Instance.Position, true);
            }


            // Scale & Scrolling
            if (this.HoveredWindow != null && Mouse.Instance.MouseWheel != 0.0 && !this.HoveredWindow.Collapsed)
            {
                Window window = this.HoveredWindow;
                if (Keyboard.Instance.KeyDown(Key.LeftControl))
                {
                    //Scale
                    //TODO
                }
                else
                {
                    // Scroll
                    if (!(window.Flags.HaveFlag(WindowFlags.NoScrollWithMouse)))
                    {
                        var    newScrollY         = window.ClientAreaNode.ScrollOffset.Y - Math.Sign(Mouse.Instance.MouseWheel) * 20 /*scroll step*/;
                        float  window_rounding    = (float)window.WindowContainer.RuleSet.Get <double>(StylePropertyName.WindowRounding);
                        double resize_corner_size = Math.Max(window.WindowContainer.RuleSet.FontSize * 1.35, window_rounding + 1.0 + window.WindowContainer.RuleSet.FontSize * 0.2);
                        var    contentSize        = window.ContentRect.Size;
                        var    vH = window.Rect.Height - window.TitleBarHeight - window.WindowContainer.RuleSet.BorderVertical - window.WindowContainer.RuleSet.PaddingVertical;
                        var    cH = contentSize.Height;
                        if (cH > vH)
                        {
                            newScrollY = MathEx.Clamp(newScrollY, 0, cH - vH);
                            window.SetWindowScrollY(newScrollY);
                        }
                    }
                }
            }

            // Mark all windows as not visible
            for (int i = 0; i != this.Windows.Count; i++)
            {
                Window window = this.Windows[i];
                window.WasActive = window.Active;
                window.Active    = false;
                window.Accessed  = false;

                //disable all nodes in the window
                window.ClientAreaNode.Foreach(n => { n.ActiveSelf = false; return(true); });
                window.AbsoluteVisualList.ForEach(n => n.ActiveSelf = false);
            }

            // Clear temp data
            for (int i = 0; i != this.Windows.Count; i++)
            {
                Window window = this.Windows[i];
                window.TempData.Clear();
            }

            // No window should be open at the beginning of the frame.
            // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
            this.WindowStack.Clear();
        }