Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[педальные раздатчики] настолько заебался что даже шутить уже не хочется #159

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
using Content.Client.UserInterface.Controls;
using Content.Shared._White.Event;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Content.Client._White.Event;

#pragma warning disable IDE1006 // i am going to fucking lose it

Spatison marked this conversation as resolved.
Show resolved Hide resolved
/// <summary>
/// Hopefully i never have to touch UI ever again.
/// Even if xaml thing was working for me, this would only be marginally less of a radioactive dump.
/// </summary>
public sealed class EventItemDispenserConfigBoundUserInterface : BoundUserInterface
{

[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;

static readonly Color Green = new Color(0, 255, 0);
static readonly Color Red = new Color(255, 0, 0);
static readonly Color Gray = new Color(127, 127, 127);

//EventItemDispenserConfigWindow? window; // Trying to work with robustengine's ui system makes me want to quote AM.
DefaultWindow window = default!;
EventItemDispenserComponent dispenserComp;
public EventItemDispenserConfigBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) {
IoCManager.InjectDependencies(this);
dispenserComp = _entMan.GetComponent<EventItemDispenserComponent>(Owner);
}



#region man-made horrors beyond your comprehension




#region all the controls
BoxContainer baseBox = default!;
BoxContainer optionBox = default!;
BoxContainer buttonBox = default!;
BoxContainer copypasteBox = default!;

LineEdit DispensingPrototypeLineEdit = default!;
bool DispensingPrototypeValid = false;
CheckBox AutoDisposeCheckBox = default!;
CheckBox CanManuallyDisposeCheckBox = default!;
CheckBox InfiniteCheckBox = default!;
LineEdit LimitLineEdit = default!;

CheckBox ReplaceDisposedItemsCheckBox = default!;
LineEdit DisposedReplacementPrototypeLineEdit = default!;
bool DisposedReplacementPrototypeValid = false;

CheckBox AutoCleanUpCheckBox = default!;

Button copyButton = default!;
Button pasteButton = default!;
Button confirmButton = default!;

//Button cancelButton = new(); // just hit the "x" 4head
#endregion

#region copypasta stuff
static string SavedDispensingPrototype = default!;
static bool SavedAutoDispose = default;
static bool SavedCanManuallyDispose = default;
static bool SavedInfinite = default;
static string SavedLimit = default!;
static bool SavedReplaceDisposedItems = default;
static string SavedDisposedReplacementPrototype = default!;
static bool SavedAutoCleanUp = default;

static bool saved = false;

Comment on lines +77 to +87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Избегайте использования статических переменных для хранения состояния UI

Использование статических полей для хранения состояния копирования и вставки настроек может привести к нежелательным эффектам в многопользовательской среде или при открытии нескольких экземпляров интерфейса. Рекомендуется использовать экземплярные поля или специальный класс для управления состоянием, чтобы обеспечить корректную работу интерфейса для всех пользователей.

private void CopySettings(EventArgs whatever)
{
saved = true;

SavedDispensingPrototype = DispensingPrototypeLineEdit.Text;
SavedAutoDispose = AutoDisposeCheckBox.Pressed;
SavedCanManuallyDispose = CanManuallyDisposeCheckBox.Pressed;
SavedInfinite = InfiniteCheckBox.Pressed;
SavedLimit = LimitLineEdit.Text;
SavedReplaceDisposedItems = ReplaceDisposedItemsCheckBox.Pressed;
SavedDisposedReplacementPrototype = DisposedReplacementPrototypeLineEdit.Text;
SavedAutoCleanUp = AutoCleanUpCheckBox.Pressed;

pasteButton.Disabled = false;
}

private void PasteSettings(EventArgs whatever)
{
DebugTools.Assert(saved);

DispensingPrototypeLineEdit.Text = SavedDispensingPrototype;
AutoDisposeCheckBox.Pressed = SavedAutoDispose;
CanManuallyDisposeCheckBox.Pressed = SavedCanManuallyDispose;
InfiniteCheckBox.Pressed = SavedInfinite;
LimitLineEdit.Text = SavedLimit;
ReplaceDisposedItemsCheckBox.Pressed = SavedReplaceDisposedItems;
DisposedReplacementPrototypeLineEdit.Text = SavedDisposedReplacementPrototype;
AutoCleanUpCheckBox.Pressed = SavedAutoCleanUp;

}
#endregion

private void InitializeControls(DefaultWindow window) // windows forms ahh method
{
baseBox = this.CreateDisposableControl<BoxContainer>();
baseBox.Orientation = BoxContainer.LayoutOrientation.Vertical;
baseBox.SeparationOverride = 4;
baseBox.Margin = new Thickness(4, 0);
baseBox.MinWidth = 450;
window.Contents.AddChild(baseBox);

optionBox = this.CreateDisposableControl<BoxContainer>();
optionBox.Orientation = BoxContainer.LayoutOrientation.Vertical;
baseBox.AddChild(optionBox);

buttonBox = this.CreateDisposableControl<BoxContainer>();
buttonBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
//buttonBox.Align = BoxContainer.AlignMode.End;
baseBox.AddChild(buttonBox);

copypasteBox = this.CreateDisposableControl<BoxContainer>();
//copypasteBox.HorizontalAlignment = Control.HAlignment.Left;
copypasteBox.HorizontalExpand = true;

copyButton = this.CreateDisposableControl<Button>();
copyButton.Label.Text = "Copy";
copyButton.OnPressed += CopySettings;
copypasteBox.AddChild(copyButton);

pasteButton = this.CreateDisposableControl<Button>();
pasteButton.Label.Text = "Paste";
pasteButton.OnPressed += PasteSettings;
pasteButton.Disabled = !saved;
copypasteBox.AddChild(pasteButton);

confirmButton = this.CreateDisposableControl<Button>();
confirmButton.Label.Text = "OK";
confirmButton.OnPressed += TrySubmit;
confirmButton.HorizontalAlignment = Control.HAlignment.Right;

buttonBox.AddChild(copypasteBox);
buttonBox.AddChild(confirmButton);

}

/// <summary>
/// I am not sorry.
/// </summary>
protected override void Open() // pure aids
Spatison marked this conversation as resolved.
Show resolved Hide resolved
{
base.Open(); // what's the fucking point?
window = this.CreateDisposableControl<DefaultWindow>();
window.Resizable = false;
window.OnClose += Close;
InitializeControls(window);

window.Title = _loc.GetString("eventitemdispenser-configwindow-title");
DispensingPrototypeLineEdit = AddOption<LineEdit>("eventitemdispenser-configwindow-dispensingprototype");
DispensingPrototypeLineEdit.MinWidth = 300;
DispensingPrototypeLineEdit.OnTextChanged += (args) => { DispensingPrototypeValid = ValidateProto(args); confirmButton!.Disabled = !DispensingPrototypeValid || !DisposedReplacementPrototypeValid; };
DispensingPrototypeLineEdit.OnTextEntered += TrySubmit;

AutoDisposeCheckBox = AddOption<CheckBox>("eventitemdispenser-configwindow-autodispose");
CanManuallyDisposeCheckBox = AddOption<CheckBox>("eventitemdispenser-configwindow-canmanuallydispose");

InfiniteCheckBox = AddOption<CheckBox>("eventitemdispenser-configwindow-infinite");
InfiniteCheckBox.OnPressed += (_) => {
AutoDisposeCheckBox.Disabled = !InfiniteCheckBox.Pressed;
AutoDisposeCheckBox.ModulateSelfOverride = AutoDisposeCheckBox.Disabled ? Gray : null;
};

LimitLineEdit = AddOption<LineEdit>("eventitemdispenser-configwindow-limit");
LimitLineEdit.IsValid = s => int.TryParse(s, out int _) && s.IndexOf('-') == -1; // no "_ > 0" because being able to input -0 makes me cringe
LimitLineEdit.MinWidth = 100;
LimitLineEdit.OnTextEntered += TrySubmit;

ReplaceDisposedItemsCheckBox = AddOption<CheckBox>("eventitemdispenser-configwindow-replacedisposeditems");

DisposedReplacementPrototypeLineEdit = AddOption<LineEdit>("eventitemdispenser-configwindow-disposedreplacement");
DisposedReplacementPrototypeLineEdit.MinWidth = 300;
DisposedReplacementPrototypeLineEdit.OnTextChanged += (args) => { DisposedReplacementPrototypeValid = ValidateProto(args); confirmButton!.Disabled = !DispensingPrototypeValid || !DisposedReplacementPrototypeValid; };
DisposedReplacementPrototypeLineEdit.OnTextEntered += TrySubmit;

AutoCleanUpCheckBox = AddOption<CheckBox>("eventitemdispenser-configwindow-autocleanup");

DispensingPrototypeLineEdit.SetText(dispenserComp.DispensingPrototype, true);
AutoDisposeCheckBox.Pressed = dispenserComp.AutoDispose;
CanManuallyDisposeCheckBox.Pressed = dispenserComp.CanManuallyDispose;
InfiniteCheckBox.Pressed = dispenserComp.Infinite;
LimitLineEdit.SetText(dispenserComp.Limit.ToString());
ReplaceDisposedItemsCheckBox.Pressed = dispenserComp.ReplaceDisposedItems;
DisposedReplacementPrototypeLineEdit.SetText(dispenserComp.DisposedReplacement, true);
AutoCleanUpCheckBox.Pressed = dispenserComp.AutoCleanUp;

AutoDisposeCheckBox.Disabled = !dispenserComp.Infinite;

window.OpenCentered();
}


private T AddOption<T>(string text) where T : Control, IDisposable, new()
{
var box = this.CreateDisposableControl<BoxContainer>();
box.HorizontalAlignment = Control.HAlignment.Stretch;
var label = this.CreateDisposableControl<Label>();
label.Text = _loc.GetString(text);
label.HorizontalExpand = true;
label.HorizontalAlignment = Label.HAlignment.Left;
box.AddChild(label);
var control = this.CreateDisposableControl<T>();
control.HorizontalAlignment = Control.HAlignment.Right;
control.ToolTip = _loc.GetString($"{text}-tooltip");
box.AddChild(control);
optionBox!.AddChild(box); // called after control init // i can't even remember what i meant by this, that's how bad it has got.
return control;
}
private bool ValidateProto(LineEdit.LineEditEventArgs args)
{
bool val = _proto.HasIndex(args.Text);
args.Control.ModulateSelfOverride = val ? Green : Red;
return val;
}

private void TrySubmit(EventArgs whatever)
{
if (!confirmButton.Disabled)
{
var msg = new EventItemDispenserNewConfigBoundUserInterfaceMessage()
{
DispensingPrototype = DispensingPrototypeLineEdit.Text,
AutoDispose = AutoDisposeCheckBox.Pressed,
CanManuallyDispose = CanManuallyDisposeCheckBox.Pressed,
Infinite = InfiniteCheckBox.Pressed,
Limit = int.Parse(LimitLineEdit.Text),
ReplaceDisposedItems = ReplaceDisposedItemsCheckBox.Pressed,
DisposedReplacement = DisposedReplacementPrototypeLineEdit.Text,
AutoCleanUp = AutoCleanUpCheckBox.Pressed
};
SendMessage(msg);
Close();
}
}

protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
base.ReceiveMessage(message);
if(message is EventItemDispenserNewProtoBoundUserInterfaceMessage { } msg)
{
DispensingPrototypeLineEdit.SetText(msg.DispensingPrototype);
}
}
#endregion
}
#pragma warning restore IDE1006
55 changes: 55 additions & 0 deletions Content.Client/_White/Event/EventItemDispenserSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Content.Shared._White.Event;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;

