diff --git a/Content.Client/UserInterface/Controls/RadialContainer.cs b/Content.Client/UserInterface/Controls/RadialContainer.cs
index 0efa51f63d..72555aab5f 100644
--- a/Content.Client/UserInterface/Controls/RadialContainer.cs
+++ b/Content.Client/UserInterface/Controls/RadialContainer.cs
@@ -1,23 +1,12 @@
using Robust.Client.UserInterface.Controls;
using System.Linq;
using System.Numerics;
-using Robust.Client.Graphics;
-using Robust.Shared.Prototypes;
namespace Content.Client.UserInterface.Controls;
[Virtual]
public class RadialContainer : LayoutContainer
{
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- [Dependency] private readonly IClyde _clyde= default!;
- private readonly ShaderInstance _shader;
-
- private readonly float[] _angles = new float[64];
- private readonly float[] _sectorMedians = new float[64];
- private readonly Color[] _sectorColors = new Color[64];
- private readonly Color[] _borderColors = new Color[64];
-
///
/// Increment of radius per child element to be rendered.
///
@@ -35,7 +24,11 @@ public class RadialContainer : LayoutContainer
[ViewVariables(VVAccess.ReadWrite)]
public Vector2 AngularRange
{
- get => _angularRange;
+ get
+ {
+ return _angularRange;
+ }
+
set
{
var x = value.X;
@@ -96,9 +89,7 @@ public class RadialContainer : LayoutContainer
///
public RadialContainer()
{
- IoCManager.InjectDependencies(this);
- _shader = _prototypeManager.Index("RadialMenu")
- .InstanceUnique();
+
}
///
@@ -170,67 +161,6 @@ public class RadialContainer : LayoutContainer
return base.ArrangeOverride(finalSize);
}
- ///
- protected override void Draw(DrawingHandleScreen handle)
- {
- base.Draw(handle);
-
- float selectedFrom = 0;
- float selectedTo = 0;
-
- var i = 0;
- foreach (var child in Children)
- {
- if (child is not IRadialMenuItemWithSector menuWithSector)
- {
- continue;
- }
-
- _angles[i] = menuWithSector.AngleSectorTo;
- _sectorMedians[i] = (menuWithSector.AngleSectorTo + menuWithSector.AngleSectorFrom) / 2;
-
- if (menuWithSector.IsHovered)
- {
- // menuWithSector.DrawBackground;
- // menuWithSector.DrawBorder;
- _sectorColors[i] = menuWithSector.HoverBackgroundColor;
- _borderColors[i] = menuWithSector.HoverBorderColor;
- selectedFrom = menuWithSector.AngleSectorFrom;
- selectedTo = menuWithSector.AngleSectorTo;
- }
- else
- {
- _sectorColors[i] = menuWithSector.BackgroundColor;
- _borderColors[i] = menuWithSector.BorderColor;
- }
-
- i++;
- }
-
- var screenSize = _clyde.ScreenSize;
-
- var menuCenter = new Vector2(
- ScreenCoordinates.X + (Size.X / 2) * UIScale,
- screenSize.Y - ScreenCoordinates.Y - (Size.Y / 2) * UIScale
- );
-
- _shader.SetParameter("separatorAngles", _angles);
- _shader.SetParameter("sectorMedianAngles", _sectorMedians);
- _shader.SetParameter("selectedFrom", selectedFrom);
- _shader.SetParameter("selectedTo", selectedTo);
- _shader.SetParameter("childCount", i);
- _shader.SetParameter("sectorColors", _sectorColors);
- _shader.SetParameter("borderColors", _borderColors);
- _shader.SetParameter("centerPos", menuCenter);
- _shader.SetParameter("screenSize", screenSize);
- _shader.SetParameter("innerRadius", CalculatedRadius * InnerRadiusMultiplier * UIScale);
- _shader.SetParameter("outerRadius", CalculatedRadius * OuterRadiusMultiplier * UIScale);
-
- handle.UseShader(_shader);
- handle.DrawRect(new UIBox2(0, 0, screenSize.X, screenSize.Y), Color.White);
- handle.UseShader(null);
- }
-
///
/// Specifies the different radial alignment modes
///
diff --git a/Content.Client/UserInterface/Controls/RadialMenu.cs b/Content.Client/UserInterface/Controls/RadialMenu.cs
index 35aa655f3e..9734cf2960 100644
--- a/Content.Client/UserInterface/Controls/RadialMenu.cs
+++ b/Content.Client/UserInterface/Controls/RadialMenu.cs
@@ -362,12 +362,12 @@ public interface IRadialMenuItemWithSector
///
/// Angle in radian where button sector should start.
///
- public float AngleSectorFrom { set; get; }
+ public float AngleSectorFrom { set; }
///
/// Angle in radian where button sector should end.
///
- public float AngleSectorTo { set; get; }
+ public float AngleSectorTo { set; }
///
/// Outer radius for drawing segment and pointer detection.
@@ -388,41 +388,6 @@ public interface IRadialMenuItemWithSector
/// Coordinates of center in parent component - button container.
///
public Vector2 ParentCenter { set; }
-
- ///
- /// Marker, is menu item hovered currently.
- ///
- public bool IsHovered { get; }
-
- ///
- /// Color for menu item background when it is hovered over.
- ///
- Color HoverBackgroundColor { get; }
-
- ///
- /// Color for menu item default state.
- ///
- Color BackgroundColor { get; }
-
- ///
- /// Color for menu item border when item is hovered over.
- ///
- Color HoverBorderColor { get; }
-
- ///
- /// Color for menu item border default state.
- ///
- Color BorderColor { get; }
-
- ///
- /// Marker, if menu item background should be drawn.
- ///
- public bool DrawBackground { get; }
-
- ///
- /// Marker, if menu item borders should be drawn.
- ///
- public bool DrawBorder { get; }
}
[Virtual]
@@ -448,7 +413,7 @@ public class RadialMenuTextureButtonWithSector : RadialMenuTextureButton, IRadia
/// Marker, that controls if border of segment should be rendered. Is false by default.
///
///
- /// Default color of border is same as color of background. Use
+ /// By default color of border is same as color of background. Use
/// and to change it.
///
public bool DrawBorder { get; set; } = false;
@@ -494,6 +459,12 @@ public class RadialMenuTextureButtonWithSector : RadialMenuTextureButton, IRadia
set => _hoverBorderColorSrgb = Color.ToSrgb(value);
}
+ ///
+ /// Color of separator lines.
+ /// Separator lines are used to visually separate sector of radial menu items.
+ ///
+ public Color SeparatorColor { get; set; } = new Color(128, 128, 128, 128);
+
///
float IRadialMenuItemWithSector.AngleSectorFrom
{
@@ -502,7 +473,6 @@ public class RadialMenuTextureButtonWithSector : RadialMenuTextureButton, IRadia
_angleSectorFrom = value;
_isWholeCircle = IsWholeCircle(value, _angleSectorTo);
}
- get => _angleSectorFrom;
}
///
@@ -513,7 +483,6 @@ public class RadialMenuTextureButtonWithSector : RadialMenuTextureButton, IRadia
_angleSectorTo = value;
_isWholeCircle = IsWholeCircle(_angleSectorFrom, value);
}
- get => _angleSectorTo;
}
///
@@ -535,6 +504,44 @@ public class RadialMenuTextureButtonWithSector : RadialMenuTextureButton, IRadia
{
}
+ ///
+ protected override void Draw(DrawingHandleScreen handle)
+ {
+ base.Draw(handle);
+
+ if (_parentCenter == null)
+ {
+ return;
+ }
+
+ // draw sector where space that button occupies actually is
+ var containerCenter = (_parentCenter.Value - Position) * UIScale;
+
+ var angleFrom = _angleSectorFrom + _angleOffset;
+ var angleTo = _angleSectorTo + _angleOffset;
+ if (DrawBackground)
+ {
+ var segmentColor = DrawMode == DrawModeEnum.Hover
+ ? _hoverBackgroundColorSrgb
+ : _backgroundColorSrgb;
+
+ DrawAnnulusSector(handle, containerCenter, _innerRadius * UIScale, _outerRadius * UIScale, angleFrom, angleTo, segmentColor);
+ }
+
+ if (DrawBorder)
+ {
+ var borderColor = DrawMode == DrawModeEnum.Hover
+ ? _hoverBorderColorSrgb
+ : _borderColorSrgb;
+ DrawAnnulusSector(handle, containerCenter, _innerRadius * UIScale, _outerRadius * UIScale, angleFrom, angleTo, borderColor, false);
+ }
+
+ if (!_isWholeCircle && DrawBorder)
+ {
+ DrawSeparatorLines(handle, containerCenter, _innerRadius * UIScale, _outerRadius * UIScale, angleFrom, angleTo, SeparatorColor);
+ }
+ }
+
///
protected override bool HasPoint(Vector2 point)
{
diff --git a/Content.Client/UserInterface/Controls/SimpleRadialMenu.xaml.cs b/Content.Client/UserInterface/Controls/SimpleRadialMenu.xaml.cs
index 589a97629d..15c8065a44 100644
--- a/Content.Client/UserInterface/Controls/SimpleRadialMenu.xaml.cs
+++ b/Content.Client/UserInterface/Controls/SimpleRadialMenu.xaml.cs
@@ -7,7 +7,6 @@ using Robust.Client.GameObjects;
using Robust.Shared.Timing;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Input;
-using Robust.Shared.Collections;
namespace Content.Client.UserInterface.Controls;
@@ -174,7 +173,7 @@ public partial class SimpleRadialMenu : RadialMenu
private void ClearExistingChildrenRadialButtons()
{
- var toRemove = new ValueList(ChildCount);
+ var toRemove = new List(ChildCount);
foreach (var child in Children)
{
if (child != ContextualButton && child != MenuOuterAreaButton)
diff --git a/Resources/Prototypes/Shaders/shaders.yml b/Resources/Prototypes/Shaders/shaders.yml
index 631b8ee920..6e0bbd55b4 100644
--- a/Resources/Prototypes/Shaders/shaders.yml
+++ b/Resources/Prototypes/Shaders/shaders.yml
@@ -108,9 +108,4 @@
- type: shader
id: Hologram
kind: source
- path: "/Textures/Shaders/hologram.swsl"
-
-- type: shader
- id: RadialMenu
- kind: source
- path: "/Textures/Shaders/radial-menu.swsl"
+ path: "/Textures/Shaders/hologram.swsl"
\ No newline at end of file
diff --git a/Resources/Textures/Shaders/radial-menu.swsl b/Resources/Textures/Shaders/radial-menu.swsl
deleted file mode 100644
index 30fa1a4cba..0000000000
--- a/Resources/Textures/Shaders/radial-menu.swsl
+++ /dev/null
@@ -1,148 +0,0 @@
-const highp float Thickness = 0.002;
-
-const highp float pi = 3.14159265;
-const highp float twopi = 2.0 * pi;
-const highp float halfpi = 0.5 * pi;
-const highp float invpi = 1.0 / pi;
-
-uniform highp float innerRadius;
-uniform highp float outerRadius;
-
-uniform highp vec4[64] sectorColors;
-uniform highp vec4[64] borderColors;
-
-uniform highp float[64] separatorAngles;
-uniform highp float[64] sectorMedianAngles;
-uniform highp int childCount;
-uniform highp vec2 centerPos;
-
-uniform highp float selectedFrom;
-uniform highp float selectedTo;
-uniform highp vec2 screenSize;
-
-highp float SMOOTH(highp float r, highp float R)
-{
- return 1.0 - smoothstep(R - 1.0, R + 1.0, r);
-}
-
-// line from center of circle to radius (outer arg) on theta0 angle (radian,)
-highp float separator(highp vec2 d, highp float r, highp float outer, highp float theta0, highp float thickness)
-{
- // rotate due to difference in coordinate spaces between shaders and ui
- highp float theta1 = theta0 - halfpi;
- highp vec2 p = outer * vec2(cos(theta1), -sin(theta1));
- highp float l = length(d - p * clamp(dot(d, p) / dot(p, p), 0.0, 1.0));
- return SMOOTH(l, thickness);
-}
-
-highp float circle(highp float r, highp float radius, highp float width)
-{
- return SMOOTH(r - width / 2.0, radius) - SMOOTH(r + width / 2.0, radius);
-}
-
-// get angle between current point and circle center
-highp float getAngle(highp vec2 d)
-{
- highp vec2 n = normalize(d);
- highp float angle = acos(n.x);
- int isNegativeY = int(n.y < 0.0);
- angle = angle + (twopi - angle * 2) * isNegativeY;
- // rotate
- angle = mod(angle - halfpi, twopi);
- return angle;
-}
-
-highp float pcurve(highp float x, highp float a, highp float b )
-{
- highp float k = pow(a + b,a + b) / (pow(a, a) * pow(b, b));
- return k * pow(x, a) * pow(1.0 - x, b);
-}
-
-// gets alpha for radial gradients based on pcurve
-highp float fillGradient(highp float r, highp float inner, highp float outer)
-{
- highp float nInner = inner / outer;
- highp float nR = r / outer;
- return pcurve(nR, nInner, 1.0);
-}
-
-void fragment()
-{
- highp vec4 col = vec4(0.0);
-
- //angle of the line
- highp vec2 d = FRAGCOORD.xy - centerPos;
- highp float angle = getAngle(d);
-
- highp float r = length(FRAGCOORD.xy - centerPos);
- // fill sectors
- int isInsideRange = int(r > innerRadius && r < outerRadius);
- highp float g = fillGradient(r, innerRadius, outerRadius);
-
- // trying to mix in color per button
-
- highp float from = 0;
- for (int i = 0; i < childCount; i++)
- {
- highp float to = separatorAngles[i];
- int isInSector = int(angle > from && angle < to);
- col += isInsideRange
- * vec4(sectorColors[i].xyz , g)* isInSector;
-
- from = to;
- }
-
- // get step of radial menu buttons in radian
- highp float halfSectorAngleSize = (separatorAngles[1] - separatorAngles[0]) * 0.5;
-
- for (int i = 0; i < childCount; i++)
- {
- highp float sectorMedian = sectorMedianAngles[i];
- highp float sectorMedianToAngleDiff = abs(sectorMedian - angle);
- highp vec4 borderColor = borderColors[i];
- highp vec4 borderColorLight = borderColor * 0.6;
- int isInInnerRadius = int(r > innerRadius);
- highp float iAngle = twopi - separatorAngles[i];
- // button separators
- highp float sectorFromAngle;
- int isCurrentZero = int(i > 0);
- sectorFromAngle = separatorAngles[i - 1] * isCurrentZero;
-
- col += isInInnerRadius
- * separator(d, r, outerRadius, sectorFromAngle, 0.5) * borderColor;
- col += isInInnerRadius
- * separator(d, r, outerRadius, iAngle, 0.5) * borderColor;
-
- // set up decorations
- // inner button 'square' decoration
- int isInInnerBorderRange = int(r > innerRadius + 15);
- col += isInInnerRadius * isInInnerBorderRange
- * separator(d, r, outerRadius - 15, twopi - sectorMedian - halfSectorAngleSize * 0.8, 1.0) * 0.2 * borderColorLight;
- col += isInInnerRadius * isInInnerBorderRange
- * separator(d, r, outerRadius - 15, twopi - sectorMedian + halfSectorAngleSize * 0.8, 1.0) * 0.2 * borderColorLight;
-
- int isInInnerBorderSector = int(sectorMedianToAngleDiff < halfSectorAngleSize * 0.8);
- col += isInInnerRadius * isInInnerBorderRange * isInInnerBorderSector
- * circle(r, innerRadius + 15, 2.0) * 0.2 * borderColorLight;
- col += isInInnerRadius * isInInnerBorderRange * isInInnerBorderSector
- * circle(r, outerRadius - 15, 2.0) * 0.2 * borderColorLight;
-
- // outer button decorative elements
- int isInOuterBorderOuterSector = int(sectorMedianToAngleDiff < halfSectorAngleSize * 0.2);
- col += isInOuterBorderOuterSector
- * circle(r, innerRadius - 5, 4.0) * 0.4 * borderColor;
-
- int isInOuterBorderInnerSector = int(sectorMedianToAngleDiff < halfSectorAngleSize * 0.6);
- col += isInOuterBorderInnerSector
- * circle(r, outerRadius + 10, 4.0) * 0.4 * borderColor;
-
- // outer and inner circle of sectors
- int isOnSectorBorder = int(sectorMedianToAngleDiff < halfSectorAngleSize);
- col += isOnSectorBorder
- * circle(r, innerRadius, 2.0) * borderColor;
- col += isOnSectorBorder
- * circle(r, outerRadius, 2.0) * borderColor;
- }
-
- COLOR = col;
-}