Exemple #1
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 (this.MovedWindowMoveId != 0 && this.MovedWindowMoveId == g.ActiveId)
            {
                g.KeepAliveID(this.MovedWindowMoveId);
                Debug.Assert(this.MovedWindow != null && this.MovedWindow.RootWindow != null);
                Debug.Assert(this.MovedWindow.RootWindow.MoveID == this.MovedWindowMoveId);
                if (Mouse.Instance.LeftButtonState == KeyState.Down)
                {
                    if (!this.MovedWindow.Flags.HaveFlag(WindowFlags.NoMove))
                    {
                        this.MovedWindow.Position += Mouse.Instance.MouseDelta;
                    }
                    this.FocusWindow(this.MovedWindow);
                }
                else
                {
                    g.SetActiveID(0);
                    this.MovedWindow       = null;
                    this.MovedWindowMoveId = 0;
                }
            }
            else
            {
                this.MovedWindow       = null;
                this.MovedWindowMoveId = 0;
            }

            // 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.MovedWindow ?? 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.MovedWindow != null) ? this.MovedWindow.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.Scroll.Y - Math.Sign(Mouse.Instance.MouseWheel) * 20 /*scroll step*/;
                        float  window_rounding    = (float)window.WindowContainer.RuleSet.Get <double>(GUIStyleName.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;
            }

            // 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();
        }
Exemple #2
0
        public static bool Begin(string name, ref bool open, Point position, Size size, double bg_alpha = 1, WindowFlags flags = WindowFlags.VerticalScrollbar)
        {
            if (bg_alpha < 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(bg_alpha), nameof(bg_alpha) + " cannot be negative.");
            }

            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.FirstUpdate(name, size, ref open, bg_alpha, flags, current_frame, parent_window);
            }

            // 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.WindowContainer.RuleSet.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.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;
            }

            // 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;

            window.RenderTree.CurrentContainer = window.ClientAreaNode;

            return(!window.SkipItems);
        }
        internal static void NewFrame()
        {
            GUIContext    g = Application.ImGuiContext;
            WindowManager w = g.WindowManager;

            if (!g.Initialized)
            {
                // Initialize on first frame
                g.Initialized = true;
            }

            g.ConfigFlagsLastFrame = g.ConfigFlagsCurrFrame;
            g.ConfigFlagsCurrFrame = IO.ConfigFlags;

            // Time
            g.DeltaTime = Time.deltaTime;
            g.Time     += g.DeltaTime;
            g.FrameCount++;

            Metrics.ActiveWindows = 0;

            //fps
            var detlaTime = g.Time - g.lastFPSUpdateTime;

            g.lastFrameCount++;
            if (detlaTime > 1000)
            {
                g.fps               = (int)g.lastFrameCount;
                g.lastFrameCount    = 0;
                g.lastFPSUpdateTime = g.Time;
            }

            UpdateViewportsNewFrame();

            #region Input
            //TODO move to Mouse
            #region mouse position
            if (Mouse.Instance.Position.X < 0 && Mouse.Instance.Position.Y < 0)
            {
                Mouse.Instance.Position = new Point(-9999.0f, -9999.0f);
            }
            if ((Mouse.Instance.Position.X < 0 && Mouse.Instance.Position.Y < 0) || (Mouse.Instance.LastPosition.X < 0 && Mouse.Instance.LastPosition.Y < 0))   // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta
            {
                Mouse.Instance.MouseDelta = Vector.Zero;
            }
            else
            {
                Mouse.Instance.MouseDelta = Mouse.Instance.Position - Mouse.Instance.LastPosition;
            }
            Mouse.Instance.LastPosition = Mouse.Instance.Position;
            #endregion

            #region mouse left button
            Mouse.Instance.LeftButtonPressed          = Mouse.Instance.LeftButtonState == KeyState.Down && Mouse.Instance.LeftButtonDownDuration < 0;
            Mouse.Instance.LeftButtonReleased         = Mouse.Instance.LeftButtonState == KeyState.Up && Mouse.Instance.LeftButtonDownDuration >= 0;
            Mouse.Instance.LeftButtonDownDurationPrev = Mouse.Instance.LeftButtonDownDuration;
            Mouse.Instance.LeftButtonDownDuration     = Mouse.Instance.LeftButtonState == KeyState.Down ? (Mouse.Instance.LeftButtonDownDuration < 0 ? 0 : Mouse.Instance.LeftButtonDownDuration + g.DeltaTime) : -1;
            Mouse.Instance.LeftButtonDoubleClicked    = false;
            if (Mouse.Instance.LeftButtonPressed)
            {
                if (g.Time - Mouse.Instance.LeftButtonClickedTime < Mouse.DoubleClickIntervalTimeSpan)
                {
                    if ((Mouse.Instance.Position - Mouse.Instance.LeftButtonPressedPosition).LengthSquared < Mouse.DoubleClickMaxDistance * Mouse.DoubleClickMaxDistance)
                    {
                        Mouse.Instance.LeftButtonDoubleClicked = true;
                    }
                    Mouse.Instance.LeftButtonClickedTime = -99999; // so the third click isn't turned into a double-click
                }
                else
                {
                    Mouse.Instance.LeftButtonClickedTime = g.Time;
                }
                Mouse.Instance.LeftButtonPressedPosition = Mouse.Instance.Position;
                Mouse.Instance.DragMaxDistanceSquared    = 0;
            }
            else if (Mouse.Instance.LeftButtonState == KeyState.Down)
            {
                Mouse.Instance.DragMaxDistanceSquared = Math.Max(Mouse.Instance.DragMaxDistanceSquared, (Mouse.Instance.Position - Mouse.Instance.LeftButtonPressedPosition).LengthSquared);
            }
            if (Mouse.Instance.LeftButtonPressed)
            {
                ++Mouse.Instance.LeftButtonPressedTimes;
            }
            if (Mouse.Instance.LeftButtonReleased)
            {
                ++Mouse.Instance.LeftButtonReleasedTimes;
            }
            if (Mouse.Instance.LeftButtonDoubleClicked)
            {
                ++Mouse.Instance.LeftButtonDoubleClickedTimes;
            }
            #endregion

            #region mouse right button
            Mouse.Instance.RightButtonPressed      = Mouse.Instance.RightButtonState == KeyState.Down && Mouse.Instance.RightButtonDownDuration < 0;
            Mouse.Instance.RightButtonReleased     = Mouse.Instance.RightButtonState == KeyState.Up && Mouse.Instance.RightButtonDownDuration >= 0;
            Mouse.Instance.RightButtonDownDuration = Mouse.Instance.RightButtonState == KeyState.Down ? (Mouse.Instance.RightButtonDownDuration < 0 ? 0 : Mouse.Instance.RightButtonDownDuration + g.DeltaTime) : -1;

            if (Mouse.Instance.RightButtonPressed)
            {
                ++Mouse.Instance.RightButtonPressedTimes;
            }
            if (Mouse.Instance.RightButtonReleased)
            {
                ++Mouse.Instance.RightButtonReleasedTimes;
            }
            #endregion

            #endregion

            // Update HoverId data
            // 1. record data related to previous frame
            // 2. reset
            g.HoverId                = 0;
            g.HoverIdAllowOverlap    = false;
            g.HoveredIdPreviousFrame = g.HoverId;

            // Update ActiveId data
            // 1. record data related to previous frame
            // 2. reset
            if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
            {//Clear reference to active widget if the widget isn't alive anymore
                g.SetActiveID(0, null);
            }
            g.ActiveIdPreviousFrame        = g.ActiveId;
            g.ActiveIdIsAlive              = 0;
            g.ActiveIdPreviousFrameIsAlive = false;
            g.ActiveIdIsJustActivated      = false;

            w.NewFrame(g);

            foreach (var form in w.Viewports)
            {
                if (!form.PlatformWindowCreated)
                {
                    continue;
                }
                form.ForeBackGroundRenderOpen();
            }

            // [DEBUG] Item picker tool - start with DebugStartItemPicker()
            // useful to visually select an item and break into its call-stack.
            UpdateDebugToolItemPicker();

            // Create implicit debug window - we will only render it if the user has added something to it.
            GUI.Begin("Debug##Default", Application.InitialDebugWindowRect);
        }
        internal static void Render()
        {
            GUIContext g = Application.ImGuiContext;

            if (MainForm.Closed)
            {
                return;
            }
            g.FrameCountRendered = g.FrameCount;

            Metrics.VertexNumber  = 0;
            Metrics.IndexNumber   = 0;
            Metrics.RenderWindows = 0;

            WindowManager w = g.WindowManager;

            //reset MeshBuffer and MeshList
            {
                foreach (var form in w.Viewports)
                {
                    form.MeshBuffer.Clear();
                    form.MeshBuffer.Init();
                    form.backgroundMeshList.Clear();
                    form.foregroundMeshList.Clear();
                }
                foreach (var window in w.Windows)
                {
                    window.MeshList.Clear();
                }
            }

            //build MeshList of all forms from their RenderTree
            {
                foreach (var form in w.Viewports)
                {
                    form.RenderToBackgroundList();
                }

                foreach (var window in w.Windows)
                {
                    if (!window.Active && !Utility.HasAllFlags(window.Flags, WindowFlags.ChildWindow))
                    {
                        continue;
                    }

                    window.RenderToMeshList();
                }

                foreach (var form in w.Viewports)
                {
                    form.RenderToForegroundList();
                }
            }

            //append all MeshLists to form's MeshBuffer
            {
                foreach (var form in w.Viewports)
                {
                    if (!form.PlatformWindowCreated)
                    {
                        continue;
                    }
                    if (form.Closed)
                    {
                        continue;
                    }
                    form.MeshBuffer.Append(form.backgroundMeshList);
                }
                foreach (var window in w.Windows)
                {
                    if (window.Viewport == null)
                    {
                        continue;
                    }
                    if (window.Viewport.PlatformWindowCreated == false)
                    {
                        continue;
                    }
                    if (window.Viewport.Closed)
                    {
                        continue;
                    }

                    var meshBuffer = window.Viewport.MeshBuffer;
                    meshBuffer.Append(window.MeshList);
                    if (window.Name != Metrics.WindowName)
                    {
                        Metrics.VertexNumber += meshBuffer.ShapeMesh.VertexBuffer.Count
                                                + meshBuffer.ImageMesh.VertexBuffer.Count
                                                + meshBuffer.TextMesh.VertexBuffer.Count;
                        Metrics.IndexNumber += meshBuffer.ShapeMesh.IndexBuffer.Count
                                               + meshBuffer.ImageMesh.IndexBuffer.Count
                                               + meshBuffer.TextMesh.IndexBuffer.Count;
                        Metrics.RenderWindows++;
                    }
                }
                foreach (var form in w.Viewports)
                {
                    if (!form.PlatformWindowCreated)
                    {
                        continue;
                    }
                    if (form.Closed)
                    {
                        continue;
                    }
                    form.MeshBuffer.Append(form.foregroundMeshList);
                }
            }

            //render each form's MeshBuffer to back-buffer
            foreach (var form in w.Viewports)
            {
                if (!form.PlatformWindowCreated)
                {
                    continue;
                }
                if (form.Closed)
                {
                    continue;
                }
                //TODO don't render for hidden forms

                Application.renderer.SetRenderingWindow(form.NativeWindow);
                Application.renderer.Clear(form.BackgroundColor);
                var meshBuffer = form.MeshBuffer;
                Application.renderer.DrawMeshes(
                    (int)form.ClientSize.Width, (int)form.ClientSize.Height,
                    (meshBuffer.ShapeMesh, meshBuffer.ImageMesh, meshBuffer.TextMesh));
            }

            //swap front and back-buffer
            foreach (var form in w.Viewports)
            {
                if (!form.PlatformWindowCreated)
                {
                    continue;
                }
                if (form.Closed)
                {
                    continue;
                }
                //TODO don't swap for hidden forms

                Application.renderer.SetRenderingWindow(form.NativeWindow);
                Application.renderer.SwapBuffers();
            }

            //reset to render main form
            Application.renderer.SetRenderingWindow(MainForm.NativeWindow);
        }
