Порт: Улучшение UX и дизайна консоли связи

Портировано из space-wizards/space-station-14#41899

Изменения:
- Добавлено подтверждение при изменении уровня угрозы (предотвращает случайные изменения)
- Разделены кнопки вызова/отзыва шаттла в отдельные UI области
- Созданы отдельные вкладки для объявлений и трансляции
- Разбито монолитное меню на 3 виджета: AlertLevelControls, MessagingControls, ShuttleControls
- Добавлен LCD-дисплей с таймером обратного отсчета
- Обновлены текстуры и шрифты

Локализация:
- Полностью переведены новые строки на русский язык в стиле Corvax

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-18 22:19:40 +01:00
committed by Codex
parent 8a46ade2b0
commit b840ef7255
36 changed files with 2712 additions and 234 deletions

View File

@@ -0,0 +1,14 @@
using Content.Shared.Communications;
using Robust.Shared.Prototypes;
namespace Content.Client.Communications;
[RegisterComponent]
public sealed partial class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent
{
/// <summary>
/// The prototype ID to use in the UI to show what entities a broadcast will display on
/// </summary>
[DataField]
public EntProtoId ScreenDisplayId = "Screen";
}

View File

@@ -1,9 +1,8 @@
using Content.Shared.CCVar;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Communications;
using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
namespace Content.Client.Communications.UI
{
@@ -23,37 +22,31 @@ namespace Content.Client.Communications.UI
base.Open();
_menu = this.CreateWindow<CommunicationsConsoleMenu>();
_menu.OnAnnounce += AnnounceButtonPressed;
_menu.OnBroadcast += BroadcastButtonPressed;
_menu.OnAlertLevel += AlertLevelSelected;
_menu.OnEmergencyLevel += EmergencyShuttleButtonPressed;
_menu.OnRadioAnnounce += RadioAnnounceButtonPressed;
_menu.OnScreenBroadcast += ScreenBroadcastButtonPressed;
_menu.OnAlertLevelChanged += AlertLevelSelected;
_menu.OnShuttleCalled += CallShuttle;
_menu.OnShuttleRecalled += RecallShuttle;
if (EntMan.TryGetComponent<CommunicationsConsoleComponent>(Owner, out var console))
{
_menu.SetBroadcastDisplayEntity(console.ScreenDisplayId);
}
}
public void AlertLevelSelected(string level)
{
if (_menu!.AlertLevelSelectable)
{
_menu.CurrentLevel = level;
SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level));
}
}
public void EmergencyShuttleButtonPressed()
{
if (_menu!.CountdownStarted)
RecallShuttle();
else
CallShuttle();
}
public void AnnounceButtonPressed(string message)
public void RadioAnnounceButtonPressed(string message)
{
var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
var msg = SharedChatSystem.SanitizeAnnouncement(message, maxLength);
SendMessage(new CommunicationsConsoleAnnounceMessage(msg));
}
public void BroadcastButtonPressed(string message)
public void ScreenBroadcastButtonPressed(string message)
{
SendMessage(new CommunicationsConsoleBroadcastMessage(message));
}
@@ -77,20 +70,7 @@ namespace Content.Client.Communications.UI
if (_menu != null)
{
_menu.CanAnnounce = commsState.CanAnnounce;
_menu.CanBroadcast = commsState.CanBroadcast;
_menu.CanCall = commsState.CanCall;
_menu.CountdownStarted = commsState.CountdownStarted;
_menu.AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0;
_menu.CurrentLevel = commsState.CurrentAlert;
_menu.CountdownEnd = commsState.ExpectedCountdownEnd;
_menu.UpdateCountdown();
_menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel);
_menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable;
_menu.EmergencyShuttleButton.Disabled = !_menu.CanCall;
_menu.AnnounceButton.Disabled = !_menu.CanAnnounce;
_menu.BroadcastButton.Disabled = !_menu.CanBroadcast;
_menu.UpdateState(commsState);
}
}
}

View File

@@ -1,62 +1,32 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
<comms:CommunicationsConsoleMenu xmlns="https://spacestation14.io"
xmlns:comms="clr-namespace:Content.Client.Communications.UI"
xmlns:widgets="clr-namespace:Content.Client.Communications.UI.Widgets"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'comms-console-menu-title'}"
MinSize="400 300">
<!-- Main Container -->
<BoxContainer Orientation="Vertical"
HorizontalExpand="False"
VerticalExpand="True"
Margin="6 6 6 5">
<TextEdit Name="MessageInput"
VerticalExpand="True"
HorizontalExpand="True"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
MinHeight="100"/>
<!-- ButtonsPart -->
<BoxContainer Orientation="Vertical"
VerticalAlignment="Bottom"
SeparationOverride="4">
<!-- AnnouncePart -->
<BoxContainer Orientation="Vertical"
Margin="0 2">
<Button Name="AnnounceButton"
Access="Public"
Text="{Loc 'comms-console-menu-announcement-button'}"
ToolTip="{Loc 'comms-console-menu-announcement-button-tooltip'}"
StyleClasses="OpenLeft"
Margin="0 0 1 0"
Disabled="True"/>
<Button Name="BroadcastButton"
Access="Public"
Text="{Loc 'comms-console-menu-broadcast-button'}"
ToolTip="{Loc 'comms-console-menu-broadcast-button-tooltip'}"
StyleClasses="OpenBoth"/>
<OptionButton Name="AlertLevelButton"
Access="Public"
ToolTip="{Loc 'comms-console-menu-alert-level-button-tooltip'}"
StyleClasses="OpenRight"/>
MouseFilter="Stop" MinSize="400 660" SetWidth="450">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
<controls:LayeredImageContainer StyleClasses="BrightAngleRectOutline" VerticalExpand="True">
<BoxContainer Orientation="Vertical" Margin="12 8 12 12" VerticalExpand="True">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'comms-console-menu-title'}"
StyleClasses="FancyWindowTitle" HorizontalExpand="True"/>
<TextureButton Name="CloseButton" StyleClasses="windowCloseButton"
Modulate="#646464" VerticalAlignment="Center" Margin="0 0 0 6"/>
</BoxContainer>
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<PanelContainer StyleClasses="PanelDark" VerticalExpand="True">
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<widgets:MessagingControls Name="MessagingControls" VerticalExpand="True" />
<!-- EmergencyPart -->
<BoxContainer Orientation="Vertical"
SeparationOverride="6">
<controls:HSpacer Spacing="20" />
<RichTextLabel Name="CountdownLabel"/>
<Button Name="EmergencyShuttleButton"
Access="Public"
Text="Placeholder Text"
ToolTip="{Loc 'comms-console-menu-emergency-shuttle-button-tooltip'}"/>
<widgets:AlertLevelControls Name="AlertLevelControls" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
</BoxContainer>
</controls:LayeredImageContainer>
<widgets:ShuttleControls Name="ShuttleControls" />
</BoxContainer>
</controls:FancyWindow>
</comms:CommunicationsConsoleMenu>

View File

@@ -1,137 +1,83 @@
using System.Globalization;
using Content.Client.UserInterface.Controls;
using Content.Shared.CCVar;
using System.Numerics;
using Content.Shared.Communications;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Robust.Shared.Prototypes;
namespace Content.Client.Communications.UI;
namespace Content.Client.Communications.UI
{
[GenerateTypedNameReferences]
public sealed partial class CommunicationsConsoleMenu : FancyWindow
public sealed partial class CommunicationsConsoleMenu : BaseWindow
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;
private const int DragMoveSize = 40;
private const int DragResizeSize = 7;
public bool CanAnnounce;
public bool CanBroadcast;
public bool CanCall;
public bool AlertLevelSelectable;
public bool CountdownStarted;
public string CurrentLevel = string.Empty;
public TimeSpan? CountdownEnd;
public event Action? OnEmergencyLevel;
public event Action<string>? OnAlertLevel;
public event Action<string>? OnAnnounce;
public event Action<string>? OnBroadcast;
public event Action? OnShuttleCalled;
public event Action? OnShuttleRecalled;
public event Action<string>? OnAlertLevelChanged;
public event Action<string>? OnRadioAnnounce;
public event Action<string>? OnScreenBroadcast;
public CommunicationsConsoleMenu()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
MessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder"));
CloseButton.OnPressed += _ => Close();
var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
MessageInput.OnTextChanged += (args) =>
MessagingControls.OnRadioAnnounce += message => OnRadioAnnounce?.Invoke(message);
MessagingControls.OnScreenBroadcast += message => OnScreenBroadcast?.Invoke(message);
AlertLevelControls.OnAlertLevelChanged += newLevel => OnAlertLevelChanged?.Invoke(newLevel);
ShuttleControls.OnShuttleCalled += () => OnShuttleCalled?.Invoke();
ShuttleControls.OnShuttleRecalled += () => OnShuttleRecalled?.Invoke();
}
/// <summary>
/// Use the specified prototype ID as an example display in the
/// UI subsection where users type broadcast messages
/// </summary>
public void SetBroadcastDisplayEntity(EntProtoId broadcastEntityId)
{
if (args.Control.TextLength > maxAnnounceLength)
MessagingControls.SetBroadcastDisplayEntity(broadcastEntityId);
}
/// <summary>
/// Configure UI to be consistent with the input state
/// </summary>
public void UpdateState(CommunicationsConsoleInterfaceState commsState)
{
AnnounceButton.Disabled = true;
AnnounceButton.ToolTip = Loc.GetString("comms-console-message-too-long");
MessagingControls.CanRadioAnnounce = commsState.CanAnnounce;
MessagingControls.CanScreenBroadcast = commsState.CanBroadcast;
var alertLevelSelectable = commsState.AlertLevels != null && commsState.CurrentAlertDelay <= 0;
AlertLevelControls.UpdateAlertLevels(commsState.AlertLevels, commsState.CurrentAlert, commsState.CurrentAlertColor, alertLevelSelectable);
ShuttleControls.UpdateState(commsState.CanCall, commsState.CountdownStarted, commsState.ExpectedCountdownEnd);
}
protected override DragMode GetDragModeFor(Vector2 relativeMousePos)
{
if (relativeMousePos.Y < DragMoveSize)
{
return DragMode.Move;
}
else
{
AnnounceButton.Disabled = !CanAnnounce;
AnnounceButton.ToolTip = null;
var mode = DragMode.None;
}
};
AnnounceButton.OnPressed += _ => OnAnnounce?.Invoke(Rope.Collapse(MessageInput.TextRope));
AnnounceButton.Disabled = !CanAnnounce;
BroadcastButton.OnPressed += _ => OnBroadcast?.Invoke(Rope.Collapse(MessageInput.TextRope));
BroadcastButton.Disabled = !CanBroadcast;
AlertLevelButton.OnItemSelected += args =>
if (relativeMousePos.Y > Size.Y - DragResizeSize)
{
var metadata = AlertLevelButton.GetItemMetadata(args.Id);
if (metadata != null && metadata is string cast)
{
OnAlertLevel?.Invoke(cast);
}
};
AlertLevelButton.Disabled = !AlertLevelSelectable;
EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke();
EmergencyShuttleButton.Disabled = !CanCall;
mode |= DragMode.Bottom;
}
protected override void FrameUpdate(FrameEventArgs args)
if (relativeMousePos.X > Size.X - DragResizeSize)
{
base.FrameUpdate(args);
UpdateCountdown();
mode |= DragMode.Right;
}
// The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
// If the current alert is unselectable, the only item in the alerts list will be
// the current alert. Otherwise, it will be the list of alerts, with the current alert
// selected.
public void UpdateAlertLevels(List<string>? alerts, string currentAlert)
{
AlertLevelButton.Clear();
if (alerts == null)
{
var name = currentAlert;
if (_loc.TryGetString($"alert-level-{currentAlert}", out var locName))
{
name = locName;
}
AlertLevelButton.AddItem(name);
AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, currentAlert);
}
else
{
foreach (var alert in alerts)
{
var name = alert;
if (_loc.TryGetString($"alert-level-{alert}", out var locName))
{
name = locName;
}
AlertLevelButton.AddItem(name);
AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, alert);
if (alert == currentAlert)
{
AlertLevelButton.Select(AlertLevelButton.ItemCount - 1);
}
}
}
}
public void UpdateCountdown()
{
if (!CountdownStarted)
{
CountdownLabel.SetMessage(string.Empty);
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle");
return;
}
var diff = MathHelper.Max((CountdownEnd - _timing.CurTime) ?? TimeSpan.Zero, TimeSpan.Zero);
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle");
var infoText = Loc.GetString($"comms-console-menu-time-remaining",
("time", diff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
CountdownLabel.SetMessage(infoText);
return mode;
}
}
}

