public static double SliderBehavior(Rect sliderRect, int id, bool horizontal, double value, double minValue, double maxValue, out bool hovered, out bool held) { GUIContext g = Form.current.uiContext; hovered = false; held = false; hovered = g.IsHovered(sliderRect, id); g.KeepAliveID(id); if (hovered) { g.SetHoverID(id); if (Mouse.Instance.LeftButtonPressed) //start track { g.SetActiveID(id); } } if (g.ActiveId == id) { if (Mouse.Instance.LeftButtonState == KeyState.Down) { var mousePos = Mouse.Instance.Position; if (horizontal) { var leftPoint = new Point(sliderRect.X + 10, sliderRect.Y + sliderRect.Height / 2); var rightPoint = new Point(sliderRect.Right - 10, sliderRect.Y + sliderRect.Height / 2); var minX = leftPoint.X; var maxX = rightPoint.X; var currentPointX = MathEx.Clamp(mousePos.X, minX, maxX); value = minValue + (currentPointX - minX) / (maxX - minX) * (maxValue - minValue); } else { var upPoint = new Point(sliderRect.X + sliderRect.Width / 2, sliderRect.Y + 10); var bottomPoint = new Point(sliderRect.X + sliderRect.Width / 2, sliderRect.Bottom - 10); var minY = upPoint.Y; var maxY = bottomPoint.Y; var currentPointY = MathEx.Clamp(mousePos.Y, minY, maxY); value = (float)(minValue + (currentPointY - minY) / (maxY - minY) * (maxValue - minValue)); } } else //end track { g.SetActiveID(0); } } if (g.ActiveId == id) { held = true; } return(value); }
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.MovedWindow = this.HoveredWindow; this.MovedWindowMoveId = this.HoveredRootWindow.MoveID; g.SetActiveID(this.MovedWindowMoveId, this.HoveredRootWindow); } } else if (this.FocusedWindow != null) { // Clicking on void disable focus this.FocusWindow(null); } } // Sort windows so child windows always rendered after its parent TODO optimize this windowSwapBuffer.Clear(); childWindows.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 { windowSwapBuffer.Add(window); } } foreach (var childWindow in childWindows) { var parentWindowIndex = windowSwapBuffer.FindIndex(win => win == childWindow.RootWindow); if (parentWindowIndex < 0) { throw new IndexOutOfRangeException(); } windowSwapBuffer.Insert(parentWindowIndex + 1, childWindow); } Debug.Assert(windowSwapBuffer.Count == Windows.Count); Windows.Clear(); Windows.AddRange(windowSwapBuffer); }
public static bool ToggleBehavior(Rect rect, int id, bool value, out bool hovered) { GUIContext g = Form.current.uiContext; hovered = g.IsHovered(rect, id); g.KeepAliveID(id); if (hovered) { g.SetHoverID(id); if (Mouse.Instance.LeftButtonPressed) { g.SetActiveID(id); } if (g.ActiveId == id && Mouse.Instance.LeftButtonReleased) { value = !value; g.SetActiveID(0); } } return(value); }
public static bool SelectableBehavior(Rect rect, int id, bool selected, out bool out_hovered, out bool out_held) { GUIContext g = Form.current.uiContext; bool hovered = g.IsHovered(rect, id); if (hovered) { g.SetHoverID(id); if (Mouse.Instance.LeftButtonPressed) { g.SetActiveID(id); } if (g.ActiveId == id && Mouse.Instance.LeftButtonReleased) { selected = !selected; g.SetActiveID(0); } } bool held = false; if (g.ActiveId == id) { if (Mouse.Instance.LeftButtonState == KeyState.Down) { held = true; } } out_hovered = hovered; out_held = held; return(selected); }
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); }
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); }
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); }
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(); }
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 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); }
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); }