using Robust.Client.Graphics; using Robust.Shared.Input; using Robust.Shared.Maths; using static Robust.Client.UserInterface.Controls.LayoutContainer; namespace Robust.Client.UserInterface.Controls { public class Slider : Range { public const string StylePropertyBackground = "background"; public const string StylePropertyForeground = "foreground"; public const string StylePropertyFill = "fill"; public const string StylePropertyGrabber = "grabber"; private readonly PanelContainer _foregroundPanel; private readonly PanelContainer _backgroundPanel; private readonly PanelContainer _fillPanel; private readonly PanelContainer _grabber; private bool _grabbed; private StyleBox? _backgroundStyleBoxOverride; private StyleBox? _foregroundStyleBoxOverride; private StyleBox? _fillStyleBoxOverride; private StyleBox? _grabberStyleBoxOverride; public bool Grabbed => _grabbed; public StyleBox? ForegroundStyleBoxOverride { get => _foregroundStyleBoxOverride; set { _foregroundStyleBoxOverride = value; UpdateStyleBoxes(); } } public StyleBox? BackgroundStyleBoxOverride { get => _backgroundStyleBoxOverride; set { _backgroundStyleBoxOverride = value; UpdateStyleBoxes(); } } public StyleBox? FillStyleBoxOverride { get => _fillStyleBoxOverride; set { _fillStyleBoxOverride = value; UpdateStyleBoxes(); } } public StyleBox? GrabberStyleBoxOverride { get => _grabberStyleBoxOverride; set { _grabberStyleBoxOverride = value; UpdateStyleBoxes(); } } public Slider() { MouseFilter = MouseFilterMode.Stop; AddChild(new LayoutContainer { Children = { (_backgroundPanel = new PanelContainer()), (_fillPanel = new PanelContainer()), (_foregroundPanel = new PanelContainer()), (_grabber = new PanelContainer()) } }); SetAnchorBottom(_fillPanel, 1); SetAnchorBottom(_grabber, 1); SetGrowHorizontal(_grabber, GrowDirection.Both); SetGrowVertical(_grabber, GrowDirection.Both); SetAnchorPreset(_foregroundPanel, LayoutPreset.Wide); SetAnchorPreset(_backgroundPanel, LayoutPreset.Wide); } public override float Value { get => base.Value; set { base.Value = value; UpdateValue(); } } public override void SetValueWithoutEvent(float newValue) { base.SetValueWithoutEvent(newValue); UpdateValue(); } private void UpdateValue() { var ratio = GetAsRatio(); var margin = (Width - _grabber.DesiredSize.X) * ratio + _grabber.DesiredSize.X / 2; SetMarginRight(_fillPanel, margin); SetMarginLeft(_grabber, margin); SetMarginRight(_grabber, margin); } protected override void Resized() { base.Resized(); UpdateValue(); } protected internal override void KeyBindDown(GUIBoundKeyEventArgs args) { base.KeyBindDown(args); if (args.Function != EngineKeyFunctions.UIClick) { return; } HandlePositionChange(args.RelativePosition); _grabbed = true; } protected internal override void KeyBindUp(GUIBoundKeyEventArgs args) { base.KeyBindUp(args); if (args.Function != EngineKeyFunctions.UIClick) return; _grabbed = false; } protected internal override void MouseMove(GUIMouseMoveEventArgs args) { if (!_grabbed) { return; } HandlePositionChange(args.RelativePosition); } private void HandlePositionChange(Vector2 position) { var grabberWidth = _grabber.DesiredSize.X; var ratio = (position.X - grabberWidth / 2) / (Width - grabberWidth); SetAsRatio(ratio); } protected override void StylePropertiesChanged() { base.StylePropertiesChanged(); UpdateStyleBoxes(); } private void UpdateStyleBoxes() { StyleBox? GetStyleBox(string name) { if (TryGetStyleProperty(name, out var box)) { return box; } return null; } _backgroundPanel.PanelOverride = BackgroundStyleBoxOverride ?? GetStyleBox(StylePropertyBackground); _foregroundPanel.PanelOverride = BackgroundStyleBoxOverride ?? GetStyleBox(StylePropertyForeground); _fillPanel.PanelOverride = FillStyleBoxOverride ?? GetStyleBox(StylePropertyFill); _grabber.PanelOverride = GrabberStyleBoxOverride ?? GetStyleBox(StylePropertyGrabber); } } }