namespace Content.Client._White.Event;

public class EventItemDispenserSystem : SharedEventItemDispenserSystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;

public override void Initialize()
{
SubscribeLocalEvent<EventItemDispenserComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<EventItemDispenserComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);

}
RedFoxIV marked this conversation as resolved.
Show resolved Hide resolved

private void OnInit(EntityUid uid, EventItemDispenserComponent comp, ComponentInit args)
{
UpdateVisuals(uid, comp);
}
private void OnAfterAutoHandleState(EntityUid uid, EventItemDispenserComponent comp, AfterAutoHandleStateEvent args)
RedFoxIV marked this conversation as resolved.
Show resolved Hide resolved
{
UpdateVisuals(uid, comp);
}

private void UpdateVisuals(EntityUid uid, EventItemDispenserComponent comp)
{
var sprite = Comp<SpriteComponent>(uid);
var icon = _sprite.GetPrototypeIcon(comp.DispensingPrototype).Default;
sprite.LayerSetTexture(EventItemDispenserVisualLayers.ItemPreview, icon);
float scale = comp.ItemPreviewScale;

if (scale <= 0)
{
scale = 32f / Math.Max(15, Math.Max(icon.Width, icon.Height));
}
sprite.LayerSetScale(EventItemDispenserVisualLayers.ItemPreview, new Vector2(scale));
RedFoxIV marked this conversation as resolved.
Show resolved Hide resolved
}
}

enum EventItemDispenserVisualLayers : byte
{
Base,
Lights,
Arms,
ItemPreview
}
Loading
Loading