forked from space-syndicate/space-station-14-next
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
114 changed files
with
4,178 additions
and
203 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
Content.Client/_EinsteinEngine/Language/LanguageMenuWindow.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<DefaultWindow xmlns="https://spacestation14.io" | ||
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls" | ||
Title="{Loc language-menu-window-title}" | ||
SetSize="300 300"> | ||
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150"> | ||
<PanelContainer Name="CurrentLanguageContainer" Access="Public" StyleClasses="PdaBorderRect"> | ||
<Label Name="CurrentLanguageLabel" Access="Public" Text="Current Language:" HorizontalExpand="True"></Label> | ||
</PanelContainer> | ||
|
||
<ui:HLine></ui:HLine> | ||
|
||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" HScrollEnabled="False" VScrollEnabled="True" MinHeight="50"> | ||
<BoxContainer Name="OptionsList" Access="Public" HorizontalExpand="True" SeparationOverride="2" Orientation="Vertical"> | ||
<!-- The rest here is generated programmatically --> | ||
</BoxContainer> | ||
</ScrollContainer> | ||
</BoxContainer> | ||
</DefaultWindow> |
143 changes: 143 additions & 0 deletions
143
Content.Client/_EinsteinEngine/Language/LanguageMenuWindow.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
using Content.Client._EinsteinEngine.Language.Systems; | ||
using Content.Shared._EinsteinEngine.Language; | ||
using Robust.Client.AutoGenerated; | ||
using Robust.Client.UserInterface.Controls; | ||
using Robust.Client.UserInterface.CustomControls; | ||
using Robust.Client.UserInterface.XAML; | ||
using Robust.Shared.Prototypes; | ||
|
||
namespace Content.Client._EinsteinEngine.Language; | ||
|
||
[GenerateTypedNameReferences] | ||
public sealed partial class LanguageMenuWindow : DefaultWindow | ||
{ | ||
private readonly LanguageSystem _clientLanguageSystem; | ||
private readonly List<EntryState> _entries = new(); | ||
|
||
public LanguageMenuWindow() | ||
{ | ||
RobustXamlLoader.Load(this); | ||
_clientLanguageSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<LanguageSystem>(); | ||
_clientLanguageSystem.OnLanguagesChanged += UpdateState; | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
base.Dispose(disposing); | ||
|
||
if (disposing) | ||
_clientLanguageSystem.OnLanguagesChanged -= UpdateState; | ||
} | ||
|
||
protected override void Opened() | ||
{ | ||
UpdateState(); | ||
} | ||
|
||
private void UpdateState() | ||
{ | ||
var languageSpeaker = _clientLanguageSystem.GetLocalSpeaker(); | ||
if (languageSpeaker == null) | ||
return; | ||
|
||
UpdateState(languageSpeaker.CurrentLanguage, languageSpeaker.SpokenLanguages); | ||
} | ||
|
||
public void UpdateState(ProtoId<LanguagePrototype> currentLanguage, List<ProtoId<LanguagePrototype>> spokenLanguages) | ||
{ | ||
var langName = Loc.GetString($"language-{currentLanguage}-name"); | ||
CurrentLanguageLabel.Text = Loc.GetString("language-menu-current-language", ("language", langName)); | ||
|
||
OptionsList.RemoveAllChildren(); | ||
_entries.Clear(); | ||
|
||
foreach (var language in spokenLanguages) | ||
{ | ||
AddLanguageEntry(language); | ||
} | ||
|
||
// Disable the button for the currently chosen language | ||
foreach (var entry in _entries) | ||
{ | ||
if (entry.Button != null) | ||
entry.Button.Disabled = entry.Language == currentLanguage; | ||
} | ||
} | ||
|
||
private void AddLanguageEntry(ProtoId<LanguagePrototype> language) | ||
{ | ||
var proto = _clientLanguageSystem.GetLanguagePrototype(language); | ||
var state = new EntryState { Language = language }; | ||
|
||
var container = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Vertical }; | ||
|
||
#region Header | ||
var header = new BoxContainer | ||
{ | ||
Orientation = BoxContainer.LayoutOrientation.Horizontal, | ||
HorizontalExpand = true, | ||
SeparationOverride = 2 | ||
}; | ||
|
||
var name = new Label | ||
{ | ||
Text = proto?.Name ?? Loc.GetString("generic-error"), | ||
MinWidth = 50, | ||
HorizontalExpand = true | ||
}; | ||
|
||
var button = new Button { Text = "Choose" }; | ||
button.OnPressed += _ => OnLanguageChosen(language); | ||
state.Button = button; | ||
|
||
header.AddChild(name); | ||
header.AddChild(button); | ||
|
||
container.AddChild(header); | ||
#endregion | ||
|
||
#region Collapsible description | ||
var body = new CollapsibleBody | ||
{ | ||
HorizontalExpand = true, | ||
Margin = new Thickness(4f, 4f) | ||
}; | ||
|
||
var description = new RichTextLabel { HorizontalExpand = true }; | ||
description.SetMessage(proto?.Description ?? Loc.GetString("generic-error")); | ||
body.AddChild(description); | ||
|
||
var collapser = new Collapsible(Loc.GetString("language-menu-description-header"), body) | ||
{ | ||
Orientation = BoxContainer.LayoutOrientation.Vertical, | ||
HorizontalExpand = true | ||
}; | ||
|
||
container.AddChild(collapser); | ||
#endregion | ||
|
||
// Before adding, wrap the new container in a PanelContainer to give it a distinct look | ||
var wrapper = new PanelContainer(); | ||
wrapper.StyleClasses.Add("PdaBorderRect"); | ||
|
||
wrapper.AddChild(container); | ||
OptionsList.AddChild(wrapper); | ||
|
||
_entries.Add(state); | ||
} | ||
|
||
private void OnLanguageChosen(ProtoId<LanguagePrototype> id) | ||
{ | ||
_clientLanguageSystem.RequestSetLanguage(id); | ||
|
||
// Predict the change | ||
if (_clientLanguageSystem.GetLocalSpeaker()?.SpokenLanguages is {} languages) | ||
UpdateState(id, languages); | ||
} | ||
|
||
private struct EntryState | ||
{ | ||
public ProtoId<LanguagePrototype> Language; | ||
public Button? Button; | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
Content.Client/_EinsteinEngine/Language/Systems/LanguageSystem.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using Content.Shared._EinsteinEngine.Language; | ||
using Content.Shared._EinsteinEngine.Language.Components; | ||
using Content.Shared._EinsteinEngine.Language.Events; | ||
using Content.Shared._EinsteinEngine.Language.Systems; | ||
using Robust.Client.Player; | ||
using Robust.Shared.GameStates; | ||
using Robust.Shared.Prototypes; | ||
|
||
namespace Content.Client._EinsteinEngine.Language.Systems; | ||
|
||
public sealed class LanguageSystem : SharedLanguageSystem | ||
{ | ||
[Dependency] private readonly IPlayerManager _playerManager = default!; | ||
|
||
/// <summary> | ||
/// Invoked when the languages of the local player entity change, for use in UI. | ||
/// </summary> | ||
public event Action? OnLanguagesChanged; | ||
|
||
public override void Initialize() | ||
{ | ||
_playerManager.LocalPlayerAttached += NotifyUpdate; | ||
SubscribeLocalEvent<LanguageSpeakerComponent, ComponentHandleState>(OnHandleState); | ||
} | ||
|
||
private void OnHandleState(Entity<LanguageSpeakerComponent> ent, ref ComponentHandleState args) | ||
{ | ||
if (args.Current is not LanguageSpeakerComponent.State state) | ||
return; | ||
|
||
ent.Comp.CurrentLanguage = state.CurrentLanguage; | ||
ent.Comp.SpokenLanguages = state.SpokenLanguages; | ||
ent.Comp.UnderstoodLanguages = state.UnderstoodLanguages; | ||
|
||
if (ent.Owner == _playerManager.LocalEntity) | ||
NotifyUpdate(ent); | ||
} | ||
|
||
/// <summary> | ||
/// Returns the LanguageSpeakerComponent of the local player entity. | ||
/// Will return null if the player does not have an entity, or if the client has not yet received the component state. | ||
/// </summary> | ||
public LanguageSpeakerComponent? GetLocalSpeaker() | ||
{ | ||
return CompOrNull<LanguageSpeakerComponent>(_playerManager.LocalEntity); | ||
} | ||
|
||
public void RequestSetLanguage(ProtoId<LanguagePrototype> language) | ||
{ | ||
if (GetLocalSpeaker()?.CurrentLanguage?.Equals(language) == true) | ||
return; | ||
|
||
RaiseNetworkEvent(new LanguagesSetMessage(language)); | ||
} | ||
|
||
private void NotifyUpdate(EntityUid localPlayer) | ||
{ | ||
RaiseLocalEvent(localPlayer, new LanguagesUpdateEvent(), broadcast: true); | ||
OnLanguagesChanged?.Invoke(); | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
Content.Client/_EinsteinEngine/UserInterface/Systems/Language/LanguageMenuUIController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using Content.Client._EinsteinEngine.Language; | ||
using Content.Client.Gameplay; | ||
using Content.Client.UserInterface.Controls; | ||
using Content.Shared.Input; | ||
using JetBrains.Annotations; | ||
using Robust.Client.UserInterface.Controllers; | ||
using Robust.Client.UserInterface.Controls; | ||
using Robust.Shared.Input.Binding; | ||
using Robust.Shared.Utility; | ||
using static Robust.Client.UserInterface.Controls.BaseButton; | ||
|
||
namespace Content.Client._EinsteinEngine.UserInterface.Systems.Language; | ||
|
||
[UsedImplicitly] | ||
public sealed class LanguageMenuUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState> | ||
{ | ||
public LanguageMenuWindow? LanguageWindow; | ||
private MenuButton? LanguageButton => UIManager.GetActiveUIWidgetOrNull<Client.UserInterface.Systems.MenuBar.Widgets.GameTopMenuBar>()?.LanguageButton; | ||
|
||
public void OnStateEntered(GameplayState state) | ||
{ | ||
DebugTools.Assert(LanguageWindow == null); | ||
|
||
LanguageWindow = UIManager.CreateWindow<LanguageMenuWindow>(); | ||
LayoutContainer.SetAnchorPreset(LanguageWindow, LayoutContainer.LayoutPreset.CenterTop); | ||
|
||
LanguageWindow.OnClose += () => | ||
{ | ||
if (LanguageButton != null) | ||
LanguageButton.Pressed = false; | ||
}; | ||
LanguageWindow.OnOpen += () => | ||
{ | ||
if (LanguageButton != null) | ||
LanguageButton.Pressed = true; | ||
}; | ||
|
||
CommandBinds.Builder.Bind(ContentKeyFunctions.OpenLanguageMenu, | ||
InputCmdHandler.FromDelegate(_ => ToggleWindow())).Register<LanguageMenuUIController>(); | ||
} | ||
|
||
public void OnStateExited(GameplayState state) | ||
{ | ||
if (LanguageWindow != null) | ||
{ | ||
LanguageWindow.Dispose(); | ||
LanguageWindow = null; | ||
} | ||
|
||
CommandBinds.Unregister<LanguageMenuUIController>(); | ||
} | ||
|
||
public void UnloadButton() | ||
{ | ||
if (LanguageButton == null) | ||
return; | ||
|
||
LanguageButton.OnPressed -= LanguageButtonPressed; | ||
} | ||
|
||
public void LoadButton() | ||
{ | ||
if (LanguageButton == null) | ||
return; | ||
|
||
LanguageButton.OnPressed += LanguageButtonPressed; | ||
} | ||
|
||
private void LanguageButtonPressed(ButtonEventArgs args) | ||
{ | ||
ToggleWindow(); | ||
} | ||
|
||
private void ToggleWindow() | ||
{ | ||
if (LanguageWindow == null) | ||
return; | ||
|
||
if (LanguageButton != null) | ||
LanguageButton.SetClickPressed(!LanguageWindow.IsOpen); | ||
|
||
if (LanguageWindow.IsOpen) | ||
LanguageWindow.Close(); | ||
else | ||
LanguageWindow.Open(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.