Decal Placer + add new decals for mapping (#6548)

* abomination

* okay its less unabashedly garbage now

* other UI changes

* its britney bitch

* proper greyscale full/half/quarter tiles

* misc cleanup

* rsi

* Add a palette system. It's Kara's problem now.

* oops

* a

* Departmental palette alpha tweaks

* oopy

* so true

* Update Content.Shared/Decals/ColorPalettePrototype.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* fixes for that

* neutral light color and new warning lines

* dirt

* checkerboards

* oop

Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
mirrorcult
2022-02-08 13:54:41 -07:00
committed by GitHub
parent 2d5c082eba
commit 31769edf5f
80 changed files with 1223 additions and 12 deletions

View File

@@ -0,0 +1,98 @@
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;
}
}

View File

@@ -0,0 +1,26 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.Decals.UI"
Title="{Loc 'decal-placer-window-title'}"
MinSize="250 500"
SetSize="250 500">
<BoxContainer Orientation="Vertical">
<LineEdit Name="Search" />
<ScrollContainer VerticalExpand="True">
<GridContainer Name="Grid" Columns="6">
<!-- Decals get added here by code -->
</GridContainer>
</ScrollContainer>
<ui:AlphaColorPicker Name="ColorPicker"/>
<CheckBox Name="EnableColor" Text="{Loc 'decal-placer-window-use-color'}" />
<CheckBox Name="EnableSnap" Text="{Loc 'decal-placer-window-enable-snap'}" />
<CheckBox Name="EnableCleanable" Text="{Loc 'decal-placer-window-enable-cleanable'}" />
<BoxContainer Name="SpinBoxContainer" Orientation="Horizontal">
<Label Text="{Loc 'decal-placer-window-rotation'}" Margin="0 0 0 1" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'decal-placer-window-zindex'}" Margin="0 0 0 1" />
<SpinBox Name="ZIndexSpinBox" HorizontalExpand ="True" />
</BoxContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,167 @@
using Content.Client.Stylesheets;
using Content.Shared.Decals;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Utility;
using Robust.Shared.Prototypes;
using static Robust.Client.UserInterface.Controls.BaseButton;
namespace Content.Client.Decals.UI;
[GenerateTypedNameReferences]
public sealed partial class DecalPlacerWindow : DefaultWindow
{
private readonly IPrototypeManager _prototypeManager;
private readonly DecalPlacementSystem _decalPlacementSystem;
public FloatSpinBox RotationSpinBox;
private Dictionary<string, Texture>? _decals;
private string? _selected;
private Color _color = Color.White;
private bool _useColor;
private bool _snap;
private float _rotation;
private bool _cleanable;
private int _zIndex;
public DecalPlacerWindow(IPrototypeManager prototypeManager)
{
RobustXamlLoader.Load(this);
_prototypeManager = prototypeManager;
_decalPlacementSystem = EntitySystem.Get<DecalPlacementSystem>();
// This needs to be done in C# so we can have custom stuff passed in the constructor
// and thus have a proper step size
RotationSpinBox = new FloatSpinBox(90.0f, 0)
{
HorizontalExpand = true
};
SpinBoxContainer.AddChild(RotationSpinBox);
Search.OnTextChanged += _ => RefreshList();
ColorPicker.OnColorPicked += color =>
{
_color = color;
UpdateDecalPlacementInfo();
RefreshList();
};
RotationSpinBox.OnValueChanged += args =>
{
_rotation = args.Value;
UpdateDecalPlacementInfo();
};
EnableColor.OnToggled += args =>
{
_useColor = args.Pressed;
UpdateDecalPlacementInfo();
RefreshList();
};
EnableSnap.OnToggled += args =>
{
_snap = args.Pressed;
UpdateDecalPlacementInfo();
};
EnableCleanable.OnToggled += args =>
{
_cleanable = args.Pressed;
UpdateDecalPlacementInfo();
};
// i have to make this a member method for some reason and i have no idea why its only for spinboxes
ZIndexSpinBox.ValueChanged += ZIndexSpinboxChanged;
Populate();
}
private void UpdateDecalPlacementInfo()
{
if (_selected is null)
return;
var color = _useColor ? _color : Color.White;
_decalPlacementSystem.UpdateDecalInfo(_selected, color, _rotation, _snap, _zIndex, _cleanable);
}
private void RefreshList()
{
// Clear
Grid.RemoveAllChildren();
if (_decals == null) return;
var filter = Search.Text;
foreach (var (decal, tex) in _decals)
{
if (!decal.ToLowerInvariant().Contains(filter.ToLowerInvariant()))
continue;
var button = new TextureButton
{
TextureNormal = tex,
Name = decal,
ToolTip = decal,
Modulate = _useColor ? _color : Color.White
};
button.OnPressed += ButtonOnPressed;
if (_selected == decal)
{
var panelContainer = new PanelContainer
{
PanelOverride = new StyleBoxFlat
{
BackgroundColor = StyleNano.ButtonColorDefault
},
Children =
{
button
}
};
Grid.AddChild(panelContainer);
}
else
Grid.AddChild(button);
}
}
private void ZIndexSpinboxChanged(object? sender, ValueChangedEventArgs e)
{
_zIndex = e.Value;
UpdateDecalPlacementInfo();
}
private void ButtonOnPressed(ButtonEventArgs obj)
{
if (obj.Button.Name == null) return;
_selected = obj.Button.Name;
UpdateDecalPlacementInfo();
RefreshList();
}
public void Populate()
{
var prototypes = _prototypeManager.EnumeratePrototypes<DecalPrototype>();
_decals = new Dictionary<string, Texture>();
foreach (var decalPrototype in prototypes)
{
_decals.Add(decalPrototype.ID, decalPrototype.Sprite.Frame0());
}
RefreshList();
}
protected override void Opened()
{
base.Opened();
_decalPlacementSystem.SetActive(true);
}
public override void Close()
{
base.Close();
_decalPlacementSystem.SetActive(false);
}
}

View File

@@ -0,0 +1,12 @@
<DefaultWindow xmlns="https://spacestation14.io"
Title="{Loc 'palette-color-picker-window-title'}"
MinSize="250 500"
SetSize="250 500">
<BoxContainer Orientation="Vertical">
<ItemList Name="PaletteList" VerticalExpand="True" Access="Public"/>
<BoxContainer Orientation="Horizontal">
<Label Text="Palette"/>
<OptionButton Name="Palettes"/>
</BoxContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,54 @@
using Content.Shared.Decals;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client.Decals.UI;
[GenerateTypedNameReferences]
public sealed partial class PaletteColorPicker : DefaultWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
private readonly TextureResource _tex;
public PaletteColorPicker()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_tex = _resourceCache.GetResource<TextureResource>("/Textures/Interface/Nano/button.svg.96dpi.png");
var i = 0;
foreach (var palette in _prototypeManager.EnumeratePrototypes<ColorPalettePrototype>())
{
Palettes.AddItem(palette.Name);
Palettes.SetItemMetadata(i, palette); // ew
i += 1;
}
Palettes.OnItemSelected += args =>
{
Palettes.SelectId(args.Id);
SetupList();
};
Palettes.Select(0);
SetupList();
}
private void SetupList()
{
PaletteList.Clear();
foreach (var (color, value) in (Palettes.SelectedMetadata as ColorPalettePrototype)!.Colors)
{
var item = PaletteList.AddItem(color, _tex.Texture);
item.Metadata = value;
item.IconModulate = value;
}
}
}