示例#1
0
        bool CloseButton(int id, Rect rect)
        {
            Window window = GUI.GetCurrentWindow();

            bool pressed = GUIBehavior.ButtonBehavior(rect, id, out bool hovered, out bool held);

            GUIStyle style = GUIStyle.Basic;

            style.Save();
            style.ApplySkin(GUIControlName.Button);
            style.PushBgColor(Color.White, GUIState.Normal);
            style.PushBgColor(Color.Rgb(232, 17, 35), GUIState.Hover);
            style.PushBgColor(Color.Rgb(241, 112, 122), GUIState.Active);

            // Render
            var d     = window.DrawList;
            var state = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;
            var color = style.Get <Color>(GUIStyleName.BackgroundColor, state);

            d.AddRectFilled(rect, color);

            Point center       = rect.Center;
            float cross_extent = (15 * 0.7071f) - 1.0f;
            var   fontColor    = style.Get <Color>(GUIStyleName.FontColor, state);

            d.AddLine(center + new Vector(+cross_extent, +cross_extent), center + new Vector(-cross_extent, -cross_extent), fontColor);
            d.AddLine(center + new Vector(+cross_extent, -cross_extent), center + new Vector(-cross_extent, +cross_extent), fontColor);

            style.Restore();

            return(pressed);
        }
示例#2
0
        /// <summary>
        /// Create a button. When the user click it, something will happen immediately.
        /// </summary>
        /// <param name="rect">position and size of the control</param>
        /// <param name="text">text to display on the button</param>
        /// <returns>true when the users clicks the button.</returns>
        public static bool Button(Rect rect, string text)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            int id = window.GetID(text);

            // style apply
            var style = GUIStyle.Basic;

            style.Save();
            style.ApplySkin(GUIControlName.Button);

            // rect
            rect = window.GetRect(rect);

            // interact
            bool hovered, held;
            bool pressed = GUIBehavior.ButtonBehavior(rect, id, out hovered, out held, 0);

            // render
            var d     = window.DrawList;
            var state = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            d.DrawBoxModel(rect, text, style, state);

            style.Restore();

            return(pressed);
        }
示例#3
0
        /// <summary>
        /// Create an auto-layout collapsing header.
        /// </summary>
        /// <param name="text">header text</param>
        /// <param name="open">opened</param>
        /// <param name="options">style options</param>
        /// <returns>true when opened</returns>
        /// <remarks> It is always horizontally stretched (factor 1).</remarks>
        public static bool CollapsingHeader(string text, ref bool open, LayoutOptions?options)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            int  id        = window.GetID(text);
            var  container = window.RenderTree.CurrentContainer;
            Node node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create nodes
                node = new Node(id, $"CollapsingHeader<{text}>");
                node.AttachLayoutEntry();
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.CollapsingHeader]);
            }
            node.RuleSet.ApplyOptions(options);
            node.RuleSet.ApplyOptions(Height(node.RuleSet.GetLineHeight()));
            node.ActiveSelf = true;

            container.AppendChild(node);

            // rect
            Rect rect = window.GetRect(id);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(rect, id, out var hovered, out var held, ButtonFlags.PressedOnClick);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;
            if (pressed)
            {
                open = !open;
            }

            // last item state
            window.TempData.LastItemState = node.State;

            using (var dc = node.RenderOpen())
            {
                dc.DrawBoxModel(node);
                dc.DrawGlyphRun(node.RuleSet, text, node.ContentRect.TopLeft + new Vector(node.Rect.Height + node.PaddingLeft, 0));
                dc.RenderArrow(node.Rect.Min + new Vector(node.PaddingLeft, 0),
                               node.Height, node.RuleSet.FontColor, open ? Direcion.Down : Direcion.Right, 1.0);
            }

            return(open);
        }
示例#4
0
        /// <summary>
        /// Create an auto-layout collapsing header.
        /// </summary>
        /// <param name="text">header text</param>
        /// <param name="open">opened</param>
        /// <param name="options">style options</param>
        /// <returns>true when opened</returns>
        /// <remarks> It is always horizontally stretched (factor 1).</remarks>
        public static bool CollapsingHeader(string text, ref bool open, LayoutOptions?options)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            int  id        = window.GetID(text);
            var  container = window.RenderTree.CurrentContainer;
            Node node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            var displayText = (open ? "-" : "+") + text;

            if (node == null)
            {
                //create nodes
                node = new Node(id, $"CollapsingHeader<{text}>");
                node.AttachLayoutEntry();
                container.AppendChild(node);
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.CollapsingHeader]);
                node.Geometry = new TextGeometry(displayText);
            }
            node.RuleSet.ApplyOptions(options);
            node.RuleSet.ApplyOptions(Height(node.RuleSet.GetLineHeight()));
            node.ActiveSelf = true;

            var textPrimitive = node.Geometry as TextGeometry;

            Debug.Assert(textPrimitive != null);
            textPrimitive.Text = displayText;

            // rect
            Rect rect = window.GetRect(id);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(rect, id, out var hovered, out var held, ButtonFlags.PressedOnClick);

            if (pressed)
            {
                open       = !open;
                node.State = open ? GUIState.Active : GUIState.Normal;
            }

            return(open);
        }
示例#5
0
        public static bool RadioButton(string label, bool active)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            GUIContext g  = GetCurrentContext();
            int        id = window.GetID(label);

            // style
            var style = GUIStyle.Basic;

            Size label_size = style.CalcSize(label, GUIState.Normal);

            Rect check_bb = window.GetRect(window.GetID(label + "_check"));
            Rect text_bb  = window.GetRect(id);

            Rect total_bb = Rect.Union(check_bb, text_bb);

            Point center = check_bb.Center;

            center.x = (int)center.x + 0.5f;
            center.y = (int)center.y + 0.5f;
            var radius = check_bb.Height * 0.5f;

            bool hovered, held;
            bool pressed = GUIBehavior.ButtonBehavior(total_bb, id, out hovered, out held);

            var d     = window.DrawList;
            var state = ((held && hovered) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal);

            d.AddCircleFilled(center, (float)radius, ((held && hovered) ? Color.FrameBgActive : hovered ? Color.FrameBgHovered : Color.FrameBg), 16);
            if (active)
            {
                var check_sz = Math.Min(check_bb.Width, check_bb.Height);
                var pad      = Math.Max(1.0f, (int)(check_sz / 6.0f));
                d.AddCircleFilled(center, radius - pad, Color.CheckMark, 16);
            }

            if (label_size.Width > 0.0f)
            {
                d.AddText(text_bb, label, style, state);
            }

            return(pressed);
        }
示例#6
0
        /// <summary>
        /// Create an auto-layout button. When the user click it, something will happen immediately.
        /// </summary>
        /// <param name="text">text to display on the button</param>
        /// <param name="options">style options</param>
        public static bool Button(string text, LayoutOptions?options)
        {
            var window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            var id        = window.GetID(text);
            var container = window.RenderTree.CurrentContainer;
            var node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create node
                node             = new Node(id, $"Button<{text}>");
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
                var size = node.RuleSet.CalcContentBoxSize(text, GUIState.Normal);
                node.AttachLayoutEntry(size);
            }
            container.AppendChild(node);
            node.RuleSet.ApplyOptions(options);
            node.ActiveSelf = true;

            // rect
            node.Rect = window.GetRect(id);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            // last item state
            window.TempData.LastItemState = node.State;

            // draw
            using (var dc = node.RenderOpen())
            {
                dc.DrawBoxModel(text, node.RuleSet, node.Rect);
            }

            return(pressed);
        }
示例#7
0
        public static bool ImageButton(string filePath, Size size, Point uv0, Point uv1)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            var id = window.GetID(filePath);

            // style
            var style = GUIStyle.Basic;

            style.Save();
            style.ApplySkin(GUIControlName.Button);

            // rect
            var texture = TextureUtil.GetTexture(filePath);

            if (size == Size.Empty)
            {
                size = style.CalcSize(texture, GUIState.Normal);
            }
            var rect = window.GetRect(id);

            if (rect == Layout.StackLayout.DummyRect)
            {
                style.Restore();
                return(false);
            }

            // interact
            bool hovered, held;
            bool pressed = GUIBehavior.ButtonBehavior(rect, id, out hovered, out held, 0);

            // render
            style.PushUV(uv0, uv1);
            var d     = window.DrawList;
            var state = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            d.DrawBoxModel(rect, texture, style, state);

            style.Restore();

            return(pressed);
        }
