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 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); }