View File

@@ -0,0 +1,42 @@
using Content.Client.Resources;
using Content.Client.Stylesheets;
using Content.Client.Stylesheets.Stylesheets;
using Content.Client.Stylesheets.SheetletConfigs;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using static Content.Client.Stylesheets.StylesheetHelpers;
namespace Content.Client.UserInterface.Controls;
[CommonSheetlet]
public sealed class CommunicationsConsoleSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, IButtonConfig, IIconConfig
{
public override StyleRule[] GetRules(T sheet, object config)
{
var lcdFontLarge = ResCache.GetFont("/Fonts/7SegmentDisplayDigits.ttf", 20);
return [
E<Label>().Class("LabelLCDBig")
.Prop("font-color", sheet.NegativePalette.Text)
.Prop("font", lcdFontLarge),
/// Large red texture button
E<TextureButton>().Identifier("TemptingRedButton")
.Prop(TextureButton.StylePropertyTexture, sheet.GetTextureOr(sheet.RoundedButtonPath, NanotrasenStylesheet.TextureRoot))
.Prop(Control.StylePropertyModulateSelf, sheet.NegativePalette.Element),
E<TextureButton>().Identifier("TemptingRedButton")
.Pseudo(ContainerButton.StylePseudoClassNormal)
.Prop(Control.StylePropertyModulateSelf, sheet.NegativePalette.Element),
E<TextureButton>().Identifier("TemptingRedButton")
.Pseudo(ContainerButton.StylePseudoClassDisabled)
.Prop(TextureButton.StylePropertyTexture, ResCache.GetTexture("/Textures/Interface/Nano/rounded_locked_button.svg.96dpi.png"))
.Prop(Control.StylePropertyModulateSelf, sheet.NegativePalette.DisabledElement),
E<TextureButton>().Identifier("TemptingRedButton").Pseudo(ContainerButton.StylePseudoClassHover)
.Prop(Control.StylePropertyModulateSelf, sheet.NegativePalette.HoveredElement),
E<TextureRect>().Identifier("ScrewHead")
.Prop(TextureRect.StylePropertyTexture, ResCache.GetTexture("/Textures/Interface/Diegetic/screw.svg.96dpi.png")),
];
}
}

View File

@@ -0,0 +1,22 @@
<BoxContainer xmlns="https://spacestation14.io"
Orientation="Vertical">
<!-- Info about the current alert level -->
<BoxContainer HorizontalAlignment="Center">
<Label StyleClasses="StatusFieldTitle" Margin="0 0 9 0"
Text="{Loc 'comms-console-alert-current-level-header'}" />
<Label Name="CurrentAlertLevelLabel" Margin="9 0 0 0"/>
</BoxContainer>
<Label Name="CurrentAlertLevelFlavorLabel" Align="Center" />
<!-- Controls for changing the alert level -->
<BoxContainer Margin="9 12 9 6">
<OptionButton Name="AlertLevelSelector" StyleClasses="OpenRight"
ToolTip="{Loc 'comms-console-menu-alert-level-button-tooltip'}"
HorizontalExpand="True" SizeFlagsStretchRatio="4" />
<Button Name="ConfirmAlertLevelButton" StyleClasses="OpenLeft"
HorizontalExpand="True" SizeFlagsStretchRatio="1"
Text="{Loc 'comms-console-confirm-alert-level-button'}"
Disabled="True" />
</BoxContainer>
</BoxContainer>

View File

@@ -0,0 +1,137 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.Communications.UI.Widgets;
[GenerateTypedNameReferences]
public sealed partial class AlertLevelControls : BoxContainer
{
[Dependency] private readonly ILocalizationManager _loc = default!;
private bool _alertLevelSelectable;
private string _currentAlertLevel = string.Empty;
public event Action<string>? OnAlertLevelChanged;
public AlertLevelControls()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
AlertLevelSelector.OnItemSelected += args =>
{
AlertLevelSelector.Select(args.Id);
EnableDisableConfirmLevelChangeButton();
};
ConfirmAlertLevelButton.OnPressed += _ =>
{
var metadata = AlertLevelSelector.GetItemMetadata(AlertLevelSelector.SelectedId);
if (metadata is string cast)
{
OnAlertLevelChanged?.Invoke(cast);
}
};
AlertLevelSelector.Disabled = !_alertLevelSelectable;
}
/// <summary>
/// Updates the UI components to display the current alert level and the
/// selectable alert levels
/// </summary>
public void UpdateAlertLevels(List<string>? alerts,
string currentAlert,
Color currentAlertColor,
bool alertLevelSelectable)
{
_alertLevelSelectable = alertLevelSelectable;
_currentAlertLevel = currentAlert;
CurrentAlertLevelLabel.Text = GetLocalizedAlertName(currentAlert);
CurrentAlertLevelLabel.ModulateSelfOverride = currentAlertColor;
AlertLevelSelector.Disabled = alerts == null || !_alertLevelSelectable;
// If user had changed the selection, but hadn't pressed the confirm
// button at the point we received an update message, we want to
// remember what they had selected, so we can attempt to re-select it
// if it's still an option in the new set of alert level possibilities.
string? previousSelection = null;
if (AlertLevelSelector.ItemCount > 1)
{
var metadata = AlertLevelSelector.GetItemMetadata(AlertLevelSelector.SelectedId);
if (metadata is string cast)
{
previousSelection = cast;
}
}
// The server will only send alert levels which are selectable, but
// unfortunately, for a short time after changing the alert level, no
// level is selectable, so we won't have any levels to put into the
// alert level list. Here, we make a dummy item to handle that; this
// item also informs the user what this combo box is for.
AlertLevelSelector.Clear();
AlertLevelSelector.AddItem(Loc.GetString("comms-console-change-alert-level-button"));
AlertLevelSelector.Select(0);
if (alerts != null)
{
foreach (var alert in alerts)
{
AlertLevelSelector.AddItem(GetLocalizedAlertName(alert));
AlertLevelSelector.SetItemMetadata(AlertLevelSelector.ItemCount - 1, alert);
if (alert == previousSelection)
{
AlertLevelSelector.Select(AlertLevelSelector.ItemCount - 1);
}
}
}
if (_loc.TryGetString($"comms-console-level-{currentAlert}-flavour-label", out var flavour))
{
CurrentAlertLevelFlavorLabel.Text = flavour;
}
else
{
CurrentAlertLevelFlavorLabel.Text = string.Empty;
}
EnableDisableConfirmLevelChangeButton();
}
/// <summary>
/// Configure the "confirm alert level changed" button to be consistent with
/// the server state and user interactions
/// </summary>
private void EnableDisableConfirmLevelChangeButton()
{
// Disable the button when:
// 1. Server says we can't change level
// 2. User selected special info option (id 0)
// 3. User selected the same level the station is currently on
var selectedId = AlertLevelSelector.SelectedId;
ConfirmAlertLevelButton.Disabled = !_alertLevelSelectable || selectedId == 0;
if (selectedId != 0)
{
var metadata = AlertLevelSelector.GetItemMetadata(selectedId);
if (metadata is string selected)
{
ConfirmAlertLevelButton.Disabled |= selected == _currentAlertLevel;
}
}
}
/// <summary>
/// Utility function to convert an alert level identifier into a localized string
/// </summary>
private string GetLocalizedAlertName(string alertName)
{
if (_loc.TryGetString($"alert-level-{alertName}", out var locName))
{
return locName;
}
return alertName;
}
}

View File

