Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BAR control to DMF support #1375

Merged
merged 14 commits into from
Dec 9, 2023
108 changes: 108 additions & 0 deletions OpenDreamClient/Interface/Controls/ControlBar.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System.Globalization;
using OpenDreamClient.Interface.Descriptors;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;

namespace OpenDreamClient.Interface.Controls;

internal sealed class ControlBar : InterfaceControl {
private ProgressBar? _bar;
private Slider? _slider;
private Control _container = default!; // Created by base constructor

private ControlDescriptorBar BarDescriptor => (ControlDescriptorBar)ElementDescriptor;

public ControlBar(ControlDescriptor controlDescriptor, ControlWindow window) : base(controlDescriptor, window) {
}

protected override void UpdateElementDescriptor() {
base.UpdateElementDescriptor();

//width
float barWidth = BarDescriptor.Width ?? 10f;

//TODO dir - these both need RT level changes
//TODO angles

//is-slider
if (BarDescriptor.IsSlider) {
if (_slider is null) {
_slider = new Slider {
MaxValue = 100,
MinValue = 0,
Margin = new Thickness(4),
HorizontalExpand = true,
VerticalExpand = (barWidth == 0f),
MinHeight = barWidth,
Value = BarDescriptor.Value ?? 0.0f
};

_slider.OnValueChanged += OnValueChanged;

if (_bar is not null) {
_container.RemoveChild(_bar);
_bar = null;
}

_container.AddChild(_slider);
} else {
_slider.Value = BarDescriptor.Value ?? 0.0f;
}

//bar-color
if (_slider.TryGetStyleProperty<StyleBoxFlat>(Slider.StylePropertyGrabber, out var box)) {
box.BackgroundColor = BarDescriptor.BarColor ?? Color.Transparent;
_slider.GrabberStyleBoxOverride = box;
}
} else {
if (_bar is null) {
_bar = new ProgressBar {
MaxValue = 100,
MinValue = 0,
Margin = new Thickness(4),
HorizontalExpand = true,
VerticalExpand = (barWidth == 0f),
MinHeight = barWidth,
Value = BarDescriptor.Value ?? 0.0f
};

_bar.OnValueChanged += OnValueChanged;

if (_slider is not null) {
_container.RemoveChild(_slider);
_slider = null;
}

_container.AddChild(_bar);
} else {
_bar.Value = BarDescriptor.Value ?? 0.0f;
}

//bar-color
if (_bar.TryGetStyleProperty<StyleBoxFlat>(ProgressBar.StylePropertyForeground, out var box)) {
box.BackgroundColor = BarDescriptor.BarColor ?? Color.Transparent;
_bar.ForegroundStyleBoxOverride = box;
}
}
}

private void OnValueChanged(Robust.Client.UserInterface.Controls.Range range) {
//don't run while you're still sliding, only after
// TODO: RT doesn't update Grabbed until after OnValueChanged, fix that
//if (_slider is not null && _slider.Grabbed)
// return;

if (BarDescriptor.OnChange != null) {
var valueReplaced =
BarDescriptor.OnChange.Replace("[[*]]", range.Value.ToString(CultureInfo.InvariantCulture));

_interfaceManager.RunCommand(valueReplaced);
}
}

protected override Control CreateUIElement() {
_container = new Control();
return _container;
}
}
1 change: 1 addition & 0 deletions OpenDreamClient/Interface/Controls/ControlWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ public override void AddChild(ElementDescriptor descriptor) {
ControlDescriptorLabel => new ControlLabel(controlDescriptor, this),
ControlDescriptorGrid => new ControlGrid(controlDescriptor, this),
ControlDescriptorTab => new ControlTab(controlDescriptor, this),
ControlDescriptorBar => new ControlBar(controlDescriptor, this),
_ => throw new Exception($"Invalid descriptor {controlDescriptor.GetType()}")
};

Expand Down
22 changes: 22 additions & 0 deletions OpenDreamClient/Interface/Descriptors/ControlDescriptors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public WindowDescriptor() {
"LABEL" => typeof(ControlDescriptorLabel),
"GRID" => typeof(ControlDescriptorGrid),
"TAB" => typeof(ControlDescriptorTab),
"BAR" => typeof(ControlDescriptorBar),
_ => null
};

Expand Down Expand Up @@ -163,6 +164,26 @@ public sealed partial class ControlDescriptorTab : ControlDescriptor {
}


public sealed partial class ControlDescriptorBar : ControlDescriptor {
[DataField("width")]
public int? Width = 10; //width of the progress bar in pixels. In the default EAST dir, this is more accurately thought of as "height"
[DataField("dir")]
public string? Dir = "east"; //valid values: north/east/south/west/clockwise/cw/counterclockwise/ccw
[DataField("angle1")]
public int? Angle1 = 0; //start angle
[DataField("angle2")]
public int? Angle2 = 180; //end angle
[DataField("bar-color")]
public Color? BarColor = null; //insanely, the default is null which causes the bar not to render regardless of value
[DataField("is-slider")]
public bool IsSlider = false;
[DataField("value")]
public float? Value = 0f; //position of the progress bar
[DataField("on-change")]
public string? OnChange = null;

}

public sealed class DMFColorSerializer : ITypeReader<Color, ValueDataNode> {
public Color Read(ISerializationManager serializationManager,
ValueDataNode node,
Expand All @@ -188,3 +209,4 @@ public ValidationNode Validate(ISerializationManager serializationManager, Value
throw new NotImplementedException();
}
}

10 changes: 10 additions & 0 deletions OpenDreamClient/Interface/DreamStylesheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ public static Stylesheet Make() {
})
.Prop("font", notoSansFont10),

//BarControl - composed of ProgressBar and Slider
Element<ProgressBar>()
.Prop(ProgressBar.StylePropertyBackground, new StyleBoxFlat { BackgroundColor = Color.LightGray, BorderThickness = new Thickness(1), BorderColor = Color.Black})
.Prop(ProgressBar.StylePropertyForeground, new StyleBoxFlat { BackgroundColor = Color.Transparent, BorderThickness = new Thickness(1), BorderColor = Color.Black}),
Element<Slider>()
.Prop(Slider.StylePropertyBackground, new StyleBoxFlat { BackgroundColor = Color.Transparent, BorderThickness = new Thickness(1), BorderColor = Color.Black})
.Prop(Slider.StylePropertyForeground, new StyleBoxFlat { BackgroundColor = Color.LightGray, BorderThickness = new Thickness(1), BorderColor = Color.Black})
.Prop(Slider.StylePropertyGrabber, new StyleBoxFlat { BackgroundColor = Color.Transparent, BorderThickness = new Thickness(1), BorderColor = Color.Black, ContentMarginLeftOverride=10, ContentMarginRightOverride=10})
.Prop(Slider.StylePropertyFill, new StyleBoxFlat { BackgroundColor = Color.Transparent, BorderThickness = new Thickness(0), BorderColor = Color.Black}),

});
}
}
Loading