Exemple #5
0
        public static void DrawTextBox(Rect rect, int id, string text, InputTextContext context, GUIState state)
        {
            GUIContext    g      = Form.current.uiContext;
            WindowManager w      = g.WindowManager;
            Window        window = w.CurrentWindow;

            var d     = window.DrawList;
            var style = GUIStyle.Basic;
            // draw text, selection and caret
            var contentRect = style.GetContentRect(rect);

            d.PushClipRect(contentRect, true);
            if (g.ActiveId == id)
            {
                //Calculate positions and sizes
                var   textContext = TextMeshUtil.GetTextContext(context.Text, rect.Size, style, GUIState.Normal);
                var   offsetOfTextRect = contentRect.TopLeft;
                float pointX, pointY;
                float caretHeight;
                textContext.IndexToXY(context.CaretIndex, false, out pointX, out pointY, out caretHeight);
                var caretTopPoint    = new Point(pointX, pointY);
                var caretBottomPoint = new Point(pointX, pointY + caretHeight);
                caretTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                caretBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);

                byte caretAlpha = context.CaretAlpha;

                // Check if the caret is outside the rect. If so, move the text so the caret is always shown. FIXME this should be done in TextBoxBehaviour
                var caretX = caretTopPoint.X;
                if (caretX < contentRect.X || caretX > contentRect.Right)
                {
                    var offsetX = -(caretX - contentRect.Width - rect.X);
                    contentRect.Offset(offsetX, 0);
                    caretTopPoint.Offset(offsetX, 0);
                    caretBottomPoint.Offset(offsetX, 0);
                }

                //Draw text
                d.DrawText(contentRect, context.Text, style, GUIState.Normal);

                //Draw selection rect

                /*
                 * Note: Design
                 *
                 *  left bound            right bound
                 *     ↓                        ↓
                 *     |      A-----------------+
                 *     |      |CONTENT_CONTENT_C| => Line 1 => rect1
                 *     +------B                 |
                 *     |ONTENT_CONTENT_CONTENT_C| => Line 2 (represents inner lines) => rect2
                 *     |                 C------+
                 *     |ONTENT_CONTENT_CO| => Line 3 => rect3
                 *     +-----------------D
                 *
                 * left bound = l
                 * right bound = r
                 */
                if (context.SelectIndex != context.CaretIndex)
                {
                    float selectPointX, selectPointY;
                    textContext.IndexToXY(context.SelectIndex, false, out selectPointX, out selectPointY, out float dummyHeight);
                    var selectTopPoint    = new Point(selectPointX, selectPointY);
                    var selectBottomPoint = new Point(selectPointX, selectPointY + caretHeight);
                    selectTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    selectBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    var delta = Math.Abs(selectTopPoint.Y - caretTopPoint.Y);
                    if (delta < caretHeight) // single line
                    {
                        var selectionRect = new Rect(
                            new Point(pointX, pointY),
                            new Point(selectPointX, selectPointY + caretHeight));
                        selectionRect.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                        d.AddRectFilled(selectionRect.Min, selectionRect.Max, Color.Argb(100, 10, 102, 214));
                    }
                    else//mutiple line
                    {
                        var l = contentRect.Left;
                        var r = contentRect.Right;

                        Point A;
                        Point B;
                        Point C;
                        Point D;

                        if (selectTopPoint.Y > caretTopPoint.Y)
                        {
                            A = caretTopPoint;
                            B = caretBottomPoint;
                            C = selectTopPoint;
                            D = selectBottomPoint;
                        }
                        else
                        {
                            A = selectTopPoint;
                            B = selectBottomPoint;
                            C = caretTopPoint;
                            D = caretBottomPoint;
                        }


                        // Line 1
                        var rect1 = new Rect(A, r - A.X, caretHeight);
                        d.AddRectFilled(rect1, Color.Argb(100, 10, 102, 214), 12);
                        d.AddRect(rect1.Min, rect1.Max, Color.White, 12, 15, 2);

                        // Line 2
                        var rect2 = new Rect(new Point(l, B.Y), new Point(r, C.Y));
                        if (rect2.Height > 0.5 * caretHeight)//TODO There should more a more reasonable way to detect this: If it only has two lines, we don't draw the inner rectangle.
                        {
                            d.AddRectFilled(rect2, Color.Argb(100, 10, 102, 214), 12);
                            d.AddRect(rect2.Min, rect2.Max, Color.White, 12, 15, 2);
                        }

                        // Line 3
                        var rect3 = new Rect(new Point(l, C.Y), D);
                        d.AddRectFilled(rect3, Color.Argb(100, 10, 102, 214), 12);
                        d.AddRect(rect3.Min, rect3.Max, Color.White, 12, 15, 2);
                    }
                }

                //Draw caret
                d.PathMoveTo(caretTopPoint);
                d.PathLineTo(caretBottomPoint);
                d.PathStroke(Color.Argb(caretAlpha, 0, 0, 0), false, 2);
            }
            else
            {
                d.DrawText(contentRect, text, style, GUIState.Normal);
            }
            d.PopClipRect();

            // draw the box
            {
                d.AddRect(rect.Min, rect.Max, style.GetBorderColor(state));
            }
        }