示例#8
0
        /// <summary>
        /// Create a button. When the user click it, something will happen immediately.
        /// </summary>
        /// <param name="rect">position and size of the control</param>
        /// <param name="text">text to display on the button, optionally incuding the id: "#MyButton"</param>
        /// <param name="options">style options</param>
        /// <returns>true when the users clicks the button.</returns>
        public static bool Button(Rect rect, string text, LayoutOptions?options)
        {
            var window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            var id        = window.GetID(text);
            var container = window.AbsoluteVisualList;
            var node      = (Node)container.Find(visual => visual.Id == id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create button node
                node = new Node(id, $"Button<{text}>");
                container.Add(node);
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
            }
            node.RuleSet.ApplyStack();
            node.RuleSet.ApplyOptions(options);
            node.ActiveSelf = true;

            // rect
            node.Rect = window.GetRect(rect);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            // last item state
            window.TempData.LastItemState = node.State;

            // draw
            using (var dc = node.RenderOpen())
            {
                dc.DrawBoxModel(text, node.RuleSet, node.Rect);
            }

            return(pressed);
        }
示例#9
0
        public static bool ImageButton(string filePath, Size size, Vector offset)
        {
            var window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            var id        = window.GetID(filePath);
            var container = window.RenderTree.CurrentContainer;
            var node      = container.GetNodeById(id);

            if (node == null)
            {
                //create node
                node             = new Node(id, $"Button<{filePath}>");
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
                node.RuleSet.ObjectPosition = (offset.X, offset.Y);
                node.AttachLayoutEntry(size);
            }
            container.AppendChild(node);
            node.ActiveSelf = true;

            // rect
            node.Rect = window.GetRect(id);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            // last item state
            window.TempData.LastItemState = node.State;

            // draw
            using (var dc = node.RenderOpen())
            {
                var texture = TextureUtil.GetTexture(filePath);
                dc.DrawBoxModel(texture, node.RuleSet, node.Rect);
            }

            return(pressed);
        }
示例#10
0
        /// <summary>
        /// Create an auto-layout button. When the user click it, something will happen immediately.
        /// </summary>
        /// <param name="text">text to display on the button</param>
        /// <param name="options">style options</param>
        public static bool Button(string text, LayoutOptions?options)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            int  id        = window.GetID(text);
            var  container = window.RenderTree.CurrentContainer;
            Node node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create node
                node             = new Node(id, $"Button<{text}>");
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
                var size = node.RuleSet.CalcSize(text, GUIState.Normal);
                node.AttachLayoutEntry(size);
                container.AppendChild(node);
                node.Primitive = new TextPrimitive(text);
            }
            node.RuleSet.ApplyOptions(options);
            node.ActiveSelf = true;

            var textPrimitive = node.Primitive as TextPrimitive;

            Debug.Assert(textPrimitive != null);
            textPrimitive.Text = text;

            // rect
            node.Rect = window.GetRect(id);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            return(pressed);
        }
示例#11
0
        /// <summary>
        /// Create a button. When the user click it, something will happen immediately.
        /// </summary>
        /// <param name="rect">position and size of the control</param>
        /// <param name="text">text to display on the button, optionally incuding the id: "#MyButton"</param>
        /// <param name="options">style options</param>
        /// <returns>true when the users clicks the button.</returns>
        public static bool Button(Rect rect, string text, LayoutOptions?options)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            int  id        = window.GetID(text);
            var  container = window.AbsoluteVisualList;
            Node node      = (Node)container.Find(visual => visual.Id == id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create button node
                node = new Node(id, $"Button<{text}>");
                container.Add(node);
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
                node.Geometry = new TextGeometry(text);
            }

            node.RuleSet.ApplyOptions(options);
            node.ActiveSelf = true;

            var textPrimitive = node.Geometry as TextGeometry;

            Debug.Assert(textPrimitive != null);
            textPrimitive.Text = text;

            // rect
            node.Rect = window.GetRect(rect);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            return(pressed);
        }
示例#12
0
        /// <summary>
        /// Create a button. When the user click it, something will happen immediately.
        /// </summary>
        /// <param name="rect">position and size of the control</param>
        /// <param name="text">text to display on the button, optionally incuding the id: "#MyButton"</param>
        /// <returns>true when the users clicks the button.</returns>
        public static bool Button(Rect rect, string text)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            int  id        = window.GetID(text);
            var  container = window.NodeTreeRoot;
            Node node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create button node
                node = new Node(id, $"Button<{text}>");
                container.AppendChild(node);
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
                node.Primitive = new TextPrimitive(text);
            }

            //TODO check if text changes

            // rect
            node.Rect = window.GetRect(rect);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            return(pressed);
        }
示例#13
0
        public void FirstUpdate(string name, Size size, ref bool open, double backgroundAlpha,
                                WindowFlags flags,
                                long currentFrame, Window parentWindow)
        {
            //short names
            var form = Form.current;
            var g    = form.uiContext;
            var w    = g.WindowManager;

            this.Active          = true;
            this.BeginCount      = 0;
            this.ClipRect        = Rect.Big;
            this.LastActiveFrame = currentFrame;

            var fullScreenRect = new Rect(0, 0, form.ClientSize);

            if (flags.HaveFlag(WindowFlags.ChildWindow) && !flags.HaveFlag(WindowFlags.ComboBox | WindowFlags.Popup))
            {
                //PushClipRect(parentWindow.ClipRect, true);
                //ClipRect = GetCurrentClipRect();
            }
            else
            {
                //PushClipRect(fullScreenRect, true);
                //ClipRect = GetCurrentClipRect();
            }

            // (draw outer clip rect for test only here)

            // determine if window is collapsed
            if (!flags.HaveFlag(WindowFlags.NoTitleBar) && !flags.HaveFlag(WindowFlags.NoCollapse))
            {
                // Collapse window by double-clicking on title bar
                if (w.HoveredWindow == this && g.IsMouseHoveringRect(this.TitleBarRect) &&
                    Mouse.Instance.LeftButtonDoubleClicked)
                {
                    this.Collapsed = !this.Collapsed;
                    w.FocusWindow(this);
                    open = !this.Collapsed;//overwrite the open state
                }
            }

            this.Collapsed = !open;

            //update title bar
            var titleBarRect   = this.TitleBarRect;
            var windowRounding = (float)this.WindowContainer.RuleSet.Get <double>(GUIStyleName.WindowRounding);

            if (!flags.HaveFlag(WindowFlags.NoTitleBar))
            {
                //text
                {
                    // title text
                    var textPrimitive = (TextPrimitive)this.titleBarTitleNode.Primitive;
                    if (textPrimitive.Text != this.Name)
                    {
                        textPrimitive.Text = this.Name;
                    }
                }
            }

            this.ShowWindowClientArea(!this.Collapsed);

            if (this.Collapsed)
            {
                //TODO need to do something here?
            }
            else//show and update window client area
            {
                if (!flags.HaveFlag(WindowFlags.NoResize) && this.ResizeGripNode == null)
                {
                    var id   = this.GetID("#RESIZE");
                    var node = new Node(id, "Window_ResizeGrip");
                    node.Primitive      = new PathPrimitive();
                    this.ResizeGripNode = node;
                    this.AbsoluteVisualList.Add(node);
                }
                //resize grip
                var resizeGripColor = Color.Clear;
                if (!flags.HaveFlag(WindowFlags.AlwaysAutoResize) && !flags.HaveFlag(WindowFlags.NoResize))
                {
                    // Manual resize
                    var br         = this.Rect.BottomRight;
                    var resizeRect = new Rect(br - new Vector(windowRounding, windowRounding), br);
                    var resizeId   = this.GetID("#RESIZE");
                    GUIBehavior.ButtonBehavior(resizeRect, resizeId, out var hovered, out var held,
                                               ButtonFlags.FlattenChilds);
                    resizeGripColor =
                        held
                            ? this.WindowContainer.RuleSet.Get <Color>(GUIStyleName.ResizeGripColor, GUIState.Active)
                            : hovered
                                ? this.WindowContainer.RuleSet.Get <Color>(GUIStyleName.ResizeGripColor, GUIState.Hover)
                                : this.WindowContainer.RuleSet.Get <Color>(GUIStyleName.ResizeGripColor);

                    if (hovered || held)
                    {
                        //Mouse.Instance.Cursor = Cursor.NeswResize;
                    }

                    if (held)
                    {
                        // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
                        var t             = Mouse.Instance.Position - g.ActiveIdClickOffset - this.Position;
                        var newSizeWidth  = t.X + resizeRect.Width;
                        var newSizeHeight = t.Y + resizeRect.Height;
                        var resizeSize    = new Size(newSizeWidth, newSizeHeight);
                        this.ApplySize(resizeSize);

                        // adjust scroll parameters
                        var contentSize = this.ContentRect.Size;
                        if (contentSize != Size.Zero)
                        {
                            var vH = this.Rect.Height - this.TitleBarHeight - this.WindowContainer.RuleSet.BorderVertical - this.WindowContainer.RuleSet.PaddingVertical;
                            var cH = contentSize.Height;
                            if (cH > vH)
                            {
                                var oldScrollY = this.Scroll.Y;
                                oldScrollY    = MathEx.Clamp(oldScrollY, 0, cH - vH);
                                this.Scroll.Y = oldScrollY;
                            }
                        }
                    }
                }

                // Render resize grip
                // (after the input handling so we don't have a frame of latency)
                if (!flags.HaveFlag(WindowFlags.NoResize))
                {
                    var br           = this.Rect.BottomRight;
                    var borderBottom = this.WindowContainer.RuleSet.BorderBottom;
                    var borderRight  = this.WindowContainer.RuleSet.BorderRight;
                    var primitive    = (PathPrimitive)this.ResizeGripNode.Primitive;
                    primitive.PathClear();
                    primitive.PathLineTo(br + new Vector(-borderRight, -borderBottom));
                    primitive.PathLineTo(br + new Vector(-borderRight, -windowRounding));
                    primitive.PathArcFast(br + new Vector(-windowRounding - borderRight, -windowRounding - borderBottom), windowRounding, 0, 3);
                    primitive.PathFill(resizeGripColor);
                }

                this.ContentRect = Rect.Zero;
            }
        }
