Files
RobustToolbox/Robust.Client/UserInterface/Controls/ScrollBar.cs
T
Pieter-Jan BriersandGitHub 17ebeac107 UI Scaling Support. (#809)
Not quite perfect, but quite usable.

Adds the ability to scale the UI. Scaling is controlled via a cvar,
and can be changed at runtime.
Fractional scaling is supported.

Some controls could be better (SpriteView, TextureRect),
but for now it's a good start.
2019-05-11 16:04:14 +02:00

191 lines
5.0 KiB
C#

using System;
using JetBrains.Annotations;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Input;
using Robust.Shared.Maths;
namespace Robust.Client.UserInterface.Controls
{
[ControlWrap("ScrollBar")]
public abstract class ScrollBar : Range
{
public const string StylePropertyGrabber = "grabber";
public const string StylePseudoClassHover = "hover";
public const string StylePseudoClassGrabbed = "grabbed";
private readonly OrientationMode _orientation;
private bool _isHovered;
private (Vector2 pos, float value)? _grabData;
protected ScrollBar(OrientationMode orientation)
{
_orientation = orientation;
}
public bool IsAtEnd
{
get
{
var offset = Value + Page;
return offset > MaxValue || FloatMath.CloseTo(offset, MaxValue);
}
}
public void MoveToEnd()
{
// Will be clamped as necessary.
Value = MaxValue;
}
protected internal override void Draw(DrawingHandleScreen handle)
{
var styleBox = _getGrabberStyleBox();
styleBox?.Draw(handle, _getGrabberBox());
}
protected override void SetDefaults()
{
base.SetDefaults();
MouseFilter = MouseFilterMode.Pass;
}
protected internal override void MouseExited()
{
base.MouseExited();
_isHovered = false;
_updatePseudoClass();
}
protected internal override void MouseMove(GUIMouseMoveEventArgs args)
{
if (_grabData == null)
{
var box = _getGrabberBox();
_isHovered = box.Contains(args.RelativePosition);
_updatePseudoClass();
return;
}
var (grabPos, grabValue) = _grabData.Value;
var (grabRelX, grabRelY) = args.RelativePosition - grabPos;
float moved;
if (_orientation == OrientationMode.Horizontal)
{
moved = grabRelX;
}
else
{
moved = grabRelY;
}
var movedValue = moved / _getOrientationSize();
movedValue *= MaxValue - MinValue;
movedValue += MinValue + grabValue;
Value = movedValue;
}
protected internal override void MouseDown(GUIMouseButtonEventArgs args)
{
if (args.Button != Mouse.Button.Left)
{
return;
}
var box = _getGrabberBox();
if (!box.Contains(args.RelativePosition))
{
return;
}
_grabData = (args.RelativePosition, Value);
_updatePseudoClass();
}
protected internal override void MouseUp(GUIMouseButtonEventArgs args)
{
if (args.Button != Mouse.Button.Left)
{
return;
}
_grabData = null;
_updatePseudoClass();
}
[System.Diagnostics.Contracts.Pure]
private UIBox2 _getGrabberBox()
{
var grabberOffset = GetAsRatio() * _getOrientationSize();
grabberOffset = (float) Math.Round(grabberOffset);
var grabberEnd = (Value + Page - MinValue) / (MaxValue - MinValue) * _getOrientationSize();
grabberEnd = (float) Math.Round(grabberEnd);
if (_orientation == OrientationMode.Horizontal)
{
return new UIBox2(grabberOffset, 0, grabberEnd, PixelHeight);
}
else
{
return new UIBox2(0, grabberOffset, PixelWidth, grabberEnd);
}
}
[System.Diagnostics.Contracts.Pure]
[CanBeNull]
private StyleBox _getGrabberStyleBox()
{
if (TryGetStyleProperty(StylePropertyGrabber, out StyleBox styleBox))
{
return styleBox;
}
return null;
}
[System.Diagnostics.Contracts.Pure]
private float _getOrientationSize()
{
if (_orientation == OrientationMode.Horizontal)
{
return PixelWidth;
}
else
{
return PixelHeight;
}
}
private void _updatePseudoClass()
{
if (_grabData != null)
{
StylePseudoClass = StylePseudoClassGrabbed;
}
else if (_isHovered)
{
StylePseudoClass = StylePseudoClassHover;
}
else
{
StylePseudoClass = null;
}
}
protected override Vector2 CalculateMinimumSize()
{
return _getGrabberStyleBox()?.MinimumSize ?? Vector2.Zero;
}
protected enum OrientationMode
{
Horizontal,
Vertical,
}
}
}