@@ -0,0 +1,34 @@
<TabContainer xmlns="https://spacestation14.io" >
<!-- Controls for sending radio announcements -->
<BoxContainer Orientation="Vertical" VerticalExpand="True"
TabContainer.TabTitle="{Loc 'comms-console-announce-tab-title'}">
<Label StyleClasses="StatusFieldTitle" Align="Center"
Text="{Loc 'comms-console-station-announcements-header'}" />
<PanelContainer StyleClasses="highlight"
Margin="6" VerticalExpand="True">
<PanelContainer StyleClasses="BackgroundDark" Margin="2"
HorizontalExpand="True" VerticalExpand="True">
<TextEdit Name="RadioMessageInput"
Margin="2 0 0 0" MinHeight="100"
HorizontalExpand="True" VerticalExpand="True" />
</PanelContainer>
</PanelContainer>
<Button Name="AnnounceButton" HorizontalExpand="True" Margin="6"
Text="{Loc 'comms-console-menu-announcement-button'}"
ToolTip="{Loc 'comms-console-menu-announcement-button-tooltip'}" />
</BoxContainer>
<!-- Controls for putting messages on station screens (aka broadcasting) -->
<BoxContainer Orientation="Vertical" VerticalExpand="True"
TabContainer.TabTitle="{Loc 'comms-console-broadcast-tab-title'}">
<Label StyleClasses="StatusFieldTitle" Align="Center" VAlign="Top"
VerticalExpand="True" VerticalAlignment="Top"
Text="{Loc 'comms-console-station-broadcast-header'}" />
<SpriteView Name="BroadcastEntityDisplay" Scale="8 8" />
<LineEdit Name="ScreenMessageInput" Margin="6 0 6 0"
PlaceHolder="{Loc 'comms-console-menu-broadcast-placeholder'}" />
<Button Name="BroadcastButton" HorizontalExpand="True" Margin="6"
Text="{Loc 'comms-console-menu-broadcast-button'}"
ToolTip="{Loc 'comms-console-menu-broadcast-button-tooltip'}" />
</BoxContainer>
</TabContainer>

View File

@@ -0,0 +1,117 @@
using Content.Shared.CCVar;
using Content.Shared.TextScreen;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client.Communications.UI.Widgets;
[GenerateTypedNameReferences]
public sealed partial class MessagingControls : TabContainer
{
[Dependency] private readonly ILocalizationManager _loc = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
// Entity temporarily created to display a screen preview
private EntityUid _broadcastDisplayEntity = EntityUid.Invalid;
public event Action<string>? OnRadioAnnounce;
public event Action<string>? OnScreenBroadcast;
private bool _canRadioAnnounce;
public bool CanRadioAnnounce
{
set
{
_canRadioAnnounce = value;
SyncButtonState();
}
}
private bool _canScreenBroadcast;
public bool CanScreenBroadcast
{
set
{
_canScreenBroadcast = value;
SyncButtonState();
}
}
public MessagingControls()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
RadioMessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder"));
RadioMessageInput.OnTextChanged += (_) => SyncButtonState();
AnnounceButton.OnPressed += _ =>
{
OnRadioAnnounce?.Invoke(Rope.Collapse(RadioMessageInput.TextRope));
};
var appearanceSystem = _entMan.System<SharedAppearanceSystem>();
ScreenMessageInput.OnTextChanged += args =>
{
if (_broadcastDisplayEntity.IsValid())
{
appearanceSystem.SetData(_broadcastDisplayEntity, TextScreenVisuals.ScreenText, args.Text);
}
};
BroadcastButton.OnPressed += _ =>
{
OnScreenBroadcast?.Invoke(ScreenMessageInput.Text);
};
SyncButtonState();
}
public void SetBroadcastDisplayEntity(EntProtoId broadcastEntityId)
{
_broadcastDisplayEntity = _entMan.Spawn(broadcastEntityId);
if (_broadcastDisplayEntity.IsValid())
{
BroadcastEntityDisplay.SetEntity(_broadcastDisplayEntity);
}
}
protected override void ExitedTree()
{
if (_broadcastDisplayEntity.IsValid())
{
_entMan.DeleteEntity(_broadcastDisplayEntity);
}
}
private void SyncButtonState()
{
if (_canRadioAnnounce)
{
var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
if (RadioMessageInput.TextLength > maxAnnounceLength)
{
AnnounceButton.Disabled = true;
AnnounceButton.ToolTip = _loc.GetString("comms-console-message-too-long");
}
else
{
AnnounceButton.Disabled = false;
AnnounceButton.ToolTip = _loc.GetString("comms-console-menu-announcement-button-tooltip");
}
}
else
{
AnnounceButton.Disabled = true;
AnnounceButton.ToolTip = _loc.GetString("comms-console-message-cannot-send");
}
BroadcastButton.Disabled = !_canScreenBroadcast;
}
}

View File

@@ -0,0 +1,73 @@
<Control xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<controls:StripeBack
HasTopEdge="False" HasBottomEdge="False" StyleClasses="status-warning" >
<TextureRect StyleIdentifier="ScrewHead" TextureScale="0.25 0.25"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="4"/>
<TextureRect StyleIdentifier="ScrewHead" TextureScale="0.25 0.25"
HorizontalAlignment="Right" VerticalAlignment="Top" Margin="4"/>
<TextureRect StyleIdentifier="ScrewHead" TextureScale="0.25 0.25"
HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="4"/>
<TextureRect StyleIdentifier="ScrewHead" TextureScale="0.25 0.25"
HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="4"/>
<!-- Controls for calling, recalling and displaying info for the emergency shuttle -->
<PanelContainer StyleClasses="PanelDark" Margin="20">
<BoxContainer Orientation="Vertical" Margin="8">
<Label StyleClasses="FancyWindowTitle" Align="Center"
Text="{Loc 'comms-console-shuttle-controls-header'}" />
<!-- This contains some blank `Controls` to act as dummies. This is because the
GridContainer will always left-align the children, while we want them centered.
The dummy Controls will attempt to take an even amount of space each, which
will re-center our real controls -->
<GridContainer Columns="7" HorizontalExpand="True" Margin="0 8 0 0">
<!-- Row 1: the buttons themselves -->
<Control HorizontalExpand="True" />
<controls:LayeredImageContainer>
<Control.StyleClasses>
<sys:String>PanelMount</sys:String>
<sys:String>PanelDark</sys:String>
</Control.StyleClasses>
<TextureButton Name="EmergencyShuttleCallButton"
StyleIdentifier="TemptingRedButton" MinSize="60 60"
ToolTip="{Loc 'comms-console-menu-call-shuttle'}" />
</controls:LayeredImageContainer>
<Control HorizontalExpand="True" />
<controls:LayeredImageContainer
VerticalAlignment="Center">
<Control.StyleClasses>
<sys:String>PanelMount</sys:String>
<sys:String>PanelDark</sys:String>
</Control.StyleClasses>
<Label Name="CountdownLabel" StyleClasses="LabelLCDBig"
ReservesSpace="True" Margin="6"/>
</controls:LayeredImageContainer>
<Control HorizontalExpand="True" />
<controls:LayeredImageContainer>
<Control.StyleClasses>
<sys:String>PanelMount</sys:String>
<sys:String>PanelDark</sys:String>
</Control.StyleClasses>
<TextureButton Name="EmergencyShuttleRecallButton"
StyleIdentifier="TemptingRedButton" MinSize="60 60"
ToolTip="{Loc 'comms-console-menu-recall-shuttle'}" />
</controls:LayeredImageContainer>
<Control HorizontalExpand="True" />
<!-- Row 2: The labels for the buttons -->
<Control HorizontalExpand="True" />
<Label Text="{Loc 'comms-console-call-button-label'}" Align="Center" />
<Control HorizontalExpand="True" />
<Label Text="{Loc 'comms-console-shuttle-status-label'}" Align="Center" />
<Control HorizontalExpand="True" />
<Label Text="{Loc 'comms-console-recall-button-label'}" Align="Center" />
<Control HorizontalExpand="True" />
</GridContainer>
</BoxContainer>
</PanelContainer>
</controls:StripeBack>
</Control>

View File

@@ -0,0 +1,99 @@
using Content.Shared.CCVar;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
namespace Content.Client.Communications.UI.Widgets;
[GenerateTypedNameReferences]
public sealed partial class ShuttleControls : Control
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private bool _canCall;
private bool _countdownStarted;
private TimeSpan? _countdownEnd;
public event Action? OnShuttleCalled;
public event Action? OnShuttleRecalled;
public ShuttleControls()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
EmergencyShuttleCallButton.OnPressed += _ => OnShuttleCalled?.Invoke();
EmergencyShuttleRecallButton.OnPressed += _ => OnShuttleRecalled?.Invoke();
SyncButtonState();
}
public void UpdateState(bool canCallShuttle, bool countdownStarted, TimeSpan? expectedCountdownEnd)
{
_canCall = canCallShuttle;
_countdownStarted = countdownStarted;
_countdownEnd = expectedCountdownEnd;
SyncButtonState();
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateCountdown();
}
/// <summary>
/// Syncs and animates the display of the time-to-shuttle-arrival label
/// </summary>
private void UpdateCountdown()
{
// Set the label on the LCD countdown
var countdown = _countdownEnd == null ? 0.0f : (float)Math.Max(_countdownEnd.Value.Subtract(_timing.CurTime).TotalSeconds, 0);
var remainingWholeSeconds = _countdownStarted ? (int)Math.Ceiling(countdown) : 0;
var message = (remainingWholeSeconds / 60).ToString("D2") + ":" + (remainingWholeSeconds % 60).ToString("D2");
CountdownLabel.Text = message;
CountdownLabel.Visible = _countdownStarted;
if(countdown == 0)
{
CountdownLabel.ModulateSelfOverride = Color.White;
}
else
{
// Blink the LCD
var alpha = 1.0f;
if (!_cfg.GetCVar(CCVars.ReducedMotion))
{
var subSecondsRemaining = countdown - (float)Math.Floor(countdown);
var lightEnableBlend = SmoothStep(0.1f, 0.3f, subSecondsRemaining);
var lightDisableBlend = SmoothStep(0.9f, 0.95f, subSecondsRemaining);
alpha = lightEnableBlend - lightDisableBlend;
}
CountdownLabel.ModulateSelfOverride = new Color(1.0f, 1.0f, 1.0f, alpha);
}
}
private float SmoothStep(float stepBegin, float stepEnd, float x)
{
if (x < stepBegin)
return 0;
if (x >= stepEnd)
return 1;
var t = (x - stepBegin) / (stepEnd - stepBegin);
return (3 * t * t) - (2 * t * t * t);
}
/// <summary>
/// Configure the shuttle call/recall buttons to have a consistent state
/// </summary>
private void SyncButtonState()
{
EmergencyShuttleCallButton.Disabled = !(_canCall && !_countdownStarted);
EmergencyShuttleRecallButton.Disabled = !(_canCall && _countdownStarted);
}
}