Exemple #6
0
        public Window(string name, Point position, Size size, WindowFlags Flags)
        {
            Form          form = Form.current;
            GUIContext    g    = form.uiContext;
            WindowManager w    = g.WindowManager;

            this.ID       = name.GetHashCode();
            this.Name     = name;
            this.Active   = this.WasActive = false;
            this.Position = position;
            this.FullSize = size;

            this.Flags = Flags;

            this.AbsoluteVisualList = new List <Visual>();
            this.RenderTree         = new RenderTree(this.ID, position, size);
            this.RenderContext      = new RenderContext(this.geometryRenderer, this.MeshList);

            this.IDStack.Push(this.ID);
            this.MoveID = this.GetID("#MOVE");

            this.MeshBuffer.OwnerName = this.Name;

            #region Window nodes

            {
                var windowContainer = new Node(this.GetID("window"), "window");
                this.WindowContainer = windowContainer;

                var style = windowContainer.RuleSet;
                style.BorderRadius = (2, 2, 2, 2);
                style.BorderColor  = (Color.Rgb(0x707070), Color.Rgb(0x707070), Color.Rgb(0x707070), Color.Rgb(0x707070));
                style.Set(StylePropertyName.BorderTopColor, Color.Blue, GUIState.Active);
                style.Set(StylePropertyName.BorderRightColor, Color.Blue, GUIState.Active);
                style.Set(StylePropertyName.BorderBottomColor, Color.Blue, GUIState.Active);
                style.Set(StylePropertyName.BorderLeftColor, Color.Blue, GUIState.Active);
                style.Set(StylePropertyName.BorderTopColor, Color.Gray, GUIState.Hover);
                style.Set(StylePropertyName.BorderRightColor, Color.Gray, GUIState.Hover);
                style.Set(StylePropertyName.BorderBottomColor, Color.Gray, GUIState.Hover);
                style.Set(StylePropertyName.BorderLeftColor, Color.Gray, GUIState.Hover);
                style.Set(StylePropertyName.BorderTop, 1.0);
                style.Set(StylePropertyName.BorderRight, 1.0);
                style.Set(StylePropertyName.BorderBottom, 1.0);
                style.Set(StylePropertyName.BorderLeft, 1.0);
                style.Set(StylePropertyName.PaddingTop, 5.0);
                style.Set(StylePropertyName.PaddingRight, 10.0);
                style.Set(StylePropertyName.PaddingBottom, 5.0);
                style.Set(StylePropertyName.PaddingLeft, 10.0);
                style.Set(StylePropertyName.WindowBorderColor, Color.Rgb(255, 0, 0), GUIState.Normal);
                style.Set(StylePropertyName.WindowBorderColor, Color.Rgb(0, 0, 255), GUIState.Active);
                style.Set(StylePropertyName.WindowShadowColor, Color.Argb(100, 227, 227, 227));
                style.Set(StylePropertyName.WindowShadowWidth, 15.0);
                style.Set(StylePropertyName.BackgroundColor, Color.White);
                style.Set(StylePropertyName.ResizeGripColor, Color.Argb(0x77303030));
                style.Set(StylePropertyName.ResizeGripColor, Color.Argb(0xAA303030), GUIState.Hover);
                style.Set(StylePropertyName.ResizeGripColor, Color.Argb(0xFF303030), GUIState.Active);
                style.Set(StylePropertyName.WindowRounding, 20.0);

                windowContainer.AttachLayoutGroup(true);
                windowContainer.UseBoxModel = true;
                var windowStyleOptions = GUILayout.Width(this.FullSize.Width).Height(
                    this.Collapsed ? this.CollapsedHeight : this.FullSize.Height
                    );
                windowContainer.RuleSet.ApplyOptions(windowStyleOptions);

                this.RenderTree.Root.AppendChild(windowContainer);
            }

            //title bar
            if (!Flags.HaveFlag(WindowFlags.NoTitleBar))
            {
                this.titleBar = new Node(this.GetID("titleBar"), "title bar");
                titleBar.AttachLayoutGroup(false);
                titleBar.RuleSet.ApplyOptions(GUILayout.ExpandWidth(true).Height(this.TitleBarHeight));
                titleBar.UseBoxModel = true;
                StyleRuleSetBuilder b = new StyleRuleSetBuilder(titleBar);
                b.Padding((top: 8, right: 8, bottom: 8, left: 8))
                .FontColor(Color.Black)
                .FontSize(12)
                .BackgroundColor(Color.White)
                .AlignmentVertical(Alignment.Center)
                .AlignmentHorizontal(Alignment.Start);

                this.titleIcon = new Node(this.GetID("icon"), "icon");
                titleIcon.AttachLayoutEntry(new Size(20, 20));
                titleIcon.RuleSet.ApplyOptions(GUILayout.Width(20).Height(20));
                titleIcon.UseBoxModel = false;

                this.titleText = new Node(this.GetID("title"), "title");
                var contentSize = titleText.RuleSet.CalcContentBoxSize(this.Name, GUIState.Normal);
                titleText.AttachLayoutEntry(contentSize);
                titleText.RuleSet.ApplyOptions(GUILayout.Height(20));
                titleText.UseBoxModel = false;

                var closeButton = new Node(this.GetID("close button"), "close button");
                closeButton.AttachLayoutEntry(new Size(20, 20));
                closeButton.RuleSet.ApplyOptions(GUILayout.Width(20).Height(20));
                closeButton.UseBoxModel = false;

                titleBar.AppendChild(titleIcon);
                titleBar.AppendChild(titleText);

                this.WindowContainer.AppendChild(titleBar);
            }

            //client area
            {
                this.clientArea = new Node(this.GetID("client area"), "client area");
                clientArea.AttachLayoutGroup(true);
                clientArea.RuleSet.Set(StylePropertyName.OverflowY, (int)OverflowPolicy.Scroll);
                clientArea.RuleSet.Set(StylePropertyName.ScrollBarWidth, CurrentOS.IsDesktopPlatform ? 10.0 : 20.0);
                clientArea.RuleSet.Set(StylePropertyName.ScrollBarBackgroundColor, Color.Rgb(240));
                clientArea.RuleSet.Set(StylePropertyName.ScrollBarButtonColor, Color.Rgb(205), GUIState.Normal);
                clientArea.RuleSet.Set(StylePropertyName.ScrollBarButtonColor, Color.Rgb(166), GUIState.Hover);
                clientArea.RuleSet.Set(StylePropertyName.ScrollBarButtonColor, Color.Rgb(96), GUIState.Active);
                clientArea.RuleSet.ApplyOptions(GUILayout.ExpandWidth(true).ExpandHeight(true));
                clientArea.UseBoxModel     = true;
                clientArea.RuleSet.refNode = clientArea;
#if ShowClientAreaOutline
                clientArea.RuleSet.OutlineWidth = 1;
                clientArea.RuleSet.OutlineColor = Color.DarkRed;
#endif
                this.ClientAreaNode = clientArea;
                this.WindowContainer.AppendChild(clientArea);
            }

            //resize grip (lasy-initialized)

            if (!Flags.HaveFlag(WindowFlags.NoTitleBar))
            {
                this.ShowWindowTitleBar(true);
            }
            this.ShowWindowClientArea(!this.Collapsed);
            #endregion
        }