示例#14
0
        public void FirstUpdate(string name, Size size, ref bool open, double backgroundAlpha,
                                WindowFlags flags,
                                long currentFrame, Window parentWindow)
        {
            //short names
            var g = Application.ImGuiContext;
            var w = g.WindowManager;

            this.Active          = true;
            this.BeginCount      = 0;
            this.LastActiveFrame = currentFrame;

            // update viewport
            UpdateWindowViewport(this);
            w.CurrentViewport = Viewport;
            if (Viewport != null)
            {
                Viewport.LastFrameActive = g.FrameCount;
            }

            // determine if window is collapsed
            if (!flags.HaveFlag(WindowFlags.NoTitleBar) && !flags.HaveFlag(WindowFlags.NoCollapse))
            {
                // Collapse window by double-clicking on title bar
                if (w.HoveredWindow == this && g.IsMouseHoveringRect(this.TitleBarRect) &&
                    Mouse.Instance.LeftButtonDoubleClicked)
                {
                    this.Collapsed = !this.Collapsed;
                    w.FocusWindow(this);
                    open = !this.Collapsed; //overwrite the open state
                }
            }

            this.Collapsed = !open;

            //window container
            using (var dc = WindowContainer.RenderOpen())
            {
                dc.DrawBoxModel(WindowContainer);
            }

            //update title bar
            var windowRounding = (float)this.WindowContainer.RuleSet.Get <double>(StylePropertyName.WindowRounding);

            if (!flags.HaveFlag(WindowFlags.NoTitleBar))
            {
                // background
                using (var dc = this.titleBar.RenderOpen())
                {
                    dc.DrawBoxModel(this.titleBar.RuleSet, this.titleBar.Rect);
                }

                //icon
                using (var dc = titleIcon.RenderOpen())
                {
                    dc.DrawImage(@"assets/images/logo.png", this.titleIcon.Rect);
                }

                //title
                using (var dc = titleText.RenderOpen())
                {
                    dc.DrawGlyphRun(titleText.RuleSet, this.Name, titleText.Rect.TopLeft);
                }
            }

            this.ShowWindowClientArea(!this.Collapsed);

            if (!this.Collapsed)
            {
                //show and update window client area
                using (var dc = clientArea.RenderOpen())
                {
                    dc.DrawBoxModel(clientArea);
                }

                if (!flags.HaveFlag(WindowFlags.NoResize))
                {
                    if (this.ResizeGripNode == null)
                    {
                        var id   = this.GetID("#RESIZE");
                        var node = new Node(id, "Window_ResizeGrip");
                        this.ResizeGripNode = node;
                        this.AbsoluteVisualList.Add(node);
                    }

                    //resize grip
                    this.ResizeGripNode.ActiveSelf = true;
                    var resizeGripColor = Color.Clear;
                    var br = this.Rect.BottomRight;
                    if (!flags.HaveFlag(WindowFlags.AlwaysAutoResize) && !flags.HaveFlag(WindowFlags.NoResize))
                    {
                        // Manual resize
                        var resizeRect = new Rect(
                            br - new Vector(this.WindowContainer.PaddingLeft + this.WindowContainer.BorderLeft,
                                            this.WindowContainer.PaddingBottom + this.WindowContainer.BorderLeft),
                            br);
                        var resizeId = this.GetID("#RESIZE");
                        GUIBehavior.ButtonBehavior(resizeRect, resizeId, out var hovered, out var held,
                                                   ButtonFlags.FlattenChilds);
                        resizeGripColor =
                            held
                                ? this.WindowContainer.RuleSet.Get <Color>(StylePropertyName.ResizeGripColor, GUIState.Active)
                                : hovered
                                    ? this.WindowContainer.RuleSet.Get <Color>(StylePropertyName.ResizeGripColor, GUIState.Hover)
                                    : this.WindowContainer.RuleSet.Get <Color>(StylePropertyName.ResizeGripColor);

                        if (hovered || held)
                        {
                            Mouse.Instance.Cursor = (Cursor.NwseResize);
                        }
                        else
                        {
                            Mouse.Instance.Cursor = (Cursor.Default);
                        }

                        if (held)
                        {
                            // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
                            var t             = Mouse.Instance.Position - g.ActiveIdClickOffset - this.Position;
                            var newSizeWidth  = t.X + resizeRect.Width;
                            var newSizeHeight = t.Y + resizeRect.Height;
                            var resizeSize    = new Size(newSizeWidth, newSizeHeight);
                            this.ApplySize(resizeSize);
                        }
                    }

                    // Render resize grip
                    // (after the input handling so we don't have a frame of latency)
                    var borderBottom  = this.WindowContainer.RuleSet.BorderBottom;
                    var paddingBottom = this.WindowContainer.RuleSet.PaddingBottom;
                    var borderRight   = this.WindowContainer.RuleSet.BorderRight;
                    var paddingRight  = this.WindowContainer.RuleSet.PaddingRight;
                    using (var dc = this.ResizeGripNode.RenderOpen())
                    {
                        var path   = new PathGeometry();
                        var figure = new PathFigure();
                        var A      = br + new Vector(-10 - borderRight - paddingRight, 0);
                        var B      = br + new Vector(0, -10 - borderBottom - paddingBottom);
                        figure.StartPoint = A;
                        figure.IsFilled   = true;
                        figure.Segments.Add(new LineSegment(B, false));
                        figure.Segments.Add(new LineSegment(br, false));
                        figure.Segments.Add(new LineSegment(A, false));
                        path.Figures.Add(figure);
                        dc.DrawGeometry(new Brush(resizeGripColor), null, path);
                    }
                }

                this.ContentRect = Rect.Zero;
            }
        }
示例#15
0
        /// <summary>
        /// Create an auto-layout collapsing header.
        /// </summary>
        /// <param name="text">header text</param>
        /// <param name="open">opened</param>
        /// <returns>true when opened</returns>
        /// <remarks> It is horizontally stretched (factor 1).</remarks>
        public static bool CollapsingHeader(string text, ref bool open, float scale = 1)
        {
            GUIContext g      = GetCurrentContext();
            Window     window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            var id = window.GetID(text);

            // style apply
            var style = GUIStyle.Basic;

            style.PushStretchFactor(false, 1); //+1, always expand width
            style.PushPadding(2);              //4

            // rect
            var  height = style.GetLineHeight();
            Rect rect   = window.GetRect(id, new Size(0, height));

            if (rect == Layout.StackLayout.DummyRect) //TODO how shold dummy rect be correctly handled in every control?
            {
                style.PopStyle();                     //-1
                style.PopStyle(4);                    //-4
                return(false);
            }

            // interact
            bool hovered, held;
            bool pressed = GUIBehavior.ButtonBehavior(rect, id, out hovered, out held, ButtonFlags.PressedOnClick);

            if (pressed)
            {
                open = !open;
            }

            // render
            {
                DrawList d = window.DrawList;
                style.PushBgColor(new Color(0.40f, 0.40f, 0.90f, 0.45f), GUIState.Normal); //+1 TODO It's stupid to sprcifiy style like this. There should be a better way to do this.
                style.PushBgColor(new Color(0.45f, 0.45f, 0.90f, 0.80f), GUIState.Hover);  //+1
                style.PushBgColor(new Color(0.53f, 0.53f, 0.87f, 0.80f), GUIState.Active); //+1
                var   state = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;
                Color col   = style.Get <Color>(GUIStyleName.BackgroundColor, state);
                d.RenderFrame(rect.Min, rect.Max, col, false, 0);
                style.PopStyle(3);
                d.RenderCollapseTriangle(rect.Min, open, rect.Height, Color.Black, scale);
                rect.X += rect.Height;
                var delta = rect.Width - rect.Height;
                if (delta > 0)
                {
                    rect.Width = delta;
                }
                d.DrawText(rect, text, style, state);
            }

            // style restore
            style.PopStyle();  //-1
            style.PopStyle(4); //-4

            return(open);
        }
