Skip to content

Commit

Permalink
Add BAR control to DMF support (#1375)
Browse files Browse the repository at this point in the history
* start, don't forget to restore defaultinterface

* basic functionality

* finish

* well that was an easy fix

* fix

* Some code quality

* Use `VerticalExpand` instead of the resize event

* Use `Control` instead of `BoxContainer`
We're not laying out multiple controls, no need for a container

* Replace `[[*]]` in `on-change`

---------

Co-authored-by: amy <[email protected]>
Co-authored-by: wixoaGit <[email protected]>
  • Loading branch information
3 people authored Dec 9, 2023
1 parent 1767929 commit d5b739e
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
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}),

});
}
}

0 comments on commit d5b739e

Please sign in to comment.