Exemple #7
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);
        }
Exemple #8
0
        internal void NewFrame()
        {
            current = this;
            GUIContext    g = this.uiContext;
            WindowManager w = g.WindowManager;

            if (!g.Initialized)
            {
                // Initialize on first frame
                g.Initialized = true;
            }

            // Time
            g.DeltaTime = Time.deltaTime;
            g.Time     += g.DeltaTime;
            g.FrameCount++;

            //fps
            var detlaTime = g.Time - g.lastFPSUpdateTime;

            g.lastFrameCount++;
            if (detlaTime > 1000)
            {
                g.fps               = (int)g.lastFrameCount;
                g.lastFrameCount    = 0;
                g.lastFPSUpdateTime = g.Time;
            }

            #region Input

            #region mouse position
            if (Mouse.Instance.Position.X < 0 && Mouse.Instance.Position.Y < 0)
            {
                Mouse.Instance.Position = new Point(-9999.0f, -9999.0f);
            }
            if ((Mouse.Instance.Position.X < 0 && Mouse.Instance.Position.Y < 0) || (Mouse.Instance.LastPosition.X < 0 && Mouse.Instance.LastPosition.Y < 0))   // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta
            {
                Mouse.Instance.MouseDelta = Vector.Zero;
            }
            else
            {
                Mouse.Instance.MouseDelta = Mouse.Instance.Position - Mouse.Instance.LastPosition;
            }
            Mouse.Instance.LastPosition = Mouse.Instance.Position;
            #endregion

            #region mouse left button
            Mouse.Instance.LeftButtonPressed          = Mouse.Instance.LeftButtonState == KeyState.Down && Mouse.Instance.LeftButtonDownDuration < 0;
            Mouse.Instance.LeftButtonReleased         = Mouse.Instance.LeftButtonState == KeyState.Up && Mouse.Instance.LeftButtonDownDuration >= 0;
            Mouse.Instance.LeftButtonDownDurationPrev = Mouse.Instance.LeftButtonDownDuration;
            Mouse.Instance.LeftButtonDownDuration     = Mouse.Instance.LeftButtonState == KeyState.Down ? (Mouse.Instance.LeftButtonDownDuration < 0 ? 0 : Mouse.Instance.LeftButtonDownDuration + g.DeltaTime) : -1;
            Mouse.Instance.LeftButtonDoubleClicked    = false;
            if (Mouse.Instance.LeftButtonPressed)
            {
                if (g.Time - Mouse.Instance.LeftButtonClickedTime < Mouse.DoubleClickIntervalTimeSpan)
                {
                    if ((Mouse.Instance.Position - Mouse.Instance.LeftButtonPressedPos).LengthSquared < Mouse.DoubleClickMaxDistance * Mouse.DoubleClickMaxDistance)
                    {
                        Mouse.Instance.LeftButtonDoubleClicked = true;
                    }
                    Mouse.Instance.LeftButtonClickedTime = -99999; // so the third click isn't turned into a double-click
                }
                else
                {
                    Mouse.Instance.LeftButtonClickedTime = g.Time;
                }
                Mouse.Instance.LeftButtonPressedPos   = Mouse.Instance.Position;
                Mouse.Instance.DragMaxDiatanceSquared = 0;
            }
            else if (Mouse.Instance.LeftButtonState == KeyState.Down)
            {
                Mouse.Instance.DragMaxDiatanceSquared = Math.Max(Mouse.Instance.DragMaxDiatanceSquared, (Mouse.Instance.Position - Mouse.Instance.LeftButtonPressedPos).LengthSquared);
            }
            if (Mouse.Instance.LeftButtonPressed)
            {
                ++Mouse.Instance.LeftButtonPressedTimes;
            }
            if (Mouse.Instance.LeftButtonReleased)
            {
                ++Mouse.Instance.LeftButtonReleasedTimes;
            }
            if (Mouse.Instance.LeftButtonDoubleClicked)
            {
                ++Mouse.Instance.LeftButtonDoubleClickedTimes;
            }
            #endregion

            #region mouse right button
            Mouse.Instance.RightButtonPressed      = Mouse.Instance.RightButtonState == KeyState.Down && Mouse.Instance.RightButtonDownDuration < 0;
            Mouse.Instance.RightButtonReleased     = Mouse.Instance.RightButtonState == KeyState.Up && Mouse.Instance.RightButtonDownDuration >= 0;
            Mouse.Instance.RightButtonDownDuration = Mouse.Instance.RightButtonState == KeyState.Down ? (Mouse.Instance.RightButtonDownDuration < 0 ? 0 : Mouse.Instance.RightButtonDownDuration + g.DeltaTime) : -1;

            if (Mouse.Instance.RightButtonPressed)
            {
                ++Mouse.Instance.RightButtonPressedTimes;
            }
            if (Mouse.Instance.RightButtonReleased)
            {
                ++Mouse.Instance.RightButtonReleasedTimes;
            }
            #endregion

            #endregion

            // Clear reference to active widget if the widget isn't alive anymore
            g.HoveredIdPreviousFrame = g.HoverId;
            g.HoverId             = 0;
            g.HoverIdAllowOverlap = false;
            if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
            {
                g.SetActiveID(0);
            }
            g.ActiveIdPreviousFrame   = g.ActiveId;
            g.ActiveIdIsAlive         = false;
            g.ActiveIdIsJustActivated = false;

            w.NewFrame(g);

            // Create implicit window - we will only render it if the user has added something to it.
            GUI.Begin("Debug", ref this.debugWindowOpen, (0, 0), (200, 140), 0.8);
        }
Exemple #9
0
        public static bool Begin(string name, ref bool open, Point position, Size size, double bg_alpha = 1, WindowFlags flags = WindowFlags.VerticalScrollbar)
        {
            if (bg_alpha < 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(bg_alpha), nameof(bg_alpha) + " cannot be negative.");
            }

            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.FirstUpdate(name, size, ref open, bg_alpha, flags, current_frame, parent_window);
                ImGui.Development.Metrics.ActiveWindows++;
            }

            // 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.Position  = position;
            }

            // 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;

            window.RenderTree.CurrentContainer = window.ClientAreaNode;

            return(!window.SkipItems);
        }
Exemple #10
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);
        }
Exemple #11
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);
        }
