242 lines
7.1 KiB
C#
242 lines
7.1 KiB
C#
using Content.Client._Sunrise.MarkingEffectsClient;
|
|
using Content.Shared._Sunrise.MarkingEffects;
|
|
using Robust.Client.UserInterface;
|
|
using Robust.Client.UserInterface.Controls;
|
|
|
|
namespace Content.Client._Sunrise.UserInterface.Controls;
|
|
|
|
public sealed class MarkingEffectSelectorSliders : Control
|
|
{
|
|
private MarkingEffect Effect { get; set; }
|
|
|
|
private static readonly Dictionary<MarkingEffectType, IMarkingEffectUiBuilder> UiBuilders = new()
|
|
{
|
|
{ MarkingEffectType.Color, new ColorMarkingEffectUiBuilder() },
|
|
{ MarkingEffectType.Gradient, new GradientMarkingEffectUiBuilder() },
|
|
{ MarkingEffectType.RoughGradient, new RoughGradientMarkingEffectUiBuilder() },
|
|
};
|
|
|
|
private readonly Dictionary<string, CustomColorSelectorSliders> _colorSelectors = new();
|
|
|
|
private readonly OptionButton _typeSelector;
|
|
private readonly List<MarkingEffectType> _types = new();
|
|
|
|
private MarkingEffectType _currentType;
|
|
|
|
private readonly BoxContainer _selectorsContainer;
|
|
private readonly BoxContainer _slidersContainer;
|
|
private readonly BoxContainer _toggleContainer;
|
|
|
|
public Action<MarkingEffect>? OnColorChanged;
|
|
|
|
public MarkingEffectType CurrentType
|
|
{
|
|
get => _currentType;
|
|
set
|
|
{
|
|
if (_currentType == value)
|
|
return;
|
|
|
|
_currentType = value;
|
|
Populate(_currentType);
|
|
}
|
|
}
|
|
|
|
public MarkingEffectSelectorSliders(MarkingEffect? defaultEffect = null)
|
|
{
|
|
defaultEffect ??= ColorMarkingEffect.White;
|
|
|
|
_typeSelector = new OptionButton();
|
|
_typeSelector.HorizontalExpand = true;
|
|
foreach (var type in Enum.GetValues<MarkingEffectType>())
|
|
{
|
|
_typeSelector.AddItem(Loc.GetString($"marking-effect-type-{type.ToString().ToLower()}"));
|
|
_types.Add(type);
|
|
}
|
|
|
|
_typeSelector.OnItemSelected += args =>
|
|
{
|
|
CurrentType = _types[args.Id];
|
|
_typeSelector.Select(args.Id);
|
|
OnColorsChanged();
|
|
};
|
|
|
|
var rootBox = new BoxContainer
|
|
{ Orientation = BoxContainer.LayoutOrientation.Vertical };
|
|
AddChild(rootBox);
|
|
|
|
var headerBox = new BoxContainer();
|
|
rootBox.AddChild(headerBox);
|
|
headerBox.AddChild(_typeSelector);
|
|
|
|
var bodyBox = new BoxContainer
|
|
{ Orientation = BoxContainer.LayoutOrientation.Vertical };
|
|
rootBox.AddChild(bodyBox);
|
|
|
|
_selectorsContainer = new BoxContainer();
|
|
bodyBox.AddChild(_selectorsContainer);
|
|
|
|
_slidersContainer = new BoxContainer
|
|
{ Orientation = BoxContainer.LayoutOrientation.Vertical };
|
|
bodyBox.AddChild(_slidersContainer);
|
|
|
|
_toggleContainer = new BoxContainer();
|
|
bodyBox.AddChild(_toggleContainer);
|
|
|
|
|
|
_currentType = defaultEffect.Type;
|
|
_typeSelector.TrySelect(_types.IndexOf(_currentType));
|
|
Effect = defaultEffect;
|
|
Populate(_currentType, defaultEffect);
|
|
}
|
|
|
|
public CustomColorSelectorSliders CreateSelector(string key = "base", MarkingEffectType type = MarkingEffectType.Color)
|
|
{
|
|
var colorSelector = new CustomColorSelectorSliders(
|
|
CustomColorSelectorSliders.ColorSelectorType.Hsv,
|
|
Loc.GetString($"marking-effect-{type.ToString().ToLower()}-color-{key}"));
|
|
|
|
colorSelector.HorizontalExpand = true;
|
|
colorSelector.HorizontalAlignment = HAlignment.Stretch;
|
|
|
|
if (Effect.Colors.TryGetValue(key, out var defaultColor))
|
|
colorSelector.Color = defaultColor;
|
|
|
|
colorSelector.OnColorChanged += _ => OnColorsChanged();
|
|
|
|
_colorSelectors.Add(key, colorSelector);
|
|
|
|
var selectorContainer = new BoxContainer
|
|
{
|
|
HorizontalExpand = true,
|
|
HorizontalAlignment = HAlignment.Stretch,
|
|
};
|
|
|
|
_selectorsContainer.AddChild(selectorContainer);
|
|
selectorContainer.AddChild(colorSelector);
|
|
|
|
return colorSelector;
|
|
}
|
|
|
|
public void CreateSlider(string label,
|
|
int defaultValue,
|
|
int minValue,
|
|
int maxValue,
|
|
Action<float> onValueChanged)
|
|
{
|
|
var slider = new Slider
|
|
{
|
|
HorizontalExpand = true,
|
|
VerticalAlignment = VAlignment.Center,
|
|
};
|
|
|
|
slider.MinValue = minValue;
|
|
slider.MaxValue = maxValue;
|
|
slider.Value = defaultValue;
|
|
|
|
var sliderContainer = new BoxContainer();
|
|
|
|
var sliderLabel = new Label();
|
|
sliderLabel.Text = label;
|
|
|
|
var spinBox = new SpinBox
|
|
{
|
|
IsValid = value => IsSpinBoxValid(value, minValue, maxValue)
|
|
};
|
|
spinBox.InitDefaultButtons();
|
|
spinBox.Value = defaultValue;
|
|
|
|
|
|
|
|
sliderContainer.AddChild(sliderLabel);
|
|
sliderContainer.AddChild(slider);
|
|
sliderContainer.AddChild(spinBox);
|
|
_slidersContainer.AddChild(sliderContainer);
|
|
|
|
BindSlider(slider, spinBox, onValueChanged);
|
|
}
|
|
|
|
private void BindSlider(Slider slider, SpinBox spinBox, Action<float> setValue)
|
|
{
|
|
slider.OnReleased += val =>
|
|
{
|
|
setValue(val.Value);
|
|
spinBox.Value = (int)(val.Value);
|
|
OnColorsChanged();
|
|
};
|
|
|
|
spinBox.ValueChanged += val =>
|
|
{
|
|
setValue(val.Value);
|
|
slider.SetValueWithoutEvent(val.Value);
|
|
OnColorsChanged();
|
|
};
|
|
}
|
|
|
|
public void CreateToggle(string label, bool defaultValue, Action<bool> onValueChanged)
|
|
{
|
|
var button = new Button
|
|
{
|
|
Text = label,
|
|
ToggleMode = true,
|
|
Pressed = defaultValue,
|
|
HorizontalExpand = true,
|
|
};
|
|
|
|
button.OnToggled += _ => OnColorsChanged();
|
|
|
|
_toggleContainer.AddChild(button);
|
|
|
|
BindToggle(button, onValueChanged);
|
|
}
|
|
|
|
private void BindToggle(Button toggle, Action<bool> setValue)
|
|
{
|
|
toggle.OnToggled += val =>
|
|
{
|
|
setValue(val.Pressed);
|
|
OnColorsChanged();
|
|
};
|
|
}
|
|
|
|
private bool IsSpinBoxValid(int value, float min, float max)
|
|
{
|
|
return (value >= min) && (value <= max);
|
|
}
|
|
|
|
private void OnColorsChanged()
|
|
{
|
|
foreach (var (key, selector) in _colorSelectors)
|
|
{
|
|
Effect.Colors[key] = selector.Color;
|
|
}
|
|
|
|
OnColorChanged?.Invoke(Effect);
|
|
}
|
|
|
|
private void Populate(MarkingEffectType type, MarkingEffect? defaultEffect = null)
|
|
{
|
|
_colorSelectors.Clear();
|
|
_selectorsContainer.DisposeAllChildren();
|
|
_slidersContainer.DisposeAllChildren();
|
|
_toggleContainer.DisposeAllChildren();
|
|
|
|
Logger.Debug($"{defaultEffect}");
|
|
|
|
defaultEffect ??= type switch
|
|
{
|
|
MarkingEffectType.Color => ColorMarkingEffect.White,
|
|
MarkingEffectType.Gradient => new GradientMarkingEffect(),
|
|
MarkingEffectType.RoughGradient => new RoughGradientMarkingEffect(),
|
|
_ => ColorMarkingEffect.White,
|
|
};
|
|
|
|
Effect = defaultEffect;
|
|
|
|
if (UiBuilders.TryGetValue(type, out var builder))
|
|
builder.BuildUI(Effect, this);
|
|
else
|
|
Logger.Warning($"No UI builder for marking effect: {type}");
|
|
}
|
|
}
|
|
|