示例#16
0
文件: TreeNode.cs 项目: zwcloud/ImGui
        internal static bool DoTreeNode(int id, string text, ref bool open)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            window.TempData.LastItemId = id;

            //get or create the root node
            var container = window.RenderTree.CurrentContainer;
            var node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create nodes
                node = new Node(id, $"TreeNode<{text}>");
                node.AttachLayoutEntry();
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.TreeNode]);
            }
            container.AppendChild(node);
            var lineHeight = node.RuleSet.GetLineHeight();

            node.RuleSet.ApplyOptions(Height(lineHeight));
            node.ActiveSelf = true;

            // rect
            Rect rect = window.GetRect(id);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(rect, id, out var hovered, out var held, ButtonFlags.PressedOnClickRelease);

            node.State = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;
            if (pressed)
            {
                open = !open;
            }

            // last item state
            window.TempData.LastItemState = node.State;

            using (var dc = node.RenderOpen())
            {
                dc.DrawRectangle(new Brush(node.RuleSet.BackgroundColor), null, rect);
                dc.DrawGlyphRun(node.RuleSet, text, node.ContentRect.TopLeft + new Vector(rect.Height + node.PaddingLeft, 0));
                dc.RenderArrow(rect.Min + new Vector(node.RuleSet.PaddingTop, lineHeight * 0.15),
                               node.Height, node.RuleSet.FontColor, open ? Internal.Direcion.Down : Internal.Direcion.Right, 0.7);
            }

            if (open)
            {
                window.CheckStackSize(id, true);
                PushID(id);

                BeginHorizontal("#TreeContent");
                Space("Space", 20);
                BeginVertical("#Items");

                var cpId = HashCode.Combine(id, 23);
                window.CheckStackSize(cpId, true);
                PushID(cpId);
            }

            return(open);
        }
示例#17
0
        /// <summary>
        /// Create a button that will be actived when the mouse is over it.
        /// </summary>
        /// <param name="rect">position and size of the control</param>
        /// <param name="text">text to display on the control</param>
        /// <returns>whether it is activated (the mouse is over it)</returns>
        public static bool HoverButton(Rect rect, string text)
        {
            var window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            var id        = window.GetID(text);
            var container = window.AbsoluteVisualList;
            var node      = (Node)container.Find(visual => visual.Id == id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create button node
                node = new Node(id, $"HoverButton<{text}>");
                container.Add(node);
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
            }
            node.ActiveSelf = true;

            // rect
            node.Rect = window.GetRect(rect);

            // interact
            GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            // interact
            bool result  = false;
            var  uiState = Application.ImGuiContext;

            uiState.KeepAliveID(id);
            if (hovered)
            {
                uiState.SetHoverID(id);
                if (uiState.ActiveId == 0)
                {
                    result = true;
                }
            }
            else
            {
                if (uiState.ActiveId == id)
                {
                    uiState.SetActiveID(0);
                }
                result = false;
            }
            var state = GUI.Normal;

            if (uiState.ActiveId == id)
            {
                state = GUI.Active;
            }
            node.State = state;

            // last item state
            window.TempData.LastItemState = node.State;

            // draw
            using (var dc = node.RenderOpen())
            {
                dc.DrawBoxModel(text, node.RuleSet, node.Rect);
            }

            return(result);
        }