Exemple #12
0
        public bool IsHovered(Rect bb, int id, bool flattenChildren = false)
        {
            GUIContext g = this;

            if (g.HoverId != 0 && g.HoverId != id && !g.HoverIdAllowOverlap)
            {
                return(false);
            }
            Window window = g.WindowManager.CurrentWindow;

            if (g.WindowManager.HoveredWindow != window &&
                (!flattenChildren || g.WindowManager.HoveredRootWindow != window.RootWindow))
            {
                return(false);
            }
            if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap)
            {
                return(false);
            }
            if (!IsMouseHoveringRect(bb.Min, bb.Max))
            {
                return(false);
            }
            if (!this.WindowManager.IsWindowContentHoverable(g.WindowManager.HoveredRootWindow))
            {
                return(false);
            }

            // [DEBUG] Item Picker tool!
            // We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making
            // the cost of this tool near-zero.
            // TODO Consider how to get slightly better call-stack and support picking non-hovered
            // items.
            if (g.DebugItemPickerActive && g.HoveredIdPreviousFrame == id)
            {
                Form.current.ForegroundDrawingContext.DrawRectangle(
                    null, new Rendering.Pen(Color.Argb(255, 255, 255, 0), 1), bb);
            }
            if (g.DebugItemPickerBreakID == id)
            {
                //System.Diagnostics.Debugger.Break();

                System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(2, true);
                var frames = stackTrace.GetFrames();
                if (frames != null)
                {
                    System.Diagnostics.StackFrame targetFrame = null;
                    bool nextFrame = false;
                    foreach (var frame in frames)
                    {
                        var methodInfo = frame.GetMethod();
                        if (methodInfo.IsPublic && methodInfo.DeclaringType == typeof(GUILayout))
                        {
                            nextFrame = true;
                            continue;
                        }
                        if (nextFrame)
                        {
                            targetFrame = frame;
                            break;
                        }
                    }
                    if (targetFrame != null)
                    {
                        string fileName   = targetFrame.GetFileName();
                        string methodName = targetFrame.GetMethod().Name;
                        int    lineNumber = targetFrame.GetFileLineNumber();
                        System.Diagnostics.Debug.WriteLine($"{fileName}({lineNumber}): {methodName}");
                    }
                }
            }
            return(true);
        }
Exemple #13
0
        public void EndFrame(GUIContext g)
        {
            // Click to focus window and start moving (after we're done with all our widgets)
            if (g.ActiveId == 0 && g.HoverId == 0 && Mouse.Instance.LeftButtonPressed)
            {
                if (this.HoveredRootWindow != null)
                {
                    this.FocusWindow(this.HoveredWindow);
                    if (!(this.HoveredWindow.Flags.HaveFlag(WindowFlags.NoMove)))
                    {
                        this.MovingWindow       = this.HoveredWindow;
                        this.MovingWindowMoveId = this.HoveredRootWindow.MoveId;
                        g.SetActiveID(this.MovingWindowMoveId, this.HoveredRootWindow);
                    }
                }
                else if (this.FocusedWindow != null)
                {
                    // Clicking on void disable focus
                    this.FocusWindow(null);
                }
            }

            //TODO refactor to don't rely on flag to identify window type, subclass Window instead
            // Sort windows so
            // 1. child windows always rendered after its parent
            // 2. popup windows always rendered after regular window
            windowSwapBuffer.Clear();
            childWindows.Clear();
            popupWindows.Clear();
            for (int i = 0; i < Windows.Count; i++)
            {
                var window = Windows[i];
                if (window.Active && window.Flags.HaveFlag(WindowFlags.ChildWindow))
                {
                    childWindows.Add(window);
                }
                else if (window.Flags.HaveFlag(WindowFlags.Popup))
                {
                    popupWindows.Add(window);
                }
                else
                {
                    windowSwapBuffer.Add(window);
                }
            }
            foreach (var childWindow in childWindows)
            {
                var parentWindowIndex = windowSwapBuffer.FindIndex(win => win == childWindow.RootWindow);
                if (parentWindowIndex < 0)
                {
                    throw new IndexOutOfRangeException(
                              $"Cannot find the parent window of child window<{childWindow.Name}>");
                }
                windowSwapBuffer.Insert(parentWindowIndex + 1, childWindow);
            }
            windowSwapBuffer.AddRange(popupWindows);

            Debug.Assert(windowSwapBuffer.Count == Windows.Count);

            Windows.Clear();
            Windows.AddRange(windowSwapBuffer);
        }
Exemple #14
0
        public static void DrawTextBox(Node node, int id, string text, InputTextContext context, GUIState state)
        {
            GUIContext g = Form.current.uiContext;

            Rect rect  = node.Rect;
            var  d     = node.RenderOpen();
            var  style = node.RuleSet;
            // draw text, selection and caret
            var contentRect = node.ContentRect;

            // clip text rendering to content-box
            //d.PushClip(contentRect);
            if (g.ActiveId == id)
            {
                //Calculate positions and sizes
                var   textContext = TextMeshUtil.GetTextContext(context.Text, rect.Size, style, GUIState.Normal);
                var   offsetOfTextRect = contentRect.TopLeft;
                float pointX, pointY;
                float caretHeight;
                textContext.IndexToXY(context.CaretIndex, false, out pointX, out pointY, out caretHeight);
                var caretTopPoint    = new Point(pointX, pointY);
                var caretBottomPoint = new Point(pointX, pointY + caretHeight);
                caretTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                caretBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);

                byte caretAlpha = context.CaretAlpha;

                // Check if the caret is outside the rect. If so, move the text so the caret is always shown. FIXME this should be done in TextBoxBehaviour
                var caretX = caretTopPoint.X;
                if (caretX < contentRect.X || caretX > contentRect.Right)
                {
                    var offsetX = -(caretX - contentRect.Width - rect.X);
                    contentRect.Offset(offsetX, 0);
                    caretTopPoint.Offset(offsetX, 0);
                    caretBottomPoint.Offset(offsetX, 0);
                }

                //Draw text
                d.DrawText(style, context.Text, contentRect);

                //Draw selection rect

                /*
                 * Note: Design
                 *
                 *  left bound            right bound
                 *     ↓                        ↓
                 *     |      A-----------------+
                 *     |      |CONTENT_CONTENT_C| => Line 1 => rect1
                 *     +------B                 |
                 *     |ONTENT_CONTENT_CONTENT_C| => Line 2 (represents inner lines) => rect2
                 *     |                 C------+
                 *     |ONTENT_CONTENT_CO| => Line 3 => rect3
                 *     +-----------------D
                 *
                 * left bound = l
                 * right bound = r
                 */
                if (context.SelectIndex != context.CaretIndex)
                {
                    float selectPointX, selectPointY;
                    textContext.IndexToXY(context.SelectIndex, false, out selectPointX, out selectPointY, out float dummyHeight);
                    var selectTopPoint    = new Point(selectPointX, selectPointY);
                    var selectBottomPoint = new Point(selectPointX, selectPointY + caretHeight);
                    selectTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    selectBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    var delta = Math.Abs(selectTopPoint.Y - caretTopPoint.Y);
                    if (delta < caretHeight) // single line
                    {
                        var selectionRect = new Rect(
                            new Point(pointX, pointY),
                            new Point(selectPointX, selectPointY + caretHeight));
                        selectionRect.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                        d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, selectionRect);
                    }
                    else//multiple lines
                    {
                        var l = contentRect.Left;
                        var r = contentRect.Right;

                        Point A;
                        Point B;
                        Point C;
                        Point D;

                        if (selectTopPoint.Y > caretTopPoint.Y)
                        {
                            A = caretTopPoint;
                            B = caretBottomPoint;
                            C = selectTopPoint;
                            D = selectBottomPoint;
                        }
                        else
                        {
                            A = selectTopPoint;
                            B = selectBottomPoint;
                            C = caretTopPoint;
                            D = caretBottomPoint;
                        }


                        // Line 1
                        var rect1 = new Rect(A, r - A.X, caretHeight);
                        d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, rect1);
                        d.DrawRectangle(null, new Pen(Color.White, 2), rect1);

                        // Line 2
                        var rect2 = new Rect(new Point(l, B.Y), new Point(r, C.Y));
                        if (rect2.Height > 0.5 * caretHeight)//TODO There should more a more reasonable way to detect this: If it only has two lines, we don't draw the inner rectangle.
                        {
                            d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, rect2);
                            d.DrawRectangle(null, new Pen(Color.White, 2), rect2);
                        }

                        // Line 3
                        var rect3 = new Rect(new Point(l, C.Y), D);
                        d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, rect3);
                        d.DrawRectangle(null, new Pen(Color.White, 2), rect3);
                    }
                }

                //Draw caret
                d.DrawLine(new Pen(Color.Argb(caretAlpha, 0, 0, 0), 2), caretTopPoint, caretBottomPoint);
            }
            else
            {
                d.DrawText(style, text, contentRect);
            }
            //d.Pop();
            d.Close();
        }
