mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Implement CSS-like stylesheets into GUI.
Label now reads properties from the CSS system.
This commit is contained in:
@@ -13,7 +13,8 @@ namespace SS14.Client.Interfaces.UserInterface
|
||||
{
|
||||
public interface IUserInterfaceManager
|
||||
{
|
||||
UITheme Theme { get; }
|
||||
UITheme ThemeDefaults { get; }
|
||||
Stylesheet Stylesheet { get; set; }
|
||||
|
||||
Control Focused { get; }
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace SS14.Client.ResourceManagement
|
||||
{
|
||||
if (!cache.ContentFileExists(path))
|
||||
{
|
||||
throw new FileNotFoundException("Content file does not exist for texture");
|
||||
throw new FileNotFoundException("Content file does not exist for font");
|
||||
}
|
||||
|
||||
switch (GameController.Mode)
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
<Compile Include="ResourceManagement\ResourceTypes\RSIResource.cs" />
|
||||
<Compile Include="ResourceManagement\ResourceTypes\TextureResource.cs" />
|
||||
<Compile Include="SceneTreeHolder.cs" />
|
||||
<Compile Include="UserInterface\Control.Styling.cs" />
|
||||
<Compile Include="UserInterface\Controls\BaseButton.cs" />
|
||||
<Compile Include="UserInterface\Controls\Button.cs" />
|
||||
<Compile Include="UserInterface\Controls\CheckBox.cs" />
|
||||
|
||||
111
SS14.Client/UserInterface/Control.Styling.cs
Normal file
111
SS14.Client/UserInterface/Control.Styling.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SS14.Client.UserInterface
|
||||
{
|
||||
// ReSharper disable once RequiredBaseTypesIsNotInherited
|
||||
public partial class Control
|
||||
{
|
||||
private readonly Dictionary<string, object> _styleProperties = new Dictionary<string, object>();
|
||||
private readonly HashSet<string> _styleClasses = new HashSet<string>();
|
||||
public IReadOnlyCollection<string> StyleClasses => _styleClasses;
|
||||
|
||||
private string _styleIdentifier;
|
||||
public string StyleIdentifier
|
||||
{
|
||||
get => _styleIdentifier;
|
||||
set
|
||||
{
|
||||
_styleIdentifier = value;
|
||||
Restyle();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasStyleClass(string className)
|
||||
{
|
||||
return _styleClasses.Contains(className);
|
||||
}
|
||||
|
||||
public void AddStyleClass(string className)
|
||||
{
|
||||
_styleClasses.Add(className);
|
||||
Restyle();
|
||||
}
|
||||
|
||||
public void RemoveStyleClass(string className)
|
||||
{
|
||||
_styleClasses.Remove(className);
|
||||
Restyle();
|
||||
}
|
||||
|
||||
private void Restyle()
|
||||
{
|
||||
_styleProperties.Clear();
|
||||
|
||||
// TODO: probably gonna need support for multiple stylesheets.
|
||||
var stylesheet = UserInterfaceManager.Stylesheet;
|
||||
if (stylesheet == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all rules that apply to us, sort them and apply they params again.
|
||||
var ruleList = new List<(StyleRule rule, int index)>();
|
||||
var count = 0;
|
||||
foreach (var rule in stylesheet.Rules)
|
||||
{
|
||||
if (!rule.Selector.Matches(this))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ruleList.Add((rule, count));
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// Sort by specificity.
|
||||
// The index is there to sort by if specificity is the same, in which case the last takes precedence.
|
||||
ruleList.Sort((a, b) =>
|
||||
{
|
||||
var cmp = a.rule.Specificity.CompareTo(b.rule.Specificity);
|
||||
// Reverse this sort so that high specificity is at the TOP.
|
||||
return -(cmp != 0 ? cmp : a.index.CompareTo(b.index));
|
||||
});
|
||||
|
||||
// Go over each rule.
|
||||
foreach (var (rule, _) in ruleList)
|
||||
{
|
||||
foreach (var property in rule.Properties)
|
||||
{
|
||||
if (_styleProperties.ContainsKey(property.Name))
|
||||
{
|
||||
// Since we've sorted by priority in reverse,
|
||||
// the first ones to get applied have highest priority.
|
||||
// So if we have a duplicate it's always lower priority and we can discard it.
|
||||
continue;
|
||||
}
|
||||
|
||||
_styleProperties[property.Name] = property.Value;
|
||||
}
|
||||
}
|
||||
|
||||
StylePropertiesChanged();
|
||||
}
|
||||
|
||||
protected virtual void StylePropertiesChanged()
|
||||
{
|
||||
MinimumSizeChanged();
|
||||
}
|
||||
|
||||
public bool TryGetStyleProperty<T>(string param, out T value)
|
||||
{
|
||||
if (_styleProperties.TryGetValue(param, out var val))
|
||||
{
|
||||
value = (T) val;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,31 +466,6 @@ namespace SS14.Client.UserInterface
|
||||
}
|
||||
}
|
||||
|
||||
private readonly HashSet<string> _styleClasses = new HashSet<string>();
|
||||
public IReadOnlyCollection<string> StyleClasses => _styleClasses;
|
||||
|
||||
private string _styleIdentifier;
|
||||
public string StyleIdentifier
|
||||
{
|
||||
get => _styleIdentifier;
|
||||
set => _styleIdentifier = value;
|
||||
}
|
||||
|
||||
public bool HasStyleClass(string className)
|
||||
{
|
||||
return _styleClasses.Contains(className);
|
||||
}
|
||||
|
||||
public void AddStyleClass(string className)
|
||||
{
|
||||
_styleClasses.Add(className);
|
||||
}
|
||||
|
||||
public void RemoveStyleClass(string className)
|
||||
{
|
||||
_styleClasses.Remove(className);
|
||||
}
|
||||
|
||||
public Color Modulate
|
||||
{
|
||||
get => SceneControl.Modulate.Convert();
|
||||
@@ -586,6 +561,7 @@ namespace SS14.Client.UserInterface
|
||||
Name = GetType().Name;
|
||||
Initialize();
|
||||
_applyPropertyMap();
|
||||
Restyle();
|
||||
}
|
||||
|
||||
/// <param name="name">The name the component will have.</param>
|
||||
@@ -610,6 +586,7 @@ namespace SS14.Client.UserInterface
|
||||
Name = name;
|
||||
Initialize();
|
||||
_applyPropertyMap();
|
||||
Restyle();
|
||||
}
|
||||
|
||||
|
||||
@@ -625,6 +602,7 @@ namespace SS14.Client.UserInterface
|
||||
SetupSignalHooks();
|
||||
//Logger.Debug($"Wrapping control {Name} ({GetType()} -> {control.GetType()})");
|
||||
Initialize();
|
||||
Restyle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1184,6 +1162,7 @@ namespace SS14.Client.UserInterface
|
||||
protected virtual void Parented(Control newParent)
|
||||
{
|
||||
MinimumSizeChanged();
|
||||
Restyle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1230,6 +1209,7 @@ namespace SS14.Client.UserInterface
|
||||
/// </summary>
|
||||
protected virtual void Deparented()
|
||||
{
|
||||
Restyle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace SS14.Client.UserInterface.Controls
|
||||
return;
|
||||
}
|
||||
|
||||
var uiTheme = UserInterfaceManager.Theme;
|
||||
var uiTheme = UserInterfaceManager.ThemeDefaults;
|
||||
StyleBox style;
|
||||
switch (DrawMode)
|
||||
{
|
||||
@@ -197,7 +197,7 @@ namespace SS14.Client.UserInterface.Controls
|
||||
return base.CalculateMinimumSize();
|
||||
}
|
||||
|
||||
var uiTheme = UserInterfaceManager.Theme;
|
||||
var uiTheme = UserInterfaceManager.ThemeDefaults;
|
||||
var style = uiTheme.ButtonStyleNormal;
|
||||
var font = uiTheme.DefaultFont;
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace SS14.Client.UserInterface.Controls
|
||||
return 0;
|
||||
}
|
||||
|
||||
var uiTheme = UserInterfaceManager.Theme;
|
||||
var uiTheme = UserInterfaceManager.ThemeDefaults;
|
||||
var font = uiTheme.DefaultFont;
|
||||
|
||||
var textWidth = 0;
|
||||
|
||||
@@ -13,6 +13,9 @@ namespace SS14.Client.UserInterface.Controls
|
||||
[ControlWrap(typeof(Godot.Label))]
|
||||
public class Label : Control
|
||||
{
|
||||
public const string StylePropertyFontColor = "font-color";
|
||||
public const string StylePropertyFont = "font";
|
||||
|
||||
private Vector2i? _textDimensionCache;
|
||||
|
||||
public Label(string name) : base(name)
|
||||
@@ -105,6 +108,24 @@ namespace SS14.Client.UserInterface.Controls
|
||||
set => SetFontOverride("font", _fontOverride = value);
|
||||
}
|
||||
|
||||
private Font ActualFont
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_fontOverride != null)
|
||||
{
|
||||
return _fontOverride;
|
||||
}
|
||||
|
||||
if (TryGetStyleProperty<Font>(StylePropertyFont, out var font))
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
return UserInterfaceManager.ThemeDefaults.LabelFont;
|
||||
}
|
||||
}
|
||||
|
||||
private Color? _fontColorShadowOverride;
|
||||
|
||||
public Color? FontColorShadowOverride
|
||||
@@ -113,6 +134,24 @@ namespace SS14.Client.UserInterface.Controls
|
||||
set => SetColorOverride("font_color_shadow", _fontColorShadowOverride = value);
|
||||
}
|
||||
|
||||
private Color ActualFontColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_fontColorOverride.HasValue)
|
||||
{
|
||||
return _fontColorOverride.Value;
|
||||
}
|
||||
|
||||
if (TryGetStyleProperty<Color>(StylePropertyFontColor, out var color))
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
return Color.White;
|
||||
}
|
||||
}
|
||||
|
||||
private Color? _fontColorOverride;
|
||||
|
||||
public Color? FontColorOverride
|
||||
@@ -195,8 +234,9 @@ namespace SS14.Client.UserInterface.Controls
|
||||
}
|
||||
|
||||
var newlines = 0;
|
||||
var font = _fontOverride ?? UserInterfaceManager.Theme.LabelFont;
|
||||
var font = ActualFont;
|
||||
var baseLine = new Vector2(hOffset, font.Ascent + vOffset);
|
||||
var actualFontColor = ActualFontColor;
|
||||
foreach (var chr in _text)
|
||||
{
|
||||
if (chr == '\n')
|
||||
@@ -205,7 +245,7 @@ namespace SS14.Client.UserInterface.Controls
|
||||
baseLine = new Vector2(hOffset, font.Ascent + font.Height * newlines);
|
||||
}
|
||||
|
||||
var advance = font.DrawChar(handle, chr, baseLine, FontColorOverride ?? Color.White);
|
||||
var advance = font.DrawChar(handle, chr, baseLine, actualFontColor);
|
||||
baseLine += new Vector2(advance, 0);
|
||||
}
|
||||
}
|
||||
@@ -250,7 +290,7 @@ namespace SS14.Client.UserInterface.Controls
|
||||
return;
|
||||
}
|
||||
|
||||
var font = _fontOverride ?? UserInterfaceManager.Theme.LabelFont;
|
||||
var font = ActualFont;
|
||||
var height = font.Height;
|
||||
var maxLineSize = 0;
|
||||
var currentLineSize = 0;
|
||||
|
||||
@@ -161,11 +161,11 @@ namespace SS14.Client.UserInterface.Controls
|
||||
return;
|
||||
}
|
||||
|
||||
var styleBox = UserInterfaceManager.Theme.LineEditBox;
|
||||
var styleBox = UserInterfaceManager.ThemeDefaults.LineEditBox;
|
||||
var drawBox = new UIBox2(Vector2.Zero, Size);
|
||||
var contentBox = styleBox.GetContentBox(drawBox);
|
||||
styleBox.Draw(handle, drawBox);
|
||||
var font = UserInterfaceManager.Theme.DefaultFont;
|
||||
var font = UserInterfaceManager.ThemeDefaults.DefaultFont;
|
||||
|
||||
var baseLine = new Vector2i(0, (int)(contentBox.Height + font.Ascent)/2) + contentBox.TopLeft;
|
||||
|
||||
@@ -200,8 +200,8 @@ namespace SS14.Client.UserInterface.Controls
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
var font = UserInterfaceManager.Theme.DefaultFont;
|
||||
return new Vector2(0, font.Height) + UserInterfaceManager.Theme.LineEditBox.MinimumSize;
|
||||
var font = UserInterfaceManager.ThemeDefaults.DefaultFont;
|
||||
return new Vector2(0, font.Height) + UserInterfaceManager.ThemeDefaults.LineEditBox.MinimumSize;
|
||||
}
|
||||
|
||||
public enum AlignMode
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace SS14.Client.UserInterface.Controls
|
||||
|
||||
if (!GameController.OnGodot)
|
||||
{
|
||||
var panel = _panelOverride ?? UserInterfaceManager.Theme.PanelPanel;
|
||||
var panel = _panelOverride ?? UserInterfaceManager.ThemeDefaults.PanelPanel;
|
||||
panel.Draw(handle, UIBox2.FromDimensions(Vector2.Zero, Size));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace SS14.Client.UserInterface.CustomControls
|
||||
[ControlWrap("res://Engine/Scenes/SS14Window/SS14Window.tscn")]
|
||||
public class SS14Window : Panel
|
||||
{
|
||||
public const string StyleClassWindowTitle = "windowTitle";
|
||||
|
||||
[Dependency] private readonly IDisplayManager _displayManager;
|
||||
|
||||
public SS14Window() : base()
|
||||
@@ -87,6 +89,8 @@ namespace SS14.Client.UserInterface.CustomControls
|
||||
CloseButton.OnPressed += CloseButtonPressed;
|
||||
|
||||
Contents = GetChild("Contents");
|
||||
|
||||
TitleLabel.AddStyleClass(StyleClassWindowTitle);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using SS14.Shared.Utility;
|
||||
|
||||
namespace SS14.Client.UserInterface
|
||||
{
|
||||
@@ -9,7 +11,7 @@ namespace SS14.Client.UserInterface
|
||||
/// </summary>
|
||||
public sealed class Stylesheet
|
||||
{
|
||||
private IReadOnlyList<StyleRule> Rules { get; }
|
||||
public IReadOnlyList<StyleRule> Rules { get; }
|
||||
|
||||
public Stylesheet(IReadOnlyList<StyleRule> rules)
|
||||
{
|
||||
@@ -26,12 +28,67 @@ namespace SS14.Client.UserInterface
|
||||
{
|
||||
Selector = selector;
|
||||
Properties = properties;
|
||||
Specificity = selector.CalculateSpecificity();
|
||||
}
|
||||
|
||||
public StyleSpecificity Specificity { get; }
|
||||
public Selector Selector { get; }
|
||||
public IReadOnlyList<StyleProperty> Properties { get; }
|
||||
}
|
||||
|
||||
// https://specifishity.com/
|
||||
public struct StyleSpecificity : IComparable<StyleSpecificity>, IComparable
|
||||
{
|
||||
public readonly int IdSelectors;
|
||||
public readonly int ClassSelectors;
|
||||
public readonly int TypeSelectors;
|
||||
|
||||
public StyleSpecificity(int idSelectors, int classSelectors, int typeSelectors)
|
||||
{
|
||||
IdSelectors = idSelectors;
|
||||
ClassSelectors = classSelectors;
|
||||
TypeSelectors = typeSelectors;
|
||||
}
|
||||
|
||||
public static StyleSpecificity operator +(StyleSpecificity a, StyleSpecificity b)
|
||||
{
|
||||
return new StyleSpecificity(
|
||||
a.IdSelectors + b.IdSelectors,
|
||||
a.ClassSelectors + b.ClassSelectors,
|
||||
a.TypeSelectors + b.TypeSelectors);
|
||||
}
|
||||
|
||||
public int CompareTo(StyleSpecificity other)
|
||||
{
|
||||
var idSelectorsComparison = IdSelectors.CompareTo(other.IdSelectors);
|
||||
if (idSelectorsComparison != 0)
|
||||
{
|
||||
return idSelectorsComparison;
|
||||
}
|
||||
|
||||
var classSelectorsComparison = ClassSelectors.CompareTo(other.ClassSelectors);
|
||||
if (classSelectorsComparison != 0)
|
||||
{
|
||||
return classSelectorsComparison;
|
||||
}
|
||||
|
||||
return TypeSelectors.CompareTo(other.TypeSelectors);
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return 1;
|
||||
return obj is StyleSpecificity other
|
||||
? CompareTo(other)
|
||||
: throw new ArgumentException($"Object must be of type {nameof(StyleSpecificity)}");
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"({IdSelectors}-{ClassSelectors}-{TypeSelectors})";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single property in a rule, with a name and an object value.
|
||||
/// </summary>
|
||||
@@ -50,6 +107,7 @@ namespace SS14.Client.UserInterface
|
||||
public abstract class Selector
|
||||
{
|
||||
public abstract bool Matches(Control control);
|
||||
public abstract StyleSpecificity CalculateSpecificity();
|
||||
}
|
||||
|
||||
public sealed class SelectorElement : Selector
|
||||
@@ -57,16 +115,19 @@ namespace SS14.Client.UserInterface
|
||||
public SelectorElement(
|
||||
string elementType,
|
||||
IReadOnlyCollection<string> elementClasses,
|
||||
string elementId)
|
||||
string elementId,
|
||||
string pseudoClass)
|
||||
{
|
||||
ElementType = elementType;
|
||||
ElementClasses = elementClasses;
|
||||
ElementId = elementId;
|
||||
PseudoClass = pseudoClass;
|
||||
}
|
||||
|
||||
public string ElementType { get; }
|
||||
public IReadOnlyCollection<string> ElementClasses { get; }
|
||||
public string ElementId { get; }
|
||||
public string PseudoClass { get; }
|
||||
|
||||
public override bool Matches(Control control)
|
||||
{
|
||||
@@ -93,9 +154,19 @@ namespace SS14.Client.UserInterface
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override StyleSpecificity CalculateSpecificity()
|
||||
{
|
||||
var countId = ElementId == null ? 0 : 1;
|
||||
var countClasses = (ElementClasses?.Count ?? 0) + (PseudoClass == null ? 0 : 1);
|
||||
var countTypes = ElementType == null ? 0 : 1;
|
||||
return new StyleSpecificity(countId, countClasses, countTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SelectorDescendant : Selector
|
||||
// Temporarily hidden due to performance concerns.
|
||||
// Like seriously this thing is O(n!)
|
||||
internal sealed class SelectorDescendant : Selector
|
||||
{
|
||||
public SelectorDescendant([NotNull] Selector ascendant, [NotNull] Selector descendant)
|
||||
{
|
||||
@@ -128,8 +199,14 @@ namespace SS14.Client.UserInterface
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
public override StyleSpecificity CalculateSpecificity()
|
||||
{
|
||||
return Ascendant.CalculateSpecificity() + Descendant.CalculateSpecificity();
|
||||
}
|
||||
}
|
||||
|
||||
// Temporarily hidden due to performance concerns.
|
||||
public sealed class SelectorChild : Selector
|
||||
{
|
||||
public SelectorChild(Selector parent, Selector child)
|
||||
@@ -150,5 +227,10 @@ namespace SS14.Client.UserInterface
|
||||
|
||||
return Parent.Matches(control.Parent) && Child.Matches(control);
|
||||
}
|
||||
|
||||
public override StyleSpecificity CalculateSpecificity()
|
||||
{
|
||||
return Parent.CalculateSpecificity() + Child.CalculateSpecificity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ using SS14.Shared.Maths;
|
||||
|
||||
namespace SS14.Client.UserInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// Fallback theme system for GUI.
|
||||
/// </summary>
|
||||
public abstract class UITheme
|
||||
{
|
||||
public abstract Font DefaultFont { get; }
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace SS14.Client.UserInterface
|
||||
[Dependency] private readonly IDisplayManager _displayManager;
|
||||
[Dependency] private readonly IResourceCache _resourceCache;
|
||||
|
||||
public UITheme Theme { get; private set; }
|
||||
|
||||
public UITheme ThemeDefaults { get; private set; }
|
||||
public Stylesheet Stylesheet { get; set; }
|
||||
public Control Focused { get; private set; }
|
||||
|
||||
// When a control receives a mouse down it must also receive a mouse up and mouse moves, always.
|
||||
@@ -59,7 +59,7 @@ namespace SS14.Client.UserInterface
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Theme = new UIThemeDefault();
|
||||
ThemeDefaults = new UIThemeDefault();
|
||||
|
||||
if (GameController.OnGodot)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,8 @@ namespace SS14.UnitTesting.Client
|
||||
{
|
||||
internal class DummyUserInterfaceManager : IUserInterfaceManagerInternal
|
||||
{
|
||||
public UITheme Theme { get; } = new UIThemeDummy();
|
||||
public UITheme ThemeDefaults { get; } = new UIThemeDummy();
|
||||
public Stylesheet Stylesheet { get; set; }
|
||||
|
||||
public Control Focused => throw new System.NotImplementedException();
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using NUnit.Framework;
|
||||
using SS14.Client.Interfaces.UserInterface;
|
||||
using SS14.Client.UserInterface;
|
||||
using SS14.Client.UserInterface.Controls;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Utility;
|
||||
|
||||
namespace SS14.UnitTesting.Client.UserInterface
|
||||
@@ -13,14 +15,14 @@ namespace SS14.UnitTesting.Client.UserInterface
|
||||
[Test]
|
||||
public void TestSelectors()
|
||||
{
|
||||
var selectorElementLabel = new SelectorElement("Label", null, null);
|
||||
var selectorElementLabel = new SelectorElement("Label", null, null, null);
|
||||
|
||||
var label = new Label();
|
||||
var panel = new Panel {StyleIdentifier = "bar"};
|
||||
Assert.That(selectorElementLabel.Matches(label), Is.True);
|
||||
Assert.That(selectorElementLabel.Matches(panel), Is.False);
|
||||
|
||||
selectorElementLabel = new SelectorElement("Label", new []{"foo"}, null);
|
||||
selectorElementLabel = new SelectorElement("Label", new []{"foo"}, null, null);
|
||||
Assert.That(selectorElementLabel.Matches(label), Is.False);
|
||||
Assert.That(selectorElementLabel.Matches(panel), Is.False);
|
||||
|
||||
@@ -36,9 +38,40 @@ namespace SS14.UnitTesting.Client.UserInterface
|
||||
// Make sure it doesn't throw.
|
||||
label.RemoveStyleClass("foo");
|
||||
|
||||
selectorElementLabel = new SelectorElement(null, null, "bar");
|
||||
selectorElementLabel = new SelectorElement(null, null, "bar", null);
|
||||
Assert.That(selectorElementLabel.Matches(label), Is.False);
|
||||
Assert.That(selectorElementLabel.Matches(panel), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStyleProperties()
|
||||
{
|
||||
var sheet = new Stylesheet(new []
|
||||
{
|
||||
new StyleRule(new SelectorElement("Label", null, "baz", null), new []
|
||||
{
|
||||
new StyleProperty("foo", "honk"),
|
||||
}),
|
||||
new StyleRule(new SelectorElement("Label", null, null, null), new []
|
||||
{
|
||||
new StyleProperty("foo", "heh"),
|
||||
}),
|
||||
new StyleRule(new SelectorElement("Label", null, null, null), new []
|
||||
{
|
||||
new StyleProperty("foo", "bar"),
|
||||
}),
|
||||
});
|
||||
|
||||
var uiMgr = IoCManager.Resolve<IUserInterfaceManager>();
|
||||
uiMgr.Stylesheet = sheet;
|
||||
|
||||
var control = new Label();
|
||||
control.TryGetStyleProperty("foo", out string value);
|
||||
Assert.That(value, Is.EqualTo("bar"));
|
||||
|
||||
control.StyleIdentifier = "baz";
|
||||
control.TryGetStyleProperty("foo", out value);
|
||||
Assert.That(value, Is.EqualTo("honk"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user