mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-10-16 23:49:19 +02:00
Draw depot couplers as an icon and a link bar in the state's colour
Each state gets its own icon and colour, and a bar under it ties the two cards: broken when free, thicker when permanent, absent at the back. Green is gone - on the strip it already means selected or turned round.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using Material.Icons;
|
||||||
using StarterNG.Classes;
|
using StarterNG.Classes;
|
||||||
|
|
||||||
namespace StarterNG.Views;
|
namespace StarterNG.Views;
|
||||||
@@ -26,14 +27,21 @@ public enum CouplerState
|
|||||||
NoEndSignals
|
NoEndSignals
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>How a coupler is drawn on the consist strip, so its state reads at a glance.</summary>
|
/// <summary>
|
||||||
|
/// How a coupler is drawn on the consist strip, so its state reads at a glance:
|
||||||
|
/// an icon and a bar under it that ties the two cards, both in the state's colour.
|
||||||
|
/// Green is left out - on the strip it means selected or turned round.
|
||||||
|
/// </summary>
|
||||||
public static class CouplerLook
|
public static class CouplerLook
|
||||||
{
|
{
|
||||||
private static readonly IBrush Dim = new SolidColorBrush(Color.Parse("#808080"));
|
private static readonly IBrush Steel = Solid("#C3CBD3");
|
||||||
private static readonly IBrush Green = new SolidColorBrush(Color.Parse("#41C400"));
|
private static readonly IBrush Dim = Solid("#6B737B");
|
||||||
private static readonly IBrush Blue = new SolidColorBrush(Color.Parse("#4AA3FF"));
|
private static readonly IBrush Sky = Solid("#4FB8FF");
|
||||||
private static readonly IBrush Red = new SolidColorBrush(Color.Parse("#E5484D"));
|
private static readonly IBrush Violet = Solid("#B08CFF");
|
||||||
private static readonly IBrush Amber = new SolidColorBrush(Color.Parse("#E0A030"));
|
private static readonly IBrush Red = Solid("#FF5A5A");
|
||||||
|
private static readonly IBrush Amber = Solid("#F0A030");
|
||||||
|
|
||||||
|
private static IBrush Solid(string color) => new SolidColorBrush(Color.Parse(color));
|
||||||
|
|
||||||
public static CouplerState StateOf(Coupling coupling, bool trailing)
|
public static CouplerState StateOf(Coupling coupling, bool trailing)
|
||||||
{
|
{
|
||||||
@@ -47,26 +55,31 @@ public static class CouplerLook
|
|||||||
return (flags & Coupling.ControlMU) != 0 ? CouplerState.MultipleUnit : CouplerState.Coupled;
|
return (flags & Coupling.ControlMU) != 0 ? CouplerState.MultipleUnit : CouplerState.Coupled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Box drawing and a plain disc: Windows draws no colour emoji for these.
|
public static MaterialIconKind Icon(CouplerState state) => state switch
|
||||||
public static string Glyph(CouplerState state) => state switch
|
|
||||||
{
|
{
|
||||||
CouplerState.Free => "╎",
|
CouplerState.Free => MaterialIconKind.LinkVariantOff,
|
||||||
CouplerState.Permanent => "═",
|
CouplerState.Permanent => MaterialIconKind.LinkLock,
|
||||||
CouplerState.EndSignals => "●",
|
CouplerState.EndSignals => MaterialIconKind.RecordCircle,
|
||||||
_ => "≣"
|
CouplerState.NoEndSignals => MaterialIconKind.AlertCircleOutline,
|
||||||
|
_ => MaterialIconKind.LinkVariant
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>The colour of the glyph; null keeps the ordinary text colour.</summary>
|
public static IBrush Brush(CouplerState state) => state switch
|
||||||
public static IBrush? Brush(CouplerState state) => state switch
|
|
||||||
{
|
{
|
||||||
CouplerState.Free => Dim,
|
CouplerState.Free => Dim,
|
||||||
CouplerState.MultipleUnit => Green,
|
CouplerState.MultipleUnit => Sky,
|
||||||
CouplerState.Permanent => Blue,
|
CouplerState.Permanent => Violet,
|
||||||
CouplerState.EndSignals => Red,
|
CouplerState.EndSignals => Red,
|
||||||
CouplerState.NoEndSignals => Amber,
|
CouplerState.NoEndSignals => Amber,
|
||||||
_ => null
|
_ => Steel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>The bar under the icon: none at the back, broken where nothing is coupled.</summary>
|
||||||
|
public static bool HasBar(CouplerState state) => state is not (CouplerState.EndSignals or CouplerState.NoEndSignals);
|
||||||
|
|
||||||
|
/// <summary>Thicker where the vehicles do not part in shunting.</summary>
|
||||||
|
public static double BarThickness(CouplerState state) => state == CouplerState.Permanent ? 5 : 3;
|
||||||
|
|
||||||
/// <summary>What the coupler connects, by the names the coupler editor uses.</summary>
|
/// <summary>What the coupler connects, by the names the coupler editor uses.</summary>
|
||||||
public static IReadOnlyList<string> Connections(Coupling coupling) =>
|
public static IReadOnlyList<string> Connections(Coupling coupling) =>
|
||||||
Enumerable.Range(0, CouplingBits.BitKeys.Length)
|
Enumerable.Range(0, CouplingBits.BitKeys.Length)
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Shapes;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Layout;
|
using Avalonia.Layout;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
@@ -413,36 +415,34 @@ public sealed class VehicleCards
|
|||||||
public Control BuildCoupler(ConsistItem item, bool trailing = false)
|
public Control BuildCoupler(ConsistItem item, bool trailing = false)
|
||||||
{
|
{
|
||||||
var coupling = Consist.TailCar(item).Coupling;
|
var coupling = Consist.TailCar(item).Coupling;
|
||||||
var glyph = new TextBlock
|
var icon = new MaterialIcon { Width = 18, Height = 18, HorizontalAlignment = HorizontalAlignment.Center };
|
||||||
|
var bar = new Line
|
||||||
{
|
{
|
||||||
FontSize = 18,
|
StartPoint = new Point(0, 0),
|
||||||
VerticalAlignment = VerticalAlignment.Center,
|
EndPoint = new Point(22, 0),
|
||||||
HorizontalAlignment = HorizontalAlignment.Center
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
StrokeLineCap = PenLineCap.Round
|
||||||
};
|
};
|
||||||
var coupler = new Button
|
var coupler = new Button
|
||||||
{
|
{
|
||||||
Padding = new Thickness(4, 6, 4, 6),
|
Padding = new Thickness(3, 6, 3, 6),
|
||||||
MinWidth = 0,
|
MinWidth = 0,
|
||||||
Cursor = _hand,
|
Cursor = _hand,
|
||||||
VerticalAlignment = VerticalAlignment.Center,
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
Content = glyph
|
Content = new StackPanel { Spacing = 4, Children = { icon, bar } }
|
||||||
};
|
};
|
||||||
coupler.Classes.Add("Basic");
|
coupler.Classes.Add("Basic");
|
||||||
|
|
||||||
void Restyle()
|
void Restyle()
|
||||||
{
|
{
|
||||||
var state = CouplerLook.StateOf(coupling, trailing);
|
var state = CouplerLook.StateOf(coupling, trailing);
|
||||||
glyph.Text = CouplerLook.Glyph(state);
|
var brush = CouplerLook.Brush(state);
|
||||||
if (CouplerLook.Brush(state) is { } brush)
|
icon.Kind = CouplerLook.Icon(state);
|
||||||
{
|
icon.Foreground = brush;
|
||||||
glyph.Foreground = brush;
|
bar.Opacity = CouplerLook.HasBar(state) ? 1 : 0; // kept in the layout, so every icon sits level
|
||||||
glyph.Opacity = 1;
|
bar.Stroke = brush;
|
||||||
}
|
bar.StrokeThickness = CouplerLook.BarThickness(state);
|
||||||
else
|
bar.StrokeDashArray = state == CouplerState.Free ? new AvaloniaList<double> { 1.5, 1.5 } : null;
|
||||||
{
|
|
||||||
glyph.ClearValue(TextBlock.ForegroundProperty);
|
|
||||||
glyph.Opacity = 0.7;
|
|
||||||
}
|
|
||||||
ToolTip.SetTip(coupler, CouplerLook.Describe(coupling, trailing));
|
ToolTip.SetTip(coupler, CouplerLook.Describe(coupling, trailing));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user