Exemple #15
0
        public Window(string name, Point position, Size size, WindowFlags Flags)
        {
            Form       form = Form.current;
            GUIContext g    = form.uiContext;

            this.ID   = name.GetHashCode();
            this.Name = name;
            this.IDStack.Push(this.ID);
            this.Flags    = Flags;
            this.PosFloat = position;
            this.Position = new Point((int)PosFloat.X, (int)PosFloat.Y);
            this.Size     = this.FullSize = size;
            this.DrawList = new DrawList();
            this.MoveID   = GetID("#MOVE");
            this.Active   = WasActive = false;

            // window styles
            {
                var style = new GUIStyle();
                style.Set(GUIStyleName.BorderTop, 1.0);
                style.Set(GUIStyleName.BorderRight, 1.0);
                style.Set(GUIStyleName.BorderBottom, 1.0);
                style.Set(GUIStyleName.BorderLeft, 1.0);
                style.Set(GUIStyleName.PaddingTop, 5.0);
                style.Set(GUIStyleName.PaddingRight, 10.0);
                style.Set(GUIStyleName.PaddingBottom, 5.0);
                style.Set(GUIStyleName.PaddingLeft, 10.0);
                style.Set(GUIStyleName.WindowBorderColor, Color.Rgb(170, 170, 170), GUIState.Normal);
                style.Set(GUIStyleName.WindowBorderColor, Color.Rgb(24, 131, 215), GUIState.Active);
                style.Set(GUIStyleName.WindowShadowColor, Color.Argb(100, 227, 227, 227));
                style.Set(GUIStyleName.WindowShadowWidth, 15.0);
                style.Set(GUIStyleName.BackgroundColor, Color.White);
                style.Set(GUIStyleName.ResizeGripSize, 20.0);
                style.Set(GUIStyleName.ResizeGripColor, Color.Argb(75, 102, 102, 102));
                style.Set(GUIStyleName.ResizeGripColor, Color.Argb(150, 102, 102, 102), GUIState.Hover);
                style.Set(GUIStyleName.ResizeGripColor, Color.Argb(225, 102, 102, 102), GUIState.Active);
                style.Set(GUIStyleName.WindowRounding, 3.0);
                style.Set(GUIStyleName.ScrollBarWidth, CurrentOS.IsDesktopPlatform ? 10.0 : 20.0);
                style.Set(GUIStyleName.ScrollBarBackgroundColor, Color.Rgb(240));
                style.Set(GUIStyleName.ScrollBarButtonColor, Color.Rgb(205), GUIState.Normal);
                style.Set(GUIStyleName.ScrollBarButtonColor, Color.Rgb(166), GUIState.Hover);
                style.Set(GUIStyleName.ScrollBarButtonColor, Color.Rgb(96), GUIState.Active);
                this.Style = style;
            }

            // window header styles
            {
                var style = new GUIStyle();
                style.Set(GUIStyleName.BackgroundColor, Color.White);
                style.Set(GUIStyleName.BackgroundColor, Color.White, GUIState.Active);
                style.Set(GUIStyleName.BackgroundColor, Color.White, GUIState.Disabled);
                style.Set <double>(GUIStyleName.BorderTopLeftRadius, 3.0);
                style.Set <double>(GUIStyleName.BorderTopRightRadius, 3.0);
                style.Set(GUIStyleName.PaddingTop, 8.0);
                style.Set(GUIStyleName.PaddingRight, 8.0);
                style.Set(GUIStyleName.PaddingBottom, 8.0);
                style.Set(GUIStyleName.PaddingLeft, 8.0);
                style.Set(GUIStyleName.FontColor, Color.Black, GUIState.Normal);
                style.Set(GUIStyleName.FontColor, Color.Rgb(153, 153, 153), GUIState.Active);
                style.FontFamily   = GUIStyle.Default.FontFamily;
                style.FontSize     = 12.0;
                this.TitleBarStyle = style;
            }

            var scrollBarWidth = this.Style.Get <double>(GUIStyleName.ScrollBarWidth);
            var clientSize     = new Size(
                this.Size.Width - scrollBarWidth - this.Style.PaddingHorizontal - this.Style.BorderHorizontal,
                this.Size.Height - this.Style.PaddingVertical - this.Style.BorderVertical - this.TitleBarHeight);

            this.StackLayout = new StackLayout(this.ID, clientSize);
        }
