Fingerprints filter for records station computer (#15017)
* add new labels and buttons for records stantion console * add fingerprint fields for server * set buttons and updates for fingerPrints filters * set fingerprints filters * final set for finger prints filters * add new trhaslates for station records computer * some fix for the PR * refactor server side station record console system * add message for filters * add tranlates * add new ui with several filters * updetes prints with server side logic * resolve conflicts with DNA * resolve conflicts with DNA * deleted unused variable and rename some fields * added description for new state * added select for filter * set multiplay filters for the console * added new translates * add class filters & fixed issue with reset line edit * fix dublicate with set the selectId for option button * fixed review notes * fixed review notes forget changet fix name * add event TextEntered for better usability * fixed review notes 3 * fixed formating in xaml * fixed array with _filterTypes * fixed ui and made it in minimalistic style * fixed generalstationRecordFilter class, move method * delete margin after line edit * fix placeholder for lineEdit * fix placeholder for lineEdit, the review note * Revert "fixed generalstationRecordFilter class, move method" This reverts commit 1b35c6ac44e7dafe9a1f0560eb177152b822f20b. * impliment short swith in method IsSkippedRecord * fixed review notes, remaked method IsSkipped and fix casing * fixed the review note about check null record name
This commit is contained in:
@@ -16,6 +16,7 @@ public sealed class GeneralStationRecordConsoleBoundUserInterface : BoundUserInt
|
||||
|
||||
_window = new();
|
||||
_window.OnKeySelected += OnKeySelected;
|
||||
_window.OnFiltersChanged += OnFiltersChanged;
|
||||
_window.OnClose += Close;
|
||||
|
||||
_window.OpenCentered();
|
||||
@@ -26,6 +27,13 @@ public sealed class GeneralStationRecordConsoleBoundUserInterface : BoundUserInt
|
||||
SendMessage(new SelectGeneralStationRecord(key));
|
||||
}
|
||||
|
||||
private void OnFiltersChanged(
|
||||
GeneralStationRecordFilterType type, string filterValue)
|
||||
{
|
||||
GeneralStationRecordsFilterMsg msg = new(type, filterValue);
|
||||
SendMessage(msg);
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
Title="{Loc 'general-station-record-console-window-title'}"
|
||||
MinSize="750 500">
|
||||
<BoxContainer>
|
||||
<!-- Record listing -->
|
||||
<BoxContainer Orientation="Vertical" Margin="5 5 5 5" MinWidth="250" VerticalExpand="True">
|
||||
<Label Name="RecordListingStatus" Visible="False" />
|
||||
<ScrollContainer VerticalExpand="True">
|
||||
<ItemList Name="RecordListing" />
|
||||
</ScrollContainer>
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Margin="5 5 5 10" HorizontalExpand="true" VerticalAlignment="Center">
|
||||
<OptionButton Name="StationRecordsFilterType" MinWidth="200" Margin="0 0 10 0"/>
|
||||
<LineEdit Name="StationRecordsFiltersValue"
|
||||
PlaceHolder="{Loc 'general-station-record-for-filter-line-placeholder'}" HorizontalExpand="True"/>
|
||||
<Button Name="StationRecordsFilters" Text="{Loc 'general-station-record-console-search-records'}"/>
|
||||
<Button Name="StationRecordsFiltersReset" Text="{Loc 'general-station-record-console-reset-filters'}"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Vertical" Margin="5 5 5 5">
|
||||
<Label Name="RecordContainerStatus" Visible="False" Text="{Loc 'general-station-record-console-select-record-info'}"/>
|
||||
<BoxContainer Name="RecordContainer" Orientation="Vertical" />
|
||||
<BoxContainer VerticalExpand="True">
|
||||
<!-- Record listing -->
|
||||
<BoxContainer Orientation="Vertical" Margin="5" MinWidth="250" MaxWidth="250">
|
||||
<Label Name="RecordListingStatus" Visible="False" />
|
||||
<ScrollContainer VerticalExpand="True">
|
||||
<ItemList Name="RecordListing" />
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Vertical" Margin="5">
|
||||
<Label Name="RecordContainerStatus" Visible="False" Text="{Loc 'general-station-record-console-select-record-info'}"/>
|
||||
<BoxContainer Name="RecordContainer" Orientation="Vertical" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
|
||||
@@ -12,12 +12,24 @@ namespace Content.Client.StationRecords;
|
||||
public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
|
||||
{
|
||||
public Action<StationRecordKey?>? OnKeySelected;
|
||||
|
||||
public Action<GeneralStationRecordFilterType, string>? OnFiltersChanged;
|
||||
|
||||
private bool _isPopulating;
|
||||
|
||||
private GeneralStationRecordFilterType _currentFilterType;
|
||||
|
||||
public GeneralStationRecordConsoleWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
_currentFilterType = GeneralStationRecordFilterType.Name;
|
||||
|
||||
foreach (var item in Enum.GetValues<GeneralStationRecordFilterType>())
|
||||
{
|
||||
StationRecordsFilterType.AddItem(GetTypeFilterLocals(item), (int)item);
|
||||
}
|
||||
|
||||
RecordListing.OnItemSelected += args =>
|
||||
{
|
||||
if (_isPopulating || RecordListing[args.ItemIndex].Metadata is not StationRecordKey cast)
|
||||
@@ -33,20 +45,66 @@ public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
|
||||
if (!_isPopulating)
|
||||
OnKeySelected?.Invoke(null);
|
||||
};
|
||||
|
||||
StationRecordsFilterType.OnItemSelected += eventArgs =>
|
||||
{
|
||||
var type = (GeneralStationRecordFilterType)eventArgs.Id;
|
||||
|
||||
if (_currentFilterType != type)
|
||||
{
|
||||
_currentFilterType = type;
|
||||
FilterListingOfRecords();
|
||||
}
|
||||
};
|
||||
|
||||
StationRecordsFiltersValue.OnTextEntered += args =>
|
||||
{
|
||||
FilterListingOfRecords(args.Text);
|
||||
};
|
||||
|
||||
StationRecordsFilters.OnPressed += _ =>
|
||||
{
|
||||
FilterListingOfRecords(StationRecordsFiltersValue.Text);
|
||||
};
|
||||
|
||||
StationRecordsFiltersReset.OnPressed += _ =>
|
||||
{
|
||||
StationRecordsFiltersValue.Text = "";
|
||||
FilterListingOfRecords();
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateState(GeneralStationRecordConsoleState state)
|
||||
{
|
||||
if (state.Filter != null)
|
||||
{
|
||||
if (state.Filter.Type != _currentFilterType)
|
||||
{
|
||||
_currentFilterType = state.Filter.Type;
|
||||
}
|
||||
|
||||
if (state.Filter.Value != StationRecordsFiltersValue.Text)
|
||||
{
|
||||
StationRecordsFiltersValue.Text = state.Filter.Value;
|
||||
}
|
||||
}
|
||||
|
||||
StationRecordsFilterType.SelectId((int)_currentFilterType);
|
||||
|
||||
if (state.RecordListing == null)
|
||||
{
|
||||
RecordListingStatus.Visible = true;
|
||||
RecordListing.Visible = false;
|
||||
RecordListingStatus.Text = Loc.GetString("general-station-record-console-empty-state");
|
||||
RecordContainer.Visible = false;
|
||||
RecordContainerStatus.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
RecordListingStatus.Visible = false;
|
||||
RecordListing.Visible = true;
|
||||
RecordContainer.Visible = true;
|
||||
|
||||
PopulateRecordListing(state.RecordListing!, state.SelectedKey);
|
||||
|
||||
RecordContainerStatus.Visible = state.Record == null;
|
||||
@@ -65,18 +123,17 @@ public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
|
||||
RecordContainer.RemoveAllChildren();
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateRecordListing(Dictionary<StationRecordKey, string> listing, StationRecordKey? selected)
|
||||
{
|
||||
RecordListing.Clear();
|
||||
RecordListing.ClearSelected();
|
||||
|
||||
_isPopulating = true;
|
||||
|
||||
foreach (var (key, name) in listing)
|
||||
{
|
||||
var item = RecordListing.AddItem(name);
|
||||
item.Metadata = key;
|
||||
|
||||
if (selected != null && key.ID == selected.Value.ID)
|
||||
{
|
||||
item.Selected = true;
|
||||
@@ -131,4 +188,17 @@ public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
|
||||
RecordContainer.AddChild(control);
|
||||
}
|
||||
}
|
||||
|
||||
private void FilterListingOfRecords(string text = "")
|
||||
{
|
||||
if (!_isPopulating)
|
||||
{
|
||||
OnFiltersChanged?.Invoke(_currentFilterType, text);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetTypeFilterLocals(GeneralStationRecordFilterType type)
|
||||
{
|
||||
return Loc.GetString($"general-station-record-{type.ToString().ToLower()}-filter");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ namespace Content.Server.StationRecords;
|
||||
public sealed class GeneralStationRecordConsoleComponent : Component
|
||||
{
|
||||
public StationRecordKey? ActiveKey { get; set; }
|
||||
public GeneralStationRecordsFilter? Filter { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.StationRecords;
|
||||
using Robust.Server.GameObjects;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Server.StationRecords.Systems;
|
||||
|
||||
@@ -14,6 +15,7 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
|
||||
{
|
||||
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, BoundUIOpenedEvent>(UpdateUserInterface);
|
||||
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, SelectGeneralStationRecord>(OnKeySelected);
|
||||
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, GeneralStationRecordsFilterMsg>(OnFiltersChanged);
|
||||
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, RecordModifiedEvent>(UpdateUserInterface);
|
||||
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, AfterGeneralRecordCreatedEvent>(UpdateUserInterface);
|
||||
}
|
||||
@@ -30,7 +32,19 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
|
||||
private void UpdateUserInterface(EntityUid uid, GeneralStationRecordConsoleComponent? console = null)
|
||||
private void OnFiltersChanged(EntityUid uid,
|
||||
GeneralStationRecordConsoleComponent component, GeneralStationRecordsFilterMsg msg)
|
||||
{
|
||||
if (component.Filter == null ||
|
||||
component.Filter.Type != msg.Type || component.Filter.Value != msg.Value)
|
||||
{
|
||||
component.Filter = new GeneralStationRecordsFilter(msg.Type, msg.Value);
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateUserInterface(EntityUid uid,
|
||||
GeneralStationRecordConsoleComponent? console = null)
|
||||
{
|
||||
if (!Resolve(uid, ref console))
|
||||
{
|
||||
@@ -39,27 +53,39 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
|
||||
|
||||
var owningStation = _stationSystem.GetOwningStation(uid);
|
||||
|
||||
|
||||
|
||||
if (!TryComp<StationRecordsComponent>(owningStation, out var stationRecordsComponent))
|
||||
{
|
||||
_userInterface.GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)?.SetState(new GeneralStationRecordConsoleState(null, null, null));
|
||||
GeneralStationRecordConsoleState state = new(null, null, null, null);
|
||||
SetStateForInterface(uid, state);
|
||||
return;
|
||||
}
|
||||
|
||||
var enumerator = _stationRecordsSystem.GetRecordsOfType<GeneralStationRecord>(owningStation.Value, stationRecordsComponent);
|
||||
var consoleRecords =
|
||||
_stationRecordsSystem.GetRecordsOfType<GeneralStationRecord>(owningStation.Value, stationRecordsComponent);
|
||||
|
||||
var listing = new Dictionary<StationRecordKey, string>();
|
||||
foreach (var pair in enumerator)
|
||||
|
||||
foreach (var pair in consoleRecords)
|
||||
{
|
||||
if (console != null && console.Filter != null
|
||||
&& IsSkippedRecord(console.Filter, pair.Item2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
listing.Add(pair.Item1, pair.Item2.Name);
|
||||
}
|
||||
|
||||
if (listing.Count == 0)
|
||||
{
|
||||
_userInterface.GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)?.SetState(new GeneralStationRecordConsoleState(null, null, null));
|
||||
GeneralStationRecordConsoleState state = new(null, null, null, console.Filter);
|
||||
SetStateForInterface(uid, state);
|
||||
return;
|
||||
}
|
||||
else if (listing.Count == 1)
|
||||
{
|
||||
console.ActiveKey = listing.Keys.First();
|
||||
}
|
||||
|
||||
GeneralStationRecord? record = null;
|
||||
if (console.ActiveKey != null)
|
||||
@@ -68,8 +94,41 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
|
||||
stationRecordsComponent);
|
||||
}
|
||||
|
||||
GeneralStationRecordConsoleState newState = new(console.ActiveKey, record, listing, console.Filter);
|
||||
SetStateForInterface(uid, newState);
|
||||
}
|
||||
|
||||
private void SetStateForInterface(EntityUid uid, GeneralStationRecordConsoleState newState)
|
||||
{
|
||||
_userInterface
|
||||
.GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)?
|
||||
.SetState(new GeneralStationRecordConsoleState(console.ActiveKey, record, listing));
|
||||
.GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)
|
||||
?.SetState(newState);
|
||||
}
|
||||
|
||||
private bool IsSkippedRecord(GeneralStationRecordsFilter filter,
|
||||
GeneralStationRecord someRecord)
|
||||
{
|
||||
bool isFilter = filter.Value.Length > 0;
|
||||
string filterLowerCaseValue = "";
|
||||
|
||||
if (!isFilter)
|
||||
return false;
|
||||
|
||||
filterLowerCaseValue = filter.Value.ToLower();
|
||||
|
||||
return filter.Type switch
|
||||
{
|
||||
GeneralStationRecordFilterType.Name =>
|
||||
!someRecord.Name.ToLower().Contains(filterLowerCaseValue),
|
||||
GeneralStationRecordFilterType.Prints => someRecord.Fingerprint != null
|
||||
&& IsFilterWithSomeCodeValue(someRecord.Fingerprint, filterLowerCaseValue),
|
||||
GeneralStationRecordFilterType.DNA => someRecord.DNA != null
|
||||
&& IsFilterWithSomeCodeValue(someRecord.DNA, filterLowerCaseValue),
|
||||
};
|
||||
}
|
||||
|
||||
private bool IsFilterWithSomeCodeValue(string value, string filter)
|
||||
{
|
||||
return !value.ToLower().StartsWith(filter);
|
||||
}
|
||||
}
|
||||
|
||||
38
Content.Shared/StationRecords/GeneralStationRecordsFilter.cs
Normal file
38
Content.Shared/StationRecords/GeneralStationRecordsFilter.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.StationRecords;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class GeneralStationRecordsFilter
|
||||
{
|
||||
public GeneralStationRecordFilterType Type { get; set; }
|
||||
= GeneralStationRecordFilterType.Name;
|
||||
public string Value { get; set; } = "";
|
||||
public GeneralStationRecordsFilter(GeneralStationRecordFilterType filterType, string newValue = "")
|
||||
{
|
||||
Type = filterType;
|
||||
Value = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class GeneralStationRecordsFilterMsg : BoundUserInterfaceMessage
|
||||
{
|
||||
public string Value { get; }
|
||||
public GeneralStationRecordFilterType Type { get; }
|
||||
|
||||
public GeneralStationRecordsFilterMsg(GeneralStationRecordFilterType filterType,
|
||||
string filterValue)
|
||||
{
|
||||
Type = filterType;
|
||||
Value = filterValue;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum GeneralStationRecordFilterType : byte
|
||||
{
|
||||
Name,
|
||||
Prints,
|
||||
DNA,
|
||||
}
|
||||
@@ -20,6 +20,10 @@ public enum GeneralStationRecordConsoleKey : byte
|
||||
/// - SelectedKey non-null, Record non-null, RecordListing non-null
|
||||
/// - The selected key has a record tied to it, and the record has been sent.
|
||||
///
|
||||
/// - there is added new filters and so added new states
|
||||
/// -SelectedKey null, Record null, RecordListing null, filters non-null
|
||||
/// the station may have data, but they all did not pass through the filters
|
||||
///
|
||||
/// Other states are erroneous.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
@@ -31,15 +35,18 @@ public sealed class GeneralStationRecordConsoleState : BoundUserInterfaceState
|
||||
public StationRecordKey? SelectedKey { get; }
|
||||
public GeneralStationRecord? Record { get; }
|
||||
public Dictionary<StationRecordKey, string>? RecordListing { get; }
|
||||
|
||||
public GeneralStationRecordConsoleState(StationRecordKey? key, GeneralStationRecord? record, Dictionary<StationRecordKey, string>? recordListing)
|
||||
public GeneralStationRecordsFilter? Filter { get; }
|
||||
public GeneralStationRecordConsoleState(StationRecordKey? key, GeneralStationRecord? record,
|
||||
Dictionary<StationRecordKey, string>? recordListing, GeneralStationRecordsFilter? newFilter)
|
||||
{
|
||||
SelectedKey = key;
|
||||
Record = record;
|
||||
RecordListing = recordListing;
|
||||
Filter = newFilter;
|
||||
}
|
||||
|
||||
public bool IsEmpty() => SelectedKey == null && Record == null && RecordListing == null;
|
||||
public bool IsEmpty() => SelectedKey == null
|
||||
&& Record == null && RecordListing == null;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -9,3 +9,10 @@ general-station-record-console-record-species = Species: {$species}
|
||||
general-station-record-console-record-gender = Gender: {$gender}
|
||||
general-station-record-console-record-fingerprint = Fingerprint: {$fingerprint}
|
||||
general-station-record-console-record-dna = DNA: {$dna}
|
||||
|
||||
general-station-record-for-filter-line-placeholder = Input text and press "Enter"
|
||||
general-station-record-name-filter = Name of person
|
||||
general-station-record-prints-filter = Fingerprints
|
||||
general-station-record-dna-filter = DNA
|
||||
general-station-record-console-search-records = Search
|
||||
general-station-record-console-reset-filters = Reset
|
||||
Reference in New Issue
Block a user