View File

@@ -42,7 +42,8 @@ public sealed class PdaSheetlet : Sheetlet<NanotrasenStylesheet>
E<PanelContainer>()
.Class("PdaBorderRect")
.Prop(PanelContainer.StylePropertyPanel, angleBorderRect),
.Prop(PanelContainer.StylePropertyPanel, angleBorderRect)
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#00000040")),
//PDA - Buttons
E<PdaSettingsButton>()

View File

@@ -0,0 +1,70 @@
using Content.Client.Resources;
using Content.Client.Stylesheets;
using Content.Client.Stylesheets.Palette;
using Content.Client.Stylesheets.Sheetlets;
using Content.Client.Stylesheets.Stylesheets;
using Content.Client.Stylesheets.SheetletConfigs;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using static Content.Client.Stylesheets.StylesheetHelpers;
namespace Content.Client.UserInterface.Controls;
[CommonSheetlet]
public sealed class LayeredImageContainerSheetlet : Sheetlet<NanotrasenStylesheet>
{
public override StyleRule[] GetRules(NanotrasenStylesheet sheet, object config)
{
IPanelConfig panelCfg = sheet;
var panelMountBaseTex = ResCache.GetTexture("/Textures/Interface/Diegetic/PanelMountBase.svg.96dpi.png");
var panelMountHighlightTex = ResCache.GetTexture("/Textures/Interface/Diegetic/PanelMountHighlight.svg.96dpi.png");
var panelMountBaseStyleBox = new StyleBoxTexture
{
Texture = panelMountBaseTex,
PatchMarginLeft = 16,
PatchMarginTop = 16,
PatchMarginRight = 24,
PatchMarginBottom = 24
};
var panelMountHighlightStyleBox = new StyleBoxTexture
{
Texture = panelMountHighlightTex,
PatchMarginLeft = 16,
PatchMarginTop = 16,
PatchMarginRight = 24,
PatchMarginBottom = 24
};
var borderTex = sheet.GetTexture(panelCfg.GeometricPanelBorderPath).IntoPatch(StyleBox.Margin.All, 10);
return [
// Adds a raised border with rounded corners around a UI element
E<LayeredImageContainer>().Class(LayeredImageContainer.StyleClassPanelMount)
.Prop(LayeredImageContainer.StylePropertyMinimumContentMargin, new Thickness(10, 10, 16, 16)),
E<LayeredImageContainer>().Class(LayeredImageContainer.StyleClassPanelMount)
.ParentOf(E<PanelContainer>().Identifier("Foreground1"))
.Prop(PanelContainer.StylePropertyPanel, panelMountBaseStyleBox),
E<LayeredImageContainer>().Class(LayeredImageContainer.StyleClassPanelMount)
.ParentOf(E<PanelContainer>().Identifier("Foreground2"))
.Prop(PanelContainer.StylePropertyPanel, panelMountHighlightStyleBox),
E<LayeredImageContainer>().Class(StyleClass.PanelDark)
.ParentOf(E<PanelContainer>().Identifier("Foreground1"))
.Prop(Control.StylePropertyModulateSelf, sheet.SecondaryPalette.BackgroundDark),
/// Bright AngleRect with a subtle outline
E<LayeredImageContainer>().Class(LayeredImageContainer.StyleClassBrightAngleRect)
.ParentOf(E<PanelContainer>().Identifier("Background1"))
.Prop(PanelContainer.StylePropertyPanel, StyleBoxHelpers.BaseStyleBox(sheet))
.Prop(Control.StylePropertyModulateSelf, Palettes.Cyan.BackgroundLight),
E<LayeredImageContainer>().Class(LayeredImageContainer.StyleClassBrightAngleRect)
.ParentOf(E<PanelContainer>().Identifier("Background2"))
.Prop(PanelContainer.StylePropertyPanel, borderTex)
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#00000040")),
];
}
}

View File

@@ -1,4 +1,5 @@
using Content.Client.Stylesheets.SheetletConfigs;
using Content.Client.Stylesheets.Palette;
using Content.Client.Stylesheets.SheetletConfigs;
using Content.Client.Stylesheets.Stylesheets;
using Content.Client.UserInterface.Controls;
using Robust.Client.Graphics;
@@ -14,16 +15,25 @@ public sealed class StripebackSheetlet<T> : Sheetlet<T> where T : PalettedStyles
{
IStripebackConfig stripebackCfg = sheet;
var stripeTex = sheet.GetTextureOr(stripebackCfg.StripebackPath, NanotrasenStylesheet.TextureRoot);
var stripeBack = new StyleBoxTexture
{
Texture = sheet.GetTextureOr(stripebackCfg.StripebackPath, NanotrasenStylesheet.TextureRoot),
Texture = stripeTex,
Mode = StyleBoxTexture.StretchMode.Tile,
Modulate = sheet.PrimaryPalette.BackgroundDark
};
var stripeBackWarning = new StyleBoxTexture {
Texture = stripeTex,
Mode = StyleBoxTexture.StretchMode.Tile,
Modulate = Palettes.Amber.Element
};
return
[
E<StripeBack>()
.Prop(StripeBack.StylePropertyBackground, stripeBack),
E<StripeBack>().Class(StyleClass.StatusWarning)
.Prop(StripeBack.StylePropertyBackground, stripeBackWarning),
];
}
}

View File

@@ -59,6 +59,7 @@ public static class StyleClass
public const string ButtonBig = "ButtonBig";
public const string CrossButtonRed = "CrossButtonRed";
public const string RefreshButton = "RefreshButton";
public const string ItemStatus = "ItemStatus";

View File

@@ -0,0 +1,8 @@
<controls:LayeredImageContainer xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls">
<PanelContainer StyleIdentifier="Background1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<PanelContainer StyleIdentifier="Background2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<Control Name="ContentsContainer"/>
<PanelContainer StyleIdentifier="Foreground1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<PanelContainer StyleIdentifier="Foreground2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</controls:LayeredImageContainer>

View File

@@ -0,0 +1,46 @@
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.UserInterface.Controls;
/// <summary>
/// A generic container which can layer multiple styleboxes over/under the
/// contents of of the child controls. This container contains two forground
/// panels and two background panels, each of which can be styled independently.
/// Background panels will be rendered underneath the child controls, while
/// foreground panels will be rendered above. The use of two panels for each
/// level allows for one level to use a stylized graphic, typically including
/// some modulation to color-match the surrounding UI, while the second level
/// can be used for shadows or highlights, which would typically not have such
/// modulation.
/// </summary>
[GenerateTypedNameReferences]
public partial class LayeredImageContainer : Container
{
// Adds a raised border with rounded corners around a UI element
public const string StyleClassPanelMount = "PanelMount";
// Bright AngleRect with a subtle outline
public const string StyleClassBrightAngleRect = "BrightAngleRectOutline";
// The least amount of margin that a child needs to have to avoid drawing under
// undesirable parts of the images. Children can add additional margins if desired
public const string StylePropertyMinimumContentMargin = "MinimumContentMargin";
public LayeredImageContainer()
{
RobustXamlLoader.Load(this);
XamlChildren = ContentsContainer.Children;
}
protected override void StylePropertiesChanged()
{
if (TryGetStyleProperty<Thickness>(StylePropertyMinimumContentMargin, out var contentMargin))
{
ContentsContainer.Margin = contentMargin;
}
}
}

View File

@@ -135,6 +135,7 @@ namespace Content.Server.Communications
List<string>? levels = null;
string currentLevel = default!;
float currentDelay = 0;
var currentAlertColor = Color.White;
if (stationUid != null)
{
@@ -150,6 +151,11 @@ namespace Content.Server.Communications
{
levels.Add(id);
}
if (id == alertComp.CurrentLevel)
{
currentAlertColor = detail.Color;
}
}
}
@@ -163,6 +169,7 @@ namespace Content.Server.Communications
CanCallOrRecall(comp),
levels,
currentLevel,
currentAlertColor,
currentDelay,
_roundEndSystem.ExpectedCountdownEnd
));

View File