Exemple #16
0
        public Window(string name, Point position, Size size, WindowFlags Flags)
        {
            Form          form = Form.current;
            GUIContext    g    = form.uiContext;
            WindowManager w    = g.WindowManager;

            this.ID       = name.GetHashCode();
            this.Name     = name;
            this.Active   = this.WasActive = false;
            this.Position = position;
            this.FullSize = size;

            this.Flags = Flags;

            this.AbsoluteVisualList = new List <Visual>();
            this.RenderTree         = new RenderTree(this.ID, position, size);

            this.IDStack.Push(this.ID);
            this.MoveID = this.GetID("#MOVE");

            #region Window nodes

            {
                var windowContainer = new Node(this.GetID("window"), "window");
                this.WindowContainer = windowContainer;

                var style = windowContainer.RuleSet;
                style.BackgroundColor = Color.White;
                style.Border          = (1, 1, 1, 1);
                style.BorderColor     = (Color.Black, Color.Black, Color.Black, Color.Black);
                style.Set(GUIStyleName.BorderTopColor, Color.Blue, GUIState.Active);
                style.Set(GUIStyleName.BorderRightColor, Color.Blue, GUIState.Active);
                style.Set(GUIStyleName.BorderBottomColor, Color.Blue, GUIState.Active);
                style.Set(GUIStyleName.BorderLeftColor, Color.Blue, GUIState.Active);
                style.Set(GUIStyleName.BorderTopColor, Color.Gray, GUIState.Hover);
                style.Set(GUIStyleName.BorderRightColor, Color.Gray, GUIState.Hover);
                style.Set(GUIStyleName.BorderBottomColor, Color.Gray, GUIState.Hover);
                style.Set(GUIStyleName.BorderLeftColor, Color.Gray, GUIState.Hover);
                style.Set(GUIStyleName.BorderTop, 1.0);
                style.Set(GUIStyleName.BorderRight, 1.0);
                style.Set(GUIStyleName.BorderBottom, 1.0);
                style.Set(GUIStyleName.BorderLeft, 1.0);
                style.Set(GUIStyleName.PaddingTop, 5.0);
                style.Set(GUIStyleName.PaddingRight, 10.0);
                style.Set(GUIStyleName.PaddingBottom, 5.0);
                style.Set(GUIStyleName.PaddingLeft, 10.0);
                style.Set(GUIStyleName.WindowBorderColor, Color.Rgb(255, 0, 0), GUIState.Normal);
                style.Set(GUIStyleName.WindowBorderColor, Color.Rgb(0, 0, 255), GUIState.Active);
                style.Set(GUIStyleName.WindowShadowColor, Color.Argb(100, 227, 227, 227));
                style.Set(GUIStyleName.WindowShadowWidth, 15.0);
                style.Set(GUIStyleName.BackgroundColor, Color.White);
                style.Set(GUIStyleName.ResizeGripColor, Color.Argb(75, 102, 102, 102));
                style.Set(GUIStyleName.ResizeGripColor, Color.Argb(150, 102, 102, 102), GUIState.Hover);
                style.Set(GUIStyleName.ResizeGripColor, Color.Argb(225, 102, 102, 102), GUIState.Active);
                style.Set(GUIStyleName.WindowRounding, 20.0);
                style.Set(GUIStyleName.ScrollBarWidth, CurrentOS.IsDesktopPlatform ? 10.0 : 20.0);
                style.Set(GUIStyleName.ScrollBarBackgroundColor, Color.Rgb(240));
                style.Set(GUIStyleName.ScrollBarButtonColor, Color.Rgb(205), GUIState.Normal);
                style.Set(GUIStyleName.ScrollBarButtonColor, Color.Rgb(166), GUIState.Hover);
                style.Set(GUIStyleName.ScrollBarButtonColor, Color.Rgb(96), GUIState.Active);

                windowContainer.AttachLayoutGroup(true);
                windowContainer.UseBoxModel = true;
                var windowStyleOptions = GUILayout.Width(this.FullSize.Width).Height(
                    this.Collapsed ? this.CollapsedHeight : this.FullSize.Height
                    );
                windowContainer.RuleSet.ApplyOptions(windowStyleOptions);

                this.RenderTree.Root.AppendChild(windowContainer);
            }

            //title bar
            {
                var titleBarContainer = new Node(this.GetID("titleBar"), "title bar");
                this.titleBarNode = titleBarContainer;
                titleBarContainer.AttachLayoutGroup(false);
                titleBarContainer.RuleSet.ApplyOptions(GUILayout.ExpandWidth(true).Height(this.TitleBarHeight));
                titleBarContainer.UseBoxModel = true;
                StyleRuleSetBuilder b = new StyleRuleSetBuilder(titleBarContainer);
                b.Padding((top: 8, right: 8, bottom: 8, left: 8))
                .FontColor(Color.Black)
                .FontSize(12)
                .BackgroundColor(Color.White)
                .AlignmentVertical(Alignment.Center)
                .AlignmentHorizontal(Alignment.Start);

                var icon = new Node(this.GetID("icon"), "icon");
                icon.AttachLayoutEntry(new Size(20, 20));
                icon.RuleSet.ApplyOptions(GUILayout.Width(20).Height(20));
                icon.UseBoxModel = false;
                icon.Primitive   = new ImagePrimitive(@"assets/images/logo.png");

                var title       = new Node(this.GetID("title"), "title");
                var contentSize = title.RuleSet.CalcSize(this.Name, GUIState.Normal);
                title.AttachLayoutEntry(contentSize);
                title.RuleSet.ApplyOptions(GUILayout.Height(20));
                title.UseBoxModel      = false;
                title.Primitive        = new TextPrimitive(this.Name);
                this.titleBarTitleNode = title;

                var closeButton = new Node(this.GetID("close button"), "close button");
                closeButton.AttachLayoutEntry(new Size(20, 20));
                closeButton.RuleSet.ApplyOptions(GUILayout.Width(20).Height(20));
                closeButton.UseBoxModel = false;
                PathPrimitive path = new PathPrimitive();
                path.PathRect(new Rect(0, 0, 20, 20));
                closeButton.Primitive = path;

                titleBarContainer.AppendChild(icon);
                titleBarContainer.AppendChild(title);
                //titleBarContainer.AppendChild(closeButton);
                this.WindowContainer.AppendChild(titleBarContainer);
            }

            //client area
            {
                var node = new Node(this.GetID("client area"), "client area");
                node.AttachLayoutGroup(true);
                node.RuleSet.ApplyOptions(GUILayout.ExpandWidth(true).ExpandHeight(true));
                node.UseBoxModel          = true;
                node.RuleSet.OutlineWidth = 1;
                node.RuleSet.OutlineColor = Color.Red;
                node.RuleSet.refNode      = node;
                this.ClientAreaNode       = node;
                this.WindowContainer.AppendChild(node);
            }

            //resize grip (lasy-initialized)

            this.ShowWindowTitleBar(true);
            this.ShowWindowClientArea(!this.Collapsed);
            #endregion
        }
Exemple #17
0
        /// <summary>
        /// Create an auto-layout vertical slider that user can drag to select a value.
        /// </summary>
        /// <param name="label">label of the slider</param>
        /// <param name="value">The value the slider shows.</param>
        /// <param name="minValue">The value at the top end of the slider.</param>
        /// <param name="maxValue">The value at the bottom end of the slider.</param>
        /// <returns>The value set by the user.</returns>
        /// <remarks>minValue &lt;= value &lt;= maxValue</remarks>
        public static double VSlider(string label, double value, double minValue, double maxValue)
        {
            GUIContext g      = GetCurrentContext();
            Window     window = GetCurrentWindow();

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

            var id = window.GetID(label);

            // style apply
            var style = GUIStyle.Basic;

            // rect
            Size size = style.CalcSize(label, GUIState.Normal);

            style.PushStretchFactor(true, 1);//+1
            {
                var minSilderHeight = 200;
                size.Width   = 20;
                size.Height += minSilderHeight;
            }
            var rect = window.GetRect(id);

            // interact
            var spacing      = GUISkin.Instance.InternalStyle.Get <double>(GUIStyleName._ControlLabelSpacing);
            var labelHeight  = GUISkin.Instance.InternalStyle.Get <double>(GUIStyleName._LabelHeight);
            var sliderHeight = rect.Height - spacing - labelHeight;

            if (sliderHeight <= 0)
            {
                sliderHeight = 1;
            }
            var sliderRect = new Rect(rect.X, rect.Y,
                                      rect.Width,
                                      sliderHeight);

            bool hovered, held;

            value = GUIBehavior.SliderBehavior(sliderRect, id, false, value, minValue, maxValue, out hovered, out held);

            // render
            var state = GUI.Normal;

            if (hovered)
            {
                state = GUI.Hover;
            }
            if (g.ActiveId == id && Mouse.Instance.LeftButtonState == KeyState.Down)
            {
                state = GUI.Active;
            }
            GUIAppearance.DrawVSlider(rect, label, value, minValue, maxValue, state, sliderRect, labelHeight);

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

            return(value);
        }