示例#18
0
        public void Setup(string name, Point position, Size size, ref bool open, double bg_alpha, WindowFlags flags,
                          long current_frame, Window parent_window)
        {
            Form          form = Form.current;
            GUIContext    g    = form.uiContext;
            WindowManager w    = g.WindowManager;

            this.Active          = true;
            this.BeginCount      = 0;
            this.ClipRect        = Rect.Big;
            this.LastActiveFrame = current_frame;

            // clear draw list, setup outer clip rect
            this.DrawList.Clear();
            this.DrawList.Init();
            Rect fullScreenRect = new Rect(0, 0, form.ClientSize);

            if (flags.HaveFlag(WindowFlags.ChildWindow) && !flags.HaveFlag(WindowFlags.ComboBox | WindowFlags.Popup))
            {
                this.DrawList.PushClipRect(parent_window.ClipRect, true);
                this.ClipRect = this.DrawList.GetCurrentClipRect();
            }
            else
            {
                this.DrawList.PushClipRect(fullScreenRect, true);
                this.ClipRect = this.DrawList.GetCurrentClipRect();
            }

            // draw outer clip rect
            //this.DrawList.AddRect(this.ClipRect.TopLeft, this.ClipRect.BottomRight, Color.Blue);//test only

            // Collapse window by double-clicking on title bar
            if (!(flags.HaveFlag(WindowFlags.NoTitleBar)) && !(flags.HaveFlag(WindowFlags.NoCollapse)))
            {
                if (w.HoveredWindow == this && g.IsMouseHoveringRect(this.TitleBarRect) &&
                    Mouse.Instance.LeftButtonDoubleClicked)
                {
                    this.Collapsed = !this.Collapsed;
                    w.FocusWindow(this);
                }
            }
            else
            {
                this.Collapsed = false;
            }

            #region size

            this.ApplySize(this.FullSize);
            this.Size = this.Collapsed ? this.TitleBarRect.Size : this.FullSize;

            #endregion

            #region position

            this.Position = new Point((int)this.PosFloat.X, (int)this.PosFloat.Y);
            if (flags.HaveFlag(WindowFlags.ChildWindow))
            {
                this.Position = this.PosFloat = position;
                this.Size     = this.FullSize = size; // 'size' provided by user passed via BeginChild()->Begin().
            }

            #endregion

            // Draw window + handle manual resize
            GUIStyle style           = this.Style;
            GUIStyle titleBarStyle   = this.TitleBarStyle;
            Rect     title_bar_rect  = this.TitleBarRect;
            float    window_rounding = (float)style.Get <double>(GUIStyleName.WindowRounding);
            if (this.Collapsed)
            {
                // Draw title bar only
                this.DrawList.AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, new Color(0.40f, 0.40f, 0.80f, 0.50f));
            }
            else
            {
                Color  resize_col         = Color.Clear;
                double rezie_size         = this.Style.Get <double>(GUIStyleName.ResizeGripSize);
                double resize_corner_size = Math.Max(rezie_size * 1.35, window_rounding + 1.0 + rezie_size * 0.2);
                if (!flags.HaveFlag(WindowFlags.AlwaysAutoResize) && !flags.HaveFlag(WindowFlags.NoResize))
                {
                    // Manual resize
                    var  br = this.Rect.BottomRight;
                    Rect resize_rect = new Rect(br - new Vector(resize_corner_size * 0.75f, resize_corner_size * 0.75f), br);
                    int  resize_id = this.GetID("#RESIZE");
                    bool hovered, held;
                    GUIBehavior.ButtonBehavior(resize_rect, resize_id, out hovered, out held, ButtonFlags.FlattenChilds);
                    resize_col =
                        held
                            ? style.Get <Color>(GUIStyleName.ResizeGripColor, GUIState.Active)
                            : hovered
                                ? style.Get <Color>(GUIStyleName.ResizeGripColor, GUIState.Hover)
                                : style.Get <Color>(GUIStyleName.ResizeGripColor);

                    if (hovered || held)
                    {
                        //Mouse.Instance.Cursor = Cursor.NeswResize;
                    }

                    if (held)
                    {
                        // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
                        var t = Mouse.Instance.Position - g.ActiveIdClickOffset - this.Position;
                        var new_size_width  = t.X + resize_rect.Width;
                        var new_size_height = t.Y + resize_rect.Height;
                        new_size_width =
                            MathEx.Clamp(new_size_width, 330, fullScreenRect.Width); //min size of a window is 145x235
                        new_size_height = MathEx.Clamp(new_size_height, 150, fullScreenRect.Height);
                        Size resize_size = new Size(new_size_width, new_size_height);
                        this.ApplySize(resize_size);

                        // adjust scroll parameters
                        var contentSize = this.ContentRect.Size;
                        if (contentSize != Size.Zero)
                        {
                            var vH = this.Rect.Height - this.TitleBarHeight - this.Style.BorderVertical -
                                     this.Style.PaddingVertical;
                            var cH = contentSize.Height;
                            if (cH > vH)
                            {
                                var oldScrollY = this.Scroll.Y;
                                oldScrollY    = MathEx.Clamp(oldScrollY, 0, cH - vH);
                                this.Scroll.Y = oldScrollY;
                            }
                        }
                    }

                    this.Size      = this.FullSize;
                    title_bar_rect = this.TitleBarRect;
                }


                // Window background
                Color bg_color = style.BackgroundColor;
                if (bg_alpha >= 0.0f)
                {
                    bg_color.A = bg_alpha;
                }
                if (bg_color.A > 0.0f)
                {
                    this.DrawList.AddRectFilled(this.Position + new Vector(0, this.TitleBarHeight),
                                                this.Rect.BottomRight, bg_color, window_rounding,
                                                flags.HaveFlag(WindowFlags.NoTitleBar) ? 15 : 4 | 8);
                }

                // Title bar
                if (!flags.HaveFlag(WindowFlags.NoTitleBar))
                {
                    this.DrawList.AddRectFilled(title_bar_rect.TopLeft, title_bar_rect.BottomRight,
                                                w.FocusedWindow == this
                            ? titleBarStyle.Get <Color>(GUIStyleName.BackgroundColor, GUIState.Active)
                            : titleBarStyle.Get <Color>(GUIStyleName.BackgroundColor), window_rounding, 1 | 2);
                }

                // Render resize grip
                // (after the input handling so we don't have a frame of latency)
                if (!flags.HaveFlag(WindowFlags.NoResize))
                {
                    Point br           = this.Rect.BottomRight;
                    var   borderBottom = this.Style.BorderBottom;
                    var   borderRight  = this.Style.BorderRight;
                    this.DrawList.PathLineTo(br + new Vector(-resize_corner_size, -borderBottom));
                    this.DrawList.PathLineTo(br + new Vector(-borderRight, -resize_corner_size));
                    this.DrawList.PathArcToFast(
                        new Point(br.X - window_rounding - borderRight, br.Y - window_rounding - borderBottom), window_rounding,
                        0, 3);
                    this.DrawList.PathFill(resize_col);
                }

                // Scroll bar
                if (flags.HaveFlag(WindowFlags.VerticalScrollbar))
                {
                    //get content size without clip
                    var contentPosition = this.ContentRect.TopLeft;
                    var contentSize     = this.ContentRect.Size;
                    if (contentSize != Size.Zero)
                    {
                        int id = this.GetID("#SCROLLY");

                        double scrollBarWidth = this.Style.Get <double>(GUIStyleName.ScrollBarWidth);
                        Point  scroll_TopLeft = new Point(
                            this.Rect.Right - scrollBarWidth - this.Style.BorderRight - this.Style.PaddingRight,
                            this.Rect.Top + this.TitleBarHeight + this.Style.BorderTop + this.Style.PaddingTop);
                        var sH = this.Rect.Height - this.TitleBarHeight - this.Style.BorderVertical -
                                 this.Style.PaddingVertical
                                 + (flags.HaveFlag(WindowFlags.NoResize) ? 0 : -resize_corner_size);
                        var vH = this.Rect.Height - this.TitleBarHeight - this.Style.BorderVertical -
                                 this.Style.PaddingVertical;
                        Point scroll_BottomRight = scroll_TopLeft + new Vector(scrollBarWidth, sH);
                        Rect  bgRect             = new Rect(scroll_TopLeft, scroll_BottomRight);

                        var cH     = contentSize.Height;
                        var top    = this.Scroll.Y * sH / cH;
                        var height = sH * vH / cH;

                        if (height < sH)
                        {
                            // handle mouse click/drag
                            bool held            = false;
                            bool hovered         = false;
                            bool previously_held = (g.ActiveId == id);
                            GUIBehavior.ButtonBehavior(bgRect, id, out hovered, out held);
                            if (held)
                            {
                                top = Mouse.Instance.Position.Y - bgRect.Y - 0.5 * height;
                                top = MathEx.Clamp(top, 0, sH - height);
                                var targetScrollY = top * cH / sH;
                                this.SetWindowScrollY(targetScrollY);
                            }

                            Point scrollButton_TopLeft    = scroll_TopLeft + new Vector(0, top);
                            Point scrllButton_BottomRight = scrollButton_TopLeft + new Vector(scrollBarWidth, height);
                            Rect  buttonRect = new Rect(scrollButton_TopLeft, scrllButton_BottomRight);

                            //Draw vertical scroll bar and button
                            {
                                var bgColor     = this.Style.Get <Color>(GUIStyleName.ScrollBarBackgroundColor);
                                var buttonColor = this.Style.Get <Color>(GUIStyleName.ScrollBarButtonColor,
                                                                         held ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal);
                                this.DrawList.AddRectFilled(bgRect.TopLeft, buttonRect.TopRight, bgColor);
                                this.DrawList.AddRectFilled(buttonRect.TopLeft, buttonRect.BottomRight, buttonColor);
                                this.DrawList.AddRectFilled(buttonRect.BottomLeft, bgRect.BottomRight, bgColor);
                            }
                        }
                        else
                        {
                            var bgColor = this.Style.Get <Color>(GUIStyleName.ScrollBarBackgroundColor);
                            this.DrawList.AddRectFilled(bgRect.TopLeft, bgRect.BottomRight, bgColor);
                        }
                    }
                }
                this.ContentRect = Rect.Zero;
            }

            // draw title bar text
            if (!flags.HaveFlag(WindowFlags.NoTitleBar))
            {
                // title text
                var state = w.FocusedWindow == this ? GUIState.Active : GUIState.Normal;
                this.DrawList.DrawBoxModel(title_bar_rect, name, titleBarStyle, state);

                // close button
                if (CloseButton(this.GetID("#CLOSE"), new Rect(title_bar_rect.TopRight + new Vector(-45, 0), title_bar_rect.BottomRight)))
                {
                    open = false;
                }
            }

            // Borders
            if (flags.HaveFlag(WindowFlags.ShowBorders))
            {
                var state = w.FocusedWindow == this ? GUIState.Active : GUIState.Normal;
                // window border
                var borderColor = this.Style.Get <Color>(GUIStyleName.WindowBorderColor, state);
                this.DrawList.AddRect(this.Position, this.Position + new Vector(this.Size.Width, this.Size.Height),
                                      borderColor, window_rounding);
                // window shadow
#if false
                {
                    var state       = w.FocusedWindow == this ? GUIState.Active : GUIState.Normal;
                    var shadowColor = this.Style.Get <Color>(GUIStyleName.WindowShadowColor, state);
                    var shadowWidth = this.Style.Get <double>(GUIStyleName.WindowShadowWidth, state);
                    var d           = this.DrawList;

                    //top-left corner

                    d.AddRectFilledGradientTopLeftToBottomRight(this.Rect.TopLeft + new Vector(-shadowWidth, -shadowWidth), this.Rect.TopLeft, Color.Clear, shadowColor);
                    //top
                    d.AddRectFilledGradient(this.Rect.TopLeft + new Vector(0, -shadowWidth), this.Rect.TopRight, Color.Clear, shadowColor);
                    d.AddRectFilledGradient(this.Rect.BottomLeft, this.Rect.BottomRight + new Vector(0, shadowWidth), shadowColor, Color.Clear);
                }
#endif
            }

            // Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
            this.WindowClippedRect = this.Rect;
            this.WindowClippedRect.Intersect(this.ClipRect);
        }
示例#19
0
        /// <summary>
        /// Create an auto-layout button that will be actived when the mouse is over it.
        /// </summary>
        /// <param name="text">text to display on the button</param>
        /// <param name="options">layout options that specify layouting properties. See also <see cref="GUILayout.Width"/>, <see cref="GUILayout.Height"/>, <see cref="GUILayout.ExpandWidth"/>, <see cref="GUILayout.ExpandHeight"/>, <see cref="GUILayout.StretchWidth"/>, <see cref="GUILayout.StretchHeight"/></param>
        /// <returns>whether it is activated (the mouse is over it)</returns>
        public static bool HoverButton(string text, LayoutOptions?options)
        {
            var window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            var id        = window.GetID(text);
            var container = window.RenderTree.CurrentContainer;
            var node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create button node
                node = new Node(id, $"HoverButton<{text}>");
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
                var size = node.RuleSet.CalcContentBoxSize(text, GUIState.Normal);
                node.AttachLayoutEntry(size);
                node.UseBoxModel = true;
            }
            container.AppendChild(node);
            node.RuleSet.ApplyOptions(options);
            node.ActiveSelf = true;

            // rect
            node.Rect = window.GetRect(id);

            // interact
            GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            bool result = false;
            // interact
            var uiState = Application.ImGuiContext;

            uiState.KeepAliveID(id);
            if (hovered)
            {
                uiState.SetHoverID(id);
                if (uiState.ActiveId == 0)
                {
                    uiState.SetActiveID(id);
                    result = true;
                }
            }
            else
            {
                if (uiState.ActiveId == id)
                {
                    uiState.SetActiveID(0);
                }
                result = false;
            }
            var state = GUI.Normal;

            if (uiState.ActiveId == id)
            {
                state = GUI.Active;
            }
            node.State = state;

            // last item state
            window.TempData.LastItemState = node.State;

            // draw
            using (var dc = node.RenderOpen())
            {
                dc.DrawBoxModel(text, node.RuleSet, node.Rect);
            }

            return(result);
        }