@@ -17,9 +17,10 @@ namespace Content.Shared.Communications
public readonly bool CountdownStarted;
public List<string>? AlertLevels;
public string CurrentAlert;
public Color CurrentAlertColor;
public float CurrentAlertDelay;
public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List<string>? alertLevels, string currentAlert, float currentAlertDelay, TimeSpan? expectedCountdownEnd = null)
public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List<string>? alertLevels, string currentAlert, Color currentAlertColor, float currentAlertDelay, TimeSpan? expectedCountdownEnd = null)
{
CanAnnounce = canAnnounce;
CanCall = canCall;
@@ -27,6 +28,7 @@ namespace Content.Shared.Communications
CountdownStarted = expectedCountdownEnd != null;
AlertLevels = alertLevels;
CurrentAlert = currentAlert;
CurrentAlertColor = currentAlertColor;
CurrentAlertDelay = currentAlertDelay;
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,20 +1,31 @@
# User interface
comms-console-menu-title = Communications Console
comms-console-menu-announcement-placeholder = Announcement text...
comms-console-menu-announcement-button = Announce
comms-console-menu-broadcast-placeholder = Broadcast text...
comms-console-menu-announcement-button = Announce over radio
comms-console-menu-announcement-button-tooltip = Send your message as a station-wide radio announcement.
comms-console-menu-broadcast-button = Broadcast
comms-console-menu-broadcast-button = Display on screens
comms-console-menu-broadcast-button-tooltip = Broadcast your message to wall-mounted screens around the station. Note: They fit only ten characters!
comms-console-menu-alert-level-button-tooltip = Change the station alert level. Applies immediately on selecting.
comms-console-menu-alert-level-button-tooltip = Change the station alert level.
comms-console-menu-call-shuttle = Call emergency shuttle
comms-console-menu-recall-shuttle = Recall emergency shuttle
comms-console-menu-emergency-shuttle-button-tooltip = Calls or recalls the emergency shuttle. You can only recall when there's enough time left.
comms-console-menu-time-remaining = Time remaining: {$time}
comms-console-change-alert-level-button = Change status
comms-console-confirm-alert-level-button = Confirm
comms-console-call-button-label = Call
comms-console-recall-button-label = Recall
comms-console-shuttle-status-label = Arrival time
comms-console-shuttle-controls-header = EMERGENCY SHUTTLE CONTROLS
comms-console-alert-current-level-header = Alert level
comms-console-station-announcements-header = Station Announcements
comms-console-station-broadcast-header = Station Broadcast
comms-console-announce-tab-title = Radio
comms-console-broadcast-tab-title = Screen
# Popup
comms-console-permission-denied = Permission denied
comms-console-shuttle-unavailable = Shuttle is currently unavailable
comms-console-message-too-long = Message is too long
comms-console-message-cannot-send = Communications temporarily disabled
# Placeholder values
comms-console-announcement-sent-by = Sent by
@@ -26,3 +37,13 @@ comms-console-announcement-title-centcom = Central Command
comms-console-announcement-title-nukie = Syndicate Nuclear Operative
comms-console-announcement-title-station-ai = Station AI
comms-console-announcement-title-wizard = Wizard
# Flavor text for alert levels
comms-console-level-green-flavour-label = Work is to proceed as normal
comms-console-level-blue-flavour-label = Record suspicious activity with form NT-4772-b
comms-console-level-violet-flavour-label = Maintain social distancing
comms-console-level-yellow-flavour-label = Prepare to hold your breath
comms-console-level-red-flavour-label = Remain vigilant
comms-console-level-gamma-flavour-label = Suggest extreme caution
comms-console-level-delta-flavour-label = Good luck
comms-console-level-epsilon-flavour-label = You're fired

View File

@@ -1,25 +1,49 @@
# User interface
comms-console-menu-title = Консоль связи
comms-console-menu-announcement-placeholder = Текст объявления...
comms-console-menu-announcement-button = Сделать объявление
comms-console-menu-broadcast-placeholder = Текст трансляции...
comms-console-menu-announcement-button = Объявить по радио
comms-console-menu-announcement-button-tooltip = Отправьте своё сообщение в качестве радиообъявления на всю станцию.
comms-console-menu-broadcast-button = Трансляция
comms-console-menu-broadcast-button = Показать на экранах
comms-console-menu-broadcast-button-tooltip = Транслируйте своё сообщение на настенные экраны по всей станции. Примечание: помещается всего десять символов!
comms-console-menu-alert-level-button-tooltip = Изменение уровня угрозы станции. Применяется сразу после выбора.
comms-console-menu-call-shuttle = Вызвать
comms-console-menu-recall-shuttle = Отозвать
comms-console-menu-emergency-shuttle-button-tooltip = Вызывает или отзывает эвакуационный шаттл. Вы можете отозвать шаттл, только если осталось достаточно времени.
comms-console-menu-time-remaining = Оставшееся время: { $time }
comms-console-menu-alert-level-button-tooltip = Изменить уровень угрозы станции.
comms-console-menu-call-shuttle = Вызвать эвакуационный шаттл
comms-console-menu-recall-shuttle = Отозвать эвакуационный шаттл
comms-console-change-alert-level-button = Изменить статус
comms-console-confirm-alert-level-button = Подтвердить
comms-console-call-button-label = Вызвать
comms-console-recall-button-label = Отозвать
comms-console-shuttle-status-label = Время прибытия
comms-console-shuttle-controls-header = УПРАВЛЕНИЕ ЭВАКУАЦИОННЫМ ШАТТЛОМ
comms-console-alert-current-level-header = Уровень угрозы
comms-console-station-announcements-header = Объявления станции
comms-console-station-broadcast-header = Трансляция станции
comms-console-announce-tab-title = Радио
comms-console-broadcast-tab-title = Экран
# Popup
comms-console-permission-denied = В доступе отказано
comms-console-shuttle-unavailable = В настоящее время шаттл недоступен
comms-console-message-too-long = Сообщение слишком длинное
comms-console-message-cannot-send = Связь временно отключена
# Placeholder values
comms-console-announcement-sent-by = Отправитель
comms-console-announcement-unknown-sender = Неизвестный
# Comms console variant titles
comms-console-announcement-title-station = Консоль связи
comms-console-announcement-title-centcom = Центральное командование
comms-console-announcement-title-nukie = Ядерные оперативники Синдиката
comms-console-announcement-title-station-ai = Станционный ИИ
comms-console-announcement-title-wizard = Волшебник
# Flavor text for alert levels
comms-console-level-green-flavour-label = Работа в штатном режиме
comms-console-level-blue-flavour-label = Фиксируйте подозрительную активность
comms-console-level-violet-flavour-label = Соблюдайте социальную дистанцию
comms-console-level-yellow-flavour-label = Приготовьтесь задержать дыхание
comms-console-level-red-flavour-label = Сохраняйте бдительность
comms-console-level-gamma-flavour-label = Рекомендуется крайняя осторожность
comms-console-level-delta-flavour-label = Удачи
comms-console-level-epsilon-flavour-label = Вы уволены

View File

@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="49"
height="49"
viewBox="0 0 12.964581 12.964581"
version="1.1"
id="svg97402"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="PanelMountBase.svg"
inkscape:export-filename="PanelMountBase.svg.96dpi.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview97404"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
inkscape:zoom="13.915198"
inkscape:cx="20.301544"
inkscape:cy="29.643848"
inkscape:window-width="1916"
inkscape:window-height="1034"
inkscape:window-x="0"
inkscape:window-y="44"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs97399">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath50614">
<rect
style="display:inline;fill:#b6b6b6;fill-opacity:1;stroke:none;stroke-width:0.7;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="rect50616"
width="30.108149"
height="13.222547"
x="146.07838"
y="216.62383"
rx="1.4750348"
ry="1.4496408" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99525">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:3.95991;stroke-linecap:round;stroke-linejoin:round"
id="rect99527"
width="60"
height="90"
x="0"
y="0" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99685">
<g
id="g99689"
transform="matrix(0.55711614,0,0,0.55573006,162.92021,216.61309)">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99687"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99691">
<g
id="g99695">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99693"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99697">
<g
id="g99701">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99699"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99711">
<g
id="g99715"
transform="matrix(0.55711614,0,0,0.55573006,146.08647,216.61288)">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.04406;stroke-linecap:round;stroke-linejoin:round"
id="rect99713"
width="15.799728"
height="23.758703"
x="0.0094064204"
y="0.054201871" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99717">
<g
id="g99721">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.04406;stroke-linecap:round;stroke-linejoin:round"
id="rect99719"
width="15.799728"
height="23.758703"
x="0.0094064204"
y="0.054201871" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99723">
<g
id="g99727">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.04406;stroke-linecap:round;stroke-linejoin:round"
id="rect99725"
width="15.799728"
height="23.758703"
x="0.0094064204"
y="0.054201871" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99794">
<g
id="g99798"
transform="matrix(0.55711614,0,0,0.55573006,162.92021,216.61309)">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99796"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99800">
<g
id="g99804">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99802"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99806">
<g
id="g99810">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99808"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99883">
<path
id="path99885"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke-width:1.665;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 7.9375,0 C 3.5401295,0 0,3.5401295 0,7.9375 v 7.9375 c 0,4.397371 3.5401295,7.9375 7.9375,7.9375 h 7.9375 c 4.397371,0 7.9375,-3.540129 7.9375,-7.9375 V 7.9375 C 23.8125,3.5401295 20.272371,0 15.875,0 Z m 2.205033,6.6145833 h 3.527434 c 1.954387,0 3.52795,1.5735631 3.52795,3.5279497 v 3.527434 c 0,1.954387 -1.573563,3.52795 -3.52795,3.52795 h -3.527434 c -1.9543866,0 -3.5279497,-1.573563 -3.5279497,-3.52795 v -3.527434 c 0,-1.9543866 1.5735631,-3.5279497 3.5279497,-3.5279497 z" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath100370">
<path
id="path100372"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke-width:1.665;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 7.9375,1e-7 C 3.540129,1e-7 0,3.5401295 0,7.9375 v 7.9375 c 0,4.397371 3.540129,7.9375 7.9375,7.9375 h 7.9375 c 4.397371,0 7.9375,-3.540129 7.9375,-7.9375 V 7.9375 C 23.8125,3.5401295 20.272371,1e-7 15.875,1e-7 Z m 2.205033,6.6145832 h 3.527434 c 1.954387,0 3.52795,1.5735631 3.52795,3.5279497 v 3.527434 c 0,1.954387 -1.573563,3.52795 -3.52795,3.52795 h -3.527434 c -1.9543871,0 -3.5279499,-1.573563 -3.5279499,-3.52795 v -3.527434 c 0,-1.9543866 1.5735628,-3.5279497 3.5279499,-3.5279497 z" />
</clipPath>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect99812"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke-width:0.764443;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 3.8107566,0.22044249 c -2.0189409,0 -3.64430097,1.62536021 -3.64430097,3.64430101 v 3.6443013 c 0,2.0189404 1.62536007,3.6443002 3.64430097,3.6443002 h 3.6443009 c 2.0189412,0 3.6443025,-1.6253598 3.6443025,-3.6443002 V 3.8647435 c 0,-2.0189408 -1.6253613,-3.64430101 -3.6443025,-3.64430101 z M 4.8231413,3.2573599 h 1.6195315 c 0.897307,0 1.6197684,0.7224614 1.6197684,1.6197684 v 1.6195314 c 0,0.897307 -0.7224614,1.6197687 -1.6197684,1.6197687 H 4.8231413 c -0.8973069,0 -1.6197683,-0.7224617 -1.6197683,-1.6197687 V 4.8771283 c 0,-0.897307 0.7224614,-1.6197684 1.6197683,-1.6197684 z"
inkscape:label="Base" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

View File

@@ -0,0 +1,455 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="49"
height="49"
viewBox="0 0 12.964581 12.964581"
version="1.1"
id="svg97402"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="PanelMountHighlight.svg"
inkscape:export-filename="PanelMountHighlight.svg.96dpi.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview97404"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
inkscape:zoom="13.459184"
inkscape:cx="26.338893"
inkscape:cy="19.280516"
inkscape:window-width="1916"
inkscape:window-height="1052"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs97399">
<inkscape:path-effect
effect="powerclip"
id="path-effect83389"
is_visible="true"
lpeversion="1"
inverse="true"
flatten="false"
hide_clip="false"
message="Use fill-rule evenodd on &lt;b&gt;fill and stroke&lt;/b&gt; dialog if no flatten result after convert clip to paths." />
<inkscape:path-effect
effect="powerclip"
id="path-effect78221"
is_visible="true"
lpeversion="1"
inverse="true"
flatten="false"
hide_clip="false"
message="Use fill-rule evenodd on &lt;b&gt;fill and stroke&lt;/b&gt; dialog if no flatten result after convert clip to paths." />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath50614">
<rect
style="display:inline;fill:#b6b6b6;fill-opacity:1;stroke:none;stroke-width:0.7;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="rect50616"
width="30.108149"
height="13.222547"
x="146.07838"
y="216.62383"
rx="1.4750348"
ry="1.4496408" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99525">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:3.95991;stroke-linecap:round;stroke-linejoin:round"
id="rect99527"
width="60"
height="90"
x="0"
y="0" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99685">
<g
id="g99689"
transform="matrix(0.55711614,0,0,0.55573006,162.92021,216.61309)">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99687"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99691">
<g
id="g99695">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99693"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99697">
<g
id="g99701">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99699"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99711">
<g
id="g99715"
transform="matrix(0.55711614,0,0,0.55573006,146.08647,216.61288)">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.04406;stroke-linecap:round;stroke-linejoin:round"
id="rect99713"
width="15.799728"
height="23.758703"
x="0.0094064204"
y="0.054201871" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99717">
<g
id="g99721">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.04406;stroke-linecap:round;stroke-linejoin:round"
id="rect99719"
width="15.799728"
height="23.758703"
x="0.0094064204"
y="0.054201871" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99723">
<g
id="g99727">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.04406;stroke-linecap:round;stroke-linejoin:round"
id="rect99725"
width="15.799728"
height="23.758703"
x="0.0094064204"
y="0.054201871" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99794">
<g
id="g99798"
transform="matrix(0.55711614,0,0,0.55573006,162.92021,216.61309)">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99796"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99800">
<g
id="g99804">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99802"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99806">
<g
id="g99810">
<rect
style="opacity:0.545894;fill:#ffffff;stroke-width:1.58593;stroke-linecap:round;stroke-linejoin:round"
id="rect99808"
width="15.799728"
height="23.793234"
x="8.0127716"
y="0.019266307" />
</g>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath99883">
<path
id="path99885"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke-width:1.665;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 7.9375,0 C 3.5401295,0 0,3.5401295 0,7.9375 v 7.9375 c 0,4.397371 3.5401295,7.9375 7.9375,7.9375 h 7.9375 c 4.397371,0 7.9375,-3.540129 7.9375,-7.9375 V 7.9375 C 23.8125,3.5401295 20.272371,0 15.875,0 Z m 2.205033,6.6145833 h 3.527434 c 1.954387,0 3.52795,1.5735631 3.52795,3.5279497 v 3.527434 c 0,1.954387 -1.573563,3.52795 -3.52795,3.52795 h -3.527434 c -1.9543866,0 -3.5279497,-1.573563 -3.5279497,-3.52795 v -3.527434 c 0,-1.9543866 1.5735631,-3.5279497 3.5279497,-3.5279497 z" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath100370">
<path
id="path100372"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke-width:1.665;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 7.9375,1e-7 C 3.540129,1e-7 0,3.5401295 0,7.9375 v 7.9375 c 0,4.397371 3.540129,7.9375 7.9375,7.9375 h 7.9375 c 4.397371,0 7.9375,-3.540129 7.9375,-7.9375 V 7.9375 C 23.8125,3.5401295 20.272371,1e-7 15.875,1e-7 Z m 2.205033,6.6145832 h 3.527434 c 1.954387,0 3.52795,1.5735631 3.52795,3.5279497 v 3.527434 c 0,1.954387 -1.573563,3.52795 -3.52795,3.52795 h -3.527434 c -1.9543871,0 -3.5279499,-1.573563 -3.5279499,-3.52795 v -3.527434 c 0,-1.9543866 1.5735628,-3.5279497 3.5279499,-3.5279497 z" />
</clipPath>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter100374"
x="-0.016537434"
y="-0.016422829"
width="1.0330749"
height="1.0328457">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.3306537"
id="feGaussianBlur100376" />
</filter>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter100378"
x="-0.022721409"
y="-0.022721409"
width="1.0454428"
height="1.0454428">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.53369547"
id="feGaussianBlur100380" />
</filter>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter102682"
x="-0.06964116"
y="-0.069533732"
width="1.1392823"
height="1.1390675">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.32737963"
id="feGaussianBlur102684" />
</filter>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter103118"
x="-0.081623544"
y="-0.084951162"
width="1.1632471"
height="1.1699023">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.38748406"
id="feGaussianBlur103120" />
</filter>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath31206">
<path
id="path31208"
style="display:inline;opacity:1;fill:#0000ff;fill-opacity:1;stroke-width:0.764442;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 3.8107566,0.22044249 c -2.0189409,0 -3.64430097,1.62536021 -3.64430097,3.64430091 v 3.6443014 c 0,2.0189404 1.62536007,3.6443002 3.64430097,3.6443002 h 3.6443008 c 2.0189414,0 3.6443026,-1.6253598 3.6443026,-3.6443002 V 3.8647434 c 0,-2.0189407 -1.6253612,-3.64430091 -3.6443026,-3.64430091 z M 4.8231414,3.25736 h 1.6195315 c 0.8973069,0 1.6197682,0.7224613 1.6197682,1.6197683 v 1.6195315 c 0,0.8973069 -0.7224613,1.6197685 -1.6197682,1.6197685 H 4.8231414 c -0.897307,0 -1.6197683,-0.7224616 -1.6197683,-1.6197685 V 4.8771283 c 0,-0.897307 0.7224613,-1.6197683 1.6197683,-1.6197683 z"
inkscape:label="Base" />
</clipPath>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter52441"
x="-0.070652017"
y="-0.075159612"
width="1.141304"
height="1.1503192">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.33137071"
id="feGaussianBlur52443" />
</filter>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath57529">
<path
id="path57531"
style="display:inline;opacity:1;fill:#25252a;fill-opacity:1;stroke-width:0.764442;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 3.8107566,0.22044249 c -2.0189409,0 -3.64430097,1.62536021 -3.64430097,3.64430091 v 3.6443014 c 0,2.0189404 1.62536007,3.6443002 3.64430097,3.6443002 h 3.6443008 c 2.0189414,0 3.6443026,-1.6253598 3.6443026,-3.6443002 V 3.8647434 c 0,-2.0189407 -1.6253612,-3.64430091 -3.6443026,-3.64430091 z M 4.8231414,3.25736 h 1.6195315 c 0.8973069,0 1.6197682,0.7224613 1.6197682,1.6197683 v 1.6195315 c 0,0.8973069 -0.7224613,1.6197685 -1.6197682,1.6197685 H 4.8231414 c -0.897307,0 -1.6197683,-0.7224616 -1.6197683,-1.6197685 V 4.8771283 c 0,-0.897307 0.7224613,-1.6197683 1.6197683,-1.6197683 z"
inkscape:label="Base" />
</clipPath>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter62695"
x="-0.06487865"
y="-0.075681583"
width="1.1297573"
height="1.1513632">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.69279285"
id="feGaussianBlur62697" />
</filter>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath72317">
<path
id="path72319"
style="display:inline;opacity:1;fill:#25252a;fill-opacity:1;stroke-width:0.764442;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 3.8107566,0.22044249 c -2.0189409,0 -3.64430097,1.62536021 -3.64430097,3.64430091 v 3.6443014 c 0,2.0189404 1.62536007,3.6443002 3.64430097,3.6443002 h 3.6443008 c 2.0189414,0 3.6443026,-1.6253598 3.6443026,-3.6443002 V 3.8647434 c 0,-2.0189407 -1.6253612,-3.64430091 -3.6443026,-3.64430091 z M 4.8231414,3.25736 h 1.6195315 c 0.8973069,0 1.6197682,0.7224613 1.6197682,1.6197683 v 1.6195315 c 0,0.8973069 -0.7224613,1.6197685 -1.6197682,1.6197685 H 4.8231414 c -0.897307,0 -1.6197683,-0.7224616 -1.6197683,-1.6197685 V 4.8771283 c 0,-0.897307 0.7224613,-1.6197683 1.6197683,-1.6197683 z"
inkscape:label="Base" />
</clipPath>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter72329"
x="-0.032947097"
y="-0.053309845"
width="1.0658942"
height="1.1066197">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.420369"
id="feGaussianBlur72331" />
</filter>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath83385">
<path
id="path83387"
style="display:none;opacity:1;fill:#25252a;fill-opacity:1;stroke-width:0.716466;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 3.7316887,0.48491864 c -1.8922335,0 -3.41558702,1.52335366 -3.41558702,3.41558706 v 3.4155875 c 0,1.892233 1.52335352,3.4155858 3.41558702,3.4155858 h 3.415587 c 1.892234,0 3.4155883,-1.5233528 3.4155883,-3.4155858 V 3.9005057 c 0,-1.8922334 -1.5233543,-3.41558706 -3.4155883,-3.41558706 z M 4.680537,3.3312412 h 1.5178908 c 0.8409926,0 1.5181127,0.6771202 1.5181127,1.5181128 v 1.5178908 c 0,0.8409925 -0.6771201,1.5181129 -1.5181127,1.5181129 H 4.680537 c -0.8409926,0 -1.5181128,-0.6771204 -1.5181128,-1.5181129 V 4.849354 c 0,-0.8409926 0.6771202,-1.5181128 1.5181128,-1.5181128 z"
inkscape:label="Base" />
<path
id="lpe_path-effect83389"
style="display:block;opacity:1;fill:#25252a;fill-opacity:1;stroke-width:0.716466;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
class="powerclip"
d="M -5.1273168,-4.7811946 H 17.719696 V 17.390729 H -5.1273168 Z m 8.8590055,5.26611324 c -1.8922335,0 -3.41558702,1.52335366 -3.41558702,3.41558706 v 3.4155875 c 0,1.892233 1.52335352,3.4155858 3.41558702,3.4155858 h 3.415587 c 1.892234,0 3.4155883,-1.5233528 3.4155883,-3.4155858 V 3.9005057 c 0,-1.8922334 -1.5233543,-3.41558706 -3.4155883,-3.41558706 z M 4.680537,3.3312412 c -0.8409926,0 -1.5181128,0.6771202 -1.5181128,1.5181128 v 1.5178908 c 0,0.8409925 0.6771202,1.5181129 1.5181128,1.5181129 h 1.5178908 c 0.8409926,0 1.5181127,-0.6771204 1.5181127,-1.5181129 V 4.849354 c 0,-0.8409926 -0.6771201,-1.5181128 -1.5181127,-1.5181128 z" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath89494">
<path
id="path89496"
style="display:inline;opacity:1;fill:#25252a;fill-opacity:1;stroke-width:0.764442;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 3.8107566,0.22044249 c -2.018941,0 -3.64430097,1.62536021 -3.64430097,3.64430091 v 3.6443014 c 0,2.0189404 1.62535997,3.6442992 3.64430097,3.6442992 h 3.6443008 c 2.0189414,0 3.6443026,-1.6253588 3.6443026,-3.6442992 V 3.8647434 c 0,-2.0189407 -1.6253612,-3.64430091 -3.6443026,-3.64430091 z M 4.8231414,3.25736 h 1.6195315 c 0.8973069,0 1.6197682,0.7224613 1.6197682,1.6197683 v 1.6195315 c 0,0.8973069 -0.7224613,1.6197685 -1.6197682,1.6197685 H 4.8231414 c -0.897307,0 -1.6197683,-0.7224616 -1.6197683,-1.6197685 V 4.8771283 c 0,-0.897307 0.7224613,-1.6197683 1.6197683,-1.6197683 z"
inkscape:label="Base_ClipInnerShadow" />
</clipPath>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter89498"
x="-0.10656911"
y="-0.10916244"
width="1.2131382"
height="1.2183249">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.99100453"
id="feGaussianBlur89500" />
</filter>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path83383"
style="display:none;opacity:1;fill:#25252a;fill-opacity:1;stroke-width:0.764442;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 3.8107565,0.22044249 c -2.0189409,0 -3.64430087,1.62536021 -3.64430087,3.64430091 v 3.6443014 c 0,2.0189403 1.62535997,3.6442992 3.64430087,3.6442992 h 3.6443009 c 2.0189414,0 3.6443026,-1.6253589 3.6443026,-3.6442992 V 3.8647434 c 0,-2.0189407 -1.6253612,-3.64430091 -3.6443026,-3.64430091 z M 4.8231414,3.2573599 h 1.6195315 c 0.897307,0 1.6197683,0.7224614 1.6197683,1.6197684 v 1.6195315 c 0,0.8973069 -0.7224613,1.6197685 -1.6197683,1.6197685 H 4.8231414 c -0.897307,0 -1.6197684,-0.7224616 -1.6197684,-1.6197685 V 4.8771283 c 0,-0.897307 0.7224614,-1.6197684 1.6197684,-1.6197684 z"
inkscape:label="Base_Template" />
<path
id="rect19555"
style="display:none;opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.479999;stroke-linecap:round;stroke-linejoin:round;filter:url(#filter62695)"
inkscape:label="Highlight"
d="M -5.4236243,-3.413155 V 18.55656 H 20.204264 V -3.413155 Z m 9.543085,3.8664299 h 3.8267549 c 2.0189392,0 5.0928104,1.6252826 5.0928104,3.6442214 v 3.6442213 c 0,2.0189384 -3.2564047,5.1817184 -5.2753439,5.1817184 H 4.1194607 c -2.0189388,0 -3.6442213,-2.364531 -3.6442213,-4.3834689 V 4.0974963 c 0,-2.0189388 1.6252825,-3.6442214 3.6442213,-3.6442214 z M 5.860661,3.9873765 c -0.897306,0 -1.6195391,0.7227498 -1.6195391,1.6200559 v 1.6195391 c 0,0.8973061 -0.00663,1.1219441 0.89068,1.1219441 H 6.751341 c 0.8973061,0 1.6200558,-0.722233 1.6200558,-1.6195391 V 5.1098374 c 0,-0.8973061 0.00611,-1.1224609 -0.8911967,-1.1224609 z"
clip-path="url(#clipPath57529)"
sodipodi:nodetypes="cccccssssssssssssssssss" />
<path
id="rect70854"
style="display:inline;opacity:0.0272194;mix-blend-mode:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.479999;stroke-linecap:round;stroke-linejoin:round;filter:url(#filter72329)"
d="M -5.55488,-2.9837738 V 15.941166 H 25.066501 V -2.9837738 Z m 9.4521345,3.27783552 h 3.6442214 c 2.0189392,0 5.4648381,1.62528258 5.4648381,3.64422138 v 3.6442213 c 0,2.0189384 -3.4458989,5.3884686 -5.4648381,5.3884686 H 3.8972545 c -2.0189388,0 -3.64422126,-3.3695302 -3.64422126,-5.3884686 V 3.9382831 c 0,-2.0189388 1.62528246,-3.64422138 3.64422126,-3.64422138 z M 5.1636819,4.0318807 C 4.2663822,4.028485 4.1271797,4.273952 4.1384651,5.1711871 l 0.021102,1.6777013 c 0.011285,0.8972352 -0.1472776,1.340814 0.7500284,1.340814 h 1.6195391 c 0.8973061,0 1.6200558,-0.722233 1.6200558,-1.6195391 V 4.9506242 c 0,-0.8388383 -0.2789043,-0.9085006 -1.1762041,-0.9118964 z"
clip-path="url(#clipPath72317)"
sodipodi:nodetypes="cccccssssssssssssssssss"
inkscape:label="HighlightAttempt2" />
<path
id="path48781"
style="display:inline;opacity:0.490203;mix-blend-mode:normal;fill:#000000;fill-opacity:1;stroke-width:0.764443;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;filter:url(#filter52441)"
d="M 4.8385425,1.135747 C 3.8532515,1.1745581 2.072675,2.0061285 1.6289413,3.9757027 L 0.73329837,7.9511393 C 0.28956477,9.9207131 2.1791242,11.595439 4.1980651,11.595439 H 7.842366 c 2.0189412,0 4.08204,-1.6253593 4.08204,-3.6442997 V 4.306838 c 0,-2.0189408 -2.0646633,-3.36887855 -4.08204,-3.2894131 z m 0.3719073,2.4432889 h 1.6195315 c 1.7459202,0 1.6197684,0.093379 1.6197684,1.7401869 v 1.6195314 c 0,0.897307 -0.7224614,1.6197687 -1.6197684,1.6197687 H 5.2104498 c -1.8303035,0 -1.7420092,-0.084453 -1.7420092,-1.6197687 V 5.3192228 c 0,-0.897307 0.3645222,-1.7401869 1.7420092,-1.7401869 z"
inkscape:label="OuterShadow"
transform="matrix(1.0669618,0,0,1.0669618,-0.17081279,-0.29694717)"
clip-path="url(#clipPath83385)"
sodipodi:nodetypes="ssssssssssssssssss"
inkscape:path-effect="#path-effect83389"
inkscape:original-d="M 4.8385425,1.135747 C 3.8532515,1.1745581 2.072675,2.0061285 1.6289413,3.9757027 L 0.73329837,7.9511393 C 0.28956477,9.9207131 2.1791242,11.595439 4.1980651,11.595439 H 7.842366 c 2.0189412,0 4.08204,-1.6253593 4.08204,-3.6442997 V 4.306838 c 0,-2.0189408 -2.0646633,-3.36887855 -4.08204,-3.2894131 z m 0.3719073,2.4432889 h 1.6195315 c 1.7459202,0 1.6197684,0.093379 1.6197684,1.7401869 v 1.6195314 c 0,0.897307 -0.7224614,1.6197687 -1.6197684,1.6197687 H 5.2104498 c -1.8303035,0 -1.7420092,-0.084453 -1.7420092,-1.6197687 V 5.3192228 c 0,-0.897307 0.3645222,-1.7401869 1.7420092,-1.7401869 z" />
<path
id="rect84192"
style="display:inline;opacity:0.757436;mix-blend-mode:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.479999;stroke-linecap:round;stroke-linejoin:round;filter:url(#filter89498)"
d="M -5.6229603,-5.315903 V 16.47191 H 16.695054 V -5.315903 Z m 5.90983543,4.2894047 H 9.3338044 c 2.0189396,0 1.5174656,2.7634527 1.5174656,4.7823914 v 3.6442213 c 0,2.0189383 -1.4741734,3.4564736 -3.4931128,3.4564736 H 3.7139358 c -2.0189388,0 -5.4378275,-0.8817264 -5.4378275,-2.9006647 V 1.0035299 c 0,-2.0189387 -0.00817,-2.0300282 2.01076683,-2.0300282 z M 4.726277,2.92066 c -1.013297,0 -1.8932306,0.7964555 -1.8932306,1.8475742 v 1.6195391 c 0,0.897306 1.3608451,0.68026 2.2581512,0.68026 H 5.736869 c 0.8973061,0 1.4066862,-0.3744647 1.4066862,-1.2717707 V 4.3969071 c 0,-0.8973061 0.099567,-1.4762471 -0.7977391,-1.4762471 z"
clip-path="url(#clipPath89494)"
sodipodi:nodetypes="cccccssssssssssssssssss"
inkscape:label="InnerShadow" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Orig">
<path
style="display:none;opacity:0.375299;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter103118)"
d="m 0.8735199,9.609286 2.0625332,2.61454 c 0,0 7.0427542,0.255099 8.5324559,-0.985215 1.489702,-1.2403138 0.43774,-8.2898438 0.43774,-8.2898438 l -1.756333,-1.6502879 -1.7077554,0.024419 0.270157,7.3141066 z"
id="path103116"
sodipodi:nodetypes="cczccccc" />
<path
id="path100388"
style="display:none;opacity:0.393294;mix-blend-mode:normal;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.66502;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter102682)"
d="m 9.1712948,1.2337949 c -4.397371,0 -7.9374999,3.5401293 -7.9374999,7.9374999 v 7.9375012 c 0,4.397371 2.9641899,7.397461 7.3615609,7.397461 h 7.9375012 c 4.397371,0 7.9375,-3.540129 7.9375,-7.9375 V 8.6312558 c 0,-4.3973706 -2.96419,-7.3974609 -7.361561,-7.3974609 z m 1.3337892,5.840008 h 4.398679 c 1.954387,0 3.52795,2.3481383 3.52795,4.3025261 v 3.527434 c 0,1.954387 -1.573563,3.52795 -3.52795,3.52795 h -3.527434 c -1.9543882,0 -4.3991959,-1.573563 -4.3991959,-3.52795 v -3.527434 c 0,-1.9543878 1.573563,-4.3025261 3.5279509,-4.3025261 z"
sodipodi:nodetypes="ssssssssssssssssss"
transform="matrix(0.45912452,0,0,0.45912452,0,0.05897862)"
inkscape:label="WholeShadow" />
<path
id="rect99887"
style="display:none;opacity:0.0499596;mix-blend-mode:normal;fill:#ffffff;fill-opacity:1;stroke-width:1.665;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;filter:url(#filter100374)"
d="m -2.3988392,-9.3735876 c -4.39737,0 -7.9374978,3.540129 -7.9374978,7.9374994 V 31.009995 c 0,4.39737 3.5401278,7.9375 7.9374978,7.9375 H 29.71238 c 4.39737,0 7.9375,-3.54013 7.9375,-7.9375 V -1.4360882 c 0,-4.3973704 -3.54013,-7.9374994 -7.9375,-7.9374994 z M 8.8087458,0.88211668 h 7.9375002 c 4.397367,0 7.9375,3.54013412 7.9375,7.93750012 v 7.9375012 c 0,4.397367 -3.540133,7.9375 -7.9375,7.9375 H 8.8087458 c -4.397366,0 -7.93750012,-3.540133 -7.93750012,-7.9375 V 8.8196168 c 0,-4.397366 3.54013412,-7.93750012 7.93750012,-7.93750012 z M 11.013778,7.4966998 c -1.9543842,0 -3.5279492,1.573565 -3.5279492,3.5279502 v 3.527435 c 0,1.954385 1.573565,3.52795 3.5279492,3.52795 h 3.527435 c 1.954385,0 3.52795,-1.573565 3.52795,-3.52795 V 11.02465 c 0,-1.9543852 -1.573565,-3.5279502 -3.52795,-3.5279502 z"
clip-path="url(#clipPath100370)"
transform="matrix(0.45912452,0,0,0.45912452,0.16645565,0.22044247)"
inkscape:label="BevelHighlight" />
<path
id="rect99870"
style="display:none;opacity:0.376017;mix-blend-mode:normal;fill:#000000;fill-opacity:1;stroke-width:1.665;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;filter:url(#filter100378)"
d="m -9.5880647,-17.514693 c -4.3973713,0 -7.9375003,3.540129 -7.9375003,7.9374997 V 30.920593 c 0,4.397371 3.540129,7.9375 7.9375003,7.9375 H 30.909721 c 4.397371,0 7.9375,-3.540129 7.9375,-7.9375 V -9.5771933 c 0,-4.3973707 -3.540129,-7.9374997 -7.9375,-7.9374997 z m 16.280143,16.2801435 h 7.9374997 c 4.397367,0 7.9375,3.5401338 7.9375,7.9375 V 14.64045 c 0,4.397367 -3.540133,7.9375 -7.9375,7.9375 H 6.6920783 c -4.397366,0 -7.9375,-3.540133 -7.9375,-7.9375 V 6.7029505 c 0,-4.3973662 3.540134,-7.9375 7.9375,-7.9375 z m 2.205033,6.6145833 c -1.954384,0 -3.52795,1.5735654 -3.52795,3.5279492 v 3.527434 c 0,1.954385 1.573566,3.52795 3.52795,3.52795 h 3.5274337 c 1.954385,0 3.52795,-1.573565 3.52795,-3.52795 V 8.907983 c 0,-1.9543838 -1.573565,-3.5279492 -3.52795,-3.5279492 z"
clip-path="url(#clipPath99883)"
inkscape:label="BevelShadow"
transform="matrix(0.45912452,0,0,0.45912452,0.16774353,0.21343947)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="64"
height="64"
viewBox="0 0 64 64"
version="1.1"
id="svg1"
sodipodi:docname="screw.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
inkscape:export-filename="screw.svg.96dpi.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="linearGradient1"
inkscape:collect="always">
<stop
style="stop-color:#c4c3c3;stop-opacity:1;"
offset="0"
id="stop1" />
<stop
style="stop-color:#494949;stop-opacity:1;"
offset="1"
id="stop2" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1"
id="radialGradient2"
cx="22.482365"
cy="13.063787"
fx="22.482365"
fy="13.063787"
r="32.000001"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6223868,1.8591502,-2.9470613,2.5718795,21.027806,-57.524045)" />
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="4.9725211"
inkscape:cx="37.506125"
inkscape:cy="58.521622"
inkscape:window-width="1916"
inkscape:window-height="1052"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<circle
style="fill:url(#radialGradient2);stroke:#5f5f5f;stroke-width:0.0306299;stroke-linecap:square;stroke-linejoin:round;fill-opacity:1"
id="path1"
cx="31.999947"
cy="31.999908"
r="31.984686" />
<rect
style="fill:#5f5f5f;stroke:#5f5f5f;stroke-width:1.00157;stroke-linecap:square;stroke-linejoin:round"
id="rect4"
width="44.042046"
height="10.859682"
x="10.457473"
y="26.948099"
ry="4.3779716" />
<path
id="rect5"
style="fill:#5f5f5f;stroke:#5f5f5f;stroke-width:1.00157;stroke-linecap:square;stroke-linejoin:round"
d="m 30.947265,9.979492 c -2.425396,0 -4.376953,1.951557 -4.376953,4.376953 V 26.569336 H 14.357423 c -2.425397,0 -4.3789075,1.953509 -4.3789075,4.378906 v 2.103516 c 0,2.425396 1.9535105,4.378906 4.3789075,4.378906 h 12.212889 v 12.21289 c 0,2.425397 1.951557,4.376954 4.376953,4.376954 h 2.105469 c 2.425396,-10e-7 4.376953,-1.951557 4.376953,-4.376954 v -12.21289 h 12.212891 c 2.425396,0 4.378906,-1.953511 4.378906,-4.378906 v -2.103516 c 0,-2.425397 -1.95351,-4.378906 -4.378906,-4.378906 H 37.429687 V 14.356445 c 0,-2.425396 -1.951557,-4.376953 -4.376953,-4.376953 z" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,2 @@
sample:
filter: true

