Adds colorable sliders & RGB/HSV color picker (#7441)
This commit is contained in:
@@ -4,6 +4,7 @@ using Content.Client.Stylesheets;
|
|||||||
using Content.Shared.CharacterAppearance;
|
using Content.Shared.CharacterAppearance;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
@@ -72,87 +73,6 @@ namespace Content.Client.CharacterAppearance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ColorSlider : Control
|
|
||||||
{
|
|
||||||
private readonly Slider _slider;
|
|
||||||
private readonly LineEdit _textBox;
|
|
||||||
private byte _colorValue;
|
|
||||||
private bool _ignoreEvents;
|
|
||||||
|
|
||||||
public event Action? OnValueChanged;
|
|
||||||
|
|
||||||
public byte ColorValue
|
|
||||||
{
|
|
||||||
get => _colorValue;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_ignoreEvents = true;
|
|
||||||
_colorValue = value;
|
|
||||||
_slider.Value = value;
|
|
||||||
_textBox.Text = value.ToString();
|
|
||||||
_ignoreEvents = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ColorSlider(string styleClass)
|
|
||||||
{
|
|
||||||
_slider = new Slider
|
|
||||||
{
|
|
||||||
StyleClasses = {styleClass},
|
|
||||||
HorizontalExpand = true,
|
|
||||||
VerticalAlignment = VAlignment.Center,
|
|
||||||
MaxValue = byte.MaxValue
|
|
||||||
};
|
|
||||||
_textBox = new LineEdit
|
|
||||||
{
|
|
||||||
MinSize = (50, 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
AddChild(new BoxContainer
|
|
||||||
{
|
|
||||||
Orientation = LayoutOrientation.Horizontal,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
_slider,
|
|
||||||
_textBox
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_slider.OnValueChanged += _ =>
|
|
||||||
{
|
|
||||||
if (_ignoreEvents)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_colorValue = (byte) _slider.Value;
|
|
||||||
_textBox.Text = _colorValue.ToString();
|
|
||||||
|
|
||||||
OnValueChanged?.Invoke();
|
|
||||||
};
|
|
||||||
|
|
||||||
_textBox.OnTextChanged += ev =>
|
|
||||||
{
|
|
||||||
if (_ignoreEvents)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (int.TryParse(ev.Text, out var result))
|
|
||||||
{
|
|
||||||
result = MathHelper.Clamp(result, 0, byte.MaxValue);
|
|
||||||
|
|
||||||
_ignoreEvents = true;
|
|
||||||
_colorValue = (byte) result;
|
|
||||||
_slider.Value = result;
|
|
||||||
_ignoreEvents = false;
|
|
||||||
|
|
||||||
OnValueChanged?.Invoke();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class HairStylePicker : Control
|
public sealed class HairStylePicker : Control
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SpriteAccessoryManager _spriteAccessoryManager = default!;
|
[Dependency] private readonly SpriteAccessoryManager _spriteAccessoryManager = default!;
|
||||||
@@ -163,10 +83,7 @@ namespace Content.Client.CharacterAppearance
|
|||||||
private readonly ItemList _items;
|
private readonly ItemList _items;
|
||||||
|
|
||||||
private readonly Control _colorContainer;
|
private readonly Control _colorContainer;
|
||||||
private readonly ColorSlider _colorSliderR;
|
private readonly ColorSelectorSliders _colorSelectors;
|
||||||
private readonly ColorSlider _colorSliderG;
|
|
||||||
private readonly ColorSlider _colorSliderB;
|
|
||||||
|
|
||||||
private Color _lastColor;
|
private Color _lastColor;
|
||||||
private SpriteAccessoryCategories _categories;
|
private SpriteAccessoryCategories _categories;
|
||||||
|
|
||||||
@@ -181,9 +98,7 @@ namespace Content.Client.CharacterAppearance
|
|||||||
_colorContainer.Visible = canColor;
|
_colorContainer.Visible = canColor;
|
||||||
_lastColor = color;
|
_lastColor = color;
|
||||||
|
|
||||||
_colorSliderR.ColorValue = color.RByte;
|
_colorSelectors.Color = color;
|
||||||
_colorSliderG.ColorValue = color.GByte;
|
|
||||||
_colorSliderB.ColorValue = color.BByte;
|
|
||||||
|
|
||||||
foreach (var item in _items)
|
foreach (var item in _items)
|
||||||
{
|
{
|
||||||
@@ -217,14 +132,8 @@ namespace Content.Client.CharacterAppearance
|
|||||||
Orientation = LayoutOrientation.Vertical
|
Orientation = LayoutOrientation.Vertical
|
||||||
};
|
};
|
||||||
vBox.AddChild(_colorContainer);
|
vBox.AddChild(_colorContainer);
|
||||||
_colorContainer.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
|
_colorContainer.AddChild(_colorSelectors = new ());
|
||||||
_colorContainer.AddChild(_colorSliderG = new ColorSlider(StyleNano.StyleClassSliderGreen));
|
_colorSelectors.OnColorChanged += color => ColorValueChanged(color);
|
||||||
_colorContainer.AddChild(_colorSliderB = new ColorSlider(StyleNano.StyleClassSliderBlue));
|
|
||||||
|
|
||||||
Action colorValueChanged = ColorValueChanged;
|
|
||||||
_colorSliderR.OnValueChanged += colorValueChanged;
|
|
||||||
_colorSliderG.OnValueChanged += colorValueChanged;
|
|
||||||
_colorSliderB.OnValueChanged += colorValueChanged;
|
|
||||||
|
|
||||||
_items = new ItemList
|
_items = new ItemList
|
||||||
{
|
{
|
||||||
@@ -235,14 +144,8 @@ namespace Content.Client.CharacterAppearance
|
|||||||
_items.OnItemSelected += ItemSelected;
|
_items.OnItemSelected += ItemSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ColorValueChanged()
|
private void ColorValueChanged(Color newColor)
|
||||||
{
|
{
|
||||||
var newColor = new Color(
|
|
||||||
_colorSliderR.ColorValue,
|
|
||||||
_colorSliderG.ColorValue,
|
|
||||||
_colorSliderB.ColorValue
|
|
||||||
);
|
|
||||||
|
|
||||||
OnHairColorPicked?.Invoke(newColor);
|
OnHairColorPicked?.Invoke(newColor);
|
||||||
_lastColor = newColor;
|
_lastColor = newColor;
|
||||||
UpdateStylePickerColor();
|
UpdateStylePickerColor();
|
||||||
@@ -280,9 +183,7 @@ namespace Content.Client.CharacterAppearance
|
|||||||
{
|
{
|
||||||
public event Action<Color>? OnEyeColorPicked;
|
public event Action<Color>? OnEyeColorPicked;
|
||||||
|
|
||||||
private readonly ColorSlider _colorSliderR;
|
private readonly ColorSelectorSliders _colorSelectors;
|
||||||
private readonly ColorSlider _colorSliderG;
|
|
||||||
private readonly ColorSlider _colorSliderB;
|
|
||||||
|
|
||||||
private Color _lastColor;
|
private Color _lastColor;
|
||||||
|
|
||||||
@@ -290,9 +191,7 @@ namespace Content.Client.CharacterAppearance
|
|||||||
{
|
{
|
||||||
_lastColor = color;
|
_lastColor = color;
|
||||||
|
|
||||||
_colorSliderR.ColorValue = color.RByte;
|
_colorSelectors.Color = color;
|
||||||
_colorSliderG.ColorValue = color.GByte;
|
|
||||||
_colorSliderB.ColorValue = color.BByte;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EyeColorPicker()
|
public EyeColorPicker()
|
||||||
@@ -303,24 +202,13 @@ namespace Content.Client.CharacterAppearance
|
|||||||
};
|
};
|
||||||
AddChild(vBox);
|
AddChild(vBox);
|
||||||
|
|
||||||
vBox.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
|
vBox.AddChild(_colorSelectors = new ColorSelectorSliders());
|
||||||
vBox.AddChild(_colorSliderG = new ColorSlider(StyleNano.StyleClassSliderGreen));
|
|
||||||
vBox.AddChild(_colorSliderB = new ColorSlider(StyleNano.StyleClassSliderBlue));
|
|
||||||
|
|
||||||
Action colorValueChanged = ColorValueChanged;
|
_colorSelectors.OnColorChanged += ColorValueChanged;
|
||||||
_colorSliderR.OnValueChanged += colorValueChanged;
|
|
||||||
_colorSliderG.OnValueChanged += colorValueChanged;
|
|
||||||
_colorSliderB.OnValueChanged += colorValueChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ColorValueChanged()
|
private void ColorValueChanged(Color newColor)
|
||||||
{
|
{
|
||||||
var newColor = new Color(
|
|
||||||
_colorSliderR.ColorValue,
|
|
||||||
_colorSliderG.ColorValue,
|
|
||||||
_colorSliderB.ColorValue
|
|
||||||
);
|
|
||||||
|
|
||||||
OnEyeColorPicked?.Invoke(newColor);
|
OnEyeColorPicked?.Invoke(newColor);
|
||||||
|
|
||||||
_lastColor = newColor;
|
_lastColor = newColor;
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using Content.Client.CharacterAppearance;
|
|
||||||
using Content.Client.Stylesheets;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
|
|
||||||
namespace Content.Client.Decals.UI;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is just copied from EyeColorPicker btw. I might make it more generic
|
|
||||||
/// </summary>
|
|
||||||
public sealed class AlphaColorPicker : Control
|
|
||||||
{
|
|
||||||
public event Action<Color>? OnColorPicked;
|
|
||||||
|
|
||||||
private readonly ColorSlider _colorSliderR;
|
|
||||||
private readonly ColorSlider _colorSliderG;
|
|
||||||
private readonly ColorSlider _colorSliderB;
|
|
||||||
private readonly ColorSlider _colorSliderA;
|
|
||||||
private PaletteColorPicker? _picker;
|
|
||||||
|
|
||||||
private Color _lastColor;
|
|
||||||
|
|
||||||
public void SetData(Color color)
|
|
||||||
{
|
|
||||||
_lastColor = color;
|
|
||||||
|
|
||||||
_colorSliderR.ColorValue = color.RByte;
|
|
||||||
_colorSliderG.ColorValue = color.GByte;
|
|
||||||
_colorSliderB.ColorValue = color.BByte;
|
|
||||||
_colorSliderA.ColorValue = color.AByte;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AlphaColorPicker()
|
|
||||||
{
|
|
||||||
Button pickerOpen;
|
|
||||||
var vBox = new BoxContainer
|
|
||||||
{
|
|
||||||
Orientation = BoxContainer.LayoutOrientation.Vertical
|
|
||||||
};
|
|
||||||
AddChild(vBox);
|
|
||||||
|
|
||||||
vBox.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
|
|
||||||
vBox.AddChild(_colorSliderG = new ColorSlider(StyleNano.StyleClassSliderGreen));
|
|
||||||
vBox.AddChild(_colorSliderB = new ColorSlider(StyleNano.StyleClassSliderBlue));
|
|
||||||
vBox.AddChild(_colorSliderA = new ColorSlider(StyleNano.StyleClassSliderWhite));
|
|
||||||
vBox.AddChild(pickerOpen = new Button
|
|
||||||
{
|
|
||||||
Text = "Palette"
|
|
||||||
});
|
|
||||||
|
|
||||||
pickerOpen.OnPressed += _ =>
|
|
||||||
{
|
|
||||||
if (_picker is null)
|
|
||||||
{
|
|
||||||
_picker = new PaletteColorPicker();
|
|
||||||
_picker.OpenToLeft();
|
|
||||||
_picker.PaletteList.OnItemSelected += args =>
|
|
||||||
{
|
|
||||||
SetData((args.ItemList.GetSelected().First().Metadata as Color?)!.Value);
|
|
||||||
ColorValueChanged();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_picker.IsOpen)
|
|
||||||
{
|
|
||||||
_picker.Close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_picker.Open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var colorValueChanged = ColorValueChanged;
|
|
||||||
_colorSliderR.OnValueChanged += colorValueChanged;
|
|
||||||
_colorSliderG.OnValueChanged += colorValueChanged;
|
|
||||||
_colorSliderB.OnValueChanged += colorValueChanged;
|
|
||||||
_colorSliderA.OnValueChanged += colorValueChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ColorValueChanged()
|
|
||||||
{
|
|
||||||
var newColor = new Color(
|
|
||||||
_colorSliderR.ColorValue,
|
|
||||||
_colorSliderG.ColorValue,
|
|
||||||
_colorSliderB.ColorValue,
|
|
||||||
_colorSliderA.ColorValue
|
|
||||||
);
|
|
||||||
|
|
||||||
OnColorPicked?.Invoke(newColor);
|
|
||||||
|
|
||||||
_lastColor = newColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
</GridContainer>
|
</GridContainer>
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
|
|
||||||
<ui:AlphaColorPicker Name="ColorPicker"/>
|
<ColorSelectorSliders Name="ColorPicker" IsAlphaVisible="True" />
|
||||||
<CheckBox Name="EnableColor" Text="{Loc 'decal-placer-window-use-color'}" />
|
<CheckBox Name="EnableColor" Text="{Loc 'decal-placer-window-use-color'}" />
|
||||||
<CheckBox Name="EnableSnap" Text="{Loc 'decal-placer-window-enable-snap'}" />
|
<CheckBox Name="EnableSnap" Text="{Loc 'decal-placer-window-enable-snap'}" />
|
||||||
<CheckBox Name="EnableCleanable" Text="{Loc 'decal-placer-window-enable-cleanable'}" />
|
<CheckBox Name="EnableCleanable" Text="{Loc 'decal-placer-window-enable-cleanable'}" />
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public sealed partial class DecalPlacerWindow : DefaultWindow
|
|||||||
SpinBoxContainer.AddChild(RotationSpinBox);
|
SpinBoxContainer.AddChild(RotationSpinBox);
|
||||||
|
|
||||||
Search.OnTextChanged += _ => RefreshList();
|
Search.OnTextChanged += _ => RefreshList();
|
||||||
ColorPicker.OnColorPicked += color =>
|
ColorPicker.OnColorChanged += color =>
|
||||||
{
|
{
|
||||||
_color = color;
|
_color = color;
|
||||||
UpdateDecalPlacementInfo();
|
UpdateDecalPlacementInfo();
|
||||||
|
|||||||
@@ -1183,6 +1183,12 @@ namespace Content.Client.Stylesheets
|
|||||||
new StyleProperty(Slider.StylePropertyFill, sliderFillBox),
|
new StyleProperty(Slider.StylePropertyFill, sliderFillBox),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
new StyleRule(SelectorElement.Type(typeof(ColorableSlider)), new []
|
||||||
|
{
|
||||||
|
new StyleProperty(ColorableSlider.StylePropertyFillWhite, sliderFillWhite),
|
||||||
|
new StyleProperty(ColorableSlider.StylePropertyBackgroundWhite, sliderFillWhite),
|
||||||
|
}),
|
||||||
|
|
||||||
new StyleRule(new SelectorElement(typeof(Slider), new []{StyleClassSliderRed}, null, null), new []
|
new StyleRule(new SelectorElement(typeof(Slider), new []{StyleClassSliderRed}, null, null), new []
|
||||||
{
|
{
|
||||||
new StyleProperty(Slider.StylePropertyFill, sliderFillRed),
|
new StyleProperty(Slider.StylePropertyFill, sliderFillRed),
|
||||||
|
|||||||
Reference in New Issue
Block a user