示例#20
0
        /// <summary>
        /// Create a button. When the user click it, something will happen immediately.
        /// </summary>
        /// <param name="rect">position and size of the control</param>
        /// <param name="text">text to display on the button</param>
        /// <returns>true when the users clicks the button.</returns>
        public static bool Button(Rect rect, string text)
        {
            Window window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            int  id = window.GetID(text);
            var  t = window.RenderTree.CurrentContainer;
            Node node = t.GetNodeById(id);
            Node backgroundNode = null, textNode = null;

            if (node == null)
            {
                //create button node
                node = new Node(id, $"Button<{text}>");
                t.Add(node);
                window.IDStack.Push(id);

                //background
                var backgroundNodeId = window.GetID("Background");
                backgroundNode           = new Node(backgroundNodeId, "Background");
                backgroundNode.Primitive = new PathPrimitive();
                backgroundNode.IsFill    = true;

                //text
                var textNodeId = window.GetID("Text");
                textNode = new Node(textNodeId, "Text");
                var textPrimitive = new TextPrimitive();
                textPrimitive.Text = text;
                textNode.Primitive = textPrimitive;

                node.Add(backgroundNode);
                node.Add(textNode);
                window.IDStack.Pop();
            }
            else
            {
                backgroundNode = node.GetNodeByName("Background");
                textNode       = node.GetNodeByName("Text");
            }

            Debug.Assert(backgroundNode != null);
            Debug.Assert(textNode != null);

            // rect
            backgroundNode.Rect = window.GetRect(rect);
            textNode.Rect       = backgroundNode.Rect;

            var primitive = backgroundNode.Primitive as PathPrimitive;

            Debug.Assert(primitive != null, nameof(primitive) + " != null");
            primitive.PathClear();
            primitive.PathRect(backgroundNode.Rect);

            // style apply
            var style = GUIStyle.Basic;

            style.Save();
            style.ApplySkin(GUIControlName.Button);

            // interact
            bool pressed = GUIBehavior.ButtonBehavior(backgroundNode.Rect, node.Id, out var hovered, out var held, 0);
            var  state   = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            var brush = backgroundNode.Brush;

            brush.FillColor = style.Get <Color>(GUIStyleName.BackgroundColor, state);

            var strokeStyle = backgroundNode.StrokeStyle;

            strokeStyle.Color = style.GetBorderColor(state);

            style.Restore();

            return(pressed);
        }
示例#21
0
        internal static ComboBoxContext comboBoxContext;//TODO move this to Window.storage

        public static int ComboBox(Rect rect, string[] texts)
        {
            var window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(comboBoxContext.SelectedIndex);
            }

            //get or create the root node
            var id        = window.GetID(texts);
            var container = window.AbsoluteVisualList;
            var node      = (Node)container.Find(visual => visual.Id == id);

            if (node == null)
            {
                //create button node
                node = new Node(id, $"Combobox<{texts[0]}..>");
                container.Add(node);
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.ComboBox]);
                //set initial states TODO move to shared storage
                GUI.comboBoxContext               = new ComboBoxContext();
                GUI.comboBoxContext.Texts         = texts;
                GUI.comboBoxContext.Text          = texts[0];
                GUI.comboBoxContext.SelectedIndex = 0;
            }
            node.RuleSet.ApplyStack();
            node.ActiveSelf = true;

            // rect
            node.Rect = window.GetRect(rect);

            // interact
            var pressed = GUIBehavior.ButtonBehavior(node.Rect, node.Id, out var hovered, out var held);

            if (pressed)
            {
                node.State = GUIState.Active;

                comboBoxContext.WindowOpened = !comboBoxContext.WindowOpened;
            }

            comboBoxContext.Text = comboBoxContext.Texts[comboBoxContext.SelectedIndex];

            // last item state
            window.TempData.LastItemState = node.State;

            //combo
            if (comboBoxContext.WindowOpened)
            {
                //calculate window rect
                Rect comboPopupWindowRect;
                {
                    var maxLength       = 0;
                    var maxLengthString = string.Empty;
                    foreach (var s in texts)
                    {
                        if (s.Length <= maxLength)
                        {
                            continue;
                        }
                        maxLength       = s.Length;
                        maxLengthString = s;
                    }

                    var size = node.RuleSet.CalcSize(maxLengthString);
                    size.Height *= texts.Length;

                    size += new Vector(100, 100);
                    //TEMP HACK Extend the size a little: otherwise a LayoutException will happen

                    var clientPos = node.Rect.BottomLeft;
                    comboPopupWindowRect = new Rect(clientPos, size);
                }

                GUILayout.SetNextWindowPos(comboPopupWindowRect.Location);
                var clickedIndx = -1;
                Begin($"##ComboWindow_{node.Name}", comboPopupWindowRect,
                      WindowFlags.Popup | WindowFlags.NoTitleBar | WindowFlags.NoCollapse
                      | WindowFlags.NoMove | WindowFlags.NoResize | WindowFlags.NoScrollbar);
                {
                    GUILayout.BeginVertical("ComboBox");
                    for (var i = 0; i < texts.Length; i++)
                    {
                        if (GUILayout.Button(texts[i]))
                        {
                            clickedIndx = i;
                        }
                    }
                    GUILayout.EndVertical();
                }
                End();
                if (clickedIndx >= 0)
                {
                    comboBoxContext.SelectedIndex = clickedIndx;
                    comboBoxContext.WindowOpened  = false;
                    node.State = Normal;
                }
            }

            //render
            using var g = node.RenderOpen();
            var ruleSet = node.RuleSet;

            g.DrawBoxModel(node.RuleSet, node.Rect);
            g.RenderArrow(node.Rect.Min + new Vector(node.PaddingLeft, 0), node.Height,
                          node.RuleSet.FontColor, Internal.Direcion.Down, 1.0);
            g.DrawGlyphRun(comboBoxContext.Text, ruleSet.FontSize, ruleSet.FontFamily, ruleSet.FontColor,
                           node.Rect.Min + new Vector(node.Height + ruleSet.PaddingLeft, ruleSet.PaddingTop));

            return(comboBoxContext.SelectedIndex);
        }
示例#22
0
        public static bool RadioButton(string text, bool active)
        {
            var window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            //get or create the root node
            var id        = window.GetID(text);
            var container = window.RenderTree.CurrentContainer;
            var node      = container.GetNodeById(id);

            text = Utility.FindRenderedText(text);
            if (node == null)
            {
                //create node
                node             = new Node(id, $"RadioButton<{text}>");
                node.UseBoxModel = true;
                node.RuleSet.Replace(GUISkin.Current[GUIControlName.Button]);
                var size = node.RuleSet.CalcContentBoxSize(text, GUIState.Normal);
                size.Width += size.Height + node.RuleSet.PaddingLeft;
                node.AttachLayoutEntry(size);
            }
            container.AppendChild(node);

            node.ActiveSelf = true;

            // rect
            node.Rect = window.GetRect(id);

            bool pressed = GUIBehavior.ButtonBehavior(node.Rect, id, out var hovered, out var held);

            node.State = (held && hovered) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;

            // last item state
            window.TempData.LastItemState = node.State;

            using (var d = node.RenderOpen())
            {
                Color backgroundCircleColor;
                switch (node.State)
                {
                case GUIState.Active:
                    backgroundCircleColor = Color.DarkBlue;
                    break;

                case GUIState.Hover:
                    backgroundCircleColor = Color.Argb(200, 173, 216, 230);
                    break;

                default:
                    backgroundCircleColor = Color.LightBlue;
                    break;
                }


                Point center = new Point(node.Rect.X + node.Height / 2, node.Rect.Y + node.Height / 2);
                center.x = (int)center.x + 0.3f;
                center.y = (int)center.y + 0.3f;
                var radius = node.Rect.Height * 0.3f;

                d.DrawEllipse(new Brush(backgroundCircleColor), null, center, radius, radius);
                if (active)
                {
                    var pad = Math.Max(1.0f, (int)(node.Height * 0.15));
                    d.DrawEllipse(new Brush(Color.Black), null, center, radius - pad, radius - pad);
                }

                if (!string.IsNullOrWhiteSpace(text))
                {
                    d.DrawGlyphRun(node.RuleSet, text, node.Rect.Location + new Vector(node.Rect.Height + node.RuleSet.PaddingLeft, 0));
                }
            }

            return(pressed);
        }