Exemple #18
0
        public static string TextBoxBehavior(int id, Rect rect, string text, out bool hovered, out bool active, out InputTextContext context, InputTextFlags flags = 0, Func <char, bool> checker = null)
        {
            GUIContext g = Form.current.uiContext;

            active  = false;
            hovered = g.IsHovered(rect, id);
            if (hovered)
            {
                g.SetHoverID(id);

                if (Mouse.Instance.LeftButtonPressed)
                {
                    g.SetActiveID(id);
                }
            }
            else
            {
                if (Mouse.Instance.LeftButtonPressed)
                {
                    if (g.ActiveId == id)
                    {
                        g.SetActiveID(0);
                    }
                }
            }

            if (g.ActiveId == id && g.InputTextState.inputTextContext.Id != id)     //editing text box changed to TextBox<id>
            {
                g.InputTextState.stateMachine.CurrentState = "Active";              //reset state
                g.InputTextState.inputTextContext          = new InputTextContext() //reset input text context data
                {
                    Id            = id,
                    CaretIndex    = 0,
                    SelectIndex   = 0,
                    Selecting     = false,
                    CaretPosition = Point.Zero,
                    Flags         = flags,
                    Checker       = checker,
                    Rect          = rect,
                    Text          = text
                };
            }

            context = null;
            if (g.ActiveId == id)
            {
                active = true;

                var stateMachine = g.InputTextState.stateMachine;
                context      = g.InputTextState.inputTextContext;
                context.Rect = rect;

                // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.
                // Down the line we should have a cleaner library-wide concept of Selected vs Active.
                g.ActiveIdAllowOverlap = !Mouse.Instance.LeftButtonPressed;

#if INSPECT_STATE
                var A = stateMachine.CurrentState;
#endif
                if (Mouse.Instance.LeftButtonPressed)
                {
                    stateMachine.MoveNext(TextBoxCommand.MoveCaret, context);
                }

                if (hovered && Mouse.Instance.LeftButtonState == KeyState.Down &&
                    stateMachine.CurrentState != TextBoxState.ActiveSelecting)
                {
                    stateMachine.MoveNext(TextBoxCommand.MoveCaret, context);
                    stateMachine.MoveNext(TextBoxCommand.BeginSelect, context);
                }

                if (hovered && Mouse.Instance.LeftButtonState == KeyState.Up)
                {
                    stateMachine.MoveNext(TextBoxCommand.EndSelect, context);
                }

                if (stateMachine.CurrentState == TextBoxState.Active)
                {
                    stateMachine.MoveNext(TextBoxCommand.DoEdit, context);
                }
                if (stateMachine.CurrentState == TextBoxState.ActiveSelecting)
                {
                    stateMachine.MoveNext(TextBoxCommand.DoSelect, context);
                }
                stateMachine.MoveNext(TextBoxCommand.MoveCaretKeyboard, context);
#if INSPECT_STATE
                var B = stateMachine.CurrentState;
                Debug.WriteLineIf(A != B,
                                  string.Format("TextBox<{0}> {1}=>{2} CaretIndex: {3}, SelectIndex: {4}",
                                                id, A, B, context.CaretIndex, context.SelectIndex));
#endif
                return(context.Text);
            }
            return(text);
        }
Exemple #19
0
        internal static bool DoPolygonButton(Rect rect, IReadOnlyList <Point> points, Rect textRect, string text)
        {
            Form       form     = Form.current;
            GUIContext g        = form.uiContext;
            Window     window   = g.WindowManager.CurrentWindow;
            DrawList   d        = window.DrawList;
            int        id       = window.GetID(text);
            var        mousePos = Mouse.Instance.Position;

            var clicked = false;
            var hovered = MathEx.IsPointInPolygon(mousePos, points, new Vector(rect.X, rect.Y));

            textRect.Offset(rect.X, rect.Y);

            //control logic
            g.KeepAliveID(id);
            if (hovered)
            {
                g.SetHoverID(id);

                if (Mouse.Instance.LeftButtonPressed)//start track
                {
                    g.SetActiveID(id);
                }

                if (Mouse.Instance.LeftButtonReleased)//end track
                {
                    clicked = true;
                    g.SetActiveID(GUIContext.None);
                }
            }

            // ui representation
            var state = GUI.Normal;

            if (hovered)
            {
                state = GUI.Hover;
                if (g.ActiveId == id && Mouse.Instance.LeftButtonState == KeyState.Down)
                {
                    state = GUI.Active;
                }
            }

            // ui painting
            {
                var style = GUISkin.Instance[GUIControlName.PolygonButton];

                d.PathClear();
                foreach (var point in points)
                {
                    d.PathMoveTo(point + new Vector(rect.X, rect.Y));
                }
                d.PathFill(style.FillColor);

                d.PathClear();
                foreach (var point in points)
                {
                    d.PathMoveTo(point + new Vector(rect.X, rect.Y));
                }
                d.PathStroke(style.LineColor, true, 2);

                d.DrawBoxModel(textRect, text, style, state);
            }

            return(clicked);
        }
Exemple #20
0
        public static bool ButtonBehavior(Rect bb, int id, out bool outHovered, out bool outHeld, ButtonFlags flags = 0)
        {
            GUIContext    g      = Form.current.uiContext;
            WindowManager w      = g.WindowManager;
            Window        window = w.CurrentWindow;

            if (flags.HaveFlag(ButtonFlags.Disabled))
            {
                outHovered = false;
                outHeld    = false;
                if (g.ActiveId == id)
                {
                    g.SetActiveID(0);
                }
                return(false);
            }

            if (!flags.HaveFlag(ButtonFlags.PressedOnClickRelease | ButtonFlags.PressedOnClick | ButtonFlags.PressedOnRelease | ButtonFlags.PressedOnDoubleClick))
            {
                flags |= ButtonFlags.PressedOnClickRelease;
            }

            bool pressed = false;
            bool hovered = g.IsHovered(bb, id, flags.HaveFlag(ButtonFlags.FlattenChilds));

            if (hovered)
            {
                g.SetHoverID(id);
                if (!flags.HaveFlag(ButtonFlags.NoKeyModifiers) || (!Keyboard.Instance.KeyPressed(Key.LeftControl) && !Keyboard.Instance.KeyPressed(Key.LeftShift) && !Keyboard.Instance.KeyPressed(Key.LeftAlt)))
                {
                    //                        | CLICKING        | HOLDING with ButtonFlags.Repeat
                    // PressedOnClickRelease  |  <on release>*  |  <on repeat> <on repeat> .. (NOT on release)  <-- MOST COMMON! (*) only if both click/release were over bounds
                    // PressedOnClick         |  <on click>     |  <on click> <on repeat> <on repeat> ..
                    // PressedOnRelease       |  <on release>   |  <on repeat> <on repeat> .. (NOT on release)
                    // PressedOnDoubleClick   |  <on dclick>    |  <on dclick> <on repeat> <on repeat> ..
                    if (flags.HaveFlag(ButtonFlags.PressedOnClickRelease) && Mouse.Instance.LeftButtonPressed)
                    {
                        g.SetActiveID(id, window); // Hold on ID
                        w.FocusWindow(window);
                        g.ActiveIdClickOffset = Mouse.Instance.Position - bb.Min;
                    }
                    if (((flags.HaveFlag(ButtonFlags.PressedOnClick) && Mouse.Instance.LeftButtonPressed) ||
                         (flags.HaveFlag(ButtonFlags.PressedOnDoubleClick) && Mouse.Instance.LeftButtonDoubleClicked)))
                    {
                        pressed = true;
                        g.SetActiveID(0);
                        w.FocusWindow(window);
                    }
                    if (flags.HaveFlag(ButtonFlags.PressedOnRelease) && Mouse.Instance.LeftButtonReleased)
                    {
                        if (!(flags.HaveFlag(ButtonFlags.Repeat) && Mouse.Instance.LeftButtonDownDurationPrev >= Keyboard.KeyRepeatDelay))  // Repeat mode trumps <on release>
                        {
                            pressed = true;
                        }
                        g.SetActiveID(0);
                    }

                    // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above).
                    // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings.
                    if (flags.HaveFlag(ButtonFlags.Repeat) && g.ActiveId == id && Mouse.Instance.LeftButtonDownDuration > 0.0f && g.IsMouseLeftButtonClicked(true))
                    {
                        pressed = true;
                    }
                }
            }

            bool held = false;

            if (g.ActiveId == id)
            {
                if (Mouse.Instance.LeftButtonState == KeyState.Down)
                {
                    held = true;
                }
                else
                {
                    if (hovered && flags.HaveFlag(ButtonFlags.PressedOnClickRelease))
                    {
                        if (!(flags.HaveFlag(ButtonFlags.Repeat) && Mouse.Instance.LeftButtonDownDurationPrev >= Keyboard.KeyRepeatDelay))  // Repeat mode trumps <on release>
                        {
                            pressed = true;
                        }
                    }
                    g.SetActiveID(0);
                }
            }

            // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one.
            if (hovered && flags.HaveFlag(ButtonFlags.AllowOverlapMode) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0))
            {
                hovered = pressed = held = false;
            }

            outHovered = hovered;
            outHeld    = held;

            return(pressed);
        }
Exemple #21
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);
        }