View File

@@ -7,7 +7,7 @@
viewBox="0 0 6.3499998 6.3499999"
version="1.1"
id="svg1055"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="geometric_panel_border.svg"
inkscape:export-filename="geometric_panel_border.svg.96dpi.png"
inkscape:export-xdpi="96"
@@ -29,16 +29,16 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
inkscape:cx="6.140625"
inkscape:cx="6.15625"
inkscape:cy="12.15625"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:pagecheckerboard="true"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-width="1916"
inkscape:window-height="1052"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
units="px"
inkscape:snap-page="true"
@@ -55,7 +55,10 @@
empcolor="#3f3fff"
empopacity="0.75686275"
enabled="true"
dotted="false" />
dotted="false"
spacingy="1"
spacingx="1"
units="px" />
<sodipodi:guide
position="0.26458333,2.6458333"
orientation="1,0"
@@ -136,7 +139,7 @@
transform="translate(-79.848503,-133.93878)">
<path
id="rect1684"
style="opacity:1;fill:#000000;fill-opacity:0.25;fill-rule:nonzero;stroke:none;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.247312;paint-order:normal"
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.247312;paint-order:normal"
d="m 83.55267,133.93878 2.645833,2.64583 v 3.70417 h -3.704167 l -2.645833,-2.64583 v -3.70417 z m -2.910417,3.37476 2.18149,2.18149 2.58101,0 v -2.58101 l -2.18149,-2.18149 -2.58101,0 z"
sodipodi:nodetypes="cccccccccccccc"
inkscape:label="rect1684" />

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