示例#23
0
        public static bool TreeNode(string label, ref bool open)
        {
            GUIContext g      = GetCurrentContext();
            Window     window = GetCurrentWindow();

            if (window.SkipItems)
            {
                return(false);
            }

            BeginVertical(label + "_Tree");

            var id = window.GetID(label);

            // style apply
            var style = GUIStyle.Basic;

            style.PushStretchFactor(false, 1);  //+1, always expand width
            style.PushPadding((1, 1, 1, 5));    //+4

            do
            {
                // rect
                var  lineHeight = style.GetLineHeight();
                Rect rect       = window.GetRect(id, new Size(0, lineHeight));
                if (rect == Layout.StackLayout.DummyRect)    //TODO how shold dummy rect be correctly handled in every control?
                {
                    break;
                }

                // interact
                bool hovered, held;
                bool pressed = GUIBehavior.ButtonBehavior(rect, id, out hovered, out held, ButtonFlags.PressedOnClick);
                if (pressed)
                {
                    open = !open;
                }

                // render
                {
                    DrawList d     = window.DrawList;
                    var      state = (hovered && held) ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal;
                    if (hovered || held)
                    {
                        style.PushBgColor(new Color(0.40f, 0.40f, 0.90f, 0.45f), GUIState.Normal);   //+1 TODO It's stupid to sprcifiy style like this. There should be a better way to do this.
                        style.PushBgColor(new Color(0.45f, 0.45f, 0.90f, 0.80f), GUIState.Hover);    //+1
                        style.PushBgColor(new Color(0.53f, 0.53f, 0.87f, 0.80f), GUIState.Active);   //+1
                        var color = style.Get <Color>(GUIStyleName.BackgroundColor, state);
                        d.RenderFrame(rect.Min, rect.Max, color, false, 0);
                        style.PopStyle(3);    //-3
                    }
                    d.RenderCollapseTriangle(rect.Min + new Vector(0 + style.PaddingTop, lineHeight * 0.15f), open, lineHeight, Color.White, 0.7);
                    rect.X += rect.Height;
                    var delta = rect.Width - rect.Height;
                    if (delta > 0)
                    {
                        rect.Width = delta;
                    }
                    d.DrawText(rect, label, style, state);
                }
            }while(false);

            // style restore
            style.PopStyle();    //-1
            style.PopStyle(4);   //-4

            BeginHorizontal("#Content");
            Space("Space", 20);
            BeginVertical("#Items");
            return(open);
        }