After

Width:  |  Height:  |  Size: 265 B

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="rounded_locked_button.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xml:space="preserve"
inkscape:export-filename="rounded_locked_button.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
id="metadata10"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs8" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1916"
inkscape:window-height="1034"
id="namedview6"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="15.401126"
inkscape:cx="18.277884"
inkscape:cy="7.1098696"
inkscape:window-x="0"
inkscape:window-y="44"
inkscape:window-maximized="0"
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" /><rect
x="0"
y="0"
width="32"
height="32"
rx="5"
fill="#ffffff"
id="rect2" /><g
style="fill:none"
id="g33005"
transform="translate(8.3669405,5.989995)"><path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 7.63304,0.51001 c -2.93277,0 -5.29412,2.42131 -5.29412,5.42857 v 0.90476 c -0.97058,0 -1.764701,0.81429 -1.764701,1.80953 v 9.04763 c 0,0.9952 0.794121,1.8095 1.764701,1.8095 H 12.9272 c 0.9705,0 1.7647,-0.8143 1.7647,-1.8095 V 8.65287 c 0,-0.99524 -0.7942,-1.80953 -1.7647,-1.80953 V 5.93858 c 0,-3.00726 -2.3614,-5.42857 -5.29416,-5.42857 z m 0,1.80952 c 2.00841,0 3.52946,1.55964 3.52946,3.61905 V 6.84334 H 4.10363 V 5.93858 c 0,-2.05941 1.52101,-3.61905 3.52941,-3.61905 z M 9.39775,13.1767 c 0,-0.9953 -0.79412,-1.8095 -1.76471,-1.8095 -0.97059,0 -1.7647,0.8142 -1.7647,1.8095 0,0.9952 0.79411,1.8095 1.7647,1.8095 0.97059,0 1.76471,-0.8143 1.76471,-1.8095 z"
fill="#7b7e9e"
id="path32996" /></g></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

View File

@@ -59,7 +59,7 @@
id="layer1"
transform="translate(0,-288.53331)">
<rect
style="opacity:1;vector-effect:none;fill:#1e1e22;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.44710034;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
style="opacity:1;vector-effect:none;fill:#FFFFFF;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.44710034;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect1707"
width="8.4666672"
height="8.4666672"

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 370 B