示例#24
0
        public static bool Begin(string name, ref bool open, Point position, Size size, double bg_alpha = 1, WindowFlags flags = WindowFlags.VerticalScrollbar)
        {
            Form          form = Form.current;
            GUIContext    g    = form.uiContext;
            WindowManager w    = g.WindowManager;

            Debug.Assert(name != null);                        // Window name required
            Debug.Assert(g.Initialized);                       // Forgot to call NewFrame()
            Debug.Assert(g.FrameCountEnded != g.FrameCount);   // Called Render() or EndFrame() and haven't called NewFrame() again yet

            if (flags.HaveFlag(WindowFlags.NoInputs))
            {
                flags |= WindowFlags.NoMove | WindowFlags.NoResize;
            }

            // Find or create
            Window window = w.FindWindowByName(name) ?? w.CreateWindow(name, position, size, flags);

            // Check if this is the first call of Begin
            long current_frame            = g.FrameCount;
            bool first_begin_of_the_frame = (window.LastActiveFrame != current_frame);

            if (first_begin_of_the_frame)
            {
                window.Flags = flags;
            }
            else
            {
                flags = window.Flags;
            }

            // Add to stack
            Window parent_window = w.WindowStack.Count != 0 ? w.WindowStack[w.WindowStack.Count - 1] : null;

            w.WindowStack.Add(window);
            w.CurrentWindow = window;
            Debug.Assert(parent_window != null || !flags.HaveFlag(WindowFlags.ChildWindow));

            // Update known root window (if we are a child window, otherwise window == window->RootWindow)
            int root_idx;

            for (root_idx = w.WindowStack.Count - 1; root_idx > 0; root_idx--)
            {
                if (!(w.WindowStack[root_idx].Flags.HaveFlag(WindowFlags.ChildWindow)))
                {
                    break;
                }
            }
            window.RootWindow = w.WindowStack[root_idx];

            // When reusing window again multiple times a frame, just append content (don't need to setup again)
            if (first_begin_of_the_frame)
            {
                window.Active          = true;
                window.BeginCount      = 0;
                window.ClipRect        = Rect.Big;
                window.LastActiveFrame = current_frame;

                // clear draw list, setup outer clip rect
                window.DrawList.Clear();
                window.DrawList.Init();
                Rect fullScreenRect = new Rect(0, 0, form.ClientSize);
                if (flags.HaveFlag(WindowFlags.ChildWindow) && !flags.HaveFlag(WindowFlags.ComboBox | WindowFlags.Popup))
                {
                    window.DrawList.PushClipRect(parent_window.ClipRect, true);
                    window.ClipRect = window.DrawList.GetCurrentClipRect();
                }
                else
                {
                    window.DrawList.PushClipRect(fullScreenRect, true);
                    window.ClipRect = window.DrawList.GetCurrentClipRect();
                }

                // draw outer clip rect
                //window.DrawList.AddRect(window.ClipRect.TopLeft, window.ClipRect.BottomRight, Color.Blue);//test only

                // Collapse window by double-clicking on title bar
                if (!(flags.HaveFlag(WindowFlags.NoTitleBar)) && !(flags.HaveFlag(WindowFlags.NoCollapse)))
                {
                    if (w.HoveredWindow == window && g.IsMouseHoveringRect(window.TitleBarRect) && Mouse.Instance.LeftButtonDoubleClicked)
                    {
                        window.Collapsed = !window.Collapsed;
                        w.FocusWindow(window);
                    }
                }
                else
                {
                    window.Collapsed = false;
                }

                #region size
                window.ApplySize(window.FullSize);
                window.Size = window.Collapsed ? window.TitleBarRect.Size : window.FullSize;
                #endregion

                #region position
                window.Position = new Point((int)window.PosFloat.X, (int)window.PosFloat.Y);
                if (flags.HaveFlag(WindowFlags.ChildWindow))
                {
                    window.Position = window.PosFloat = position;
                    window.Size     = window.FullSize = size; // 'size' provided by user passed via BeginChild()->Begin().
                }
                #endregion

                // Draw window + handle manual resize
                GUIStyle style           = window.Style;
                GUIStyle titleBarStyle   = window.TitleBarStyle;
                Rect     title_bar_rect  = window.TitleBarRect;
                float    window_rounding = (float)style.Get <double>(GUIStyleName.WindowRounding);
                if (window.Collapsed)
                {
                    // Draw title bar only
                    window.DrawList.AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, new Color(0.40f, 0.40f, 0.80f, 0.50f));
                }
                else
                {
                    Color  resize_col         = Color.Clear;
                    double rezie_size         = window.Style.Get <double>(GUIStyleName.ResizeGripSize);
                    double resize_corner_size = Math.Max(rezie_size * 1.35, window_rounding + 1.0 + rezie_size * 0.2);
                    if (!flags.HaveFlag(WindowFlags.AlwaysAutoResize) && !flags.HaveFlag(WindowFlags.NoResize))
                    {
                        // Manual resize
                        var  br = window.Rect.BottomRight;
                        Rect resize_rect = new Rect(br - new Vector(resize_corner_size * 0.75f, resize_corner_size * 0.75f), br);
                        int  resize_id = window.GetID("#RESIZE");
                        bool hovered, held;
                        GUIBehavior.ButtonBehavior(resize_rect, resize_id, out hovered, out held, ButtonFlags.FlattenChilds);
                        resize_col =
                            held ? style.Get <Color>(GUIStyleName.ResizeGripColor, GUIState.Active) :
                            hovered?style.Get <Color>(GUIStyleName.ResizeGripColor, GUIState.Hover) :
                                style.Get <Color>(GUIStyleName.ResizeGripColor);

                        if (hovered || held)
                        {
                            //Mouse.Instance.Cursor = Cursor.NeswResize;
                        }

                        if (held)
                        {
                            // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
                            var t = Mouse.Instance.Position - g.ActiveIdClickOffset - window.Position;
                            var new_size_width  = t.X + resize_rect.Width;
                            var new_size_height = t.Y + resize_rect.Height;
                            new_size_width  = MathEx.Clamp(new_size_width, 330, fullScreenRect.Width);//min size of a window is 145x235
                            new_size_height = MathEx.Clamp(new_size_height, 150, fullScreenRect.Height);
                            Size resize_size = new Size(new_size_width, new_size_height);
                            window.ApplySize(resize_size);

                            // adjust scroll parameters
                            var contentSize = window.ContentRect.Size;
                            if (contentSize != Size.Zero)
                            {
                                var vH = window.Rect.Height - window.TitleBarHeight - window.Style.BorderVertical - window.Style.PaddingVertical;
                                var cH = contentSize.Height;
                                if (cH > vH)
                                {
                                    var oldScrollY = window.Scroll.Y;
                                    oldScrollY      = MathEx.Clamp(oldScrollY, 0, cH - vH);
                                    window.Scroll.Y = oldScrollY;
                                }
                            }
                        }

                        window.Size    = window.FullSize;
                        title_bar_rect = window.TitleBarRect;
                    }


                    // Window background
                    Color bg_color = style.BackgroundColor;
                    if (bg_alpha >= 0.0f)
                    {
                        bg_color.A = bg_alpha;
                    }
                    if (bg_color.A > 0.0f)
                    {
                        window.DrawList.AddRectFilled(window.Position + new Vector(0, window.TitleBarHeight), window.Rect.BottomRight, bg_color, window_rounding, flags.HaveFlag(WindowFlags.NoTitleBar) ? 15 : 4 | 8);
                    }

                    // Title bar
                    if (!flags.HaveFlag(WindowFlags.NoTitleBar))
                    {
                        window.DrawList.AddRectFilled(title_bar_rect.TopLeft, title_bar_rect.BottomRight,
                                                      w.FocusedWindow == window ?
                                                      titleBarStyle.Get <Color>(GUIStyleName.BackgroundColor, GUIState.Active) :
                                                      titleBarStyle.Get <Color>(GUIStyleName.BackgroundColor), window_rounding, 1 | 2);
                    }

                    // Render resize grip
                    // (after the input handling so we don't have a frame of latency)
                    if (!flags.HaveFlag(WindowFlags.NoResize))
                    {
                        Point br           = window.Rect.BottomRight;
                        var   borderBottom = window.Style.BorderBottom;
                        var   borderRight  = window.Style.BorderRight;
                        window.DrawList.PathLineTo(br + new Vector(-resize_corner_size, -borderBottom));
                        window.DrawList.PathLineTo(br + new Vector(-borderRight, -resize_corner_size));
                        window.DrawList.PathArcToFast(new Point(br.X - window_rounding - borderRight, br.Y - window_rounding - borderBottom), window_rounding, 0, 3);
                        window.DrawList.PathFill(resize_col);
                    }

                    // Scroll bar
                    if (flags.HaveFlag(WindowFlags.VerticalScrollbar))
                    {
                        //get content size without clip
                        var contentPosition = window.ContentRect.TopLeft;
                        var contentSize     = window.ContentRect.Size;
                        if (contentSize != Size.Zero)
                        {
                            int id = window.GetID("#SCROLLY");

                            double scrollBarWidth = window.Style.Get <double>(GUIStyleName.ScrollBarWidth);
                            Point  scroll_TopLeft = new Point(
                                window.Rect.Right - scrollBarWidth - window.Style.BorderRight - window.Style.PaddingRight,
                                window.Rect.Top + window.TitleBarHeight + window.Style.BorderTop + window.Style.PaddingTop);
                            var   sH = window.Rect.Height - window.TitleBarHeight - window.Style.BorderVertical - window.Style.PaddingVertical - resize_corner_size;
                            var   vH = window.Rect.Height - window.TitleBarHeight - window.Style.BorderVertical - window.Style.PaddingVertical;
                            Point scroll_BottomRight = scroll_TopLeft + new Vector(scrollBarWidth, sH);
                            Rect  bgRect             = new Rect(scroll_TopLeft, scroll_BottomRight);

                            var cH     = contentSize.Height;
                            var top    = window.Scroll.Y * sH / cH;
                            var height = sH * vH / cH;

                            if (height < sH)
                            {
                                // handle mouse click/drag
                                bool held            = false;
                                bool hovered         = false;
                                bool previously_held = (g.ActiveId == id);
                                GUIBehavior.ButtonBehavior(bgRect, id, out hovered, out held);
                                if (held)
                                {
                                    top = Mouse.Instance.Position.Y - bgRect.Y - 0.5 * height;
                                    top = MathEx.Clamp(top, 0, sH - height);
                                    var targetScrollY = top * cH / sH;
                                    window.SetWindowScrollY(targetScrollY);
                                }

                                Point scrollButton_TopLeft    = scroll_TopLeft + new Vector(0, top);
                                Point scrllButton_BottomRight = scrollButton_TopLeft + new Vector(scrollBarWidth, height);
                                Rect  buttonRect = new Rect(scrollButton_TopLeft, scrllButton_BottomRight);

                                //Draw vertical scroll bar and button
                                {
                                    var bgColor     = window.Style.Get <Color>(GUIStyleName.ScrollBarBackgroundColor);
                                    var buttonColor = window.Style.Get <Color>(GUIStyleName.ScrollBarButtonColor, held ? GUIState.Active : hovered ? GUIState.Hover : GUIState.Normal);
                                    window.DrawList.AddRectFilled(bgRect.TopLeft, buttonRect.TopRight, bgColor);
                                    window.DrawList.AddRectFilled(buttonRect.TopLeft, buttonRect.BottomRight, buttonColor);
                                    window.DrawList.AddRectFilled(buttonRect.BottomLeft, bgRect.BottomRight, bgColor);
                                }
                            }
                            else
                            {
                                var bgColor = window.Style.Get <Color>(GUIStyleName.ScrollBarBackgroundColor);
                                window.DrawList.AddRectFilled(bgRect.TopLeft, bgRect.BottomRight, bgColor);
                            }
                        }
                    }
                    window.ContentRect = Rect.Zero;
                }

                // draw title bar text
                if (!flags.HaveFlag(WindowFlags.NoTitleBar))
                {
                    var state = w.FocusedWindow == window ? GUIState.Active : GUIState.Normal;
                    window.DrawList.DrawBoxModel(title_bar_rect, name, titleBarStyle, state);
                }

                // Borders
                if (flags.HaveFlag(WindowFlags.ShowBorders))
                {
                    var state = w.FocusedWindow == window ? GUIState.Active : GUIState.Normal;
                    // window border
                    var borderColor = window.Style.Get <Color>(GUIStyleName.WindowBorderColor, state);
                    window.DrawList.AddRect(window.Position, window.Position + new Vector(window.Size.Width, window.Size.Height),
                                            borderColor, window_rounding);
                    // window shadow
#if false
                    {
                        var state       = w.FocusedWindow == window ? GUIState.Active : GUIState.Normal;
                        var shadowColor = window.Style.Get <Color>(GUIStyleName.WindowShadowColor, state);
                        var shadowWidth = window.Style.Get <double>(GUIStyleName.WindowShadowWidth, state);
                        var d           = window.DrawList;

                        //top-left corner

                        d.AddRectFilledGradientTopLeftToBottomRight(window.Rect.TopLeft + new Vector(-shadowWidth, -shadowWidth), window.Rect.TopLeft, Color.Clear, shadowColor);
                        //top
                        d.AddRectFilledGradient(window.Rect.TopLeft + new Vector(0, -shadowWidth), window.Rect.TopRight, Color.Clear, shadowColor);
                        d.AddRectFilledGradient(window.Rect.BottomLeft, window.Rect.BottomRight + new Vector(0, shadowWidth), shadowColor, Color.Clear);
                    }
#endif
                }

                // Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
                window.WindowClippedRect = window.Rect;
                window.WindowClippedRect.Intersect(window.ClipRect);
            }

            // Inner clipping rectangle
            {
                // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
                // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior.
                Rect        title_bar_rect    = window.TitleBarRect;
                const float border_size       = 0;
                var         paddingHorizontal = window.Style.PaddingHorizontal;
                // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
                Rect clip_rect = new Rect(
                    new Point(Math.Floor(0.5f + title_bar_rect.Min.X + Math.Max(border_size, Math.Floor(paddingHorizontal * 0.5f))),
                              Math.Floor(0.5f + title_bar_rect.Max.Y + border_size)),
                    new Point(Math.Floor(0.5f + window.Position.X + window.Size.Width - Math.Max(border_size, Math.Floor(paddingHorizontal * 0.5f))),
                              Math.Floor(0.5f + window.Position.Y + window.Size.Height - border_size)));
                window.DrawList.PushClipRect(clip_rect, true);
                window.ClipRect = clip_rect;
                //window.DrawList.AddRect(window.ClipRect.TopLeft, window.ClipRect.BottomRight, Color.Red);//test only
            }

            // Clear 'accessed' flag last thing
            if (first_begin_of_the_frame)
            {
                window.Accessed = false;
            }
            window.BeginCount++;

            // Child window can be out of sight and have "negative" clip windows.
            // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar).
            if (flags.HaveFlag(WindowFlags.ChildWindow))
            {
                Debug.Assert(flags.HaveFlag(WindowFlags.NoTitleBar));
                window.Collapsed = parent_window != null && parent_window.Collapsed;
            }

            window.StackLayout.Begin();

            // Return false if we don't intend to display anything to allow user to perform an early out optimization
            window.SkipItems = window.Collapsed || !window.Active;
            return(!window.SkipItems);
        }