Merge branch 'master' into 2021-07-16/windoors
This commit is contained in:
@@ -8,6 +8,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.AI
|
namespace Content.Client.AI
|
||||||
{
|
{
|
||||||
@@ -169,8 +170,9 @@ namespace Content.Client.AI
|
|||||||
MouseFilter = Control.MouseFilterMode.Ignore,
|
MouseFilter = Control.MouseFilterMode.Ignore,
|
||||||
};
|
};
|
||||||
|
|
||||||
var vBox = new VBoxContainer()
|
var vBox = new BoxContainer()
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
SeparationOverride = 15,
|
SeparationOverride = 15,
|
||||||
Children = {actionLabel, pathfindingLabel},
|
Children = {actionLabel, pathfindingLabel},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Robust.Shared.GameObjects;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using static Content.Shared.AME.SharedAMEControllerComponent;
|
using static Content.Shared.AME.SharedAMEControllerComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.AME.UI
|
namespace Content.Client.AME.UI
|
||||||
{
|
{
|
||||||
@@ -30,58 +31,66 @@ namespace Content.Client.AME.UI
|
|||||||
|
|
||||||
MinSize = SetSize = (250, 250);
|
MinSize = SetSize = (250, 250);
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("ame-window-engine-status-label") + " "},
|
new Label {Text = Loc.GetString("ame-window-engine-status-label") + " "},
|
||||||
(InjectionStatus = new Label {Text = Loc.GetString("ame-window-engine-injection-status-not-injecting-label")})
|
(InjectionStatus = new Label {Text = Loc.GetString("ame-window-engine-injection-status-not-injecting-label")})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(ToggleInjection = new Button {Text = Loc.GetString("ame-window-toggle-injection-button"), StyleClasses = {StyleBase.ButtonOpenBoth}, Disabled = true}),
|
(ToggleInjection = new Button {Text = Loc.GetString("ame-window-toggle-injection-button"), StyleClasses = {StyleBase.ButtonOpenBoth}, Disabled = true}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("ame-window-fuel-status-label") + " "},
|
new Label {Text = Loc.GetString("ame-window-fuel-status-label") + " "},
|
||||||
(FuelAmount = new Label {Text = Loc.GetString("ame-window-fuel-not-inserted-text")})
|
(FuelAmount = new Label {Text = Loc.GetString("ame-window-fuel-not-inserted-text")})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(EjectButton = new Button {Text = Loc.GetString("ame-window-eject-button"), StyleClasses = {StyleBase.ButtonOpenBoth}, Disabled = true}),
|
(EjectButton = new Button {Text = Loc.GetString("ame-window-eject-button"), StyleClasses = {StyleBase.ButtonOpenBoth}, Disabled = true}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("ame-window-injection-amount-label") + " "},
|
new Label {Text = Loc.GetString("ame-window-injection-amount-label") + " "},
|
||||||
(InjectionAmount = new Label {Text = "0"})
|
(InjectionAmount = new Label {Text = "0"})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(IncreaseFuelButton = new Button {Text = Loc.GetString("ame-window-increase-fuel-button"), StyleClasses = {StyleBase.ButtonOpenRight}}),
|
(IncreaseFuelButton = new Button {Text = Loc.GetString("ame-window-increase-fuel-button"), StyleClasses = {StyleBase.ButtonOpenRight}}),
|
||||||
(DecreaseFuelButton = new Button {Text = Loc.GetString("ame-window-decrease-fuel-button"), StyleClasses = {StyleBase.ButtonOpenLeft}}),
|
(DecreaseFuelButton = new Button {Text = Loc.GetString("ame-window-decrease-fuel-button"), StyleClasses = {StyleBase.ButtonOpenLeft}}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label { Text = Loc.GetString("ame-window-core-count-label") + " "},
|
new Label { Text = Loc.GetString("ame-window-core-count-label") + " "},
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using static Content.Shared.Access.SharedIdCardConsoleComponent;
|
using static Content.Shared.Access.SharedIdCardConsoleComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Access.UI
|
namespace Content.Client.Access.UI
|
||||||
{
|
{
|
||||||
@@ -38,7 +39,10 @@ namespace Content.Client.Access.UI
|
|||||||
{
|
{
|
||||||
MinSize = SetSize = (650, 290);
|
MinSize = SetSize = (650, 290);
|
||||||
_owner = owner;
|
_owner = owner;
|
||||||
var vBox = new VBoxContainer();
|
var vBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
|
||||||
vBox.AddChild(new GridContainer
|
vBox.AddChild(new GridContainer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Actions.UI
|
namespace Content.Client.Actions.UI
|
||||||
{
|
{
|
||||||
@@ -28,8 +29,12 @@ namespace Content.Client.Actions.UI
|
|||||||
|
|
||||||
SetOnlyStyleClass(StyleNano.StyleClassTooltipPanel);
|
SetOnlyStyleClass(StyleNano.StyleClassTooltipPanel);
|
||||||
|
|
||||||
VBoxContainer vbox;
|
BoxContainer vbox;
|
||||||
AddChild(vbox = new VBoxContainer {RectClipContent = true});
|
AddChild(vbox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
|
RectClipContent = true
|
||||||
|
});
|
||||||
var nameLabel = new RichTextLabel
|
var nameLabel = new RichTextLabel
|
||||||
{
|
{
|
||||||
MaxWidth = TooltipTextMaxWidth,
|
MaxWidth = TooltipTextMaxWidth,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Actions.UI
|
namespace Content.Client.Actions.UI
|
||||||
{
|
{
|
||||||
@@ -71,12 +72,14 @@ namespace Content.Client.Actions.UI
|
|||||||
Title = Loc.GetString("ui-actionmenu-title");
|
Title = Loc.GetString("ui-actionmenu-title");
|
||||||
MinSize = (300, 300);
|
MinSize = (300, 300);
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(_searchBar = new LineEdit
|
(_searchBar = new LineEdit
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Actions.UI
|
namespace Content.Client.Actions.UI
|
||||||
{
|
{
|
||||||
@@ -174,8 +175,9 @@ namespace Content.Client.Actions.UI
|
|||||||
_cooldownGraphic = new CooldownGraphic {Progress = 0, Visible = false};
|
_cooldownGraphic = new CooldownGraphic {Progress = 0, Visible = false};
|
||||||
|
|
||||||
// padding to the left of the number to shift it right
|
// padding to the left of the number to shift it right
|
||||||
var paddingBox = new HBoxContainer()
|
var paddingBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
MinSize = (64, 64)
|
MinSize = (64, 64)
|
||||||
@@ -187,8 +189,9 @@ namespace Content.Client.Actions.UI
|
|||||||
paddingBox.AddChild(_number);
|
paddingBox.AddChild(_number);
|
||||||
|
|
||||||
// padding to the left of the small icon
|
// padding to the left of the small icon
|
||||||
var paddingBoxItemIcon = new HBoxContainer()
|
var paddingBoxItemIcon = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
MinSize = (64, 64)
|
MinSize = (64, 64)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Actions.UI
|
namespace Content.Client.Actions.UI
|
||||||
{
|
{
|
||||||
@@ -42,7 +43,7 @@ namespace Content.Client.Actions.UI
|
|||||||
private readonly Label _loadoutNumber;
|
private readonly Label _loadoutNumber;
|
||||||
private readonly Texture _lockTexture;
|
private readonly Texture _lockTexture;
|
||||||
private readonly Texture _unlockTexture;
|
private readonly Texture _unlockTexture;
|
||||||
private readonly HBoxContainer _loadoutContainer;
|
private readonly BoxContainer _loadoutContainer;
|
||||||
|
|
||||||
private readonly TextureRect _dragShadow;
|
private readonly TextureRect _dragShadow;
|
||||||
|
|
||||||
@@ -108,15 +109,17 @@ namespace Content.Client.Actions.UI
|
|||||||
};
|
};
|
||||||
AddChild(panelContainer);
|
AddChild(panelContainer);
|
||||||
|
|
||||||
var hotbarContainer = new VBoxContainer
|
var hotbarContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
SeparationOverride = 3,
|
SeparationOverride = 3,
|
||||||
HorizontalAlignment = HAlignment.Left
|
HorizontalAlignment = HAlignment.Left
|
||||||
};
|
};
|
||||||
panelContainer.AddChild(hotbarContainer);
|
panelContainer.AddChild(hotbarContainer);
|
||||||
|
|
||||||
var settingsContainer = new HBoxContainer
|
var settingsContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true
|
HorizontalExpand = true
|
||||||
};
|
};
|
||||||
hotbarContainer.AddChild(settingsContainer);
|
hotbarContainer.AddChild(settingsContainer);
|
||||||
@@ -156,8 +159,9 @@ namespace Content.Client.Actions.UI
|
|||||||
};
|
};
|
||||||
hotbarContainer.AddChild(_slotContainer);
|
hotbarContainer.AddChild(_slotContainer);
|
||||||
|
|
||||||
_loadoutContainer = new HBoxContainer
|
_loadoutContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
MouseFilter = MouseFilterMode.Stop
|
MouseFilter = MouseFilterMode.Stop
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Robust.Client.UserInterface.CustomControls;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI
|
namespace Content.Client.Administration.UI
|
||||||
{
|
{
|
||||||
@@ -65,8 +66,9 @@ namespace Content.Client.Administration.UI
|
|||||||
|
|
||||||
Title = Loc.GetString("admin-add-reagent-eui-title");
|
Title = Loc.GetString("admin-add-reagent-eui-title");
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new GridContainer
|
new GridContainer
|
||||||
@@ -88,8 +90,9 @@ namespace Content.Client.Administration.UI
|
|||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
VerticalExpand = true
|
VerticalExpand = true
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(_errorLabel = new Label
|
(_errorLabel = new Label
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Client.Administration.UI.Tabs;
|
using Content.Client.Administration.UI.Tabs;
|
||||||
using Content.Client.HUD;
|
using Content.Client.HUD;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Robust.Client.Console;
|
||||||
using Robust.Client.Console;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<VBoxContainer
|
<BoxContainer Orientation="Vertical"
|
||||||
xmlns="https://spacestation14.io">
|
xmlns="https://spacestation14.io">
|
||||||
<Control CustomMinimumSize="0 5" />
|
<Control CustomMinimumSize="0 5" />
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<!-- <Label Text="{Loc Search}" CustomMinimumSize="100 0" /> -->
|
<!-- <Label Text="{Loc Search}" CustomMinimumSize="100 0" /> -->
|
||||||
<!-- <Control CustomMinimumSize="50 0" /> -->
|
<!-- <Control CustomMinimumSize="50 0" /> -->
|
||||||
<LineEdit Name="FilterLineEdit" CustomMinimumSize="100 0" SizeFlagsHorizontal="FillExpand" PlaceHolder="{Loc Filter}"/>
|
<LineEdit Name="FilterLineEdit" CustomMinimumSize="100 0" SizeFlagsHorizontal="FillExpand" PlaceHolder="{Loc Filter}"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<!-- <Control CustomMinimumSize="0 5" /> -->
|
<!-- <Control CustomMinimumSize="0 5" /> -->
|
||||||
<ItemList
|
<ItemList
|
||||||
Name="PlayerItemList" SelectMode="Single" SizeFlagsVertical="FillExpand" SizeFlagsHorizontal="FillExpand"
|
Name="PlayerItemList" SelectMode="Single" SizeFlagsVertical="FillExpand" SizeFlagsHorizontal="FillExpand"
|
||||||
CustomMinimumSize="100 100" />
|
CustomMinimumSize="100 100" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System;
|
||||||
using System;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using static Content.Shared.Administration.PermissionsEuiMsg;
|
using static Content.Shared.Administration.PermissionsEuiMsg;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI
|
namespace Content.Client.Administration.UI
|
||||||
{
|
{
|
||||||
@@ -316,15 +317,17 @@ namespace Content.Client.Administration.UI
|
|||||||
};
|
};
|
||||||
|
|
||||||
AdminsList = new GridContainer {Columns = 5, VerticalExpand = true};
|
AdminsList = new GridContainer {Columns = 5, VerticalExpand = true};
|
||||||
var adminVBox = new VBoxContainer
|
var adminVBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children = {AdminsList, AddAdminButton},
|
Children = {AdminsList, AddAdminButton},
|
||||||
};
|
};
|
||||||
TabContainer.SetTabTitle(adminVBox, Loc.GetString("permissions-eui-menu-admins-tab-title"));
|
TabContainer.SetTabTitle(adminVBox, Loc.GetString("permissions-eui-menu-admins-tab-title"));
|
||||||
|
|
||||||
AdminRanksList = new GridContainer {Columns = 3};
|
AdminRanksList = new GridContainer {Columns = 3};
|
||||||
var rankVBox = new VBoxContainer
|
var rankVBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children = { AdminRanksList, AddAdminRankButton}
|
Children = { AdminRanksList, AddAdminRankButton}
|
||||||
};
|
};
|
||||||
TabContainer.SetTabTitle(rankVBox, Loc.GetString("permissions-eui-menu-admin-ranks-tab-title"));
|
TabContainer.SetTabTitle(rankVBox, Loc.GetString("permissions-eui-menu-admin-ranks-tab-title"));
|
||||||
@@ -451,7 +454,10 @@ namespace Content.Client.Administration.UI
|
|||||||
FlagButtons.Add(flag, (inherit, sub, plus));
|
FlagButtons.Add(flag, (inherit, sub, plus));
|
||||||
}
|
}
|
||||||
|
|
||||||
var bottomButtons = new HBoxContainer();
|
var bottomButtons = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
// show remove button.
|
// show remove button.
|
||||||
@@ -461,17 +467,20 @@ namespace Content.Client.Administration.UI
|
|||||||
|
|
||||||
bottomButtons.AddChild(SaveButton);
|
bottomButtons.AddChild(SaveButton);
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
SeparationOverride = 2,
|
SeparationOverride = 2,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -541,7 +550,10 @@ namespace Content.Client.Administration.UI
|
|||||||
HorizontalAlignment = HAlignment.Right,
|
HorizontalAlignment = HAlignment.Right,
|
||||||
HorizontalExpand = true
|
HorizontalExpand = true
|
||||||
};
|
};
|
||||||
var flagsBox = new VBoxContainer();
|
var flagsBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
|
||||||
foreach (var flag in AdminFlagsHelper.AllFlags)
|
foreach (var flag in AdminFlagsHelper.AllFlags)
|
||||||
{
|
{
|
||||||
@@ -565,7 +577,10 @@ namespace Content.Client.Administration.UI
|
|||||||
flagsBox.AddChild(checkBox);
|
flagsBox.AddChild(checkBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
var bottomButtons = new HBoxContainer();
|
var bottomButtons = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
// show remove button.
|
// show remove button.
|
||||||
@@ -575,8 +590,9 @@ namespace Content.Client.Administration.UI
|
|||||||
|
|
||||||
bottomButtons.AddChild(SaveButton);
|
bottomButtons.AddChild(SaveButton);
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
NameEdit,
|
NameEdit,
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<SS14Window
|
<SS14Window
|
||||||
xmlns="https://spacestation14.io">
|
xmlns="https://spacestation14.io">
|
||||||
<HBoxContainer HorizontalExpand="True">
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||||
<VBoxContainer HorizontalExpand="True" SizeFlagsStretchRatio="0.45">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.45">
|
||||||
<HBoxContainer HorizontalExpand="True" VerticalExpand="True"
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True"
|
||||||
SizeFlagsStretchRatio="0.1">
|
SizeFlagsStretchRatio="0.1">
|
||||||
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"
|
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"
|
||||||
SizeFlagsStretchRatio="0.6" />
|
SizeFlagsStretchRatio="0.6" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<ItemList Name="OutfitList" SelectMode="Single" VerticalExpand="True"
|
<ItemList Name="OutfitList" SelectMode="Single" VerticalExpand="True"
|
||||||
SizeFlagsStretchRatio="0.9" />
|
SizeFlagsStretchRatio="0.9" />
|
||||||
<Button Name="ConfirmButton" HorizontalExpand="True" />
|
<Button Name="ConfirmButton" HorizontalExpand="True" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
xmlns:at="clr-namespace:Content.Client.Administration.UI.Tabs.AdminTab"
|
xmlns:at="clr-namespace:Content.Client.Administration.UI.Tabs.AdminTab"
|
||||||
Margin="4"
|
Margin="4"
|
||||||
MinSize="50 50">
|
MinSize="50 50">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<GridContainer Columns="4">
|
<GridContainer Columns="4">
|
||||||
<cc:UICommandButton Command="kick" Text="{Loc Kick}" WindowType="{x:Type at:KickWindow}" />
|
<cc:UICommandButton Command="kick" Text="{Loc Kick}" WindowType="{x:Type at:KickWindow}" />
|
||||||
<cc:UICommandButton Command="ban" Text="{Loc Ban}" WindowType="{x:Type at:BanWindow}" />
|
<cc:UICommandButton Command="ban" Text="{Loc Ban}" WindowType="{x:Type at:BanWindow}" />
|
||||||
@@ -13,5 +13,5 @@
|
|||||||
<cc:UICommandButton Command="tpto" Text="{Loc Teleport}" WindowType="{x:Type at:TeleportWindow}" />
|
<cc:UICommandButton Command="tpto" Text="{Loc Teleport}" WindowType="{x:Type at:TeleportWindow}" />
|
||||||
<cc:CommandButton Command="permissions" Text="{Loc Permissions Panel}" />
|
<cc:CommandButton Command="permissions" Text="{Loc Permissions Panel}" />
|
||||||
</GridContainer>
|
</GridContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</Control>
|
</Control>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.AutoGenerated;
|
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Tabs.AdminTab
|
namespace Content.Client.Administration.UI.Tabs.AdminTab
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
<SS14Window
|
<SS14Window
|
||||||
xmlns="https://spacestation14.io"
|
xmlns="https://spacestation14.io"
|
||||||
Title="{Loc Ban}" MinSize="425 162">
|
Title="{Loc Ban}" MinSize="425 162">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Player}" MinWidth="100" />
|
<Label Text="{Loc Player}" MinWidth="100" />
|
||||||
<Control MinWidth="50" />
|
<Control MinWidth="50" />
|
||||||
<LineEdit Name="PlayerNameLine" MinWidth="100" HorizontalExpand="True" />
|
<LineEdit Name="PlayerNameLine" MinWidth="100" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Reason}" MinSize="100 0" />
|
<Label Text="{Loc Reason}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<LineEdit Name="ReasonLine" MinSize="100 0" HorizontalExpand="True" />
|
<LineEdit Name="ReasonLine" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Minutes}" MinWidth="100" />
|
<Label Text="{Loc Minutes}" MinWidth="100" />
|
||||||
<Control MinWidth="50" />
|
<Control MinWidth="50" />
|
||||||
<LineEdit Name="MinutesLine" MinWidth="100" HorizontalExpand="True" PlaceHolder="{Loc 0 minutes for a permanent ban}" />
|
<LineEdit Name="MinutesLine" MinWidth="100" HorizontalExpand="True" PlaceHolder="{Loc 0 minutes for a permanent ban}" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<Control MinWidth="50" />
|
<Control MinWidth="50" />
|
||||||
<Button Name="SubmitButton" Text="{Loc Ban}" />
|
<Button Name="SubmitButton" Text="{Loc Ban}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using JetBrains.Annotations;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
xmlns="https://spacestation14.io"
|
xmlns="https://spacestation14.io"
|
||||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||||
Title="{Loc Kick}" MinSize="425 272">
|
Title="{Loc Kick}" MinSize="425 272">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Reason}" MinWidth="100" />
|
<Label Text="{Loc Reason}" MinWidth="100" />
|
||||||
<Control MinWidth="50" />
|
<Control MinWidth="50" />
|
||||||
<LineEdit Name="ReasonLine" MinWidth="100" HorizontalExpand="True" />
|
<LineEdit Name="ReasonLine" MinWidth="100" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<cc:PlayerListControl Name="PlayerList" />
|
<cc:PlayerListControl Name="PlayerList" />
|
||||||
<Button Name="SubmitButton" Text="{Loc Kick}" />
|
<Button Name="SubmitButton" Text="{Loc Kick}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using JetBrains.Annotations;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
xmlns="https://spacestation14.io"
|
xmlns="https://spacestation14.io"
|
||||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||||
Title="{Loc Teleport}" MinSize="425 230">
|
Title="{Loc Teleport}" MinSize="425 230">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<cc:PlayerListControl Name="PlayerList" />
|
<cc:PlayerListControl Name="PlayerList" />
|
||||||
<Button Name="SubmitButton" Text="{Loc Teleport}" />
|
<Button Name="SubmitButton" Text="{Loc Teleport}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using JetBrains.Annotations;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Content.Client.Administration.Managers;
|
||||||
using Content.Client.Administration.Managers;
|
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Placement;
|
using Robust.Client.Placement;
|
||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
@@ -15,6 +14,9 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
|||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public partial class AdminbusTab : Control
|
public partial class AdminbusTab : Control
|
||||||
{
|
{
|
||||||
|
private EntitySpawnWindow? _entitySpawnWindow;
|
||||||
|
private TileSpawnWindow? _tileSpawnWindow;
|
||||||
|
|
||||||
protected override void EnteredTree()
|
protected override void EnteredTree()
|
||||||
{
|
{
|
||||||
// For the SpawnEntitiesButton and SpawnTilesButton we need to do the press manually
|
// For the SpawnEntitiesButton and SpawnTilesButton we need to do the press manually
|
||||||
@@ -23,22 +25,22 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
|||||||
SpawnTilesButton.OnPressed += SpawnTilesButtonOnOnPressed;
|
SpawnTilesButton.OnPressed += SpawnTilesButtonOnOnPressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SpawnEntitiesButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
|
private void SpawnEntitiesButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
|
||||||
{
|
{
|
||||||
var manager = IoCManager.Resolve<IAdminMenuManager>();
|
var manager = IoCManager.Resolve<IAdminMenuManager>();
|
||||||
var window = new EntitySpawnWindow(IoCManager.Resolve<IPlacementManager>(),
|
_entitySpawnWindow ??= new EntitySpawnWindow(IoCManager.Resolve<IPlacementManager>(),
|
||||||
IoCManager.Resolve<IPrototypeManager>(),
|
IoCManager.Resolve<IPrototypeManager>(),
|
||||||
IoCManager.Resolve<IResourceCache>());
|
IoCManager.Resolve<IResourceCache>());
|
||||||
manager.OpenCommand(window);
|
manager.OpenCommand(_entitySpawnWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SpawnTilesButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
|
private void SpawnTilesButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
|
||||||
{
|
{
|
||||||
var manager = IoCManager.Resolve<IAdminMenuManager>();
|
var manager = IoCManager.Resolve<IAdminMenuManager>();
|
||||||
var window = new TileSpawnWindow(IoCManager.Resolve<ITileDefinitionManager>(),
|
_tileSpawnWindow ??= new TileSpawnWindow(IoCManager.Resolve<ITileDefinitionManager>(),
|
||||||
IoCManager.Resolve<IPlacementManager>(),
|
IoCManager.Resolve<IPlacementManager>(),
|
||||||
IoCManager.Resolve<IResourceCache>());
|
IoCManager.Resolve<IResourceCache>());
|
||||||
manager.OpenCommand(window);
|
manager.OpenCommand(_tileSpawnWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<SS14Window
|
<SS14Window
|
||||||
xmlns="https://spacestation14.io" Title="Kick">
|
xmlns="https://spacestation14.io" Title="Kick">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Event}" MinSize="100 0" />
|
<Label Text="{Loc Event}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<OptionButton Name="EventsOptions" MinSize="100 0" HorizontalExpand="True" />
|
<OptionButton Name="EventsOptions" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<Button Name="PauseButton" Text="{Loc Pause}" />
|
<Button Name="PauseButton" Text="{Loc Pause}" />
|
||||||
<Button Name="ResumeButton" Text="{Loc Resume}" />
|
<Button Name="ResumeButton" Text="{Loc Resume}" />
|
||||||
<Button Name="SubmitButton" Text="{Loc Run}" />
|
<Button Name="SubmitButton" Text="{Loc Run}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.StationEvents.Managers;
|
using Content.Client.StationEvents.Managers;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<SS14Window
|
<SS14Window
|
||||||
xmlns="https://spacestation14.io" Title="{Loc Add Atmos}">
|
xmlns="https://spacestation14.io" Title="{Loc Add Atmos}">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Grid}" MinSize="100 0" />
|
<Label Text="{Loc Grid}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<Button Name="SubmitButton" Text="{Loc Add Atmos}" />
|
<Button Name="SubmitButton" Text="{Loc Add Atmos}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
<SS14Window
|
<SS14Window
|
||||||
xmlns="https://spacestation14.io" Title="{Loc Add Gas}">
|
xmlns="https://spacestation14.io" Title="{Loc Add Gas}">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Grid}" MinSize="100 0" />
|
<Label Text="{Loc Grid}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc TileX}" MinSize="100 0" />
|
<Label Text="{Loc TileX}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<SpinBox Name="TileXSpin" MinSize="100 0" HorizontalExpand="True" />
|
<SpinBox Name="TileXSpin" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc TileY}" MinSize="100 0" />
|
<Label Text="{Loc TileY}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<SpinBox Name="TileYSpin" MinSize="100 0" HorizontalExpand="True" />
|
<SpinBox Name="TileYSpin" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Gas}" MinSize="100 0" />
|
<Label Text="{Loc Gas}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<OptionButton Name="GasOptions" MinSize="100 0" HorizontalExpand="True" />
|
<OptionButton Name="GasOptions" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Amount}" MinSize="100 0" />
|
<Label Text="{Loc Amount}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<SpinBox Name="AmountSpin" MinSize="100 0" HorizontalExpand="True" />
|
<SpinBox Name="AmountSpin" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<Button Name="SubmitButton" Text="{Loc Add Gas}" />
|
<Button Name="SubmitButton" Text="{Loc Add Gas}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.Atmos.EntitySystems;
|
using Content.Client.Atmos.EntitySystems;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.AutoGenerated;
|
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Tabs.AtmosTab
|
namespace Content.Client.Administration.UI.Tabs.AtmosTab
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
<SS14Window
|
<SS14Window
|
||||||
xmlns="https://spacestation14.io" Title="{Loc Fill Gas}">
|
xmlns="https://spacestation14.io" Title="{Loc Fill Gas}">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Grid}" MinSize="100 0" />
|
<Label Text="{Loc Grid}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Gas}" MinSize="100 0" />
|
<Label Text="{Loc Gas}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<OptionButton Name="GasOptions" MinSize="100 0" HorizontalExpand="True" />
|
<OptionButton Name="GasOptions" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Amount}" MinSize="100 0" />
|
<Label Text="{Loc Amount}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<SpinBox Name="AmountSpin" MinSize="100 0" HorizontalExpand="True" />
|
<SpinBox Name="AmountSpin" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<Button Name="SubmitButton" Text="{Loc Fill Gas}" />
|
<Button Name="SubmitButton" Text="{Loc Fill Gas}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.Atmos.EntitySystems;
|
using Content.Client.Atmos.EntitySystems;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
<SS14Window
|
<SS14Window
|
||||||
xmlns="https://spacestation14.io" Title="{Loc Set Temperature}">
|
xmlns="https://spacestation14.io" Title="{Loc Set Temperature}">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Grid}" MinSize="100 0" />
|
<Label Text="{Loc Grid}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
<OptionButton Name="GridOptions" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc TileX}" MinSize="100 0" />
|
<Label Text="{Loc TileX}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<SpinBox Name="TileXSpin" MinSize="100 0" HorizontalExpand="True" />
|
<SpinBox Name="TileXSpin" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc TileY}" MinSize="100 0" />
|
<Label Text="{Loc TileY}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<SpinBox Name="TileYSpin" MinSize="100 0" HorizontalExpand="True" />
|
<SpinBox Name="TileYSpin" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc Temperature}" MinSize="100 0" />
|
<Label Text="{Loc Temperature}" MinSize="100 0" />
|
||||||
<Control MinSize="50 0" />
|
<Control MinSize="50 0" />
|
||||||
<SpinBox Name="TemperatureSpin" MinSize="100 0" HorizontalExpand="True" />
|
<SpinBox Name="TemperatureSpin" MinSize="100 0" HorizontalExpand="True" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<Button Name="SubmitButton" Text="{Loc Set Temperature}" />
|
<Button Name="SubmitButton" Text="{Loc Set Temperature}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<Control xmlns="https://spacestation14.io">
|
<Control xmlns="https://spacestation14.io">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Name="PlayerCount" HorizontalExpand="True" SizeFlagsStretchRatio="0.7"
|
<Label Name="PlayerCount" HorizontalExpand="True" SizeFlagsStretchRatio="0.7"
|
||||||
Text="{Loc Player Count}" />
|
Text="{Loc Player Count}" />
|
||||||
<Button Name="RefreshButton" HorizontalExpand="True" SizeFlagsStretchRatio="0.3"
|
<Button Name="RefreshButton" HorizontalExpand="True" SizeFlagsStretchRatio="0.3"
|
||||||
Text="{Loc Refresh}" />
|
Text="{Loc Refresh}" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<Control MinSize="0 5" />
|
<Control MinSize="0 5" />
|
||||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
|
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
|
||||||
<VBoxContainer Name="PlayerList" />
|
<BoxContainer Orientation="Vertical" Name="PlayerList" />
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</Control>
|
</Control>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Shared.Administration.Menu;
|
using Content.Shared.Administration.Menu;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
@@ -10,6 +9,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Tabs
|
namespace Content.Client.Administration.UI.Tabs
|
||||||
{
|
{
|
||||||
@@ -41,8 +41,9 @@ namespace Content.Client.Administration.UI.Tabs
|
|||||||
var altColor = Color.FromHex("#292B38");
|
var altColor = Color.FromHex("#292B38");
|
||||||
var defaultColor = Color.FromHex("#2F2F3B");
|
var defaultColor = Color.FromHex("#2F2F3B");
|
||||||
|
|
||||||
var header = new HBoxContainer
|
var header = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
SeparationOverride = 4,
|
SeparationOverride = 4,
|
||||||
Children =
|
Children =
|
||||||
@@ -85,8 +86,9 @@ namespace Content.Client.Administration.UI.Tabs
|
|||||||
var useAltColor = false;
|
var useAltColor = false;
|
||||||
foreach (var player in players)
|
foreach (var player in players)
|
||||||
{
|
{
|
||||||
var hBox = new HBoxContainer
|
var hBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
SeparationOverride = 4,
|
SeparationOverride = 4,
|
||||||
Children =
|
Children =
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.AutoGenerated;
|
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Tabs
|
namespace Content.Client.Administration.UI.Tabs
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.AutoGenerated;
|
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Tabs
|
namespace Content.Client.Administration.UI.Tabs
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace Content.Client.Alerts.UI
|
|||||||
base.EnteredTree();
|
base.EnteredTree();
|
||||||
var _chatManager = IoCManager.Resolve<IChatManager>();
|
var _chatManager = IoCManager.Resolve<IChatManager>();
|
||||||
_chatManager.OnChatBoxResized += OnChatResized;
|
_chatManager.OnChatBoxResized += OnChatResized;
|
||||||
OnChatResized(new ChatResizedEventArgs(ChatBox.InitialChatBottom));
|
OnChatResized(new ChatResizedEventArgs(HudChatBox.InitialChatBottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ExitedTree()
|
protected override void ExitedTree()
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Arcade
|
namespace Content.Client.Arcade
|
||||||
{
|
{
|
||||||
@@ -28,7 +29,7 @@ namespace Content.Client.Arcade
|
|||||||
|
|
||||||
private readonly PanelContainer _mainPanel;
|
private readonly PanelContainer _mainPanel;
|
||||||
|
|
||||||
private VBoxContainer _gameRootContainer;
|
private BoxContainer _gameRootContainer;
|
||||||
private GridContainer _gameGrid = default!;
|
private GridContainer _gameGrid = default!;
|
||||||
private GridContainer _nextBlockGrid = default!;
|
private GridContainer _nextBlockGrid = default!;
|
||||||
private GridContainer _holdBlockGrid = default!;
|
private GridContainer _holdBlockGrid = default!;
|
||||||
@@ -68,7 +69,10 @@ namespace Content.Client.Arcade
|
|||||||
|
|
||||||
#region Game Menu
|
#region Game Menu
|
||||||
// building the game container
|
// building the game container
|
||||||
_gameRootContainer = new VBoxContainer();
|
_gameRootContainer = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
|
||||||
_levelLabel = new Label
|
_levelLabel = new Label
|
||||||
{
|
{
|
||||||
@@ -92,7 +96,10 @@ namespace Content.Client.Arcade
|
|||||||
MinSize = new Vector2(1,10)
|
MinSize = new Vector2(1,10)
|
||||||
});
|
});
|
||||||
|
|
||||||
var gameBox = new HBoxContainer();
|
var gameBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
gameBox.AddChild(SetupHoldBox(backgroundTexture));
|
gameBox.AddChild(SetupHoldBox(backgroundTexture));
|
||||||
gameBox.AddChild(new Control
|
gameBox.AddChild(new Control
|
||||||
{
|
{
|
||||||
@@ -152,8 +159,9 @@ namespace Content.Client.Arcade
|
|||||||
|
|
||||||
_menuRootContainer.AddChild(pauseMenuInnerPanel);
|
_menuRootContainer.AddChild(pauseMenuInnerPanel);
|
||||||
|
|
||||||
var pauseMenuContainer = new VBoxContainer
|
var pauseMenuContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalAlignment = HAlignment.Center,
|
HorizontalAlignment = HAlignment.Center,
|
||||||
VerticalAlignment = VAlignment.Center
|
VerticalAlignment = VAlignment.Center
|
||||||
};
|
};
|
||||||
@@ -224,8 +232,9 @@ namespace Content.Client.Arcade
|
|||||||
|
|
||||||
_gameOverRootContainer.AddChild(gameOverMenuInnerPanel);
|
_gameOverRootContainer.AddChild(gameOverMenuInnerPanel);
|
||||||
|
|
||||||
var gameOverMenuContainer = new VBoxContainer
|
var gameOverMenuContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalAlignment = HAlignment.Center,
|
HorizontalAlignment = HAlignment.Center,
|
||||||
VerticalAlignment = VAlignment.Center
|
VerticalAlignment = VAlignment.Center
|
||||||
};
|
};
|
||||||
@@ -282,8 +291,9 @@ namespace Content.Client.Arcade
|
|||||||
|
|
||||||
_highscoresRootContainer.AddChild(menuInnerPanel);
|
_highscoresRootContainer.AddChild(menuInnerPanel);
|
||||||
|
|
||||||
var menuContainer = new VBoxContainer()
|
var menuContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalAlignment = HAlignment.Center,
|
HorizontalAlignment = HAlignment.Center,
|
||||||
VerticalAlignment = VAlignment.Center
|
VerticalAlignment = VAlignment.Center
|
||||||
};
|
};
|
||||||
@@ -291,7 +301,10 @@ namespace Content.Client.Arcade
|
|||||||
menuContainer.AddChild(new Label{Text = Loc.GetString("blockgame-menu-label-highscores")});
|
menuContainer.AddChild(new Label{Text = Loc.GetString("blockgame-menu-label-highscores")});
|
||||||
menuContainer.AddChild(new Control{MinSize = new Vector2(1,10)});
|
menuContainer.AddChild(new Control{MinSize = new Vector2(1,10)});
|
||||||
|
|
||||||
var highScoreBox = new HBoxContainer();
|
var highScoreBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
|
|
||||||
_localHighscoresLabel = new Label
|
_localHighscoresLabel = new Label
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Client.Atmos.Overlays;
|
using Content.Client.Atmos.Overlays;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Client.Atmos.Overlays;
|
using Content.Client.Atmos.Overlays;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent;
|
using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Atmos.UI
|
namespace Content.Client.Atmos.UI
|
||||||
{
|
{
|
||||||
@@ -61,11 +62,15 @@ namespace Content.Client.Atmos.UI
|
|||||||
LayoutContainer.SetAnchorPreset(bottomWrap, LayoutContainer.LayoutPreset.VerticalCenterWide);
|
LayoutContainer.SetAnchorPreset(bottomWrap, LayoutContainer.LayoutPreset.VerticalCenterWide);
|
||||||
LayoutContainer.SetGrowHorizontal(bottomWrap, LayoutContainer.GrowDirection.Both);
|
LayoutContainer.SetGrowHorizontal(bottomWrap, LayoutContainer.GrowDirection.Both);
|
||||||
|
|
||||||
var topContainerWrap = new VBoxContainer
|
var topContainerWrap = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(_topContainer = new VBoxContainer()),
|
(_topContainer = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
}),
|
||||||
new Control {MinSize = (0, 110)}
|
new Control {MinSize = (0, 110)}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -78,8 +83,9 @@ namespace Content.Client.Atmos.UI
|
|||||||
var fontSmall = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 10);
|
var fontSmall = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 10);
|
||||||
|
|
||||||
Button refreshButton;
|
Button refreshButton;
|
||||||
var topRow = new HBoxContainer
|
var topRow = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Margin = new Thickness(4, 4, 12, 2),
|
Margin = new Thickness(4, 4, 12, 2),
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -118,8 +124,9 @@ namespace Content.Client.Atmos.UI
|
|||||||
PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#202025") },
|
PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#202025") },
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(_statusContainer = new VBoxContainer
|
(_statusContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Margin = new Thickness(8, 8, 4, 4)
|
Margin = new Thickness(8, 8, 4, 4)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -178,10 +185,17 @@ namespace Content.Client.Atmos.UI
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Add a table with all the gases
|
// Add a table with all the gases
|
||||||
var tableKey = new VBoxContainer();
|
var tableKey = new BoxContainer
|
||||||
var tableVal = new VBoxContainer();
|
|
||||||
_statusContainer.AddChild(new HBoxContainer
|
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
var tableVal = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
_statusContainer.AddChild(new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
tableKey,
|
tableKey,
|
||||||
@@ -195,8 +209,9 @@ namespace Content.Client.Atmos.UI
|
|||||||
// This is the gas bar thingy
|
// This is the gas bar thingy
|
||||||
var height = 30;
|
var height = 30;
|
||||||
var minSize = 24; // This basically allows gases which are too small, to be shown properly
|
var minSize = 24; // This basically allows gases which are too small, to be shown properly
|
||||||
var gasBar = new HBoxContainer
|
var gasBar = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
MinSize = new Vector2(0, height)
|
MinSize = new Vector2(0, height)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,51 +2,51 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:s="clr-namespace:Content.Client.Stylesheets"
|
xmlns:s="clr-namespace:Content.Client.Stylesheets"
|
||||||
MinSize="480 400" Title="Canister">
|
MinSize="480 400" Title="Canister">
|
||||||
<VBoxContainer Margin="5 5 5 5" SeparationOverride="10">
|
<BoxContainer Orientation="Vertical" Margin="5 5 5 5" SeparationOverride="10">
|
||||||
<VBoxContainer VerticalExpand="True">
|
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-canister-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
|
<Label Text="{Loc comp-gas-canister-ui-canister-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-canister-pressure}"/>
|
<Label Text="{Loc comp-gas-canister-ui-canister-pressure}"/>
|
||||||
<Label Name="CanisterPressureLabel" Align="Center" HorizontalExpand="True"/>
|
<Label Name="CanisterPressureLabel" Align="Center" HorizontalExpand="True"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-port-status}"/>
|
<Label Text="{Loc comp-gas-canister-ui-port-status}"/>
|
||||||
<Label Name="PortStatusLabel" Align="Center" HorizontalExpand="True"/>
|
<Label Name="PortStatusLabel" Align="Center" HorizontalExpand="True"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
|
|
||||||
<VBoxContainer VerticalExpand="True">
|
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-holding-tank-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
|
<Label Text="{Loc comp-gas-canister-ui-holding-tank-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-holding-tank-label}"/>
|
<Label Text="{Loc comp-gas-canister-ui-holding-tank-label}"/>
|
||||||
<Label Name="TankLabelLabel" Text="{Loc comp-gas-canister-ui-holding-tank-label-empty}" Align="Center" HorizontalExpand="True"/>
|
<Label Name="TankLabelLabel" Text="{Loc comp-gas-canister-ui-holding-tank-label-empty}" Align="Center" HorizontalExpand="True"/>
|
||||||
<Button Name="TankEjectButton" Text="{Loc comp-gas-canister-ui-holding-tank-eject}"/>
|
<Button Name="TankEjectButton" Text="{Loc comp-gas-canister-ui-holding-tank-eject}"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-holding-tank-pressure}"/>
|
<Label Text="{Loc comp-gas-canister-ui-holding-tank-pressure}"/>
|
||||||
<Label Name="TankPressureLabel" Align="Center" HorizontalExpand="True"/>
|
<Label Name="TankPressureLabel" Align="Center" HorizontalExpand="True"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
|
|
||||||
<VBoxContainer VerticalExpand="True">
|
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-release-valve-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
|
<Label Text="{Loc comp-gas-canister-ui-release-valve-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-release-pressure}"/>
|
<Label Text="{Loc comp-gas-canister-ui-release-pressure}"/>
|
||||||
<Control VerticalExpand="True"/>
|
<Control VerticalExpand="True"/>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
<VBoxContainer HorizontalExpand="True" Margin="15 0 0 15" SeparationOverride="5">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="15 0 0 15" SeparationOverride="5">
|
||||||
<Slider Name="ReleasePressureSlider" HorizontalExpand="True"/>
|
<Slider Name="ReleasePressureSlider" HorizontalExpand="True"/>
|
||||||
<Label Name="ReleasePressureLabel" Align="Center" HorizontalExpand="True"/>
|
<Label Name="ReleasePressureLabel" Align="Center" HorizontalExpand="True"/>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc comp-gas-canister-ui-release-valve}"/>
|
<Label Text="{Loc comp-gas-canister-ui-release-valve}"/>
|
||||||
<Control HorizontalExpand="True"/>
|
<Control HorizontalExpand="True"/>
|
||||||
<Button Name="ReleaseValveOpenButton" Text="{Loc comp-gas-canister-ui-release-valve-open}" ToggleMode="True"/>
|
<Button Name="ReleaseValveOpenButton" Text="{Loc comp-gas-canister-ui-release-valve-open}" ToggleMode="True"/>
|
||||||
<Button Name="ReleaseValveCloseButton" Text="{Loc comp-gas-canister-ui-release-valve-close}" ToggleMode="True"/>
|
<Button Name="ReleaseValveCloseButton" Text="{Loc comp-gas-canister-ui-release-valve-close}" ToggleMode="True"/>
|
||||||
<Control HorizontalExpand="True"/>
|
<Control HorizontalExpand="True"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Content.Shared.Atmos.Piping;
|
using Content.Shared.Atmos.Piping;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using Content.Client.GameTicking.Managers;
|
using Content.Client.GameTicking.Managers;
|
||||||
using Content.Client.Lobby;
|
using Content.Client.Lobby;
|
||||||
using Content.Client.Viewport;
|
using Content.Client.Viewport;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Robust.Client.UserInterface.CustomControls;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
using static Robust.Client.UserInterface.Controls.ItemList;
|
using static Robust.Client.UserInterface.Controls.ItemList;
|
||||||
|
|
||||||
namespace Content.Client.Body.UI
|
namespace Content.Client.Body.UI
|
||||||
@@ -25,8 +26,9 @@ namespace Content.Client.Body.UI
|
|||||||
Owner = owner;
|
Owner = owner;
|
||||||
Title = Loc.GetString("body-scanner-display-title");
|
Title = Loc.GetString("body-scanner-display-title");
|
||||||
|
|
||||||
var hSplit = new HBoxContainer
|
var hSplit = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
// Left half
|
// Left half
|
||||||
@@ -39,20 +41,23 @@ namespace Content.Client.Body.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Right half
|
// Right half
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
// Top half of the right half
|
// Top half of the right half
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(BodyPartLabel = new Label()),
|
(BodyPartLabel = new Label()),
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label
|
new Label
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Body.UI
|
namespace Content.Client.Body.UI
|
||||||
{
|
{
|
||||||
@@ -12,7 +13,7 @@ namespace Content.Client.Body.UI
|
|||||||
{
|
{
|
||||||
public delegate void OptionSelectedCallback(int selectedOptionData);
|
public delegate void OptionSelectedCallback(int selectedOptionData);
|
||||||
|
|
||||||
private readonly VBoxContainer _optionsBox;
|
private readonly BoxContainer _optionsBox;
|
||||||
private OptionSelectedCallback? _optionSelectedCallback;
|
private OptionSelectedCallback? _optionSelectedCallback;
|
||||||
|
|
||||||
public SurgeryWindow()
|
public SurgeryWindow()
|
||||||
@@ -21,8 +22,9 @@ namespace Content.Client.Body.UI
|
|||||||
Title = Loc.GetString("surgery-window-title");
|
Title = Loc.GetString("surgery-window-title");
|
||||||
RectClipContent = true;
|
RectClipContent = true;
|
||||||
|
|
||||||
var vSplitContainer = new VBoxContainer
|
var vSplitContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new ScrollContainer
|
new ScrollContainer
|
||||||
@@ -33,8 +35,9 @@ namespace Content.Client.Body.UI
|
|||||||
VScrollEnabled = true,
|
VScrollEnabled = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(_optionsBox = new VBoxContainer
|
(_optionsBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true
|
HorizontalExpand = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -94,8 +97,9 @@ namespace Content.Client.Body.UI
|
|||||||
|
|
||||||
AddChild(Button);
|
AddChild(Button);
|
||||||
|
|
||||||
AddChild(new HBoxContainer
|
AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(SpriteView = new SpriteView
|
(SpriteView = new SpriteView
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Content.Shared.Buckle.Components;
|
||||||
using Content.Shared.Buckle.Components;
|
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Client.Stylesheets;
|
using Content.Client.Stylesheets;
|
||||||
@@ -11,6 +10,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Cargo.UI
|
namespace Content.Client.Cargo.UI
|
||||||
{
|
{
|
||||||
@@ -28,12 +28,12 @@ namespace Content.Client.Cargo.UI
|
|||||||
private Label _pointsLabel { get; set; }
|
private Label _pointsLabel { get; set; }
|
||||||
private Label _shuttleStatusLabel { get; set; }
|
private Label _shuttleStatusLabel { get; set; }
|
||||||
private Label _shuttleCapacityLabel { get; set; }
|
private Label _shuttleCapacityLabel { get; set; }
|
||||||
private VBoxContainer _requests { get; set; }
|
private BoxContainer _requests { get; set; }
|
||||||
private VBoxContainer _orders { get; set; }
|
private BoxContainer _orders { get; set; }
|
||||||
private OptionButton _categories { get; set; }
|
private OptionButton _categories { get; set; }
|
||||||
private LineEdit _searchBar { get; set; }
|
private LineEdit _searchBar { get; set; }
|
||||||
|
|
||||||
public VBoxContainer Products { get; set; }
|
public BoxContainer Products { get; set; }
|
||||||
public Button CallShuttleButton { get; set; }
|
public Button CallShuttleButton { get; set; }
|
||||||
public Button PermissionsButton { get; set; }
|
public Button PermissionsButton { get; set; }
|
||||||
|
|
||||||
@@ -50,9 +50,15 @@ namespace Content.Client.Cargo.UI
|
|||||||
else
|
else
|
||||||
Title = Loc.GetString("cargo-console-menu-title");
|
Title = Loc.GetString("cargo-console-menu-title");
|
||||||
|
|
||||||
var rows = new VBoxContainer();
|
var rows = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
|
||||||
var accountName = new HBoxContainer();
|
var accountName = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
var accountNameLabel = new Label {
|
var accountNameLabel = new Label {
|
||||||
Text = Loc.GetString("cargo-console-menu-account-name-label") + " ",
|
Text = Loc.GetString("cargo-console-menu-account-name-label") + " ",
|
||||||
StyleClasses = { StyleNano.StyleClassLabelKeyText }
|
StyleClasses = { StyleNano.StyleClassLabelKeyText }
|
||||||
@@ -64,7 +70,10 @@ namespace Content.Client.Cargo.UI
|
|||||||
accountName.AddChild(_accountNameLabel);
|
accountName.AddChild(_accountNameLabel);
|
||||||
rows.AddChild(accountName);
|
rows.AddChild(accountName);
|
||||||
|
|
||||||
var points = new HBoxContainer();
|
var points = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
var pointsLabel = new Label
|
var pointsLabel = new Label
|
||||||
{
|
{
|
||||||
Text = Loc.GetString("cargo-console-menu-points-label") + " ",
|
Text = Loc.GetString("cargo-console-menu-points-label") + " ",
|
||||||
@@ -78,7 +87,10 @@ namespace Content.Client.Cargo.UI
|
|||||||
points.AddChild(_pointsLabel);
|
points.AddChild(_pointsLabel);
|
||||||
rows.AddChild(points);
|
rows.AddChild(points);
|
||||||
|
|
||||||
var shuttleStatus = new HBoxContainer();
|
var shuttleStatus = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
var shuttleStatusLabel = new Label
|
var shuttleStatusLabel = new Label
|
||||||
{
|
{
|
||||||
Text = Loc.GetString("cargo-console-menu-shuttle-status-label") + " ",
|
Text = Loc.GetString("cargo-console-menu-shuttle-status-label") + " ",
|
||||||
@@ -92,7 +104,10 @@ namespace Content.Client.Cargo.UI
|
|||||||
shuttleStatus.AddChild(_shuttleStatusLabel);
|
shuttleStatus.AddChild(_shuttleStatusLabel);
|
||||||
rows.AddChild(shuttleStatus);
|
rows.AddChild(shuttleStatus);
|
||||||
|
|
||||||
var shuttleCapacity = new HBoxContainer();
|
var shuttleCapacity = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
var shuttleCapacityLabel = new Label
|
var shuttleCapacityLabel = new Label
|
||||||
{
|
{
|
||||||
Text = Loc.GetString("cargo-console-menu-order-capacity-label") + " ",
|
Text = Loc.GetString("cargo-console-menu-order-capacity-label") + " ",
|
||||||
@@ -106,7 +121,10 @@ namespace Content.Client.Cargo.UI
|
|||||||
shuttleCapacity.AddChild(_shuttleCapacityLabel);
|
shuttleCapacity.AddChild(_shuttleCapacityLabel);
|
||||||
rows.AddChild(shuttleCapacity);
|
rows.AddChild(shuttleCapacity);
|
||||||
|
|
||||||
var buttons = new HBoxContainer();
|
var buttons = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
CallShuttleButton = new Button()
|
CallShuttleButton = new Button()
|
||||||
{
|
{
|
||||||
//Text = Loc.GetString("Call Shuttle"),
|
//Text = Loc.GetString("Call Shuttle"),
|
||||||
@@ -123,7 +141,10 @@ namespace Content.Client.Cargo.UI
|
|||||||
buttons.AddChild(PermissionsButton);
|
buttons.AddChild(PermissionsButton);
|
||||||
rows.AddChild(buttons);
|
rows.AddChild(buttons);
|
||||||
|
|
||||||
var category = new HBoxContainer();
|
var category = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
_categories = new OptionButton
|
_categories = new OptionButton
|
||||||
{
|
{
|
||||||
Prefix = Loc.GetString("cargo-console-menu-categories-label") + " ",
|
Prefix = Loc.GetString("cargo-console-menu-categories-label") + " ",
|
||||||
@@ -146,8 +167,9 @@ namespace Content.Client.Cargo.UI
|
|||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
SizeFlagsStretchRatio = 6
|
SizeFlagsStretchRatio = 6
|
||||||
};
|
};
|
||||||
Products = new VBoxContainer()
|
Products = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
VerticalExpand = true
|
VerticalExpand = true
|
||||||
};
|
};
|
||||||
@@ -164,17 +186,22 @@ namespace Content.Client.Cargo.UI
|
|||||||
{
|
{
|
||||||
VerticalExpand = true
|
VerticalExpand = true
|
||||||
};
|
};
|
||||||
var rAndOVBox = new VBoxContainer();
|
var rAndOVBox = new BoxContainer
|
||||||
var requestsLabel = new Label { Text = Loc.GetString("cargo-console-menu-requests-label") };
|
|
||||||
_requests = new VBoxContainer // replace with scroll box so that approval buttons can be added
|
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
var requestsLabel = new Label { Text = Loc.GetString("cargo-console-menu-requests-label") };
|
||||||
|
_requests = new BoxContainer // replace with scroll box so that approval buttons can be added
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
StyleClasses = { "transparentItemList" },
|
StyleClasses = { "transparentItemList" },
|
||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
SizeFlagsStretchRatio = 1,
|
SizeFlagsStretchRatio = 1,
|
||||||
};
|
};
|
||||||
var ordersLabel = new Label { Text = Loc.GetString("cargo-console-menu-orders-label") };
|
var ordersLabel = new Label { Text = Loc.GetString("cargo-console-menu-orders-label") };
|
||||||
_orders = new VBoxContainer
|
_orders = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
StyleClasses = { "transparentItemList" },
|
StyleClasses = { "transparentItemList" },
|
||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
SizeFlagsStretchRatio = 1,
|
SizeFlagsStretchRatio = 1,
|
||||||
@@ -386,8 +413,9 @@ namespace Content.Client.Cargo.UI
|
|||||||
};
|
};
|
||||||
AddChild(MainButton);
|
AddChild(MainButton);
|
||||||
|
|
||||||
var hBox = new HBoxContainer
|
var hBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true
|
HorizontalExpand = true
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -433,8 +461,9 @@ namespace Content.Client.Cargo.UI
|
|||||||
{
|
{
|
||||||
HorizontalExpand = true;
|
HorizontalExpand = true;
|
||||||
|
|
||||||
var hBox = new HBoxContainer
|
var hBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -445,8 +474,9 @@ namespace Content.Client.Cargo.UI
|
|||||||
};
|
};
|
||||||
hBox.AddChild(Icon);
|
hBox.AddChild(Icon);
|
||||||
|
|
||||||
var vBox = new VBoxContainer
|
var vBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
VerticalExpand = true
|
VerticalExpand = true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Cargo.UI
|
namespace Content.Client.Cargo.UI
|
||||||
{
|
{
|
||||||
@@ -19,7 +20,10 @@ namespace Content.Client.Cargo.UI
|
|||||||
|
|
||||||
Title = Loc.GetString("cargo-console-order-menu-title");
|
Title = Loc.GetString("cargo-console-order-menu-title");
|
||||||
|
|
||||||
var vBox = new VBoxContainer();
|
var vBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
var gridContainer = new GridContainer { Columns = 2 };
|
var gridContainer = new GridContainer { Columns = 2 };
|
||||||
|
|
||||||
var requesterLabel = new Label { Text = Loc.GetString("cargo-console-order-menu-requester-label") };
|
var requesterLabel = new Label { Text = Loc.GetString("cargo-console-order-menu-requester-label") };
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ using Robust.Shared.Serialization.Markdown;
|
|||||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
namespace Content.Client.Changelog
|
namespace Content.Client.Changelog
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,20 +3,20 @@
|
|||||||
xmlns:ui="clr-namespace:Content.Client.HUD.UI"
|
xmlns:ui="clr-namespace:Content.Client.HUD.UI"
|
||||||
MinSize="500 400" MouseFilter="Stop">
|
MinSize="500 400" MouseFilter="Stop">
|
||||||
<PanelContainer StyleClasses="AngleRect" />
|
<PanelContainer StyleClasses="AngleRect" />
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<HBoxContainer>
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Margin="6 0 0 0" HorizontalExpand="True" Text="{Loc 'changelog-window-title'}" VAlign="Center"
|
<Label Margin="6 0 0 0" HorizontalExpand="True" Text="{Loc 'changelog-window-title'}" VAlign="Center"
|
||||||
StyleClasses="LabelHeading" />
|
StyleClasses="LabelHeading" />
|
||||||
<TextureButton Margin="0 0 8 0" Name="CloseButton" StyleClasses="windowCloseButton"
|
<TextureButton Margin="0 0 8 0" Name="CloseButton" StyleClasses="windowCloseButton"
|
||||||
VerticalAlignment="Center" />
|
VerticalAlignment="Center" />
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<ui:HighDivider />
|
<ui:HighDivider />
|
||||||
|
|
||||||
<ScrollContainer VerticalExpand="True" HScrollEnabled="False">
|
<ScrollContainer VerticalExpand="True" HScrollEnabled="False">
|
||||||
<VBoxContainer Name="ChangelogBody" />
|
<BoxContainer Orientation="Vertical" Name="ChangelogBody" />
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
|
|
||||||
<PanelContainer StyleClasses="LowDivider" />
|
<PanelContainer StyleClasses="LowDivider" />
|
||||||
<Label Name="VersionLabel" HorizontalAlignment="Right" StyleClasses="LabelSubText" Margin="4 0" />
|
<Label Name="VersionLabel" HorizontalAlignment="Right" StyleClasses="LabelSubText" Margin="4 0" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</changelog:ChangelogWindow>
|
</changelog:ChangelogWindow>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using static Content.Client.Changelog.ChangelogManager;
|
using static Content.Client.Changelog.ChangelogManager;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Changelog
|
namespace Content.Client.Changelog
|
||||||
{
|
{
|
||||||
@@ -94,10 +95,14 @@ namespace Content.Client.Changelog
|
|||||||
var upArrow =
|
var upArrow =
|
||||||
_resourceCache.GetTexture("/Textures/Interface/Changelog/up_arrow.svg.192dpi.png");
|
_resourceCache.GetTexture("/Textures/Interface/Changelog/up_arrow.svg.192dpi.png");
|
||||||
|
|
||||||
var readDivider = new VBoxContainer();
|
var readDivider = new BoxContainer
|
||||||
|
|
||||||
var hBox = new HBoxContainer
|
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
|
|
||||||
|
var hBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalAlignment = HAlignment.Center,
|
HorizontalAlignment = HAlignment.Center,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -148,8 +153,9 @@ namespace Content.Client.Changelog
|
|||||||
{
|
{
|
||||||
var text = new RichTextLabel();
|
var text = new RichTextLabel();
|
||||||
text.SetMessage(FormattedMessage.FromMarkup(change.Message));
|
text.SetMessage(FormattedMessage.FromMarkup(change.Message));
|
||||||
ChangelogBody.AddChild(new HBoxContainer
|
ChangelogBody.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Margin = new Thickness(14, 1, 10, 2),
|
Margin = new Thickness(14, 1, 10, 2),
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using static Content.Shared.CharacterAppearance.Components.SharedMagicMirrorComponent;
|
using static Content.Shared.CharacterAppearance.Components.SharedMagicMirrorComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.CharacterAppearance
|
namespace Content.Client.CharacterAppearance
|
||||||
{
|
{
|
||||||
@@ -107,8 +108,9 @@ namespace Content.Client.CharacterAppearance
|
|||||||
MinSize = (50, 0)
|
MinSize = (50, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
AddChild(new HBoxContainer
|
AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
_slider,
|
_slider,
|
||||||
@@ -204,10 +206,16 @@ namespace Content.Client.CharacterAppearance
|
|||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
var vBox = new VBoxContainer();
|
var vBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
AddChild(vBox);
|
AddChild(vBox);
|
||||||
|
|
||||||
_colorContainer = new VBoxContainer();
|
_colorContainer = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
vBox.AddChild(_colorContainer);
|
vBox.AddChild(_colorContainer);
|
||||||
_colorContainer.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
|
_colorContainer.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
|
||||||
_colorContainer.AddChild(_colorSliderG = new ColorSlider(StyleNano.StyleClassSliderGreen));
|
_colorContainer.AddChild(_colorSliderG = new ColorSlider(StyleNano.StyleClassSliderGreen));
|
||||||
@@ -289,7 +297,10 @@ namespace Content.Client.CharacterAppearance
|
|||||||
|
|
||||||
public EyeColorPicker()
|
public EyeColorPicker()
|
||||||
{
|
{
|
||||||
var vBox = new VBoxContainer();
|
var vBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
AddChild(vBox);
|
AddChild(vBox);
|
||||||
|
|
||||||
vBox.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
|
vBox.AddChild(_colorSliderR = new ColorSlider(StyleNano.StyleClassSliderRed));
|
||||||
@@ -340,8 +351,9 @@ namespace Content.Client.CharacterAppearance
|
|||||||
_eyeColorPicker = new EyeColorPicker {SizeFlagsHorizontal = SizeFlags.FillExpand};
|
_eyeColorPicker = new EyeColorPicker {SizeFlagsHorizontal = SizeFlags.FillExpand};
|
||||||
_eyeColorPicker.OnEyeColorPicked += newColor => owner.EyeColorSelected(newColor);
|
_eyeColorPicker.OnEyeColorPicked += newColor => owner.EyeColorSelected(newColor);
|
||||||
|
|
||||||
Contents.AddChild(new HBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
SeparationOverride = 8,
|
SeparationOverride = 8,
|
||||||
Children = {_hairStylePicker, _facialHairStylePicker, _eyeColorPicker}
|
Children = {_hairStylePicker, _facialHairStylePicker, _eyeColorPicker}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -62,19 +62,21 @@ namespace Content.Client.CharacterInfo.Components
|
|||||||
public Label NameLabel { get; }
|
public Label NameLabel { get; }
|
||||||
public Label SubText { get; }
|
public Label SubText { get; }
|
||||||
|
|
||||||
public VBoxContainer ObjectivesContainer { get; }
|
public BoxContainer ObjectivesContainer { get; }
|
||||||
|
|
||||||
public CharacterInfoControl(IResourceCache resourceCache)
|
public CharacterInfoControl(IResourceCache resourceCache)
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
AddChild(new HBoxContainer
|
AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(SpriteView = new SpriteView { Scale = (2, 2)}),
|
(SpriteView = new SpriteView { Scale = (2, 2)}),
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
VerticalAlignment = VAlignment.Top,
|
VerticalAlignment = VAlignment.Top,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -100,7 +102,10 @@ namespace Content.Client.CharacterInfo.Components
|
|||||||
Text = Loc.GetString("character-info-objectives-label"),
|
Text = Loc.GetString("character-info-objectives-label"),
|
||||||
HorizontalAlignment = HAlignment.Center
|
HorizontalAlignment = HAlignment.Center
|
||||||
});
|
});
|
||||||
ObjectivesContainer = new VBoxContainer();
|
ObjectivesContainer = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
AddChild(ObjectivesContainer);
|
AddChild(ObjectivesContainer);
|
||||||
|
|
||||||
AddChild(new Placeholder()
|
AddChild(new Placeholder()
|
||||||
@@ -116,8 +121,9 @@ namespace Content.Client.CharacterInfo.Components
|
|||||||
ObjectivesContainer.RemoveAllChildren();
|
ObjectivesContainer.RemoveAllChildren();
|
||||||
foreach (var (groupId, objectiveConditions) in characterInfoMessage.Objectives)
|
foreach (var (groupId, objectiveConditions) in characterInfoMessage.Objectives)
|
||||||
{
|
{
|
||||||
var vbox = new VBoxContainer
|
var vbox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Modulate = Color.Gray
|
Modulate = Color.Gray
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,7 +135,10 @@ namespace Content.Client.CharacterInfo.Components
|
|||||||
|
|
||||||
foreach (var objectiveCondition in objectiveConditions)
|
foreach (var objectiveCondition in objectiveConditions)
|
||||||
{
|
{
|
||||||
var hbox = new HBoxContainer();
|
var hbox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
hbox.AddChild(new ProgressTextureRect
|
hbox.AddChild(new ProgressTextureRect
|
||||||
{
|
{
|
||||||
Texture = objectiveCondition.SpriteSpecifier.Frame0(),
|
Texture = objectiveCondition.SpriteSpecifier.Frame0(),
|
||||||
@@ -140,8 +149,9 @@ namespace Content.Client.CharacterInfo.Components
|
|||||||
{
|
{
|
||||||
MinSize = (10,0)
|
MinSize = (10,0)
|
||||||
});
|
});
|
||||||
hbox.AddChild(new VBoxContainer
|
hbox.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label{Text = objectiveCondition.Title},
|
new Label{Text = objectiveCondition.Title},
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.CharacterInterface
|
namespace Content.Client.CharacterInterface
|
||||||
{
|
{
|
||||||
@@ -110,14 +111,17 @@ namespace Content.Client.CharacterInterface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CharacterWindow : SS14Window
|
public class CharacterWindow : SS14Window
|
||||||
{
|
{
|
||||||
private readonly VBoxContainer _contentsVBox;
|
private readonly BoxContainer _contentsVBox;
|
||||||
private readonly List<ICharacterUI> _windowComponents;
|
private readonly List<ICharacterUI> _windowComponents;
|
||||||
|
|
||||||
public CharacterWindow(List<ICharacterUI> windowComponents)
|
public CharacterWindow(List<ICharacterUI> windowComponents)
|
||||||
{
|
{
|
||||||
Title = "Character";
|
Title = "Character";
|
||||||
|
|
||||||
_contentsVBox = new VBoxContainer();
|
_contentsVBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
Contents.AddChild(_contentsVBox);
|
Contents.AddChild(_contentsVBox);
|
||||||
|
|
||||||
windowComponents.Sort((a, b) => ((int) a.Priority).CompareTo((int) b.Priority));
|
windowComponents.Sort((a, b) => ((int) a.Priority).CompareTo((int) b.Priority));
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Content.Client.Chat
|
|||||||
ChatChannel.Radio => Color.Green,
|
ChatChannel.Radio => Color.Green,
|
||||||
ChatChannel.OOC => Color.LightSkyBlue,
|
ChatChannel.OOC => Color.LightSkyBlue,
|
||||||
ChatChannel.Dead => Color.MediumPurple,
|
ChatChannel.Dead => Color.MediumPurple,
|
||||||
ChatChannel.AdminChat => Color.Red,
|
ChatChannel.Admin => Color.Red,
|
||||||
_ => Color.DarkGray
|
_ => Color.DarkGray
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
42
Content.Client/Chat/ChatInput.cs
Normal file
42
Content.Client/Chat/ChatInput.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using Content.Client.Chat.UI;
|
||||||
|
using Content.Client.Viewport;
|
||||||
|
using Content.Shared.Chat;
|
||||||
|
using Content.Shared.Input;
|
||||||
|
using Robust.Client.Input;
|
||||||
|
using Robust.Shared.Input.Binding;
|
||||||
|
|
||||||
|
namespace Content.Client.Chat
|
||||||
|
{
|
||||||
|
public static class ChatInput
|
||||||
|
{
|
||||||
|
public static void SetupChatInputHandlers(IInputManager inputManager, ChatBox chatBox)
|
||||||
|
{
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.FocusChat,
|
||||||
|
InputCmdHandler.FromDelegate(_ => GameScreen.FocusChat(chatBox)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.FocusLocalChat,
|
||||||
|
InputCmdHandler.FromDelegate(_ => GameScreen.FocusChannel(chatBox, ChatSelectChannel.Local)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.FocusOOC,
|
||||||
|
InputCmdHandler.FromDelegate(_ => GameScreen.FocusChannel(chatBox, ChatSelectChannel.OOC)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.FocusAdminChat,
|
||||||
|
InputCmdHandler.FromDelegate(_ => GameScreen.FocusChannel(chatBox, ChatSelectChannel.Admin)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.FocusRadio,
|
||||||
|
InputCmdHandler.FromDelegate(_ => GameScreen.FocusChannel(chatBox, ChatSelectChannel.Radio)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.FocusDeadChat,
|
||||||
|
InputCmdHandler.FromDelegate(_ => GameScreen.FocusChannel(chatBox, ChatSelectChannel.Dead)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.FocusConsoleChat,
|
||||||
|
InputCmdHandler.FromDelegate(_ => GameScreen.FocusChannel(chatBox, ChatSelectChannel.Console)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.CycleChatChannelForward,
|
||||||
|
InputCmdHandler.FromDelegate(_ => chatBox.CycleChatChannel(true)));
|
||||||
|
|
||||||
|
inputManager.SetInputCommand(ContentKeyFunctions.CycleChatChannelBackward,
|
||||||
|
InputCmdHandler.FromDelegate(_ => chatBox.CycleChatChannel(false)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Content.Client.Administration.Managers;
|
using Content.Client.Administration.Managers;
|
||||||
using Content.Client.Chat.UI;
|
using Content.Client.Chat.UI;
|
||||||
using Content.Client.Ghost;
|
using Content.Client.Ghost;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Chat;
|
using Content.Shared.Chat;
|
||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -52,23 +53,17 @@ namespace Content.Client.Chat.Managers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The max amount of characters an entity can send in one message
|
/// The max amount of characters an entity can send in one message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private int _maxMessageLength = 1000;
|
public int MaxMessageLength => _cfg.GetCVar(CCVars.ChatMaxMessageLength);
|
||||||
|
|
||||||
public const char ConCmdSlash = '/';
|
private readonly List<StoredChatMessage> _history = new();
|
||||||
public const char OOCAlias = '[';
|
public IReadOnlyList<StoredChatMessage> History => _history;
|
||||||
public const char MeAlias = '@';
|
|
||||||
public const char AdminChatAlias = ']';
|
|
||||||
public const char RadioAlias = ';';
|
|
||||||
|
|
||||||
private readonly List<StoredChatMessage> _filteredHistory = new();
|
// currently enabled channel filters set by the user.
|
||||||
|
// All values default to on, even if they aren't a filterable chat channel currently.
|
||||||
// currently enabled channel filters set by the user. If an entry is not in this
|
|
||||||
// list it has not been explicitly set yet, thus will default to enabled when it first
|
|
||||||
// becomes filterable (added to _filterableChannels)
|
|
||||||
// Note that these are persisted here, at the manager,
|
// Note that these are persisted here, at the manager,
|
||||||
// rather than the chatbox so that these settings persist between instances of different
|
// rather than the chatbox so that these settings persist between instances of different
|
||||||
// chatboxes.
|
// chatboxes.
|
||||||
public readonly Dictionary<ChatChannel, bool> _channelFilters = new();
|
public ChatChannel ChannelFilters { get; private set; } = (ChatChannel) ushort.MaxValue;
|
||||||
|
|
||||||
// Maintains which channels a client should be able to filter (for showing in the chatbox)
|
// Maintains which channels a client should be able to filter (for showing in the chatbox)
|
||||||
// and select (for attempting to send on).
|
// and select (for attempting to send on).
|
||||||
@@ -80,18 +75,16 @@ namespace Content.Client.Chat.Managers
|
|||||||
//
|
//
|
||||||
// Note that Command is an available selection in the chatbox channel selector,
|
// Note that Command is an available selection in the chatbox channel selector,
|
||||||
// which is not actually a chat channel but is always available.
|
// which is not actually a chat channel but is always available.
|
||||||
private readonly HashSet<ChatChannel> _filterableChannels = new();
|
public ChatSelectChannel SelectableChannels { get; private set; }
|
||||||
private readonly List<ChatChannel> _selectableChannels = new();
|
public ChatChannel FilterableChannels { get; private set; }
|
||||||
|
|
||||||
// Flag Enums for holding filtered channels
|
|
||||||
private ChatChannel _filteredChannels;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For currently disabled chat filters,
|
/// For currently disabled chat filters,
|
||||||
/// unread messages (messages received since the channel has been filtered
|
/// unread messages (messages received since the channel has been filtered out).
|
||||||
/// out). Never goes above 10 (9+ should be shown when at 10)
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<ChatChannel, byte> _unreadMessages = new();
|
private readonly Dictionary<ChatChannel, int> _unreadMessages = new();
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<ChatChannel, int> UnreadMessages => _unreadMessages;
|
||||||
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
[Dependency] private readonly IClientNetManager _netManager = default!;
|
[Dependency] private readonly IClientNetManager _netManager = default!;
|
||||||
@@ -100,16 +93,23 @@ namespace Content.Client.Chat.Managers
|
|||||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||||
[Dependency] private readonly IClientAdminManager _adminMgr = default!;
|
[Dependency] private readonly IClientAdminManager _adminMgr = default!;
|
||||||
|
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current chat box control. This can be modified, so do not depend on saving a reference to this.
|
/// Current chat box control. This can be modified, so do not depend on saving a reference to this.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ChatBox? CurrentChatBox { get; private set; }
|
public ChatBox? CurrentChatBox { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when CurrentChatBox is resized (including after setting initial default size)
|
/// Invoked when CurrentChatBox is resized (including after setting initial default size)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<ChatResizedEventArgs>? OnChatBoxResized;
|
public event Action<ChatResizedEventArgs>? OnChatBoxResized;
|
||||||
|
|
||||||
|
public event Action<ChatPermissionsUpdatedEventArgs>? ChatPermissionsUpdated;
|
||||||
|
public event Action? UnreadMessageCountsUpdated;
|
||||||
|
public event Action<StoredChatMessage>? MessageAdded;
|
||||||
|
public event Action? FiltersUpdated;
|
||||||
|
|
||||||
private Control _speechBubbleRoot = null!;
|
private Control _speechBubbleRoot = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -128,15 +128,11 @@ namespace Content.Client.Chat.Managers
|
|||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_netManager.RegisterNetMessage<MsgChatMessage>(OnChatMessage);
|
_netManager.RegisterNetMessage<MsgChatMessage>(OnChatMessage);
|
||||||
_netManager.RegisterNetMessage<ChatMaxMsgLengthMessage>(OnMaxLengthReceived);
|
|
||||||
|
|
||||||
_speechBubbleRoot = new LayoutContainer();
|
_speechBubbleRoot = new LayoutContainer();
|
||||||
LayoutContainer.SetAnchorPreset(_speechBubbleRoot, LayoutContainer.LayoutPreset.Wide);
|
LayoutContainer.SetAnchorPreset(_speechBubbleRoot, LayoutContainer.LayoutPreset.Wide);
|
||||||
_userInterfaceManager.StateRoot.AddChild(_speechBubbleRoot);
|
_userInterfaceManager.StateRoot.AddChild(_speechBubbleRoot);
|
||||||
_speechBubbleRoot.SetPositionFirst();
|
_speechBubbleRoot.SetPositionFirst();
|
||||||
|
|
||||||
// When connexion is achieved, request the max chat message length
|
|
||||||
_netManager.Connected += RequestMaxLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInject()
|
public void PostInject()
|
||||||
@@ -178,83 +174,58 @@ namespace Content.Client.Chat.Managers
|
|||||||
// for any newly-granted channels
|
// for any newly-granted channels
|
||||||
private void UpdateChannelPermissions()
|
private void UpdateChannelPermissions()
|
||||||
{
|
{
|
||||||
|
var oldSelectable = SelectableChannels;
|
||||||
|
SelectableChannels = default;
|
||||||
|
FilterableChannels = default;
|
||||||
|
|
||||||
|
// Can always send console stuff.
|
||||||
|
SelectableChannels |= ChatSelectChannel.Console;
|
||||||
|
|
||||||
// can always send/recieve OOC
|
// can always send/recieve OOC
|
||||||
if (!_selectableChannels.Contains(ChatChannel.OOC))
|
SelectableChannels |= ChatSelectChannel.OOC;
|
||||||
{
|
FilterableChannels |= ChatChannel.OOC;
|
||||||
_selectableChannels.Add(ChatChannel.OOC);
|
|
||||||
}
|
|
||||||
AddFilterableChannel(ChatChannel.OOC);
|
|
||||||
|
|
||||||
// can always hear server (nobody can actually send server messages).
|
// can always hear server (nobody can actually send server messages).
|
||||||
AddFilterableChannel(ChatChannel.Server);
|
FilterableChannels |= ChatChannel.Server;
|
||||||
|
|
||||||
// can always hear local / radio / emote
|
// can always hear local / radio / emote
|
||||||
AddFilterableChannel(ChatChannel.Local);
|
// todo: this makes no sense the lobby exists fix this.
|
||||||
AddFilterableChannel(ChatChannel.Radio);
|
FilterableChannels |= ChatChannel.Local;
|
||||||
AddFilterableChannel(ChatChannel.Emotes);
|
FilterableChannels |= ChatChannel.Radio;
|
||||||
|
FilterableChannels |= ChatChannel.Emotes;
|
||||||
|
|
||||||
// Can only send local / radio / emote when attached to a non-ghost entity.
|
// Can only send local / radio / emote when attached to a non-ghost entity.
|
||||||
// TODO: this logic is iffy (checking if controlling something that's NOT a ghost), is there a better way to check this?
|
// TODO: this logic is iffy (checking if controlling something that's NOT a ghost), is there a better way to check this?
|
||||||
if (!_playerManager.LocalPlayer?.ControlledEntity?.HasComponent<GhostComponent>() ?? false)
|
if (!IsGhost)
|
||||||
{
|
{
|
||||||
_selectableChannels.Add(ChatChannel.Local);
|
SelectableChannels |= ChatSelectChannel.Local;
|
||||||
_selectableChannels.Add(ChatChannel.Radio);
|
SelectableChannels |= ChatSelectChannel.Radio;
|
||||||
_selectableChannels.Add(ChatChannel.Emotes);
|
SelectableChannels |= ChatSelectChannel.Emotes;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_selectableChannels.Remove(ChatChannel.Local);
|
|
||||||
_selectableChannels.Remove(ChatChannel.Radio);
|
|
||||||
_selectableChannels.Remove(ChatChannel.Emotes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only ghosts and admins can send / see deadchat.
|
// Only ghosts and admins can send / see deadchat.
|
||||||
// TODO: Should spectators also be able to see deadchat?
|
if (_adminMgr.HasFlag(AdminFlags.Admin) || IsGhost)
|
||||||
if (_adminMgr.HasFlag(AdminFlags.Admin) ||
|
|
||||||
(_playerManager?.LocalPlayer?.ControlledEntity?.HasComponent<GhostComponent>() ?? false))
|
|
||||||
{
|
{
|
||||||
AddFilterableChannel(ChatChannel.Dead);
|
FilterableChannels |= ChatChannel.Dead;
|
||||||
if (!_selectableChannels.Contains(ChatChannel.Dead))
|
SelectableChannels |= ChatSelectChannel.Dead;
|
||||||
{
|
|
||||||
_selectableChannels.Add(ChatChannel.Dead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_filterableChannels.Remove(ChatChannel.Dead);
|
|
||||||
_selectableChannels.Remove(ChatChannel.Dead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// only admins can see / filter asay
|
// only admins can see / filter asay
|
||||||
if (_adminMgr.HasFlag(AdminFlags.Admin))
|
if (_adminMgr.HasFlag(AdminFlags.Admin))
|
||||||
{
|
{
|
||||||
AddFilterableChannel(ChatChannel.AdminChat);
|
FilterableChannels |= ChatChannel.Admin;
|
||||||
if (!_selectableChannels.Contains(ChatChannel.AdminChat))
|
SelectableChannels |= ChatSelectChannel.Admin;
|
||||||
{
|
|
||||||
_selectableChannels.Add(ChatChannel.AdminChat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_selectableChannels.Remove(ChatChannel.AdminChat);
|
|
||||||
_filterableChannels.Remove(ChatChannel.AdminChat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Necessary so that we always have a channel to fall back to.
|
||||||
|
DebugTools.Assert((SelectableChannels & ChatSelectChannel.OOC) != 0, "OOC must always be available");
|
||||||
|
DebugTools.Assert((FilterableChannels & ChatChannel.OOC) != 0, "OOC must always be available");
|
||||||
|
|
||||||
// let our chatbox know all the new settings
|
// let our chatbox know all the new settings
|
||||||
CurrentChatBox?.SetChannelPermissions(_selectableChannels, _filterableChannels, _channelFilters, _unreadMessages, true);
|
ChatPermissionsUpdated?.Invoke(new ChatPermissionsUpdatedEventArgs {OldSelectableChannels = oldSelectable});
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds the channel to the set of filterable channels, defaulting it as enabled
|
|
||||||
/// if it doesn't currently have an explicit enable/disable setting
|
|
||||||
/// </summary>
|
|
||||||
private void AddFilterableChannel(ChatChannel channel)
|
|
||||||
{
|
|
||||||
if (!_channelFilters.ContainsKey(channel))
|
|
||||||
_channelFilters[channel] = true;
|
|
||||||
_filterableChannels.Add(channel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsGhost => _playerManager.LocalPlayer?.ControlledEntity?.HasComponent<GhostComponent>() ?? false;
|
||||||
|
|
||||||
public void FrameUpdate(FrameEventArgs delta)
|
public void FrameUpdate(FrameEventArgs delta)
|
||||||
{
|
{
|
||||||
@@ -296,27 +267,19 @@ namespace Content.Client.Chat.Managers
|
|||||||
|
|
||||||
public void SetChatBox(ChatBox chatBox)
|
public void SetChatBox(ChatBox chatBox)
|
||||||
{
|
{
|
||||||
if (CurrentChatBox != null)
|
|
||||||
{
|
|
||||||
CurrentChatBox.TextSubmitted -= OnChatBoxTextSubmitted;
|
|
||||||
CurrentChatBox.FilterToggled -= OnFilterButtonToggled;
|
|
||||||
CurrentChatBox.OnResized -= ChatBoxOnResized;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentChatBox = chatBox;
|
CurrentChatBox = chatBox;
|
||||||
if (CurrentChatBox != null)
|
}
|
||||||
|
|
||||||
|
public void ClearUnfilteredUnreads()
|
||||||
{
|
{
|
||||||
CurrentChatBox.TextSubmitted += OnChatBoxTextSubmitted;
|
foreach (var channel in _unreadMessages.Keys.ToArray())
|
||||||
CurrentChatBox.FilterToggled += OnFilterButtonToggled;
|
{
|
||||||
CurrentChatBox.OnResized += ChatBoxOnResized;
|
if ((ChannelFilters & channel) != 0)
|
||||||
|
_unreadMessages.Remove(channel);
|
||||||
CurrentChatBox.SetChannelPermissions(_selectableChannels, _filterableChannels, _channelFilters, _unreadMessages, false);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RepopulateChat(_filteredHistory);
|
public void ChatBoxOnResized(ChatResizedEventArgs chatResizedEventArgs)
|
||||||
}
|
|
||||||
|
|
||||||
private void ChatBoxOnResized(ChatResizedEventArgs chatResizedEventArgs)
|
|
||||||
{
|
{
|
||||||
OnChatBoxResized?.Invoke(chatResizedEventArgs);
|
OnChatBoxResized?.Invoke(chatResizedEventArgs);
|
||||||
}
|
}
|
||||||
@@ -334,158 +297,86 @@ namespace Content.Client.Chat.Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteChatMessage(StoredChatMessage message)
|
public void OnChatBoxTextSubmitted(ChatBox chatBox, ReadOnlyMemory<char> text, ChatSelectChannel channel)
|
||||||
{
|
|
||||||
Logger.Debug($"{message.Channel}: {message.Message}");
|
|
||||||
|
|
||||||
if (IsFiltered(message.Channel))
|
|
||||||
{
|
|
||||||
Logger.Debug($"Message filtered: {message.Channel}: {message.Message}");
|
|
||||||
// accumulate unread
|
|
||||||
if (message.Read) return;
|
|
||||||
if (!_unreadMessages.TryGetValue(message.Channel, out var count))
|
|
||||||
{
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
count = (byte) Math.Min(count + 1, 10);
|
|
||||||
_unreadMessages[message.Channel] = count;
|
|
||||||
CurrentChatBox?.UpdateUnreadMessageCounts(_unreadMessages);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var color = Color.DarkGray;
|
|
||||||
var messageText = FormattedMessage.EscapeText(message.Message);
|
|
||||||
if (!string.IsNullOrEmpty(message.MessageWrap))
|
|
||||||
{
|
|
||||||
messageText = string.Format(message.MessageWrap, messageText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.MessageColorOverride != Color.Transparent)
|
|
||||||
{
|
|
||||||
color = message.MessageColorOverride;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = ChatHelper.ChatColor(message.Channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentChatBox == null) return;
|
|
||||||
CurrentChatBox.AddLine(messageText, message.Channel, color);
|
|
||||||
// TODO: Can make this "smarter" later by only setting it false when the message has been scrolled to
|
|
||||||
message.Read = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnChatBoxTextSubmitted(ChatBox chatBox, string text)
|
|
||||||
{
|
{
|
||||||
DebugTools.Assert(chatBox == CurrentChatBox);
|
DebugTools.Assert(chatBox == CurrentChatBox);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
var str = text.ToString();
|
||||||
return;
|
|
||||||
|
|
||||||
// Check if message is longer than the character limit
|
switch (channel)
|
||||||
if (text.Length > _maxMessageLength)
|
|
||||||
{
|
|
||||||
if (CurrentChatBox != null)
|
|
||||||
{
|
|
||||||
string locWarning = Loc.GetString("chat-manager-max-message-length",
|
|
||||||
("maxMessageLength", _maxMessageLength));
|
|
||||||
CurrentChatBox.AddLine(locWarning, ChatChannel.Server, Color.Orange);
|
|
||||||
CurrentChatBox.ClearOnEnter = false; // The text shouldn't be cleared if it hasn't been sent
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (text[0])
|
|
||||||
{
|
|
||||||
case ConCmdSlash:
|
|
||||||
{
|
{
|
||||||
|
case ChatSelectChannel.Console:
|
||||||
// run locally
|
// run locally
|
||||||
var conInput = text.Substring(1);
|
_consoleHost.ExecuteCommand(text.ToString());
|
||||||
_consoleHost.ExecuteCommand(conInput);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case OOCAlias:
|
case ChatSelectChannel.OOC:
|
||||||
{
|
_consoleHost.ExecuteCommand($"ooc \"{CommandParsing.Escape(str)}\"");
|
||||||
var conInput = text.Substring(1);
|
|
||||||
if (string.IsNullOrWhiteSpace(conInput))
|
|
||||||
return;
|
|
||||||
_consoleHost.ExecuteCommand($"ooc \"{CommandParsing.Escape(conInput)}\"");
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case AdminChatAlias:
|
case ChatSelectChannel.Admin:
|
||||||
{
|
_consoleHost.ExecuteCommand($"asay \"{CommandParsing.Escape(str)}\"");
|
||||||
var conInput = text.Substring(1);
|
break;
|
||||||
if (string.IsNullOrWhiteSpace(conInput))
|
|
||||||
return;
|
case ChatSelectChannel.Emotes:
|
||||||
if (_adminMgr.HasFlag(AdminFlags.Admin))
|
_consoleHost.ExecuteCommand($"me \"{CommandParsing.Escape(str)}\"");
|
||||||
{
|
break;
|
||||||
_consoleHost.ExecuteCommand($"asay \"{CommandParsing.Escape(conInput)}\"");
|
|
||||||
}
|
case ChatSelectChannel.Dead:
|
||||||
|
if (IsGhost)
|
||||||
|
goto case ChatSelectChannel.Local;
|
||||||
|
else if (_adminMgr.HasFlag(AdminFlags.Admin))
|
||||||
|
_consoleHost.ExecuteCommand($"dsay \"{CommandParsing.Escape(str)}\"");
|
||||||
else
|
else
|
||||||
{
|
Logger.WarningS("chat", "Tried to speak on deadchat without being ghost or admin.");
|
||||||
_consoleHost.ExecuteCommand($"ooc \"{CommandParsing.Escape(conInput)}\"");
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
|
case ChatSelectChannel.Radio:
|
||||||
|
_consoleHost.ExecuteCommand($"say \";{CommandParsing.Escape(str)}\"");
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case MeAlias:
|
case ChatSelectChannel.Local:
|
||||||
{
|
_consoleHost.ExecuteCommand($"say \"{CommandParsing.Escape(str)}\"");
|
||||||
var conInput = text.Substring(1);
|
|
||||||
if (string.IsNullOrWhiteSpace(conInput))
|
|
||||||
return;
|
|
||||||
_consoleHost.ExecuteCommand($"me \"{CommandParsing.Escape(conInput)}\"");
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
throw new ArgumentOutOfRangeException(nameof(channel), channel, null);
|
||||||
var conInput = CurrentChatBox?.DefaultChatFormat != null
|
|
||||||
? string.Format(CurrentChatBox.DefaultChatFormat, CommandParsing.Escape(text))
|
|
||||||
: text;
|
|
||||||
_consoleHost.ExecuteCommand(conInput);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFilterButtonToggled(ChatChannel channel, bool enabled)
|
public void OnFilterButtonToggled(ChatChannel channel, bool enabled)
|
||||||
{
|
{
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
_channelFilters[channel] = true;
|
ChannelFilters |= channel;
|
||||||
_filteredChannels &= ~channel;
|
|
||||||
_unreadMessages.Remove(channel);
|
_unreadMessages.Remove(channel);
|
||||||
CurrentChatBox?.UpdateUnreadMessageCounts(_unreadMessages);
|
UnreadMessageCountsUpdated?.Invoke();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_channelFilters[channel] = false;
|
ChannelFilters &= ~channel;
|
||||||
_filteredChannels |= channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RepopulateChat(_filteredHistory);
|
FiltersUpdated?.Invoke();
|
||||||
}
|
|
||||||
|
|
||||||
private void RepopulateChat(IEnumerable<StoredChatMessage> filteredMessages)
|
|
||||||
{
|
|
||||||
if (CurrentChatBox == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentChatBox.Contents.Clear();
|
|
||||||
|
|
||||||
foreach (var msg in filteredMessages)
|
|
||||||
{
|
|
||||||
WriteChatMessage(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnChatMessage(MsgChatMessage msg)
|
private void OnChatMessage(MsgChatMessage msg)
|
||||||
{
|
{
|
||||||
// Log all incoming chat to repopulate when filter is un-toggled
|
// Log all incoming chat to repopulate when filter is un-toggled
|
||||||
var storedMessage = new StoredChatMessage(msg);
|
var storedMessage = new StoredChatMessage(msg);
|
||||||
_filteredHistory.Add(storedMessage);
|
_history.Add(storedMessage);
|
||||||
WriteChatMessage(storedMessage);
|
MessageAdded?.Invoke(storedMessage);
|
||||||
|
|
||||||
|
if (!storedMessage.Read)
|
||||||
|
{
|
||||||
|
Logger.Debug($"Message filtered: {storedMessage.Channel}: {storedMessage.Message}");
|
||||||
|
if (!_unreadMessages.TryGetValue(msg.Channel, out var count))
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
count += 1;
|
||||||
|
_unreadMessages[msg.Channel] = count;
|
||||||
|
UnreadMessageCountsUpdated?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
// Local messages that have an entity attached get a speech bubble.
|
// Local messages that have an entity attached get a speech bubble.
|
||||||
if (msg.SenderEntity == default)
|
if (msg.SenderEntity == default)
|
||||||
@@ -498,7 +389,7 @@ namespace Content.Client.Chat.Managers
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ChatChannel.Dead:
|
case ChatChannel.Dead:
|
||||||
if (!_playerManager.LocalPlayer?.ControlledEntity?.HasComponent<GhostComponent>() ?? true)
|
if (!IsGhost)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
AddSpeechBubble(msg, SpeechBubble.SpeechType.Say);
|
AddSpeechBubble(msg, SpeechBubble.SpeechType.Say);
|
||||||
@@ -510,17 +401,6 @@ namespace Content.Client.Chat.Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMaxLengthReceived(ChatMaxMsgLengthMessage msg)
|
|
||||||
{
|
|
||||||
_maxMessageLength = msg.MaxMessageLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RequestMaxLength(object? sender, NetChannelArgs args)
|
|
||||||
{
|
|
||||||
ChatMaxMsgLengthMessage msg = _netManager.CreateNetMessage<ChatMaxMsgLengthMessage>();
|
|
||||||
_netManager.ClientSendMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddSpeechBubble(MsgChatMessage msg, SpeechBubble.SpeechType speechType)
|
private void AddSpeechBubble(MsgChatMessage msg, SpeechBubble.SpeechType speechType)
|
||||||
{
|
{
|
||||||
if (!_entityManager.TryGetEntity(msg.SenderEntity, out var entity))
|
if (!_entityManager.TryGetEntity(msg.SenderEntity, out var entity))
|
||||||
@@ -604,7 +484,8 @@ namespace Content.Client.Chat.Managers
|
|||||||
|
|
||||||
private void CreateSpeechBubble(IEntity entity, SpeechBubbleData speechData)
|
private void CreateSpeechBubble(IEntity entity, SpeechBubbleData speechData)
|
||||||
{
|
{
|
||||||
var bubble = SpeechBubble.CreateSpeechBubble(speechData.Type, speechData.Message, entity, _eyeManager, this);
|
var bubble =
|
||||||
|
SpeechBubble.CreateSpeechBubble(speechData.Type, speechData.Message, entity, _eyeManager, this);
|
||||||
|
|
||||||
if (_activeSpeechBubbles.TryGetValue(entity.Uid, out var existing))
|
if (_activeSpeechBubbles.TryGetValue(entity.Uid, out var existing))
|
||||||
{
|
{
|
||||||
@@ -631,11 +512,6 @@ namespace Content.Client.Chat.Managers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsFiltered(ChatChannel channel)
|
|
||||||
{
|
|
||||||
return _filteredChannels.HasFlag(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class SpeechBubbleQueueData
|
private sealed class SpeechBubbleQueueData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Content.Client.Chat.UI;
|
using Content.Client.Chat.UI;
|
||||||
|
using Content.Shared.Chat;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -7,6 +9,10 @@ namespace Content.Client.Chat.Managers
|
|||||||
{
|
{
|
||||||
public interface IChatManager
|
public interface IChatManager
|
||||||
{
|
{
|
||||||
|
ChatChannel ChannelFilters { get; }
|
||||||
|
ChatSelectChannel SelectableChannels { get; }
|
||||||
|
ChatChannel FilterableChannels { get; }
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
void FrameUpdate(FrameEventArgs delta);
|
void FrameUpdate(FrameEventArgs delta);
|
||||||
@@ -20,9 +26,29 @@ namespace Content.Client.Chat.Managers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
ChatBox? CurrentChatBox { get; }
|
ChatBox? CurrentChatBox { get; }
|
||||||
|
|
||||||
|
IReadOnlyDictionary<ChatChannel, int> UnreadMessages { get; }
|
||||||
|
IReadOnlyList<StoredChatMessage> History { get; }
|
||||||
|
int MaxMessageLength { get; }
|
||||||
|
bool IsGhost { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when CurrentChatBox is resized (including after setting initial default size)
|
/// Invoked when CurrentChatBox is resized (including after setting initial default size)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event Action<ChatResizedEventArgs>? OnChatBoxResized;
|
event Action<ChatResizedEventArgs>? OnChatBoxResized;
|
||||||
|
|
||||||
|
event Action<ChatPermissionsUpdatedEventArgs>? ChatPermissionsUpdated;
|
||||||
|
event Action? UnreadMessageCountsUpdated;
|
||||||
|
event Action<StoredChatMessage>? MessageAdded;
|
||||||
|
event Action? FiltersUpdated;
|
||||||
|
|
||||||
|
void ClearUnfilteredUnreads();
|
||||||
|
void ChatBoxOnResized(ChatResizedEventArgs chatResizedEventArgs);
|
||||||
|
void OnChatBoxTextSubmitted(ChatBox chatBox, ReadOnlyMemory<char> text, ChatSelectChannel channel);
|
||||||
|
void OnFilterButtonToggled(ChatChannel channel, bool enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ChatPermissionsUpdatedEventArgs
|
||||||
|
{
|
||||||
|
public ChatSelectChannel OldSelectableChannels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,973 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Client.Alerts.UI;
|
|
||||||
using Content.Client.Chat.Managers;
|
|
||||||
using Content.Client.Lobby;
|
|
||||||
using Content.Client.Resources;
|
|
||||||
using Content.Client.Stylesheets;
|
|
||||||
using Content.Shared.Chat;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.ResourceManagement;
|
|
||||||
using Robust.Client.State;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.Chat.UI
|
|
||||||
{
|
|
||||||
public class ChatBox : Control
|
|
||||||
{
|
|
||||||
public const float InitialChatBottom = 235;
|
|
||||||
|
|
||||||
public delegate void TextSubmitHandler(ChatBox chatBox, string text);
|
|
||||||
|
|
||||||
public delegate void FilterToggledHandler(ChatChannel toggled, bool enabled);
|
|
||||||
|
|
||||||
public event TextSubmitHandler? TextSubmitted;
|
|
||||||
|
|
||||||
public event FilterToggledHandler? FilterToggled;
|
|
||||||
|
|
||||||
public HistoryLineEdit Input { get; private set; }
|
|
||||||
public OutputPanel Contents { get; }
|
|
||||||
|
|
||||||
public event Action<ChatResizedEventArgs>? OnResized;
|
|
||||||
|
|
||||||
// order in which the available channel filters show up when available
|
|
||||||
public static readonly IReadOnlyList<ChatChannel> ChannelFilterOrder = new List<ChatChannel>
|
|
||||||
{
|
|
||||||
ChatChannel.Local, ChatChannel.Emotes, ChatChannel.Radio, ChatChannel.OOC, ChatChannel.Dead, ChatChannel.AdminChat,
|
|
||||||
ChatChannel.Server
|
|
||||||
};
|
|
||||||
|
|
||||||
// order in which the channels show up in the channel selector
|
|
||||||
private static readonly IReadOnlyList<ChatChannel> ChannelSelectorOrder = new List<ChatChannel>
|
|
||||||
{
|
|
||||||
ChatChannel.Local, ChatChannel.Emotes, ChatChannel.Radio, ChatChannel.OOC, ChatChannel.Dead, ChatChannel.AdminChat
|
|
||||||
};
|
|
||||||
|
|
||||||
private const float FilterPopupWidth = 110;
|
|
||||||
private const int DragMarginSize = 7;
|
|
||||||
private const int MinDistanceFromBottom = 255;
|
|
||||||
private const int MinLeft = 500;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Will be Unspecified if set to Console
|
|
||||||
/// </summary>
|
|
||||||
public ChatChannel SelectedChannel = ChatChannel.Unspecified;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default formatting string for the ClientChatConsole.
|
|
||||||
/// </summary>
|
|
||||||
public string DefaultChatFormat { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public bool ReleaseFocusOnEnter { get; set; } = true;
|
|
||||||
|
|
||||||
public bool ClearOnEnter { get; set; } = true;
|
|
||||||
|
|
||||||
// when channel is changed temporarily due to typing an alias
|
|
||||||
// prefix, we save the current channel selection here to restore it when
|
|
||||||
// the message is sent
|
|
||||||
private ChatChannel? _savedSelectedChannel;
|
|
||||||
|
|
||||||
private readonly Popup _channelSelectorPopup;
|
|
||||||
private readonly Button _channelSelector;
|
|
||||||
private readonly HBoxContainer _channelSelectorHBox;
|
|
||||||
private readonly FilterButton _filterButton;
|
|
||||||
private readonly Popup _filterPopup;
|
|
||||||
private readonly PanelContainer _filterPopupPanel;
|
|
||||||
private readonly VBoxContainer _filterVBox;
|
|
||||||
private DragMode _currentDrag = DragMode.None;
|
|
||||||
private Vector2 _dragOffsetTopLeft;
|
|
||||||
private Vector2 _dragOffsetBottomRight;
|
|
||||||
private readonly IClyde _clyde;
|
|
||||||
private readonly bool _lobbyMode;
|
|
||||||
private byte _clampIn;
|
|
||||||
// currently known selectable channels as provided by ChatManager,
|
|
||||||
// never contains Unspecified (which corresponds to Console which is always available)
|
|
||||||
public List<ChatChannel> SelectableChannels = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// When lobbyMode is false, will position / add to correct location in StateRoot and
|
|
||||||
/// be resizable.
|
|
||||||
/// wWen true, will leave layout up to parent and not be resizable.
|
|
||||||
/// </summary>
|
|
||||||
public ChatBox()
|
|
||||||
{
|
|
||||||
//TODO Paul needs to fix xaml ctor args so we can pass this instead of resolving it.
|
|
||||||
var stateManager = IoCManager.Resolve<IStateManager>();
|
|
||||||
_lobbyMode = stateManager.CurrentState is LobbyState;
|
|
||||||
|
|
||||||
// TODO: Revisit the resizing stuff after https://github.com/space-wizards/RobustToolbox/issues/1392 is done,
|
|
||||||
// Probably not "supposed" to inject IClyde, but I give up.
|
|
||||||
// I can't find any other way to allow this control to properly resize when the
|
|
||||||
// window is resized. Resized() isn't reliably called when resizing the window,
|
|
||||||
// and layoutcontainer anchor / margin don't seem to adjust how we need
|
|
||||||
// them to when the window is resized. We need it to be able to resize
|
|
||||||
// within some bounds so that it doesn't overlap other UI elements, while still
|
|
||||||
// being freely resizable within those bounds.
|
|
||||||
_clyde = IoCManager.Resolve<IClyde>();
|
|
||||||
MouseFilter = MouseFilterMode.Stop;
|
|
||||||
LayoutContainer.SetMarginLeft(this, 4);
|
|
||||||
LayoutContainer.SetMarginRight(this, 4);
|
|
||||||
MinHeight = 128;
|
|
||||||
MinWidth = 200;
|
|
||||||
|
|
||||||
AddChild(new PanelContainer
|
|
||||||
{
|
|
||||||
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#25252aaa")},
|
|
||||||
VerticalExpand = true,
|
|
||||||
HorizontalExpand = true,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new VBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(Contents = new OutputPanel
|
|
||||||
{
|
|
||||||
VerticalExpand = true,
|
|
||||||
}),
|
|
||||||
new PanelContainer
|
|
||||||
{
|
|
||||||
StyleClasses = { StyleNano.StyleClassChatSubPanel },
|
|
||||||
HorizontalExpand = true,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new HBoxContainer
|
|
||||||
{
|
|
||||||
HorizontalExpand = true,
|
|
||||||
SeparationOverride = 4,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(_channelSelector = new ChannelSelectorButton
|
|
||||||
{
|
|
||||||
StyleClasses = { StyleNano.StyleClassChatChannelSelectorButton },
|
|
||||||
MinWidth = 75,
|
|
||||||
Text = Loc.GetString("hud-chatbox-ooc"),
|
|
||||||
ToggleMode = true
|
|
||||||
}),
|
|
||||||
(Input = new HistoryLineEdit
|
|
||||||
{
|
|
||||||
PlaceHolder = Loc.GetString("hud-chatbox-info"),
|
|
||||||
HorizontalExpand = true,
|
|
||||||
StyleClasses = { StyleNano.StyleClassChatLineEdit }
|
|
||||||
}),
|
|
||||||
(_filterButton = new FilterButton
|
|
||||||
{
|
|
||||||
StyleClasses = { StyleNano.StyleClassChatFilterOptionButton }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_filterPopup = new Popup
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(_filterPopupPanel = new PanelContainer
|
|
||||||
{
|
|
||||||
StyleClasses = {StyleNano.StyleClassBorderedWindowPanel},
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Control{MinSize = (4,0)},
|
|
||||||
(_filterVBox = new VBoxContainer
|
|
||||||
{
|
|
||||||
SeparationOverride = 4
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_channelSelectorPopup = new Popup
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(_channelSelectorHBox = new HBoxContainer
|
|
||||||
{
|
|
||||||
SeparationOverride = 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!_lobbyMode)
|
|
||||||
{
|
|
||||||
UserInterfaceManager.StateRoot.AddChild(this);
|
|
||||||
LayoutContainer.SetAnchorAndMarginPreset(this, LayoutContainer.LayoutPreset.TopRight, margin: 10);
|
|
||||||
LayoutContainer.SetAnchorAndMarginPreset(this, LayoutContainer.LayoutPreset.TopRight, margin: 10);
|
|
||||||
LayoutContainer.SetMarginLeft(this, -475);
|
|
||||||
LayoutContainer.SetMarginBottom(this, InitialChatBottom);
|
|
||||||
OnResized?.Invoke(new ChatResizedEventArgs(InitialChatBottom));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void EnteredTree()
|
|
||||||
{
|
|
||||||
base.EnteredTree();
|
|
||||||
_channelSelector.OnToggled += OnChannelSelectorToggled;
|
|
||||||
_filterButton.OnToggled += OnFilterButtonToggled;
|
|
||||||
Input.OnKeyBindDown += InputKeyBindDown;
|
|
||||||
Input.OnTextEntered += Input_OnTextEntered;
|
|
||||||
Input.OnTextChanged += InputOnTextChanged;
|
|
||||||
Input.OnFocusExit += InputOnFocusExit;
|
|
||||||
_channelSelectorPopup.OnPopupHide += OnChannelSelectorPopupHide;
|
|
||||||
_filterPopup.OnPopupHide += OnFilterPopupHide;
|
|
||||||
_clyde.OnWindowResized += ClydeOnOnWindowResized;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ExitedTree()
|
|
||||||
{
|
|
||||||
base.ExitedTree();
|
|
||||||
_channelSelector.OnToggled -= OnChannelSelectorToggled;
|
|
||||||
_filterButton.OnToggled -= OnFilterButtonToggled;
|
|
||||||
Input.OnKeyBindDown -= InputKeyBindDown;
|
|
||||||
Input.OnTextEntered -= Input_OnTextEntered;
|
|
||||||
Input.OnTextChanged -= InputOnTextChanged;
|
|
||||||
Input.OnFocusExit -= InputOnFocusExit;
|
|
||||||
_channelSelectorPopup.OnPopupHide -= OnChannelSelectorPopupHide;
|
|
||||||
_filterPopup.OnPopupHide -= OnFilterPopupHide;
|
|
||||||
_clyde.OnWindowResized -= ClydeOnOnWindowResized;
|
|
||||||
UnsubFilterItems();
|
|
||||||
UnsubChannelItems();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UnsubFilterItems()
|
|
||||||
{
|
|
||||||
foreach (var child in _filterVBox.Children)
|
|
||||||
{
|
|
||||||
if (child is not ChannelFilterCheckbox checkbox) continue;
|
|
||||||
checkbox.OnToggled -= OnFilterCheckboxToggled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UnsubChannelItems()
|
|
||||||
{
|
|
||||||
foreach (var child in _channelSelectorHBox.Children)
|
|
||||||
{
|
|
||||||
if (child is not ChannelItemButton button) continue;
|
|
||||||
button.OnPressed -= OnChannelSelectorItemPressed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update the available filters / selectable channels and the current filter settings using the provided
|
|
||||||
/// data.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="selectableChannels">channels currently selectable to send on</param>
|
|
||||||
/// <param name="filterableChannels">channels currently able ot filter on</param>
|
|
||||||
/// <param name="channelFilters">current settings for the channel filters, this SHOULD always have an entry if
|
|
||||||
/// there is a corresponding entry in filterableChannels, but it may also have additional
|
|
||||||
/// entries (which should not be presented to the user)</param>
|
|
||||||
/// <param name="unreadMessages">unread message counts for each disabled channel, values 10 or higher will show as 9+</param>
|
|
||||||
public void SetChannelPermissions(List<ChatChannel> selectableChannels, IReadOnlySet<ChatChannel> filterableChannels,
|
|
||||||
IReadOnlyDictionary<ChatChannel, bool> channelFilters, IReadOnlyDictionary<ChatChannel, byte> unreadMessages, bool switchIfConsole)
|
|
||||||
{
|
|
||||||
SelectableChannels = selectableChannels;
|
|
||||||
// update the channel selector
|
|
||||||
UnsubChannelItems();
|
|
||||||
_channelSelectorHBox.RemoveAllChildren();
|
|
||||||
foreach (var selectableChannel in ChannelSelectorOrder)
|
|
||||||
{
|
|
||||||
if (!selectableChannels.Contains(selectableChannel)) continue;
|
|
||||||
var newButton = new ChannelItemButton(selectableChannel);
|
|
||||||
newButton.OnPressed += OnChannelSelectorItemPressed;
|
|
||||||
_channelSelectorHBox.AddChild(newButton);
|
|
||||||
}
|
|
||||||
// console channel is always selectable and represented via Unspecified
|
|
||||||
var consoleButton = new ChannelItemButton(ChatChannel.Unspecified);
|
|
||||||
consoleButton.OnPressed += OnChannelSelectorItemPressed;
|
|
||||||
_channelSelectorHBox.AddChild(consoleButton);
|
|
||||||
|
|
||||||
|
|
||||||
if (_savedSelectedChannel.HasValue && _savedSelectedChannel.Value != ChatChannel.Unspecified &&
|
|
||||||
!selectableChannels.Contains(_savedSelectedChannel.Value))
|
|
||||||
{
|
|
||||||
// we just lost our saved selected channel, the current one will become permanent
|
|
||||||
_savedSelectedChannel = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selectableChannels.Contains(SelectedChannel) && (switchIfConsole || SelectedChannel != ChatChannel.Unspecified))
|
|
||||||
{
|
|
||||||
// our previously selected channel no longer exists or we are still on console channel because we just joined
|
|
||||||
if ((SelectedChannel & ChatChannel.IC) != 0 || SelectedChannel == ChatChannel.Unspecified)
|
|
||||||
{
|
|
||||||
if (!SafelySelectChannel(ChatChannel.Local))
|
|
||||||
SafelySelectChannel(ChatChannel.Dead);
|
|
||||||
}
|
|
||||||
else if (selectableChannels.Contains(ChatChannel.OOC))
|
|
||||||
{
|
|
||||||
SafelySelectChannel(ChatChannel.OOC);
|
|
||||||
}
|
|
||||||
else //This shouldn't happen but better to be safe than sorry
|
|
||||||
{
|
|
||||||
SafelySelectChannel(selectableChannels.First());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SafelySelectChannel(SelectedChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the channel filters
|
|
||||||
UnsubFilterItems();
|
|
||||||
_filterVBox.Children.Clear();
|
|
||||||
_filterVBox.AddChild(new Control {CustomMinimumSize = (10, 0)});
|
|
||||||
foreach (var channelFilter in ChannelFilterOrder)
|
|
||||||
{
|
|
||||||
if (!filterableChannels.Contains(channelFilter)) continue;
|
|
||||||
byte? unreadCount = null;
|
|
||||||
if (unreadMessages.TryGetValue(channelFilter, out var unread))
|
|
||||||
{
|
|
||||||
unreadCount = unread;
|
|
||||||
}
|
|
||||||
var newCheckBox = new ChannelFilterCheckbox(channelFilter, unreadCount)
|
|
||||||
{
|
|
||||||
// shouldn't happen, but if there's no explicit enable setting provided, default to enabled
|
|
||||||
Pressed = !channelFilters.TryGetValue(channelFilter, out var enabled) || enabled
|
|
||||||
};
|
|
||||||
newCheckBox.OnToggled += OnFilterCheckboxToggled;
|
|
||||||
_filterVBox.AddChild(newCheckBox);
|
|
||||||
}
|
|
||||||
_filterVBox.AddChild(new Control {CustomMinimumSize = (10, 0)});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update the unread message counts in the filters based on the provided data.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="unreadMessages">counts for each channel, any values above 9 will show as 9+</param>
|
|
||||||
public void UpdateUnreadMessageCounts(IReadOnlyDictionary<ChatChannel, byte> unreadMessages)
|
|
||||||
{
|
|
||||||
foreach (var channelFilter in _filterVBox.Children)
|
|
||||||
{
|
|
||||||
if (channelFilter is not ChannelFilterCheckbox filterCheckbox) continue;
|
|
||||||
if (unreadMessages.TryGetValue(filterCheckbox.Channel, out var unread))
|
|
||||||
{
|
|
||||||
filterCheckbox.UpdateUnreadCount(unread);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filterCheckbox.UpdateUnreadCount(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnFilterCheckboxToggled(BaseButton.ButtonToggledEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Button is not ChannelFilterCheckbox checkbox) return;
|
|
||||||
FilterToggled?.Invoke(checkbox.Channel, checkbox.Pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void OnFilterButtonToggled(BaseButton.ButtonToggledEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Pressed)
|
|
||||||
{
|
|
||||||
var globalPos = _filterButton.GlobalPosition;
|
|
||||||
var (minX, minY) = _filterPopupPanel.CombinedMinimumSize;
|
|
||||||
var box = UIBox2.FromDimensions(globalPos - (FilterPopupWidth, 0), (Math.Max(minX, FilterPopupWidth), minY));
|
|
||||||
UserInterfaceManager.ModalRoot.AddChild(_filterPopup);
|
|
||||||
_filterPopup.Open(box);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_filterPopup.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnChannelSelectorToggled(BaseButton.ButtonToggledEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Pressed)
|
|
||||||
{
|
|
||||||
var globalLeft = GlobalPosition.X;
|
|
||||||
var globalBot = GlobalPosition.Y + Height;
|
|
||||||
var box = UIBox2.FromDimensions((globalLeft, globalBot), (SizeBox.Width, AlertsUI.ChatSeparation));
|
|
||||||
UserInterfaceManager.ModalRoot.AddChild(_channelSelectorPopup);
|
|
||||||
_channelSelectorPopup.Open(box);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_channelSelectorPopup.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnFilterPopupHide()
|
|
||||||
{
|
|
||||||
OnPopupHide(_filterPopup, _filterButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnChannelSelectorPopupHide()
|
|
||||||
{
|
|
||||||
OnPopupHide(_channelSelectorPopup, _channelSelector);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPopupHide(Control popup, BaseButton button)
|
|
||||||
{
|
|
||||||
UserInterfaceManager.ModalRoot.RemoveChild(popup);
|
|
||||||
// this weird check here is because the hiding of the popup happens prior to the button
|
|
||||||
// receiving the keydown, which would cause it to then become unpressed
|
|
||||||
// and reopen immediately. To avoid this, if the popup was hidden due to clicking on the button,
|
|
||||||
// we will not auto-unpress the button, instead leaving it up to the button toggle logic
|
|
||||||
// (and this requires the button to be set to EnableAllKeybinds = true)
|
|
||||||
if (UserInterfaceManager.CurrentlyHovered != button)
|
|
||||||
{
|
|
||||||
button.Pressed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnChannelSelectorItemPressed(BaseButton.ButtonEventArgs obj)
|
|
||||||
{
|
|
||||||
if (obj.Button is not ChannelItemButton button) return;
|
|
||||||
SafelySelectChannel(button.Channel);
|
|
||||||
_channelSelectorPopup.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Selects the indicated channel, clearing out any temporarily-selected channel
|
|
||||||
/// (any currently entered text is preserved). If the specified channel is not selectable,
|
|
||||||
/// will just maintain current selection.
|
|
||||||
/// </summary>
|
|
||||||
public void SelectChannel(ChatChannel toSelect)
|
|
||||||
{
|
|
||||||
_savedSelectedChannel = null;
|
|
||||||
SafelySelectChannel(toSelect);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool SafelySelectChannel(ChatChannel toSelect)
|
|
||||||
{
|
|
||||||
if (toSelect == ChatChannel.Unspecified ||
|
|
||||||
SelectableChannels.Contains(toSelect))
|
|
||||||
{
|
|
||||||
SelectedChannel = toSelect;
|
|
||||||
_channelSelector.Text = ChannelSelectorName(toSelect);
|
|
||||||
_channelSelector.Modulate = ChatHelper.ChatColor(toSelect);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// keep current setting
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
base.KeyBindDown(args);
|
|
||||||
|
|
||||||
if (args.Function == EngineKeyFunctions.UIClick && !_lobbyMode)
|
|
||||||
{
|
|
||||||
_currentDrag = GetDragModeFor(args.RelativePosition);
|
|
||||||
|
|
||||||
if (_currentDrag != DragMode.None)
|
|
||||||
{
|
|
||||||
_dragOffsetTopLeft = args.PointerLocation.Position / UIScale - Position;
|
|
||||||
_dragOffsetBottomRight = Position + Size - args.PointerLocation.Position / UIScale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.CanFocus)
|
|
||||||
{
|
|
||||||
Input.GrabKeyboardFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
base.KeyBindUp(args);
|
|
||||||
|
|
||||||
if (args.Function != EngineKeyFunctions.UIClick || _lobbyMode)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dragOffsetTopLeft = _dragOffsetBottomRight = Vector2.Zero;
|
|
||||||
_currentDrag = DragMode.None;
|
|
||||||
|
|
||||||
// If this is done in MouseDown, Godot won't fire MouseUp as you need focus to receive MouseUps.
|
|
||||||
UserInterfaceManager.KeyboardFocused?.ReleaseKeyboardFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CycleChatChannel(bool forward)
|
|
||||||
{
|
|
||||||
Input.IgnoreNext = true;
|
|
||||||
var channels = SelectableChannels;
|
|
||||||
var idx = channels.IndexOf(SelectedChannel);
|
|
||||||
if (forward)
|
|
||||||
{
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
idx--;
|
|
||||||
}
|
|
||||||
idx = MathHelper.Mod(idx, channels.Count);
|
|
||||||
|
|
||||||
SelectChannel(channels[idx]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InputKeyBindDown(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Function == EngineKeyFunctions.TextReleaseFocus)
|
|
||||||
{
|
|
||||||
Input.ReleaseKeyboardFocus();
|
|
||||||
args.Handle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.Function == ContentKeyFunctions.CycleChatChannelForward)
|
|
||||||
{
|
|
||||||
CycleChatChannel(true);
|
|
||||||
args.Handle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.Function == ContentKeyFunctions.CycleChatChannelBackward)
|
|
||||||
{
|
|
||||||
CycleChatChannel(false);
|
|
||||||
args.Handle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we temporarily selected another channel via a prefx, undo that when we backspace on an empty input
|
|
||||||
if (args.Function == EngineKeyFunctions.TextBackspace && Input.Text.Length == 0 && _savedSelectedChannel.HasValue)
|
|
||||||
{
|
|
||||||
SafelySelectChannel(_savedSelectedChannel.Value);
|
|
||||||
_savedSelectedChannel = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: this drag and drop stuff is somewhat duplicated from Robust BaseWindow but also modified
|
|
||||||
[Flags]
|
|
||||||
private enum DragMode : byte
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Bottom = 1 << 1,
|
|
||||||
Left = 1 << 2
|
|
||||||
}
|
|
||||||
|
|
||||||
private DragMode GetDragModeFor(Vector2 relativeMousePos)
|
|
||||||
{
|
|
||||||
var mode = DragMode.None;
|
|
||||||
|
|
||||||
if (relativeMousePos.Y > Size.Y - DragMarginSize)
|
|
||||||
{
|
|
||||||
mode = DragMode.Bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (relativeMousePos.X < DragMarginSize)
|
|
||||||
{
|
|
||||||
mode |= DragMode.Left;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void MouseMove(GUIMouseMoveEventArgs args)
|
|
||||||
{
|
|
||||||
base.MouseMove(args);
|
|
||||||
|
|
||||||
if (Parent == null || _lobbyMode)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_currentDrag == DragMode.None)
|
|
||||||
{
|
|
||||||
var cursor = CursorShape.Arrow;
|
|
||||||
var previewDragMode = GetDragModeFor(args.RelativePosition);
|
|
||||||
switch (previewDragMode)
|
|
||||||
{
|
|
||||||
case DragMode.Bottom:
|
|
||||||
cursor = CursorShape.VResize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DragMode.Left:
|
|
||||||
cursor = CursorShape.HResize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DragMode.Bottom | DragMode.Left:
|
|
||||||
cursor = CursorShape.Crosshair;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultCursorShape = cursor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var top = Rect.Top;
|
|
||||||
var bottom = Rect.Bottom;
|
|
||||||
var left = Rect.Left;
|
|
||||||
var right = Rect.Right;
|
|
||||||
var (minSizeX, minSizeY) = CombinedMinimumSize;
|
|
||||||
if ((_currentDrag & DragMode.Bottom) == DragMode.Bottom)
|
|
||||||
{
|
|
||||||
bottom = Math.Max(args.GlobalPosition.Y + _dragOffsetBottomRight.Y, top + minSizeY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_currentDrag & DragMode.Left) == DragMode.Left)
|
|
||||||
{
|
|
||||||
var maxX = right - minSizeX;
|
|
||||||
left = Math.Min(args.GlobalPosition.X - _dragOffsetTopLeft.X, maxX);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClampSize(left, bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UIScaleChanged()
|
|
||||||
{
|
|
||||||
base.UIScaleChanged();
|
|
||||||
ClampAfterDelay();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClydeOnOnWindowResized(WindowResizedEventArgs obj)
|
|
||||||
{
|
|
||||||
ClampAfterDelay();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClampAfterDelay()
|
|
||||||
{
|
|
||||||
if (!_lobbyMode)
|
|
||||||
_clampIn = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void FrameUpdate(FrameEventArgs args)
|
|
||||||
{
|
|
||||||
base.FrameUpdate(args);
|
|
||||||
if (_lobbyMode) return;
|
|
||||||
// we do the clamping after a delay (after UI scale / window resize)
|
|
||||||
// because we need to wait for our parent container to properly resize
|
|
||||||
// first, so we can calculate where we should go. If we do it right away,
|
|
||||||
// we won't have the correct values from the parent to know how to adjust our margins.
|
|
||||||
if (_clampIn <= 0) return;
|
|
||||||
_clampIn -= 1;
|
|
||||||
if (_clampIn == 0) ClampSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClampSize(float? desiredLeft = null, float? desiredBottom = null)
|
|
||||||
{
|
|
||||||
if (Parent == null || _lobbyMode) return;
|
|
||||||
var top = Rect.Top;
|
|
||||||
var right = Rect.Right;
|
|
||||||
var left = desiredLeft ?? Rect.Left;
|
|
||||||
var bottom = desiredBottom ?? Rect.Bottom;
|
|
||||||
|
|
||||||
// clamp so it doesn't go too high or low (leave space for alerts UI)
|
|
||||||
var maxBottom = Parent.Size.Y - MinDistanceFromBottom;
|
|
||||||
if (maxBottom <= MinHeight)
|
|
||||||
{
|
|
||||||
// we can't fit in our given space (window made awkwardly small), so give up
|
|
||||||
// and overlap at our min height
|
|
||||||
bottom = MinHeight;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bottom = Math.Clamp(bottom, MinHeight, maxBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
var maxLeft = Parent.Size.X - MinWidth;
|
|
||||||
if (maxLeft <= MinLeft)
|
|
||||||
{
|
|
||||||
// window too narrow, give up and overlap at our max left
|
|
||||||
left = maxLeft;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
left = Math.Clamp(left, MinLeft, maxLeft);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutContainer.SetMarginLeft(this, -((right + 10) - left));
|
|
||||||
LayoutContainer.SetMarginBottom(this, bottom);
|
|
||||||
OnResized?.Invoke(new ChatResizedEventArgs(bottom));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void MouseExited()
|
|
||||||
{
|
|
||||||
base.MouseExited();
|
|
||||||
|
|
||||||
if (_currentDrag == DragMode.None && !_lobbyMode)
|
|
||||||
{
|
|
||||||
DefaultCursorShape = CursorShape.Arrow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void InputOnTextChanged(LineEdit.LineEditEventArgs obj)
|
|
||||||
{
|
|
||||||
// switch temporarily to a different channel if an alias prefix has been entered.
|
|
||||||
|
|
||||||
// are we already temporarily switching to a channel?
|
|
||||||
if (_savedSelectedChannel.HasValue) return;
|
|
||||||
|
|
||||||
var trimmed = obj.Text.Trim();
|
|
||||||
if (trimmed.Length == 0 || trimmed.Length > 1) return;
|
|
||||||
|
|
||||||
var channel = GetChannelFromPrefix(trimmed[0]);
|
|
||||||
var prevChannel = SelectedChannel;
|
|
||||||
if (channel == null || !SafelySelectChannel(channel.Value)) return;
|
|
||||||
// we ate the prefix and auto-switched (temporarily) to the channel with that prefix
|
|
||||||
_savedSelectedChannel = prevChannel;
|
|
||||||
Input.Text = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ChatChannel? GetChannelFromPrefix(char prefix)
|
|
||||||
{
|
|
||||||
return prefix switch
|
|
||||||
{
|
|
||||||
ChatManager.MeAlias => ChatChannel.Emotes,
|
|
||||||
ChatManager.RadioAlias => ChatChannel.Radio,
|
|
||||||
ChatManager.AdminChatAlias => ChatChannel.AdminChat,
|
|
||||||
ChatManager.OOCAlias => ChatChannel.OOC,
|
|
||||||
ChatManager.ConCmdSlash => ChatChannel.Unspecified,
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetPrefixFromChannel(ChatChannel channel)
|
|
||||||
{
|
|
||||||
char? prefixChar = channel switch
|
|
||||||
{
|
|
||||||
ChatChannel.Emotes => ChatManager.MeAlias,
|
|
||||||
ChatChannel.Radio => ChatManager.RadioAlias,
|
|
||||||
ChatChannel.AdminChat => ChatManager.AdminChatAlias,
|
|
||||||
ChatChannel.OOC => ChatManager.OOCAlias,
|
|
||||||
ChatChannel.Unspecified => ChatManager.ConCmdSlash,
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
|
|
||||||
return prefixChar.ToString() ?? string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ChannelSelectorName(ChatChannel channel)
|
|
||||||
{
|
|
||||||
return channel switch
|
|
||||||
{
|
|
||||||
ChatChannel.AdminChat => Loc.GetString("hud-chatbox-admin"),
|
|
||||||
ChatChannel.Unspecified => Loc.GetString("hud-chatbox-console"),
|
|
||||||
_ => Loc.GetString(channel.ToString())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddLine(string message, ChatChannel channel, Color color)
|
|
||||||
{
|
|
||||||
if (Disposed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var formatted = new FormattedMessage(3);
|
|
||||||
formatted.PushColor(color);
|
|
||||||
formatted.AddMarkup(message);
|
|
||||||
formatted.Pop();
|
|
||||||
Contents.AddMessage(formatted);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InputOnFocusExit(LineEdit.LineEditEventArgs obj)
|
|
||||||
{
|
|
||||||
// undo the temporary selection, otherwise it will be odd if user
|
|
||||||
// comes back to it later only to have their selection cleared upon sending
|
|
||||||
if (!_savedSelectedChannel.HasValue) return;
|
|
||||||
SafelySelectChannel(_savedSelectedChannel.Value);
|
|
||||||
_savedSelectedChannel = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Input_OnTextEntered(LineEdit.LineEditEventArgs args)
|
|
||||||
{
|
|
||||||
// We set it there to true so it's set to false by TextSubmitted.Invoke if necessary
|
|
||||||
ClearOnEnter = true;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(args.Text))
|
|
||||||
{
|
|
||||||
TextSubmitted?.Invoke(this, GetPrefixFromChannel(SelectedChannel)
|
|
||||||
+ args.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ClearOnEnter)
|
|
||||||
{
|
|
||||||
Input.Clear();
|
|
||||||
if (_savedSelectedChannel.HasValue)
|
|
||||||
{
|
|
||||||
SafelySelectChannel(_savedSelectedChannel.Value);
|
|
||||||
_savedSelectedChannel = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ReleaseFocusOnEnter)
|
|
||||||
{
|
|
||||||
Input.ReleaseKeyboardFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only needed to avoid the issue where right click on the button closes the popup
|
|
||||||
/// but leaves the button highlighted.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class ChannelSelectorButton : Button
|
|
||||||
{
|
|
||||||
public ChannelSelectorButton()
|
|
||||||
{
|
|
||||||
// needed so the popup is untoggled regardless of which key is pressed when hovering this button.
|
|
||||||
// If we don't have this, then right clicking the button while it's toggled on will hide
|
|
||||||
// the popup but keep the button toggled on
|
|
||||||
Mode = ActionMode.Press;
|
|
||||||
EnableAllKeybinds = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
// needed since we need EnableAllKeybinds - don't double-send both UI click and Use
|
|
||||||
if (args.Function == EngineKeyFunctions.Use) return;
|
|
||||||
base.KeyBindDown(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class FilterButton : ContainerButton
|
|
||||||
{
|
|
||||||
private static readonly Color ColorNormal = Color.FromHex("#7b7e9e");
|
|
||||||
private static readonly Color ColorHovered = Color.FromHex("#9699bb");
|
|
||||||
private static readonly Color ColorPressed = Color.FromHex("#789B8C");
|
|
||||||
|
|
||||||
private readonly TextureRect _textureRect;
|
|
||||||
|
|
||||||
public FilterButton()
|
|
||||||
{
|
|
||||||
var filterTexture = IoCManager.Resolve<IResourceCache>()
|
|
||||||
.GetTexture("/Textures/Interface/Nano/filter.svg.96dpi.png");
|
|
||||||
|
|
||||||
// needed for same reason as ChannelSelectorButton
|
|
||||||
Mode = ActionMode.Press;
|
|
||||||
EnableAllKeybinds = true;
|
|
||||||
|
|
||||||
AddChild(
|
|
||||||
(_textureRect = new TextureRect
|
|
||||||
{
|
|
||||||
Texture = filterTexture,
|
|
||||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter
|
|
||||||
})
|
|
||||||
);
|
|
||||||
ToggleMode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
// needed since we need EnableAllKeybinds - don't double-send both UI click and Use
|
|
||||||
if (args.Function == EngineKeyFunctions.Use) return;
|
|
||||||
base.KeyBindDown(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateChildColors()
|
|
||||||
{
|
|
||||||
if (_textureRect == null) return;
|
|
||||||
switch (DrawMode)
|
|
||||||
{
|
|
||||||
case DrawModeEnum.Normal:
|
|
||||||
_textureRect.ModulateSelfOverride = ColorNormal;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DrawModeEnum.Pressed:
|
|
||||||
_textureRect.ModulateSelfOverride = ColorPressed;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DrawModeEnum.Hover:
|
|
||||||
_textureRect.ModulateSelfOverride = ColorHovered;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DrawModeEnum.Disabled:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void DrawModeChanged()
|
|
||||||
{
|
|
||||||
base.DrawModeChanged();
|
|
||||||
UpdateChildColors();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void StylePropertiesChanged()
|
|
||||||
{
|
|
||||||
base.StylePropertiesChanged();
|
|
||||||
UpdateChildColors();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ChannelItemButton : Button
|
|
||||||
{
|
|
||||||
public readonly ChatChannel Channel;
|
|
||||||
|
|
||||||
public ChannelItemButton(ChatChannel channel)
|
|
||||||
{
|
|
||||||
Channel = channel;
|
|
||||||
AddStyleClass(StyleNano.StyleClassChatChannelSelectorButton);
|
|
||||||
Text = ChatBox.ChannelSelectorName(channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ChannelFilterCheckbox : CheckBox
|
|
||||||
{
|
|
||||||
public readonly ChatChannel Channel;
|
|
||||||
|
|
||||||
public ChannelFilterCheckbox(ChatChannel channel, byte? unreadCount)
|
|
||||||
{
|
|
||||||
Channel = channel;
|
|
||||||
|
|
||||||
UpdateText(unreadCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateText(byte? unread)
|
|
||||||
{
|
|
||||||
var name = Channel switch
|
|
||||||
{
|
|
||||||
ChatChannel.AdminChat => Loc.GetString("hud-chatbox-admin"),
|
|
||||||
ChatChannel.Unspecified => throw new InvalidOperationException(
|
|
||||||
"cannot create chat filter for Unspecified"),
|
|
||||||
_ => Loc.GetString(Channel.ToString())
|
|
||||||
};
|
|
||||||
|
|
||||||
if (unread > 0)
|
|
||||||
{
|
|
||||||
Text = name + " (" + (unread > 9 ? "9+" : unread) + ")";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Text = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateUnreadCount(byte? unread)
|
|
||||||
{
|
|
||||||
UpdateText(unread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly struct ChatResizedEventArgs
|
|
||||||
{
|
|
||||||
/// new bottom that the chat rect is going to have in virtual pixels
|
|
||||||
/// after the imminent relayout
|
|
||||||
public readonly float NewBottom;
|
|
||||||
|
|
||||||
public ChatResizedEventArgs(float newBottom)
|
|
||||||
{
|
|
||||||
NewBottom = newBottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
Content.Client/Chat/UI/ChatBox.xaml
Normal file
24
Content.Client/Chat/UI/ChatBox.xaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<Control xmlns="https://spacestation14.io"
|
||||||
|
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||||
|
xmlns:chatUI="clr-namespace:Content.Client.Chat.UI"
|
||||||
|
MouseFilter="Stop"
|
||||||
|
MinSize="200 128">
|
||||||
|
<PanelContainer>
|
||||||
|
<PanelContainer.PanelOverride>
|
||||||
|
<gfx:StyleBoxFlat BackgroundColor="#25252AAA" />
|
||||||
|
</PanelContainer.PanelOverride>
|
||||||
|
|
||||||
|
<BoxContainer Orientation="Vertical">
|
||||||
|
<OutputPanel Name="Contents" VerticalExpand="True" />
|
||||||
|
<PanelContainer StyleClasses="ChatSubPanel">
|
||||||
|
<BoxContainer Orientation="Horizontal" SeparationOverride="4">
|
||||||
|
<chatUI:ChannelSelectorButton Name="ChannelSelector" ToggleMode="True"
|
||||||
|
StyleClasses="chatSelectorOptionButton" MinWidth="75" />
|
||||||
|
<HistoryLineEdit Name="Input" PlaceHolder="{Loc 'hud-chatbox-info'}" HorizontalExpand="True"
|
||||||
|
StyleClasses="chatLineEdit" />
|
||||||
|
<chatUI:FilterButton Name="FilterButton" StyleClasses="chatFilterOptionButton" />
|
||||||
|
</BoxContainer>
|
||||||
|
</PanelContainer>
|
||||||
|
</BoxContainer>
|
||||||
|
</PanelContainer>
|
||||||
|
</Control>
|
||||||
740
Content.Client/Chat/UI/ChatBox.xaml.cs
Normal file
740
Content.Client/Chat/UI/ChatBox.xaml.cs
Normal file
@@ -0,0 +1,740 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Client.Alerts.UI;
|
||||||
|
using Content.Client.Chat.Managers;
|
||||||
|
using Content.Client.Resources;
|
||||||
|
using Content.Client.Stylesheets;
|
||||||
|
using Content.Shared.Chat;
|
||||||
|
using Content.Shared.Input;
|
||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.Chat.UI
|
||||||
|
{
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public partial class ChatBox : Control
|
||||||
|
{
|
||||||
|
[Dependency] protected readonly IChatManager ChatMgr = default!;
|
||||||
|
|
||||||
|
// order in which the available channel filters show up when available
|
||||||
|
private static readonly ChatChannel[] ChannelFilterOrder =
|
||||||
|
{
|
||||||
|
ChatChannel.Local,
|
||||||
|
ChatChannel.Emotes,
|
||||||
|
ChatChannel.Radio,
|
||||||
|
ChatChannel.OOC,
|
||||||
|
ChatChannel.Dead,
|
||||||
|
ChatChannel.Admin,
|
||||||
|
ChatChannel.Server
|
||||||
|
};
|
||||||
|
|
||||||
|
// order in which the channels show up in the channel selector
|
||||||
|
private static readonly ChatSelectChannel[] ChannelSelectorOrder =
|
||||||
|
{
|
||||||
|
ChatSelectChannel.Local,
|
||||||
|
ChatSelectChannel.Emotes,
|
||||||
|
ChatSelectChannel.Radio,
|
||||||
|
ChatSelectChannel.OOC,
|
||||||
|
ChatSelectChannel.Dead,
|
||||||
|
ChatSelectChannel.Admin
|
||||||
|
// NOTE: Console is not in there and it can never be permanently selected.
|
||||||
|
// You can, however, still submit commands as console by prefixing with /.
|
||||||
|
};
|
||||||
|
|
||||||
|
public const char AliasLocal = '.';
|
||||||
|
public const char AliasConsole = '/';
|
||||||
|
public const char AliasDead = '\\';
|
||||||
|
public const char AliasOOC = '[';
|
||||||
|
public const char AliasEmotes = '@';
|
||||||
|
public const char AliasAdmin = ']';
|
||||||
|
public const char AliasRadio = ';';
|
||||||
|
|
||||||
|
private static readonly Dictionary<char, ChatSelectChannel> PrefixToChannel = new()
|
||||||
|
{
|
||||||
|
{AliasLocal, ChatSelectChannel.Local},
|
||||||
|
{AliasConsole, ChatSelectChannel.Console},
|
||||||
|
{AliasOOC, ChatSelectChannel.OOC},
|
||||||
|
{AliasEmotes, ChatSelectChannel.Emotes},
|
||||||
|
{AliasAdmin, ChatSelectChannel.Admin},
|
||||||
|
{AliasRadio, ChatSelectChannel.Radio},
|
||||||
|
{AliasDead, ChatSelectChannel.Dead}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Dictionary<ChatSelectChannel, char> ChannelPrefixes =
|
||||||
|
PrefixToChannel.ToDictionary(kv => kv.Value, kv => kv.Key);
|
||||||
|
|
||||||
|
private const float FilterPopupWidth = 110;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently default channel that will be used if no prefix is specified.
|
||||||
|
/// </summary>
|
||||||
|
public ChatSelectChannel SelectedChannel { get; private set; } = ChatSelectChannel.OOC;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The "preferred" channel. Will be switched to if permissions change and the channel becomes available,
|
||||||
|
/// such as by re-entering body. Gets changed if the user manually selects a channel with the buttons.
|
||||||
|
/// </summary>
|
||||||
|
public ChatSelectChannel PreferredChannel { get; set; } = ChatSelectChannel.OOC;
|
||||||
|
|
||||||
|
public bool ReleaseFocusOnEnter { get; set; } = true;
|
||||||
|
|
||||||
|
private readonly Popup _channelSelectorPopup;
|
||||||
|
private readonly BoxContainer _channelSelectorHBox;
|
||||||
|
private readonly Popup _filterPopup;
|
||||||
|
private readonly PanelContainer _filterPopupPanel;
|
||||||
|
private readonly BoxContainer _filterVBox;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When lobbyMode is false, will position / add to correct location in StateRoot and
|
||||||
|
/// be resizable.
|
||||||
|
/// wWen true, will leave layout up to parent and not be resizable.
|
||||||
|
/// </summary>
|
||||||
|
public ChatBox()
|
||||||
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
|
||||||
|
LayoutContainer.SetMarginLeft(this, 4);
|
||||||
|
LayoutContainer.SetMarginRight(this, 4);
|
||||||
|
|
||||||
|
_filterPopup = new Popup
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_filterPopupPanel = new PanelContainer
|
||||||
|
{
|
||||||
|
StyleClasses = {StyleNano.StyleClassBorderedWindowPanel},
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new Control {MinSize = (4, 0)},
|
||||||
|
(_filterVBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Margin = new Thickness(0, 10),
|
||||||
|
Orientation = BoxContainer.LayoutOrientation.Vertical,
|
||||||
|
SeparationOverride = 4
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_channelSelectorPopup = new Popup
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_channelSelectorHBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
||||||
|
SeparationOverride = 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ChannelSelector.OnToggled += OnChannelSelectorToggled;
|
||||||
|
FilterButton.OnToggled += OnFilterButtonToggled;
|
||||||
|
Input.OnKeyBindDown += InputKeyBindDown;
|
||||||
|
Input.OnTextEntered += Input_OnTextEntered;
|
||||||
|
Input.OnTextChanged += InputOnTextChanged;
|
||||||
|
_channelSelectorPopup.OnPopupHide += OnChannelSelectorPopupHide;
|
||||||
|
_filterPopup.OnPopupHide += OnFilterPopupHide;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void EnteredTree()
|
||||||
|
{
|
||||||
|
base.EnteredTree();
|
||||||
|
|
||||||
|
ChatMgr.MessageAdded += WriteChatMessage;
|
||||||
|
ChatMgr.ChatPermissionsUpdated += OnChatPermissionsUpdated;
|
||||||
|
ChatMgr.UnreadMessageCountsUpdated += UpdateUnreadMessageCounts;
|
||||||
|
ChatMgr.FiltersUpdated += Repopulate;
|
||||||
|
|
||||||
|
// The chat manager may have messages logged from before there was a chat box.
|
||||||
|
// In this case, these messages will be marked as unread despite the filters allowing them through.
|
||||||
|
// Tell chat manager to clear these.
|
||||||
|
ChatMgr.ClearUnfilteredUnreads();
|
||||||
|
|
||||||
|
ChatPermissionsUpdated(0);
|
||||||
|
UpdateChannelSelectButton();
|
||||||
|
Repopulate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ExitedTree()
|
||||||
|
{
|
||||||
|
base.ExitedTree();
|
||||||
|
|
||||||
|
ChatMgr.MessageAdded -= WriteChatMessage;
|
||||||
|
ChatMgr.ChatPermissionsUpdated -= OnChatPermissionsUpdated;
|
||||||
|
ChatMgr.UnreadMessageCountsUpdated -= UpdateUnreadMessageCounts;
|
||||||
|
ChatMgr.FiltersUpdated -= Repopulate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnChatPermissionsUpdated(ChatPermissionsUpdatedEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
ChatPermissionsUpdated(eventArgs.OldSelectableChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChatPermissionsUpdated(ChatSelectChannel oldSelectable)
|
||||||
|
{
|
||||||
|
// update the channel selector
|
||||||
|
_channelSelectorHBox.Children.Clear();
|
||||||
|
foreach (var selectableChannel in ChannelSelectorOrder)
|
||||||
|
{
|
||||||
|
if ((ChatMgr.SelectableChannels & selectableChannel) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var newButton = new ChannelItemButton(selectableChannel);
|
||||||
|
newButton.OnPressed += OnChannelSelectorItemPressed;
|
||||||
|
_channelSelectorHBox.AddChild(newButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selected channel no longer available, switch to OOC?
|
||||||
|
if ((ChatMgr.SelectableChannels & SelectedChannel) == 0)
|
||||||
|
{
|
||||||
|
// Handle local -> dead mapping when you e.g. ghost.
|
||||||
|
// Only necessary for admins because they always have deadchat
|
||||||
|
// so the normal preferred check won't see it as newly available and do nothing.
|
||||||
|
var mappedSelect = MapLocalIfGhost(SelectedChannel);
|
||||||
|
if ((ChatMgr.SelectableChannels & mappedSelect) != 0)
|
||||||
|
SafelySelectChannel(mappedSelect);
|
||||||
|
else
|
||||||
|
SafelySelectChannel(ChatSelectChannel.OOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the preferred channel just became available, switch to it.
|
||||||
|
var pref = MapLocalIfGhost(PreferredChannel);
|
||||||
|
if ((oldSelectable & pref) == 0 && (ChatMgr.SelectableChannels & pref) != 0)
|
||||||
|
SafelySelectChannel(pref);
|
||||||
|
|
||||||
|
// update the channel filters
|
||||||
|
_filterVBox.Children.Clear();
|
||||||
|
foreach (var channelFilter in ChannelFilterOrder)
|
||||||
|
{
|
||||||
|
if ((ChatMgr.FilterableChannels & channelFilter) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int? unreadCount = null;
|
||||||
|
if (ChatMgr.UnreadMessages.TryGetValue(channelFilter, out var unread))
|
||||||
|
unreadCount = unread;
|
||||||
|
|
||||||
|
var newCheckBox = new ChannelFilterCheckbox(channelFilter, unreadCount)
|
||||||
|
{
|
||||||
|
Pressed = (ChatMgr.ChannelFilters & channelFilter) != 0
|
||||||
|
};
|
||||||
|
|
||||||
|
newCheckBox.OnToggled += OnFilterCheckboxToggled;
|
||||||
|
_filterVBox.AddChild(newCheckBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateChannelSelectButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateUnreadMessageCounts()
|
||||||
|
{
|
||||||
|
foreach (var channelFilter in _filterVBox.Children)
|
||||||
|
{
|
||||||
|
if (channelFilter is not ChannelFilterCheckbox filterCheckbox) continue;
|
||||||
|
if (ChatMgr.UnreadMessages.TryGetValue(filterCheckbox.Channel, out var unread))
|
||||||
|
{
|
||||||
|
filterCheckbox.UpdateUnreadCount(unread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filterCheckbox.UpdateUnreadCount(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnFilterCheckboxToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Button is not ChannelFilterCheckbox checkbox)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ChatMgr.OnFilterButtonToggled(checkbox.Channel, checkbox.Pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnFilterButtonToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Pressed)
|
||||||
|
{
|
||||||
|
var globalPos = FilterButton.GlobalPosition;
|
||||||
|
var (minX, minY) = _filterPopupPanel.MinSize;
|
||||||
|
var box = UIBox2.FromDimensions(globalPos - (FilterPopupWidth, 0),
|
||||||
|
(Math.Max(minX, FilterPopupWidth), minY));
|
||||||
|
UserInterfaceManager.ModalRoot.AddChild(_filterPopup);
|
||||||
|
_filterPopup.Open(box);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filterPopup.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnChannelSelectorToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Pressed)
|
||||||
|
{
|
||||||
|
var globalLeft = GlobalPosition.X;
|
||||||
|
var globalBot = GlobalPosition.Y + Height;
|
||||||
|
var box = UIBox2.FromDimensions((globalLeft, globalBot), (SizeBox.Width, AlertsUI.ChatSeparation));
|
||||||
|
UserInterfaceManager.ModalRoot.AddChild(_channelSelectorPopup);
|
||||||
|
_channelSelectorPopup.Open(box);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_channelSelectorPopup.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnFilterPopupHide()
|
||||||
|
{
|
||||||
|
OnPopupHide(_filterPopup, FilterButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnChannelSelectorPopupHide()
|
||||||
|
{
|
||||||
|
OnPopupHide(_channelSelectorPopup, ChannelSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPopupHide(Control popup, BaseButton button)
|
||||||
|
{
|
||||||
|
UserInterfaceManager.ModalRoot.RemoveChild(popup);
|
||||||
|
|
||||||
|
// this weird check here is because the hiding of the popup happens prior to the button
|
||||||
|
// receiving the keydown, which would cause it to then become unpressed
|
||||||
|
// and reopen immediately. To avoid this, if the popup was hidden due to clicking on the button,
|
||||||
|
// we will not auto-unpress the button, instead leaving it up to the button toggle logic
|
||||||
|
// (and this requires the button to be set to EnableAllKeybinds = true)
|
||||||
|
if (UserInterfaceManager.CurrentlyHovered != button)
|
||||||
|
{
|
||||||
|
button.Pressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnChannelSelectorItemPressed(BaseButton.ButtonEventArgs obj)
|
||||||
|
{
|
||||||
|
if (obj.Button is not ChannelItemButton button)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PreferredChannel = button.Channel;
|
||||||
|
SafelySelectChannel(button.Channel);
|
||||||
|
_channelSelectorPopup.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SafelySelectChannel(ChatSelectChannel toSelect)
|
||||||
|
{
|
||||||
|
toSelect = MapLocalIfGhost(toSelect);
|
||||||
|
if ((ChatMgr.SelectableChannels & toSelect) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SelectedChannel = toSelect;
|
||||||
|
UpdateChannelSelectButton();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateChannelSelectButton()
|
||||||
|
{
|
||||||
|
var (prefixChannel, _) = SplitInputContents();
|
||||||
|
|
||||||
|
var channel = prefixChannel == 0 ? SelectedChannel : prefixChannel;
|
||||||
|
|
||||||
|
ChannelSelector.Text = ChannelSelectorName(channel);
|
||||||
|
ChannelSelector.Modulate = ChannelSelectColor(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
base.KeyBindDown(args);
|
||||||
|
|
||||||
|
if (args.CanFocus)
|
||||||
|
{
|
||||||
|
Input.GrabKeyboardFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CycleChatChannel(bool forward)
|
||||||
|
{
|
||||||
|
Input.IgnoreNext = true;
|
||||||
|
|
||||||
|
var idx = Array.IndexOf(ChannelSelectorOrder, SelectedChannel);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// go over every channel until we find one we can actually select.
|
||||||
|
idx += forward ? 1 : -1;
|
||||||
|
idx = MathHelper.Mod(idx, ChannelSelectorOrder.Length);
|
||||||
|
} while ((ChatMgr.SelectableChannels & ChannelSelectorOrder[idx]) == 0);
|
||||||
|
|
||||||
|
SafelySelectChannel(ChannelSelectorOrder[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Repopulate()
|
||||||
|
{
|
||||||
|
Contents.Clear();
|
||||||
|
|
||||||
|
foreach (var msg in ChatMgr.History)
|
||||||
|
{
|
||||||
|
WriteChatMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WriteChatMessage(StoredChatMessage message)
|
||||||
|
{
|
||||||
|
Logger.DebugS("chat", $"{message.Channel}: {message.Message}");
|
||||||
|
|
||||||
|
if (IsFilteredOut(message.Channel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: Can make this "smarter" later by only setting it false when the message has been scrolled to
|
||||||
|
message.Read = true;
|
||||||
|
|
||||||
|
var messageText = FormattedMessage.EscapeText(message.Message);
|
||||||
|
if (!string.IsNullOrEmpty(message.MessageWrap))
|
||||||
|
{
|
||||||
|
messageText = string.Format(message.MessageWrap, messageText);
|
||||||
|
}
|
||||||
|
|
||||||
|
var color = message.MessageColorOverride != Color.Transparent
|
||||||
|
? message.MessageColorOverride
|
||||||
|
: ChatHelper.ChatColor(message.Channel);
|
||||||
|
|
||||||
|
AddLine(messageText, message.Channel, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsFilteredOut(ChatChannel channel)
|
||||||
|
{
|
||||||
|
return (ChatMgr.ChannelFilters & channel) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputKeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Function == EngineKeyFunctions.TextReleaseFocus)
|
||||||
|
{
|
||||||
|
Input.ReleaseKeyboardFocus();
|
||||||
|
args.Handle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Function == ContentKeyFunctions.CycleChatChannelForward)
|
||||||
|
{
|
||||||
|
CycleChatChannel(true);
|
||||||
|
args.Handle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Function == ContentKeyFunctions.CycleChatChannelBackward)
|
||||||
|
{
|
||||||
|
CycleChatChannel(false);
|
||||||
|
args.Handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private (ChatSelectChannel selChannel, ReadOnlyMemory<char> text) SplitInputContents()
|
||||||
|
{
|
||||||
|
var text = Input.Text.AsMemory().Trim();
|
||||||
|
if (text.Length == 0)
|
||||||
|
return default;
|
||||||
|
|
||||||
|
var prefixChar = text.Span[0];
|
||||||
|
var channel = GetChannelFromPrefix(prefixChar);
|
||||||
|
|
||||||
|
if ((ChatMgr.SelectableChannels & channel) != 0)
|
||||||
|
// Cut off prefix if it's valid and we can use the channel in question.
|
||||||
|
text = text[1..];
|
||||||
|
else
|
||||||
|
channel = 0;
|
||||||
|
|
||||||
|
channel = MapLocalIfGhost(channel);
|
||||||
|
|
||||||
|
// Trim from start again to cut out any whitespace between the prefix and message, if any.
|
||||||
|
return (channel, text.TrimStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputOnTextChanged(LineEdit.LineEditEventArgs obj)
|
||||||
|
{
|
||||||
|
// Update channel select button to correct channel if we have a prefix.
|
||||||
|
UpdateChannelSelectButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ChatSelectChannel GetChannelFromPrefix(char prefix)
|
||||||
|
{
|
||||||
|
return PrefixToChannel.GetValueOrDefault(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char GetPrefixFromChannel(ChatSelectChannel channel)
|
||||||
|
{
|
||||||
|
return ChannelPrefixes.GetValueOrDefault(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ChannelSelectorName(ChatSelectChannel channel)
|
||||||
|
{
|
||||||
|
return Loc.GetString($"hud-chatbox-select-channel-{channel}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color ChannelSelectColor(ChatSelectChannel channel)
|
||||||
|
{
|
||||||
|
return channel switch
|
||||||
|
{
|
||||||
|
ChatSelectChannel.Radio => Color.Green,
|
||||||
|
ChatSelectChannel.OOC => Color.LightSkyBlue,
|
||||||
|
ChatSelectChannel.Dead => Color.MediumPurple,
|
||||||
|
ChatSelectChannel.Admin => Color.Red,
|
||||||
|
_ => Color.DarkGray
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLine(string message, ChatChannel channel, Color color)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!Disposed);
|
||||||
|
|
||||||
|
var formatted = new FormattedMessage(3);
|
||||||
|
formatted.PushColor(color);
|
||||||
|
formatted.AddMarkup(message);
|
||||||
|
formatted.Pop();
|
||||||
|
Contents.AddMessage(formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Input_OnTextEntered(LineEdit.LineEditEventArgs args)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(args.Text))
|
||||||
|
{
|
||||||
|
var (prefixChannel, text) = SplitInputContents();
|
||||||
|
|
||||||
|
// Check if message is longer than the character limit
|
||||||
|
if (text.Length > ChatMgr.MaxMessageLength)
|
||||||
|
{
|
||||||
|
string locWarning = Loc.GetString(
|
||||||
|
"chat-manager-max-message-length",
|
||||||
|
("maxMessageLength", ChatMgr.MaxMessageLength));
|
||||||
|
|
||||||
|
AddLine(locWarning, ChatChannel.Server, Color.Orange);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMgr.OnChatBoxTextSubmitted(this, text, prefixChannel == 0 ? SelectedChannel : prefixChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
Input.Clear();
|
||||||
|
UpdateChannelSelectButton();
|
||||||
|
|
||||||
|
if (ReleaseFocusOnEnter)
|
||||||
|
Input.ReleaseKeyboardFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Focus(ChatSelectChannel? channel = null)
|
||||||
|
{
|
||||||
|
var selectStart = Index.End;
|
||||||
|
if (channel != null)
|
||||||
|
{
|
||||||
|
channel = MapLocalIfGhost(channel.Value);
|
||||||
|
|
||||||
|
// Channel not selectable, just do NOTHING (not even focus).
|
||||||
|
if (!((ChatMgr.SelectableChannels & channel.Value) != 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var (_, text) = SplitInputContents();
|
||||||
|
|
||||||
|
var newPrefix = GetPrefixFromChannel(channel.Value);
|
||||||
|
DebugTools.Assert(newPrefix != default, "Focus channel must have prefix!");
|
||||||
|
|
||||||
|
if (channel == SelectedChannel)
|
||||||
|
{
|
||||||
|
// New selected channel is just the selected channel,
|
||||||
|
// just remove prefix (if any) and leave text unchanged.
|
||||||
|
|
||||||
|
Input.Text = text.ToString();
|
||||||
|
selectStart = Index.Start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Change prefix to new focused channel prefix and leave text unchanged.
|
||||||
|
Input.Text = string.Concat(newPrefix.ToString(), " ", text.Span);
|
||||||
|
selectStart = Index.FromStart(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateChannelSelectButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
Input.IgnoreNext = true;
|
||||||
|
Input.GrabKeyboardFocus();
|
||||||
|
|
||||||
|
Input.CursorPosition = Input.Text.Length;
|
||||||
|
Input.SelectionStart = selectStart.GetOffset(Input.Text.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatSelectChannel MapLocalIfGhost(ChatSelectChannel channel)
|
||||||
|
{
|
||||||
|
if (channel == ChatSelectChannel.Local && ChatMgr.IsGhost)
|
||||||
|
return ChatSelectChannel.Dead;
|
||||||
|
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only needed to avoid the issue where right click on the button closes the popup
|
||||||
|
/// but leaves the button highlighted.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ChannelSelectorButton : Button
|
||||||
|
{
|
||||||
|
public ChannelSelectorButton()
|
||||||
|
{
|
||||||
|
// needed so the popup is untoggled regardless of which key is pressed when hovering this button.
|
||||||
|
// If we don't have this, then right clicking the button while it's toggled on will hide
|
||||||
|
// the popup but keep the button toggled on
|
||||||
|
Mode = ActionMode.Press;
|
||||||
|
EnableAllKeybinds = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
// needed since we need EnableAllKeybinds - don't double-send both UI click and Use
|
||||||
|
if (args.Function == EngineKeyFunctions.Use)
|
||||||
|
return;
|
||||||
|
|
||||||
|
base.KeyBindDown(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class FilterButton : ContainerButton
|
||||||
|
{
|
||||||
|
private static readonly Color ColorNormal = Color.FromHex("#7b7e9e");
|
||||||
|
private static readonly Color ColorHovered = Color.FromHex("#9699bb");
|
||||||
|
private static readonly Color ColorPressed = Color.FromHex("#789B8C");
|
||||||
|
|
||||||
|
private readonly TextureRect _textureRect;
|
||||||
|
|
||||||
|
public FilterButton()
|
||||||
|
{
|
||||||
|
var filterTexture = IoCManager.Resolve<IResourceCache>()
|
||||||
|
.GetTexture("/Textures/Interface/Nano/filter.svg.96dpi.png");
|
||||||
|
|
||||||
|
// needed for same reason as ChannelSelectorButton
|
||||||
|
Mode = ActionMode.Press;
|
||||||
|
EnableAllKeybinds = true;
|
||||||
|
|
||||||
|
AddChild(
|
||||||
|
(_textureRect = new TextureRect
|
||||||
|
{
|
||||||
|
Texture = filterTexture,
|
||||||
|
HorizontalAlignment = HAlignment.Center,
|
||||||
|
VerticalAlignment = VAlignment.Center
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
ToggleMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
// needed since we need EnableAllKeybinds - don't double-send both UI click and Use
|
||||||
|
if (args.Function == EngineKeyFunctions.Use) return;
|
||||||
|
base.KeyBindDown(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateChildColors()
|
||||||
|
{
|
||||||
|
if (_textureRect == null) return;
|
||||||
|
switch (DrawMode)
|
||||||
|
{
|
||||||
|
case DrawModeEnum.Normal:
|
||||||
|
_textureRect.ModulateSelfOverride = ColorNormal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawModeEnum.Pressed:
|
||||||
|
_textureRect.ModulateSelfOverride = ColorPressed;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawModeEnum.Hover:
|
||||||
|
_textureRect.ModulateSelfOverride = ColorHovered;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawModeEnum.Disabled:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void DrawModeChanged()
|
||||||
|
{
|
||||||
|
base.DrawModeChanged();
|
||||||
|
UpdateChildColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void StylePropertiesChanged()
|
||||||
|
{
|
||||||
|
base.StylePropertiesChanged();
|
||||||
|
UpdateChildColors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ChannelItemButton : Button
|
||||||
|
{
|
||||||
|
public readonly ChatSelectChannel Channel;
|
||||||
|
|
||||||
|
public ChannelItemButton(ChatSelectChannel channel)
|
||||||
|
{
|
||||||
|
Channel = channel;
|
||||||
|
AddStyleClass(StyleNano.StyleClassChatChannelSelectorButton);
|
||||||
|
Text = ChatBox.ChannelSelectorName(channel);
|
||||||
|
|
||||||
|
var prefix = ChatBox.GetPrefixFromChannel(channel);
|
||||||
|
if (prefix != default)
|
||||||
|
Text = Loc.GetString("hud-chatbox-select-name-prefixed", ("name", Text), ("prefix", prefix));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ChannelFilterCheckbox : CheckBox
|
||||||
|
{
|
||||||
|
public readonly ChatChannel Channel;
|
||||||
|
|
||||||
|
public ChannelFilterCheckbox(ChatChannel channel, int? unreadCount)
|
||||||
|
{
|
||||||
|
Channel = channel;
|
||||||
|
|
||||||
|
UpdateText(unreadCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateText(int? unread)
|
||||||
|
{
|
||||||
|
var name = Loc.GetString($"hud-chatbox-channel-{Channel}");
|
||||||
|
|
||||||
|
if (unread > 0)
|
||||||
|
// todo: proper fluent stuff here.
|
||||||
|
name += " (" + (unread > 9 ? "9+" : unread) + ")";
|
||||||
|
|
||||||
|
Text = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateUnreadCount(int? unread)
|
||||||
|
{
|
||||||
|
UpdateText(unread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct ChatResizedEventArgs
|
||||||
|
{
|
||||||
|
/// new bottom that the chat rect is going to have in virtual pixels
|
||||||
|
/// after the imminent relayout
|
||||||
|
public readonly float NewBottom;
|
||||||
|
|
||||||
|
public ChatResizedEventArgs(float newBottom)
|
||||||
|
{
|
||||||
|
NewBottom = newBottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
235
Content.Client/Chat/UI/HudChatBox.cs
Normal file
235
Content.Client/Chat/UI/HudChatBox.cs
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Client.Chat.UI
|
||||||
|
{
|
||||||
|
public class HudChatBox : ChatBox
|
||||||
|
{
|
||||||
|
// TODO: Revisit the resizing stuff after https://github.com/space-wizards/RobustToolbox/issues/1392 is done,
|
||||||
|
// Probably not "supposed" to inject IClyde, but I give up.
|
||||||
|
// I can't find any other way to allow this control to properly resize when the
|
||||||
|
// window is resized. Resized() isn't reliably called when resizing the window,
|
||||||
|
// and layoutcontainer anchor / margin don't seem to adjust how we need
|
||||||
|
// them to when the window is resized. We need it to be able to resize
|
||||||
|
// within some bounds so that it doesn't overlap other UI elements, while still
|
||||||
|
// being freely resizable within those bounds.
|
||||||
|
[Dependency] private readonly IClyde _clyde = default!;
|
||||||
|
|
||||||
|
public const float InitialChatBottom = 235;
|
||||||
|
private const int DragMarginSize = 7;
|
||||||
|
private const int MinDistanceFromBottom = 255;
|
||||||
|
private const int MinLeft = 500;
|
||||||
|
private DragMode _currentDrag = DragMode.None;
|
||||||
|
private Vector2 _dragOffsetTopLeft;
|
||||||
|
private Vector2 _dragOffsetBottomRight;
|
||||||
|
|
||||||
|
private byte _clampIn;
|
||||||
|
|
||||||
|
protected override void EnteredTree()
|
||||||
|
{
|
||||||
|
base.EnteredTree();
|
||||||
|
|
||||||
|
_clyde.OnWindowResized += ClydeOnOnWindowResized;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ExitedTree()
|
||||||
|
{
|
||||||
|
base.ExitedTree();
|
||||||
|
|
||||||
|
_clyde.OnWindowResized -= ClydeOnOnWindowResized;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Function == EngineKeyFunctions.UIClick)
|
||||||
|
{
|
||||||
|
_currentDrag = GetDragModeFor(args.RelativePosition);
|
||||||
|
|
||||||
|
if (_currentDrag != DragMode.None)
|
||||||
|
{
|
||||||
|
_dragOffsetTopLeft = args.PointerLocation.Position / UIScale - Position;
|
||||||
|
_dragOffsetBottomRight = Position + Size - args.PointerLocation.Position / UIScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.KeyBindDown(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
base.KeyBindUp(args);
|
||||||
|
|
||||||
|
if (args.Function != EngineKeyFunctions.UIClick)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dragOffsetTopLeft = _dragOffsetBottomRight = Vector2.Zero;
|
||||||
|
_currentDrag = DragMode.None;
|
||||||
|
|
||||||
|
// If this is done in MouseDown, Godot won't fire MouseUp as you need focus to receive MouseUps.
|
||||||
|
UserInterfaceManager.KeyboardFocused?.ReleaseKeyboardFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: this drag and drop stuff is somewhat duplicated from Robust BaseWindow but also modified
|
||||||
|
[Flags]
|
||||||
|
private enum DragMode : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Bottom = 1 << 1,
|
||||||
|
Left = 1 << 2
|
||||||
|
}
|
||||||
|
|
||||||
|
private DragMode GetDragModeFor(Vector2 relativeMousePos)
|
||||||
|
{
|
||||||
|
var mode = DragMode.None;
|
||||||
|
|
||||||
|
if (relativeMousePos.Y > Size.Y - DragMarginSize)
|
||||||
|
{
|
||||||
|
mode = DragMode.Bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relativeMousePos.X < DragMarginSize)
|
||||||
|
{
|
||||||
|
mode |= DragMode.Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void MouseMove(GUIMouseMoveEventArgs args)
|
||||||
|
{
|
||||||
|
base.MouseMove(args);
|
||||||
|
|
||||||
|
if (Parent == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_currentDrag == DragMode.None)
|
||||||
|
{
|
||||||
|
var cursor = CursorShape.Arrow;
|
||||||
|
var previewDragMode = GetDragModeFor(args.RelativePosition);
|
||||||
|
switch (previewDragMode)
|
||||||
|
{
|
||||||
|
case DragMode.Bottom:
|
||||||
|
cursor = CursorShape.VResize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DragMode.Left:
|
||||||
|
cursor = CursorShape.HResize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DragMode.Bottom | DragMode.Left:
|
||||||
|
cursor = CursorShape.Crosshair;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultCursorShape = cursor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var top = Rect.Top;
|
||||||
|
var bottom = Rect.Bottom;
|
||||||
|
var left = Rect.Left;
|
||||||
|
var right = Rect.Right;
|
||||||
|
var (minSizeX, minSizeY) = MinSize;
|
||||||
|
if ((_currentDrag & DragMode.Bottom) == DragMode.Bottom)
|
||||||
|
{
|
||||||
|
bottom = Math.Max(args.GlobalPosition.Y + _dragOffsetBottomRight.Y, top + minSizeY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentDrag & DragMode.Left) == DragMode.Left)
|
||||||
|
{
|
||||||
|
var maxX = right - minSizeX;
|
||||||
|
left = Math.Min(args.GlobalPosition.X - _dragOffsetTopLeft.X, maxX);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClampSize(left, bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UIScaleChanged()
|
||||||
|
{
|
||||||
|
base.UIScaleChanged();
|
||||||
|
ClampAfterDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClydeOnOnWindowResized(WindowResizedEventArgs obj)
|
||||||
|
{
|
||||||
|
ClampAfterDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClampAfterDelay()
|
||||||
|
{
|
||||||
|
_clampIn = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void FrameUpdate(FrameEventArgs args)
|
||||||
|
{
|
||||||
|
base.FrameUpdate(args);
|
||||||
|
|
||||||
|
// we do the clamping after a delay (after UI scale / window resize)
|
||||||
|
// because we need to wait for our parent container to properly resize
|
||||||
|
// first, so we can calculate where we should go. If we do it right away,
|
||||||
|
// we won't have the correct values from the parent to know how to adjust our margins.
|
||||||
|
if (_clampIn <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_clampIn -= 1;
|
||||||
|
if (_clampIn == 0)
|
||||||
|
ClampSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClampSize(float? desiredLeft = null, float? desiredBottom = null)
|
||||||
|
{
|
||||||
|
if (Parent == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// var top = Rect.Top;
|
||||||
|
var right = Rect.Right;
|
||||||
|
var left = desiredLeft ?? Rect.Left;
|
||||||
|
var bottom = desiredBottom ?? Rect.Bottom;
|
||||||
|
|
||||||
|
// clamp so it doesn't go too high or low (leave space for alerts UI)
|
||||||
|
var maxBottom = Parent.Size.Y - MinDistanceFromBottom;
|
||||||
|
if (maxBottom <= MinHeight)
|
||||||
|
{
|
||||||
|
// we can't fit in our given space (window made awkwardly small), so give up
|
||||||
|
// and overlap at our min height
|
||||||
|
bottom = MinHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bottom = Math.Clamp(bottom, MinHeight, maxBottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxLeft = Parent.Size.X - MinWidth;
|
||||||
|
if (maxLeft <= MinLeft)
|
||||||
|
{
|
||||||
|
// window too narrow, give up and overlap at our max left
|
||||||
|
left = maxLeft;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
left = Math.Clamp(left, MinLeft, maxLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutContainer.SetMarginLeft(this, -((right + 10) - left));
|
||||||
|
LayoutContainer.SetMarginBottom(this, bottom);
|
||||||
|
|
||||||
|
ChatMgr.ChatBoxOnResized(new ChatResizedEventArgs(bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void MouseExited()
|
||||||
|
{
|
||||||
|
base.MouseExited();
|
||||||
|
|
||||||
|
if (_currentDrag == DragMode.None)
|
||||||
|
DefaultCursorShape = CursorShape.Arrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ using Robust.Shared.Maths;
|
|||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using static Content.Shared.Chemistry.Components.SharedChemMasterComponent;
|
using static Content.Shared.Chemistry.Components.SharedChemMasterComponent;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Chemistry.UI
|
namespace Content.Client.Chemistry.UI
|
||||||
{
|
{
|
||||||
@@ -25,11 +26,11 @@ namespace Content.Client.Chemistry.UI
|
|||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
/// <summary>Contains info about the reagent container such as it's contents, if one is loaded into the dispenser.</summary>
|
/// <summary>Contains info about the reagent container such as it's contents, if one is loaded into the dispenser.</summary>
|
||||||
private readonly VBoxContainer ContainerInfo;
|
private readonly BoxContainer ContainerInfo;
|
||||||
|
|
||||||
private readonly VBoxContainer BufferInfo;
|
private readonly BoxContainer BufferInfo;
|
||||||
|
|
||||||
private readonly VBoxContainer PackagingInfo;
|
private readonly BoxContainer PackagingInfo;
|
||||||
|
|
||||||
/// <summary>Ejects the reagent container from the dispenser.</summary>
|
/// <summary>Ejects the reagent container from the dispenser.</summary>
|
||||||
public Button EjectButton { get; }
|
public Button EjectButton { get; }
|
||||||
@@ -41,8 +42,8 @@ namespace Content.Client.Chemistry.UI
|
|||||||
|
|
||||||
public event Action<ButtonEventArgs, ChemButton>? OnChemButtonPressed;
|
public event Action<ButtonEventArgs, ChemButton>? OnChemButtonPressed;
|
||||||
|
|
||||||
public HBoxContainer PillInfo { get; set; }
|
public BoxContainer PillInfo { get; set; }
|
||||||
public HBoxContainer BottleInfo { get; set; }
|
public BoxContainer BottleInfo { get; set; }
|
||||||
public SpinBox PillAmount { get; set; }
|
public SpinBox PillAmount { get; set; }
|
||||||
public SpinBox BottleAmount { get; set; }
|
public SpinBox BottleAmount { get; set; }
|
||||||
public Button CreatePills { get; }
|
public Button CreatePills { get; }
|
||||||
@@ -57,13 +58,15 @@ namespace Content.Client.Chemistry.UI
|
|||||||
MinSize = SetSize = (400, 525);
|
MinSize = SetSize = (400, 525);
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
//Container
|
//Container
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("chem-master-window-container-label")},
|
new Label {Text = Loc.GetString("chem-master-window-container-label")},
|
||||||
@@ -84,8 +87,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
//Currently empty, when server sends state data this will have container contents and fill volume.
|
//Currently empty, when server sends state data this will have container contents and fill volume.
|
||||||
(ContainerInfo = new VBoxContainer
|
(ContainerInfo = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -102,8 +106,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
new Control {MinSize = (0.0f, 10.0f)},
|
new Control {MinSize = (0.0f, 10.0f)},
|
||||||
|
|
||||||
//Buffer
|
//Buffer
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("chem-master-window-buffer-text")},
|
new Label {Text = Loc.GetString("chem-master-window-buffer-text")},
|
||||||
@@ -126,8 +131,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
//Buffer reagent list
|
//Buffer reagent list
|
||||||
(BufferInfo = new VBoxContainer
|
(BufferInfo = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -144,8 +150,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
new Control {MinSize = (0.0f, 10.0f)},
|
new Control {MinSize = (0.0f, 10.0f)},
|
||||||
|
|
||||||
//Packaging
|
//Packaging
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = $"{Loc.GetString("chem-master-window-packaging-text")} "},
|
new Label {Text = $"{Loc.GetString("chem-master-window-packaging-text")} "},
|
||||||
@@ -165,8 +172,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
//Packaging options
|
//Packaging options
|
||||||
(PackagingInfo = new VBoxContainer
|
(PackagingInfo = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -176,8 +184,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Pills
|
//Pills
|
||||||
PillInfo = new HBoxContainer
|
PillInfo = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label
|
new Label
|
||||||
@@ -213,8 +222,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
PillInfo.AddChild(CreatePills);
|
PillInfo.AddChild(CreatePills);
|
||||||
|
|
||||||
//Bottles
|
//Bottles
|
||||||
BottleInfo = new HBoxContainer
|
BottleInfo = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label
|
new Label
|
||||||
@@ -315,8 +325,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContainerInfo.Children.Add(new HBoxContainer // Name of the container and its fill status (Ex: 44/100u)
|
ContainerInfo.Children.Add(new BoxContainer // Name of the container and its fill status (Ex: 44/100u)
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = $"{state.ContainerName}: "},
|
new Label {Text = $"{state.ContainerName}: "},
|
||||||
@@ -339,8 +350,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
|
|
||||||
if (proto != null)
|
if (proto != null)
|
||||||
{
|
{
|
||||||
ContainerInfo.Children.Add(new HBoxContainer
|
ContainerInfo.Children.Add(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = $"{name}: "},
|
new Label {Text = $"{name}: "},
|
||||||
@@ -371,7 +383,10 @@ namespace Content.Client.Chemistry.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferHBox = new HBoxContainer();
|
var bufferHBox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
BufferInfo.AddChild(bufferHBox);
|
BufferInfo.AddChild(bufferHBox);
|
||||||
|
|
||||||
var bufferLabel = new Label { Text = $"{Loc.GetString("chem-master-window-buffer-label")} " };
|
var bufferLabel = new Label { Text = $"{Loc.GetString("chem-master-window-buffer-label")} " };
|
||||||
@@ -394,8 +409,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
|
|
||||||
if (proto != null)
|
if (proto != null)
|
||||||
{
|
{
|
||||||
BufferInfo.Children.Add(new HBoxContainer
|
BufferInfo.Children.Add(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
//SizeFlagsHorizontal = SizeFlags.ShrinkEnd,
|
//SizeFlagsHorizontal = SizeFlags.ShrinkEnd,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using static Content.Shared.Chemistry.Dispenser.SharedReagentDispenserComponent;
|
using static Content.Shared.Chemistry.Dispenser.SharedReagentDispenserComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Chemistry.UI
|
namespace Content.Client.Chemistry.UI
|
||||||
{
|
{
|
||||||
@@ -23,7 +24,7 @@ namespace Content.Client.Chemistry.UI
|
|||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
/// <summary>Contains info about the reagent container such as it's contents, if one is loaded into the dispenser.</summary>
|
/// <summary>Contains info about the reagent container such as it's contents, if one is loaded into the dispenser.</summary>
|
||||||
private readonly VBoxContainer ContainerInfo;
|
private readonly BoxContainer ContainerInfo;
|
||||||
|
|
||||||
/// <summary>Sets the dispense amount to 1 when pressed.</summary>
|
/// <summary>Sets the dispense amount to 1 when pressed.</summary>
|
||||||
public Button DispenseButton1 { get; }
|
public Button DispenseButton1 { get; }
|
||||||
@@ -72,13 +73,15 @@ namespace Content.Client.Chemistry.UI
|
|||||||
|
|
||||||
var dispenseAmountGroup = new ButtonGroup();
|
var dispenseAmountGroup = new ButtonGroup();
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
//First, our dispense amount buttons
|
//First, our dispense amount buttons
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("reagent-dispenser-window-amount-to-dispense-label")},
|
new Label {Text = Loc.GetString("reagent-dispenser-window-amount-to-dispense-label")},
|
||||||
@@ -104,8 +107,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
}),
|
}),
|
||||||
//Padding
|
//Padding
|
||||||
new Control {MinSize = (0.0f, 10.0f)},
|
new Control {MinSize = (0.0f, 10.0f)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("reagent-dispenser-window-container-label") + " "},
|
new Label {Text = Loc.GetString("reagent-dispenser-window-container-label") + " "},
|
||||||
@@ -126,8 +130,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
//Currently empty, when server sends state data this will have container contents and fill volume.
|
//Currently empty, when server sends state data this will have container contents and fill volume.
|
||||||
(ContainerInfo = new VBoxContainer
|
(ContainerInfo = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -263,8 +268,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContainerInfo.Children.Add(new HBoxContainer // Name of the container and its fill status (Ex: 44/100u)
|
ContainerInfo.Children.Add(new BoxContainer // Name of the container and its fill status (Ex: 44/100u)
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = $"{state.ContainerName}: "},
|
new Label {Text = $"{state.ContainerName}: "},
|
||||||
@@ -293,8 +299,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
//Check if the reagent is being moused over. If so, color it green.
|
//Check if the reagent is being moused over. If so, color it green.
|
||||||
if (proto != null && proto.ID == highlightedReagentId)
|
if (proto != null && proto.ID == highlightedReagentId)
|
||||||
{
|
{
|
||||||
ContainerInfo.Children.Add(new HBoxContainer
|
ContainerInfo.Children.Add(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label
|
new Label
|
||||||
@@ -312,8 +319,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
}
|
}
|
||||||
else //Otherwise, color it the normal colors.
|
else //Otherwise, color it the normal colors.
|
||||||
{
|
{
|
||||||
ContainerInfo.Children.Add(new HBoxContainer
|
ContainerInfo.Children.Add(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = $"{name}: "},
|
new Label {Text = $"{name}: "},
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using Content.Shared.Chemistry;
|
||||||
|
using Content.Shared.Chemistry.Reagent;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Client.Chemistry.UI
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class TransferAmountBoundUserInterface : BoundUserInterface
|
||||||
|
{
|
||||||
|
private TransferAmountWindow? _window;
|
||||||
|
|
||||||
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
_window = new TransferAmountWindow();
|
||||||
|
|
||||||
|
_window.applyButton.OnPressed += _ =>
|
||||||
|
{
|
||||||
|
if (int.TryParse(_window.amountLineEdit.Text, out var i))
|
||||||
|
{
|
||||||
|
SendMessage(new TransferAmountSetValueMessage(ReagentUnit.New(i)));
|
||||||
|
_window.Close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_window.OpenCentered();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransferAmountBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Content.Client/Chemistry/UI/TransferAmountWindow.xaml
Normal file
11
Content.Client/Chemistry/UI/TransferAmountWindow.xaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<SS14Window xmlns="https://spacestation14.io"
|
||||||
|
Title="{Loc 'ui-transfer-amount-title'}"
|
||||||
|
Resizable="False">
|
||||||
|
|
||||||
|
<VBoxContainer SeparationOverride="4" CustomMinimumSize="240 80">
|
||||||
|
<HBoxContainer>
|
||||||
|
<LineEdit Name="AmountLineEdit" HorizontalExpand="True" PlaceHolder="{Loc 'ui-transfer-amount-line-edit-placeholder'}"/>
|
||||||
|
</HBoxContainer>
|
||||||
|
<Button Name="ApplyButton" Text="{Loc 'ui-transfer-amount-apply'}"/>
|
||||||
|
</VBoxContainer>
|
||||||
|
</SS14Window>
|
||||||
19
Content.Client/Chemistry/UI/TransferAmountWindow.xaml.cs
Normal file
19
Content.Client/Chemistry/UI/TransferAmountWindow.xaml.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
|
namespace Content.Client.Chemistry.UI
|
||||||
|
{
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public partial class TransferAmountWindow : SS14Window
|
||||||
|
{
|
||||||
|
public Button applyButton => ApplyButton;
|
||||||
|
public LineEdit amountLineEdit => AmountLineEdit;
|
||||||
|
|
||||||
|
public TransferAmountWindow()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using Content.Shared.Chemistry.Solution.Components;
|
using Content.Shared.Chemistry.Solution.Components;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Robust.Client.UserInterface;
|
|||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Cloning.UI
|
namespace Content.Client.Cloning.UI
|
||||||
{
|
{
|
||||||
@@ -15,21 +16,24 @@ namespace Content.Client.Cloning.UI
|
|||||||
|
|
||||||
Title = Loc.GetString("accept-cloning-window-title");
|
Title = Loc.GetString("accept-cloning-window-title");
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(new Label()
|
(new Label()
|
||||||
{
|
{
|
||||||
Text = Loc.GetString("accept-cloning-window-prompt-text-part")
|
Text = Loc.GetString("accept-cloning-window-prompt-text-part")
|
||||||
}),
|
}),
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
Align = BoxContainer.AlignMode.Center,
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
|
Align = AlignMode.Center,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(AcceptButton = new Button
|
(AcceptButton = new Button
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using static Content.Shared.Cloning.SharedCloningPodComponent;
|
using static Content.Shared.Cloning.SharedCloningPodComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Cloning.UI
|
namespace Content.Client.Cloning.UI
|
||||||
{
|
{
|
||||||
@@ -16,7 +17,7 @@ namespace Content.Client.Cloning.UI
|
|||||||
{
|
{
|
||||||
private Dictionary<int, string?> _scanManager;
|
private Dictionary<int, string?> _scanManager;
|
||||||
|
|
||||||
private readonly VBoxContainer _scanList;
|
private readonly BoxContainer _scanList;
|
||||||
public readonly Button CloneButton;
|
public readonly Button CloneButton;
|
||||||
public readonly Button EjectButton;
|
public readonly Button EjectButton;
|
||||||
private CloningScanButton? _selectedButton;
|
private CloningScanButton? _selectedButton;
|
||||||
@@ -35,8 +36,9 @@ namespace Content.Client.Cloning.UI
|
|||||||
|
|
||||||
Title = Loc.GetString("cloning-pod-window-title");
|
Title = Loc.GetString("cloning-pod-window-title");
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new ScrollContainer
|
new ScrollContainer
|
||||||
@@ -45,11 +47,15 @@ namespace Content.Client.Cloning.UI
|
|||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(_scanList = new VBoxContainer())
|
(_scanList = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(CloneButton = new Button
|
(CloneButton = new Button
|
||||||
@@ -74,8 +80,9 @@ namespace Content.Client.Cloning.UI
|
|||||||
{
|
{
|
||||||
Text = Loc.GetString("cloning-pod-eject-body-button")
|
Text = Loc.GetString("cloning-pod-eject-body-button")
|
||||||
}),
|
}),
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label()
|
new Label()
|
||||||
@@ -219,8 +226,9 @@ namespace Content.Client.Cloning.UI
|
|||||||
ToggleMode = true,
|
ToggleMode = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
AddChild(new HBoxContainer
|
AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(EntityTextureRect = new TextureRect
|
(EntityTextureRect = new TextureRect
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using Content.Client.Inventory;
|
using Content.Client.Inventory;
|
||||||
using Content.Client.Items.Components;
|
using Content.Client.Items.Components;
|
||||||
using Content.Shared.Clothing;
|
using Content.Shared.Clothing;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using Content.Shared;
|
||||||
using Content.Shared;
|
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Robust.Client.UserInterface.CustomControls;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
using Timer = Robust.Shared.Timing.Timer;
|
using Timer = Robust.Shared.Timing.Timer;
|
||||||
|
|
||||||
namespace Content.Client.Communications.UI
|
namespace Content.Client.Communications.UI
|
||||||
@@ -42,7 +43,12 @@ namespace Content.Client.Communications.UI
|
|||||||
EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed();
|
EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed();
|
||||||
EmergencyShuttleButton.Disabled = !owner.CanCall;
|
EmergencyShuttleButton.Disabled = !owner.CanCall;
|
||||||
|
|
||||||
var vbox = new VBoxContainer() {HorizontalExpand = true, VerticalExpand = true};
|
var vbox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
|
HorizontalExpand = true,
|
||||||
|
VerticalExpand = true
|
||||||
|
};
|
||||||
vbox.AddChild(_messageInput);
|
vbox.AddChild(_messageInput);
|
||||||
vbox.AddChild(new Control(){MinSize = new Vector2(0,10), HorizontalExpand = true});
|
vbox.AddChild(new Control(){MinSize = new Vector2(0,10), HorizontalExpand = true});
|
||||||
vbox.AddChild(AnnounceButton);
|
vbox.AddChild(AnnounceButton);
|
||||||
@@ -50,7 +56,12 @@ namespace Content.Client.Communications.UI
|
|||||||
vbox.AddChild(_countdownLabel);
|
vbox.AddChild(_countdownLabel);
|
||||||
vbox.AddChild(EmergencyShuttleButton);
|
vbox.AddChild(EmergencyShuttleButton);
|
||||||
|
|
||||||
var hbox = new HBoxContainer() {HorizontalExpand = true, VerticalExpand = true};
|
var hbox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
|
HorizontalExpand = true,
|
||||||
|
VerticalExpand = true
|
||||||
|
};
|
||||||
hbox.AddChild(new Control(){MinSize = new Vector2(100,0), HorizontalExpand = true});
|
hbox.AddChild(new Control(){MinSize = new Vector2(100,0), HorizontalExpand = true});
|
||||||
hbox.AddChild(vbox);
|
hbox.AddChild(vbox);
|
||||||
hbox.AddChild(new Control(){MinSize = new Vector2(100,0), HorizontalExpand = true});
|
hbox.AddChild(new Control(){MinSize = new Vector2(100,0), HorizontalExpand = true});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using static Content.Shared.Configurable.SharedConfigurationComponent;
|
using static Content.Shared.Configurable.SharedConfigurationComponent;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Configurable.UI
|
namespace Content.Client.Configurable.UI
|
||||||
{
|
{
|
||||||
@@ -13,9 +14,8 @@ namespace Content.Client.Configurable.UI
|
|||||||
{
|
{
|
||||||
public ConfigurationBoundUserInterface Owner { get; }
|
public ConfigurationBoundUserInterface Owner { get; }
|
||||||
|
|
||||||
private readonly VBoxContainer _baseContainer;
|
private readonly BoxContainer _column;
|
||||||
private readonly VBoxContainer _column;
|
private readonly BoxContainer _row;
|
||||||
private readonly HBoxContainer _row;
|
|
||||||
|
|
||||||
private readonly List<(string name, LineEdit input)> _inputs;
|
private readonly List<(string name, LineEdit input)> _inputs;
|
||||||
|
|
||||||
@@ -28,20 +28,23 @@ namespace Content.Client.Configurable.UI
|
|||||||
|
|
||||||
Title = Loc.GetString("configuration-menu-device-title");
|
Title = Loc.GetString("configuration-menu-device-title");
|
||||||
|
|
||||||
_baseContainer = new VBoxContainer
|
BoxContainer baseContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
HorizontalExpand = true
|
HorizontalExpand = true
|
||||||
};
|
};
|
||||||
|
|
||||||
_column = new VBoxContainer
|
_column = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Margin = new Thickness(8),
|
Margin = new Thickness(8),
|
||||||
SeparationOverride = 16,
|
SeparationOverride = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
_row = new HBoxContainer
|
_row = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
SeparationOverride = 16,
|
SeparationOverride = 16,
|
||||||
HorizontalExpand = true
|
HorizontalExpand = true
|
||||||
};
|
};
|
||||||
@@ -63,9 +66,9 @@ namespace Content.Client.Configurable.UI
|
|||||||
};
|
};
|
||||||
|
|
||||||
outerColumn.AddChild(_column);
|
outerColumn.AddChild(_column);
|
||||||
_baseContainer.AddChild(outerColumn);
|
baseContainer.AddChild(outerColumn);
|
||||||
_baseContainer.AddChild(confirmButton);
|
baseContainer.AddChild(confirmButton);
|
||||||
Contents.AddChild(_baseContainer);
|
Contents.AddChild(baseContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Populate(ConfigurationBoundUserInterfaceState state)
|
public void Populate(ConfigurationBoundUserInterfaceState state)
|
||||||
@@ -97,7 +100,10 @@ namespace Content.Client.Configurable.UI
|
|||||||
|
|
||||||
_inputs.Add((field.Key, input));
|
_inputs.Add((field.Key, input));
|
||||||
|
|
||||||
var row = new HBoxContainer();
|
var row = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal
|
||||||
|
};
|
||||||
CopyProperties(_row, row);
|
CopyProperties(_row, row);
|
||||||
|
|
||||||
row.AddChild(label);
|
row.AddChild(label);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
namespace Content.Client.Construction
|
namespace Content.Client.Construction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
<SS14Window xmlns="https://spacestation14.io">
|
<SS14Window xmlns="https://spacestation14.io">
|
||||||
<HBoxContainer HorizontalExpand="True">
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||||
<VBoxContainer HorizontalExpand="True" SizeFlagsStretchRatio="0.4">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4">
|
||||||
<HBoxContainer HorizontalExpand="True">
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||||
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
|
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
|
||||||
<OptionButton Name="Category" MinSize="130 0"/>
|
<OptionButton Name="Category" MinSize="130 0"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
<ItemList Name="RecipesList" SelectMode="Single" VerticalExpand="True"/>
|
<ItemList Name="RecipesList" SelectMode="Single" VerticalExpand="True"/>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
<Control MinSize="10 0"/>
|
<Control MinSize="10 0"/>
|
||||||
<VBoxContainer HorizontalExpand="True" SizeFlagsStretchRatio="0.6">
|
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.6">
|
||||||
<Control>
|
<Control>
|
||||||
<HBoxContainer Align="Center">
|
<BoxContainer Orientation="Horizontal" Align="Center">
|
||||||
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep"/>
|
<TextureRect Name="TargetTexture" HorizontalAlignment="Right" Stretch="Keep"/>
|
||||||
<Control MinSize="10 0"/>
|
<Control MinSize="10 0"/>
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<RichTextLabel Name="TargetName"/>
|
<RichTextLabel Name="TargetName"/>
|
||||||
<RichTextLabel Name="TargetDesc"/>
|
<RichTextLabel Name="TargetDesc"/>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
</Control>
|
</Control>
|
||||||
<ItemList Name="StepList" VerticalExpand="True"/>
|
<ItemList Name="StepList" VerticalExpand="True"/>
|
||||||
<VBoxContainer>
|
<BoxContainer Orientation="Vertical">
|
||||||
<Button Name="BuildButton" Disabled="True" ToggleMode="True" VerticalExpand="True" SizeFlagsStretchRatio="0.5"/>
|
<Button Name="BuildButton" Disabled="True" ToggleMode="True" VerticalExpand="True" SizeFlagsStretchRatio="0.5"/>
|
||||||
<HBoxContainer VerticalExpand="True" SizeFlagsStretchRatio="0.5">
|
<BoxContainer Orientation="Horizontal" VerticalExpand="True" SizeFlagsStretchRatio="0.5">
|
||||||
<Button Name="EraseButton" ToggleMode="True" HorizontalExpand="True" SizeFlagsStretchRatio="0.7"/>
|
<Button Name="EraseButton" ToggleMode="True" HorizontalExpand="True" SizeFlagsStretchRatio="0.7"/>
|
||||||
<Button Name="ClearButton" HorizontalExpand="True" SizeFlagsStretchRatio="0.3"/>
|
<Button Name="ClearButton" HorizontalExpand="True" SizeFlagsStretchRatio="0.3"/>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</HBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Robust.Client.UserInterface.XAML;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
namespace Content.Client.Construction.UI
|
namespace Content.Client.Construction.UI
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.Interactable.Components;
|
using Content.Client.Interactable.Components;
|
||||||
@@ -14,6 +13,7 @@ using Robust.Shared.GameObjects;
|
|||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
using Vector2 = Robust.Shared.Maths.Vector2;
|
using Vector2 = Robust.Shared.Maths.Vector2;
|
||||||
|
|
||||||
namespace Content.Client.ContextMenu.UI
|
namespace Content.Client.ContextMenu.UI
|
||||||
@@ -64,8 +64,9 @@ namespace Content.Client.ContextMenu.UI
|
|||||||
OutlineComponent = ContextEntity.GetComponentOrNull<InteractionOutlineComponent>();
|
OutlineComponent = ContextEntity.GetComponentOrNull<InteractionOutlineComponent>();
|
||||||
|
|
||||||
AddChild(
|
AddChild(
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new LayoutContainer
|
new LayoutContainer
|
||||||
@@ -130,14 +131,16 @@ namespace Content.Client.ContextMenu.UI
|
|||||||
LayoutContainer.SetGrowVertical(_label, LayoutContainer.GrowDirection.Begin);
|
LayoutContainer.SetGrowVertical(_label, LayoutContainer.GrowDirection.Begin);
|
||||||
|
|
||||||
AddChild(
|
AddChild(
|
||||||
new HBoxContainer()
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
SeparationOverride = 6,
|
SeparationOverride = 6,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new LayoutContainer { Children = { _spriteView, _label } },
|
new LayoutContainer { Children = { _spriteView, _label } },
|
||||||
new HBoxContainer()
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
SeparationOverride = 6,
|
SeparationOverride = 6,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -180,7 +183,7 @@ namespace Content.Client.ContextMenu.UI
|
|||||||
private const int MaxItemsBeforeScroll = 10;
|
private const int MaxItemsBeforeScroll = 10;
|
||||||
private const int MarginSizeBetweenElements = 2;
|
private const int MarginSizeBetweenElements = 2;
|
||||||
|
|
||||||
public VBoxContainer List { get; }
|
public BoxContainer List { get; }
|
||||||
public int Depth { get; }
|
public int Depth { get; }
|
||||||
|
|
||||||
public ContextMenuPopup(int depth = 0)
|
public ContextMenuPopup(int depth = 0)
|
||||||
@@ -191,7 +194,10 @@ namespace Content.Client.ContextMenu.UI
|
|||||||
HScrollEnabled = false,
|
HScrollEnabled = false,
|
||||||
Children = { new PanelContainer
|
Children = { new PanelContainer
|
||||||
{
|
{
|
||||||
Children = { (List = new VBoxContainer()) },
|
Children = { (List = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
}) },
|
||||||
PanelOverride = new StyleBoxFlat { BackgroundColor = MarginColor }
|
PanelOverride = new StyleBoxFlat { BackgroundColor = MarginColor }
|
||||||
}}
|
}}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Content.Client.Examine;
|
using Content.Client.Examine;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#nullable enable
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Crayon.UI
|
namespace Content.Client.Crayon.UI
|
||||||
{
|
{
|
||||||
@@ -27,7 +28,10 @@ namespace Content.Client.Crayon.UI
|
|||||||
Title = Loc.GetString("crayon-window-title");
|
Title = Loc.GetString("crayon-window-title");
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
|
|
||||||
var vbox = new VBoxContainer();
|
var vbox = new BoxContainer
|
||||||
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical
|
||||||
|
};
|
||||||
Contents.AddChild(vbox);
|
Contents.AddChild(vbox);
|
||||||
|
|
||||||
_search = new LineEdit();
|
_search = new LineEdit();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using YamlDotNet.RepresentationModel;
|
using YamlDotNet.RepresentationModel;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Credits
|
namespace Content.Client.Credits
|
||||||
{
|
{
|
||||||
@@ -71,8 +72,9 @@ namespace Content.Client.Credits
|
|||||||
|
|
||||||
private void PopulateLicenses(ScrollContainer licensesList)
|
private void PopulateLicenses(ScrollContainer licensesList)
|
||||||
{
|
{
|
||||||
var vBox = new VBoxContainer
|
var vBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Margin = new Thickness(2, 2, 0, 0)
|
Margin = new Thickness(2, 2, 0, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,8 +95,9 @@ namespace Content.Client.Credits
|
|||||||
|
|
||||||
private void PopulatePatronsList(Control patronsList)
|
private void PopulatePatronsList(Control patronsList)
|
||||||
{
|
{
|
||||||
var vBox = new VBoxContainer
|
var vBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Margin = new Thickness(2, 2, 0, 0)
|
Margin = new Thickness(2, 2, 0, 0)
|
||||||
};
|
};
|
||||||
var patrons = LoadPatrons();
|
var patrons = LoadPatrons();
|
||||||
@@ -152,13 +155,15 @@ namespace Content.Client.Credits
|
|||||||
{
|
{
|
||||||
Button contributeButton;
|
Button contributeButton;
|
||||||
|
|
||||||
var vBox = new VBoxContainer
|
var vBox = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Margin = new Thickness(2, 2, 0, 0)
|
Margin = new Thickness(2, 2, 0, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
vBox.AddChild(new HBoxContainer
|
vBox.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalAlignment = HAlignment.Center,
|
HorizontalAlignment = HAlignment.Center,
|
||||||
SeparationOverride = 20,
|
SeparationOverride = 20,
|
||||||
Children =
|
Children =
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Robust.Client.UserInterface.CustomControls;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using static Content.Shared.Disposal.Components.SharedDisposalMailingUnitComponent;
|
using static Content.Shared.Disposal.Components.SharedDisposalMailingUnitComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Disposal.UI
|
namespace Content.Client.Disposal.UI
|
||||||
{
|
{
|
||||||
@@ -30,18 +31,21 @@ namespace Content.Client.Disposal.UI
|
|||||||
{
|
{
|
||||||
MinSize = SetSize = (460, 230);
|
MinSize = SetSize = (460, 230);
|
||||||
TargetList = new List<string>();
|
TargetList = new List<string>();
|
||||||
Contents.AddChild(new HBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Margin = new Thickness(8, 0),
|
Margin = new Thickness(8, 0),
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = $"{Loc.GetString("disposal-mailing-unit-window-state-label")} "},
|
new Label {Text = $"{Loc.GetString("disposal-mailing-unit-window-state-label")} "},
|
||||||
@@ -50,8 +54,9 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Control {MinSize = (0, 10)},
|
new Control {MinSize = (0, 10)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -73,8 +78,9 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Control {MinSize = (0, 10)},
|
new Control {MinSize = (0, 10)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -94,8 +100,9 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Control {MinSize = (0, 10)},
|
new Control {MinSize = (0, 10)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -114,8 +121,9 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Control {MinSize = (0, 10)},
|
new Control {MinSize = (0, 10)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(Power = new CheckButton {Text = Loc.GetString("disposal-mailing-unit-power-button")}),
|
(Power = new CheckButton {Text = Loc.GetString("disposal-mailing-unit-power-button")}),
|
||||||
@@ -123,13 +131,15 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Margin = new Thickness(12, 0, 8, 0),
|
Margin = new Thickness(12, 0, 8, 0),
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label
|
new Label
|
||||||
@@ -139,8 +149,9 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Control {MinSize = new Vector2(0, 8)},
|
new Control {MinSize = new Vector2(0, 8)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
VerticalExpand = true,
|
VerticalExpand = true,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -161,16 +172,19 @@ namespace Content.Client.Disposal.UI
|
|||||||
HorizontalExpand = true,
|
HorizontalExpand = true,
|
||||||
MinSize = new Vector2(0, 1),
|
MinSize = new Vector2(0, 1),
|
||||||
},
|
},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new VBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Margin = new Thickness(4, 0, 0, 0),
|
Margin = new Thickness(4, 0, 0, 0),
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Disposal.UI
|
namespace Content.Client.Disposal.UI
|
||||||
{
|
{
|
||||||
@@ -20,14 +21,16 @@ namespace Content.Client.Disposal.UI
|
|||||||
MinSize = SetSize = (500, 110);
|
MinSize = SetSize = (500, 110);
|
||||||
Title = Loc.GetString("disposal-router-window-title");
|
Title = Loc.GetString("disposal-router-window-title");
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("disposal-router-window-tags-label")},
|
new Label {Text = Loc.GetString("disposal-router-window-tags-label")},
|
||||||
new Control {MinSize = (0, 10)},
|
new Control {MinSize = (0, 10)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(TagInput = new LineEdit
|
(TagInput = new LineEdit
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Disposal.UI
|
namespace Content.Client.Disposal.UI
|
||||||
{
|
{
|
||||||
@@ -20,14 +21,16 @@ namespace Content.Client.Disposal.UI
|
|||||||
MinSize = SetSize = (500, 110);
|
MinSize = SetSize = (500, 110);
|
||||||
Title = Loc.GetString("disposal-tagger-window-title");
|
Title = Loc.GetString("disposal-tagger-window-title");
|
||||||
|
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new Label {Text = Loc.GetString("disposal-tagger-window-tag-input-label")},
|
new Label {Text = Loc.GetString("disposal-tagger-window-tag-input-label")},
|
||||||
new Control {MinSize = (0, 10)},
|
new Control {MinSize = (0, 10)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(TagInput = new LineEdit
|
(TagInput = new LineEdit
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
|
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
|
||||||
|
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||||
|
|
||||||
namespace Content.Client.Disposal.UI
|
namespace Content.Client.Disposal.UI
|
||||||
{
|
{
|
||||||
@@ -27,12 +28,14 @@ namespace Content.Client.Disposal.UI
|
|||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
MinSize = SetSize = (300, 140);
|
MinSize = SetSize = (300, 140);
|
||||||
Resizable = false;
|
Resizable = false;
|
||||||
Contents.AddChild(new VBoxContainer
|
Contents.AddChild(new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
SeparationOverride = 4,
|
SeparationOverride = 4,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -41,8 +44,9 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Control {MinSize = (0, 5)},
|
new Control {MinSize = (0, 5)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
SeparationOverride = 4,
|
SeparationOverride = 4,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
@@ -59,8 +63,9 @@ namespace Content.Client.Disposal.UI
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Control {MinSize = (0, 10)},
|
new Control {MinSize = (0, 10)},
|
||||||
new HBoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
|
Orientation = LayoutOrientation.Horizontal,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
(Engage = new Button
|
(Engage = new Button
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ namespace Content.Client.Entry
|
|||||||
"EmitSoundOnActivate",
|
"EmitSoundOnActivate",
|
||||||
"FootstepModifier",
|
"FootstepModifier",
|
||||||
"HeatResistance",
|
"HeatResistance",
|
||||||
"ItemTeleporter",
|
|
||||||
"EntityStorage",
|
"EntityStorage",
|
||||||
"Wirecutter",
|
"Wirecutter",
|
||||||
"Screwdriver",
|
"Screwdriver",
|
||||||
@@ -58,7 +57,6 @@ namespace Content.Client.Entry
|
|||||||
"CablePlacer",
|
"CablePlacer",
|
||||||
"Drink",
|
"Drink",
|
||||||
"Food",
|
"Food",
|
||||||
"FoodContainer",
|
|
||||||
"MagicMirror",
|
"MagicMirror",
|
||||||
"FloorTile",
|
"FloorTile",
|
||||||
"ShuttleController",
|
"ShuttleController",
|
||||||
@@ -78,8 +76,7 @@ namespace Content.Client.Entry
|
|||||||
"CanSpill",
|
"CanSpill",
|
||||||
"SpeedLoader",
|
"SpeedLoader",
|
||||||
"Hitscan",
|
"Hitscan",
|
||||||
"ExplosiveProjectile",
|
"StunOnCollide",
|
||||||
"StunnableProjectile",
|
|
||||||
"RandomPottedPlant",
|
"RandomPottedPlant",
|
||||||
"CommunicationsConsole",
|
"CommunicationsConsole",
|
||||||
"BarSign",
|
"BarSign",
|
||||||
@@ -97,8 +94,11 @@ namespace Content.Client.Entry
|
|||||||
"SecureEntityStorage",
|
"SecureEntityStorage",
|
||||||
"PresetIdCard",
|
"PresetIdCard",
|
||||||
"SolarControlConsole",
|
"SolarControlConsole",
|
||||||
"FlashExplosive",
|
"FlashOnTrigger",
|
||||||
"FlashProjectile",
|
"SoundOnTrigger",
|
||||||
|
"TriggerOnCollide",
|
||||||
|
"DeleteOnTrigger",
|
||||||
|
"ExplodeOnTrigger",
|
||||||
"Utensil",
|
"Utensil",
|
||||||
"UnarmedCombat",
|
"UnarmedCombat",
|
||||||
"TimedSpawner",
|
"TimedSpawner",
|
||||||
@@ -233,7 +233,7 @@ namespace Content.Client.Entry
|
|||||||
"ConveyorAssembly",
|
"ConveyorAssembly",
|
||||||
"TwoWayLever",
|
"TwoWayLever",
|
||||||
"FirelockElectronics",
|
"FirelockElectronics",
|
||||||
"ChemicalInjectionProjectile",
|
"SolutionInjectOnCollide",
|
||||||
"Machine",
|
"Machine",
|
||||||
"MachinePart",
|
"MachinePart",
|
||||||
"MachineFrame",
|
"MachineFrame",
|
||||||
@@ -276,6 +276,7 @@ namespace Content.Client.Entry
|
|||||||
"Advertise",
|
"Advertise",
|
||||||
"PowerNetworkBattery",
|
"PowerNetworkBattery",
|
||||||
"BatteryCharger",
|
"BatteryCharger",
|
||||||
|
"SpawnItemsOnUse"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
Title="{Loc 'ui-escape-title'}"
|
Title="{Loc 'ui-escape-title'}"
|
||||||
Resizable="False">
|
Resizable="False">
|
||||||
|
|
||||||
<VBoxContainer SeparationOverride="4" CustomMinimumSize="150 160">
|
<BoxContainer Orientation="Vertical" SeparationOverride="4" CustomMinimumSize="150 160">
|
||||||
<changelog:ChangelogButton />
|
<changelog:ChangelogButton />
|
||||||
<ui:VoteCallMenuButton />
|
<ui:VoteCallMenuButton />
|
||||||
<Button Name="OptionsButton" Text="{Loc 'ui-escape-options'}" />
|
<Button Name="OptionsButton" Text="{Loc 'ui-escape-options'}" />
|
||||||
<Button Name="DisconnectButton" Text="{Loc 'ui-escape-disconnect'}" />
|
<Button Name="DisconnectButton" Text="{Loc 'ui-escape-disconnect'}" />
|
||||||
<Button Name="QuitButton" Text="{Loc 'ui-escape-quit'}" />
|
<Button Name="QuitButton" Text="{Loc 'ui-escape-quit'}" />
|
||||||
</VBoxContainer>
|
</BoxContainer>
|
||||||
</SS14Window>
|
</SS14Window>
|
||||||
|
|||||||
@@ -1,198 +0,0 @@
|
|||||||
using Content.Client.HUD.UI;
|
|
||||||
using Content.Client.Stylesheets;
|
|
||||||
using Content.Shared;
|
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared;
|
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Client.EscapeMenu.UI
|
|
||||||
{
|
|
||||||
public sealed partial class OptionsMenu
|
|
||||||
{
|
|
||||||
private sealed class AudioControl : Control
|
|
||||||
{
|
|
||||||
private readonly IConfigurationManager _cfg;
|
|
||||||
private readonly IClydeAudio _clydeAudio;
|
|
||||||
|
|
||||||
private readonly Button ApplyButton;
|
|
||||||
private readonly Label MasterVolumeLabel;
|
|
||||||
private readonly Slider MasterVolumeSlider;
|
|
||||||
private readonly CheckBox AmbienceCheckBox;
|
|
||||||
private readonly CheckBox LobbyMusicCheckBox;
|
|
||||||
private readonly Button ResetButton;
|
|
||||||
|
|
||||||
public AudioControl(IConfigurationManager cfg, IClydeAudio clydeAudio)
|
|
||||||
{
|
|
||||||
_cfg = cfg;
|
|
||||||
_clydeAudio = clydeAudio;
|
|
||||||
|
|
||||||
var vBox = new VBoxContainer();
|
|
||||||
|
|
||||||
var contents = new VBoxContainer
|
|
||||||
{
|
|
||||||
Margin = new Thickness(2, 2, 2, 0),
|
|
||||||
VerticalExpand = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
MasterVolumeSlider = new Slider
|
|
||||||
{
|
|
||||||
MinValue = 0.0f,
|
|
||||||
MaxValue = 100.0f,
|
|
||||||
HorizontalExpand = true,
|
|
||||||
MinSize = (80, 8),
|
|
||||||
Rounded = true
|
|
||||||
};
|
|
||||||
|
|
||||||
MasterVolumeLabel = new Label
|
|
||||||
{
|
|
||||||
MinSize = (48, 0),
|
|
||||||
Align = Label.AlignMode.Right
|
|
||||||
};
|
|
||||||
|
|
||||||
contents.AddChild(new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Control {MinSize = (4, 0)},
|
|
||||||
new Label {Text = Loc.GetString("ui-options-master-volume")},
|
|
||||||
new Control {MinSize = (8, 0)},
|
|
||||||
MasterVolumeSlider,
|
|
||||||
new Control {MinSize = (8, 0)},
|
|
||||||
MasterVolumeLabel,
|
|
||||||
new Control {MinSize = (4, 0)},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// sets up ambience checkbox. i am sorry for not fixing the rest of this code.
|
|
||||||
AmbienceCheckBox = new CheckBox {Text = Loc.GetString("ui-options-ambient-hum")};
|
|
||||||
contents.AddChild(AmbienceCheckBox);
|
|
||||||
AmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.AmbienceBasicEnabled);
|
|
||||||
|
|
||||||
LobbyMusicCheckBox = new CheckBox {Text = Loc.GetString("ui-options-lobby-music")};
|
|
||||||
contents.AddChild(LobbyMusicCheckBox);
|
|
||||||
LobbyMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.LobbyMusicEnabled);
|
|
||||||
|
|
||||||
ApplyButton = new Button
|
|
||||||
{
|
|
||||||
Text = Loc.GetString("ui-options-apply"), TextAlign = Label.AlignMode.Center,
|
|
||||||
HorizontalAlignment = HAlignment.Right
|
|
||||||
};
|
|
||||||
|
|
||||||
vBox.AddChild(new Label
|
|
||||||
{
|
|
||||||
Text = Loc.GetString("ui-options-volume-sliders"),
|
|
||||||
FontColorOverride = StyleNano.NanoGold,
|
|
||||||
StyleClasses = {StyleNano.StyleClassLabelKeyText}
|
|
||||||
});
|
|
||||||
|
|
||||||
vBox.AddChild(contents);
|
|
||||||
|
|
||||||
ResetButton = new Button
|
|
||||||
{
|
|
||||||
Text = Loc.GetString("ui-options-reset-all"),
|
|
||||||
StyleClasses = {StyleBase.ButtonCaution},
|
|
||||||
HorizontalExpand = true,
|
|
||||||
HorizontalAlignment = HAlignment.Right
|
|
||||||
};
|
|
||||||
|
|
||||||
vBox.AddChild(new StripeBack
|
|
||||||
{
|
|
||||||
HasBottomEdge = false,
|
|
||||||
HasMargins = false,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new HBoxContainer
|
|
||||||
{
|
|
||||||
Align = BoxContainer.AlignMode.End,
|
|
||||||
HorizontalExpand = true,
|
|
||||||
VerticalExpand = true,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
ResetButton,
|
|
||||||
new Control {MinSize = (2, 0)},
|
|
||||||
ApplyButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ApplyButton.OnPressed += OnApplyButtonPressed;
|
|
||||||
ResetButton.OnPressed += OnResetButtonPressed;
|
|
||||||
MasterVolumeSlider.OnValueChanged += OnMasterVolumeSliderChanged;
|
|
||||||
AmbienceCheckBox.OnToggled += OnAmbienceCheckToggled;
|
|
||||||
LobbyMusicCheckBox.OnToggled += OnLobbyMusicCheckToggled;
|
|
||||||
|
|
||||||
AddChild(vBox);
|
|
||||||
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
ApplyButton.OnPressed -= OnApplyButtonPressed;
|
|
||||||
ResetButton.OnPressed -= OnResetButtonPressed;
|
|
||||||
MasterVolumeSlider.OnValueChanged -= OnMasterVolumeSliderChanged;
|
|
||||||
AmbienceCheckBox.OnToggled -= OnAmbienceCheckToggled;
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnMasterVolumeSliderChanged(Range range)
|
|
||||||
{
|
|
||||||
MasterVolumeLabel.Text =
|
|
||||||
Loc.GetString("ui-options-volume-percent", ("volume", MasterVolumeSlider.Value / 100));
|
|
||||||
_clydeAudio.SetMasterVolume(MasterVolumeSlider.Value / 100);
|
|
||||||
UpdateChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAmbienceCheckToggled(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
UpdateChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLobbyMusicCheckToggled(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
UpdateChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
_cfg.SetCVar(CVars.AudioMasterVolume, MasterVolumeSlider.Value / 100);
|
|
||||||
_cfg.SetCVar(CCVars.AmbienceBasicEnabled, AmbienceCheckBox.Pressed);
|
|
||||||
_cfg.SetCVar(CCVars.LobbyMusicEnabled, LobbyMusicCheckBox.Pressed);
|
|
||||||
_cfg.SaveToFile();
|
|
||||||
UpdateChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnResetButtonPressed(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reset()
|
|
||||||
{
|
|
||||||
MasterVolumeSlider.Value = _cfg.GetCVar(CVars.AudioMasterVolume) * 100;
|
|
||||||
MasterVolumeLabel.Text =
|
|
||||||
Loc.GetString("ui-options-volume-percent", ("volume", MasterVolumeSlider.Value / 100));
|
|
||||||
AmbienceCheckBox.Pressed = _cfg.GetCVar(CCVars.AmbienceBasicEnabled);
|
|
||||||
LobbyMusicCheckBox.Pressed = _cfg.GetCVar(CCVars.LobbyMusicEnabled);
|
|
||||||
UpdateChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateChanges()
|
|
||||||
{
|
|
||||||
var isMasterVolumeSame =
|
|
||||||
System.Math.Abs(MasterVolumeSlider.Value - _cfg.GetCVar(CVars.AudioMasterVolume) * 100) < 0.01f;
|
|
||||||
var isAmbienceSame = AmbienceCheckBox.Pressed == _cfg.GetCVar(CCVars.AmbienceBasicEnabled);
|
|
||||||
var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled);
|
|
||||||
var isEverythingSame = isMasterVolumeSame && isAmbienceSame && isLobbySame;
|
|
||||||
ApplyButton.Disabled = isEverythingSame;
|
|
||||||
ResetButton.Disabled = isEverythingSame;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
using Content.Client.HUD.UI;
|
|
||||||
using Content.Shared;
|
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.HUD;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared;
|
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.EscapeMenu.UI
|
|
||||||
{
|
|
||||||
public sealed partial class OptionsMenu
|
|
||||||
{
|
|
||||||
private sealed class GraphicsControl : Control
|
|
||||||
{
|
|
||||||
private static readonly float[] UIScaleOptions =
|
|
||||||
{
|
|
||||||
0f,
|
|
||||||
0.75f,
|
|
||||||
1f,
|
|
||||||
1.25f,
|
|
||||||
1.50f,
|
|
||||||
1.75f,
|
|
||||||
2f
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly IConfigurationManager _cfg;
|
|
||||||
private readonly IPrototypeManager _prototypeManager;
|
|
||||||
|
|
||||||
private readonly Button ApplyButton;
|
|
||||||
private readonly CheckBox VSyncCheckBox;
|
|
||||||
private readonly CheckBox FullscreenCheckBox;
|
|
||||||
private readonly OptionButton LightingPresetOption;
|
|
||||||
private readonly OptionButton _uiScaleOption;
|
|
||||||
private readonly OptionButton _hudThemeOption;
|
|
||||||
private readonly CheckBox _viewportStretchCheckBox;
|
|
||||||
private readonly CheckBox _viewportLowResCheckBox;
|
|
||||||
private readonly Slider _viewportScaleSlider;
|
|
||||||
private readonly Control _viewportScaleBox;
|
|
||||||
private readonly Label _viewportScaleText;
|
|
||||||
|
|
||||||
public GraphicsControl(IConfigurationManager cfg, IPrototypeManager proMan)
|
|
||||||
{
|
|
||||||
_cfg = cfg;
|
|
||||||
_prototypeManager = proMan;
|
|
||||||
var vBox = new VBoxContainer();
|
|
||||||
|
|
||||||
var contents = new VBoxContainer
|
|
||||||
{
|
|
||||||
Margin = new Thickness(2, 2, 2, 0),
|
|
||||||
VerticalExpand = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
VSyncCheckBox = new CheckBox {Text = Loc.GetString("ui-options-vsync")};
|
|
||||||
contents.AddChild(VSyncCheckBox);
|
|
||||||
VSyncCheckBox.OnToggled += OnCheckBoxToggled;
|
|
||||||
|
|
||||||
FullscreenCheckBox = new CheckBox {Text = Loc.GetString("ui-options-fullscreen")};
|
|
||||||
contents.AddChild(FullscreenCheckBox);
|
|
||||||
FullscreenCheckBox.OnToggled += OnCheckBoxToggled;
|
|
||||||
|
|
||||||
LightingPresetOption = new OptionButton {MinSize = (100, 0)};
|
|
||||||
LightingPresetOption.AddItem(Loc.GetString("ui-options-lighting-very-low"));
|
|
||||||
LightingPresetOption.AddItem(Loc.GetString("ui-options-lighting-low"));
|
|
||||||
LightingPresetOption.AddItem(Loc.GetString("ui-options-lighting-medium"));
|
|
||||||
LightingPresetOption.AddItem(Loc.GetString("ui-options-lighting-high"));
|
|
||||||
LightingPresetOption.OnItemSelected += OnLightingQualityChanged;
|
|
||||||
|
|
||||||
contents.AddChild(new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Label {Text = Loc.GetString("ui-options-lighting-label")},
|
|
||||||
new Control {MinSize = (4, 0)},
|
|
||||||
LightingPresetOption
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ApplyButton = new Button
|
|
||||||
{
|
|
||||||
Text = Loc.GetString("ui-options-apply"), TextAlign = Label.AlignMode.Center,
|
|
||||||
HorizontalAlignment = HAlignment.Right
|
|
||||||
};
|
|
||||||
|
|
||||||
_uiScaleOption = new OptionButton();
|
|
||||||
_uiScaleOption.AddItem(Loc.GetString("ui-options-scale-auto",
|
|
||||||
("scale", UserInterfaceManager.DefaultUIScale)));
|
|
||||||
_uiScaleOption.AddItem(Loc.GetString("ui-options-scale-75"));
|
|
||||||
_uiScaleOption.AddItem(Loc.GetString("ui-options-scale-100"));
|
|
||||||
_uiScaleOption.AddItem(Loc.GetString("ui-options-scale-125"));
|
|
||||||
_uiScaleOption.AddItem(Loc.GetString("ui-options-scale-150"));
|
|
||||||
_uiScaleOption.AddItem(Loc.GetString("ui-options-scale-175"));
|
|
||||||
_uiScaleOption.AddItem(Loc.GetString("ui-options-scale-200"));
|
|
||||||
_uiScaleOption.OnItemSelected += OnUIScaleChanged;
|
|
||||||
|
|
||||||
contents.AddChild(new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Label {Text = Loc.GetString("ui-options-scale-label")},
|
|
||||||
new Control {MinSize = (4, 0)},
|
|
||||||
_uiScaleOption
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_hudThemeOption = new OptionButton();
|
|
||||||
foreach (var gear in _prototypeManager.EnumeratePrototypes<HudThemePrototype>())
|
|
||||||
{
|
|
||||||
_hudThemeOption.AddItem(Loc.GetString(gear.Name));
|
|
||||||
}
|
|
||||||
_hudThemeOption.OnItemSelected += OnHudThemeChanged;
|
|
||||||
|
|
||||||
contents.AddChild(new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Label {Text = Loc.GetString("ui-options-hud-theme")},
|
|
||||||
new Control {MinSize = (4, 0)},
|
|
||||||
_hudThemeOption
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_viewportStretchCheckBox = new CheckBox
|
|
||||||
{
|
|
||||||
Text = Loc.GetString("ui-options-vp-stretch")
|
|
||||||
};
|
|
||||||
|
|
||||||
_viewportStretchCheckBox.OnToggled += _ =>
|
|
||||||
{
|
|
||||||
UpdateViewportScale();
|
|
||||||
UpdateApplyButton();
|
|
||||||
};
|
|
||||||
|
|
||||||
_viewportScaleSlider = new Slider
|
|
||||||
{
|
|
||||||
MinValue = 1,
|
|
||||||
MaxValue = 5,
|
|
||||||
Rounded = true,
|
|
||||||
MinWidth = 200
|
|
||||||
};
|
|
||||||
|
|
||||||
_viewportScaleSlider.OnValueChanged += _ =>
|
|
||||||
{
|
|
||||||
UpdateApplyButton();
|
|
||||||
UpdateViewportScale();
|
|
||||||
};
|
|
||||||
|
|
||||||
_viewportLowResCheckBox = new CheckBox { Text = Loc.GetString("ui-options-vp-low-res")};
|
|
||||||
_viewportLowResCheckBox.OnToggled += OnCheckBoxToggled;
|
|
||||||
|
|
||||||
contents.AddChild(new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
_viewportStretchCheckBox,
|
|
||||||
(_viewportScaleBox = new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(_viewportScaleText = new Label
|
|
||||||
{
|
|
||||||
Margin = new Thickness(8, 0)
|
|
||||||
}),
|
|
||||||
_viewportScaleSlider,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
contents.AddChild(_viewportLowResCheckBox);
|
|
||||||
|
|
||||||
vBox.AddChild(contents);
|
|
||||||
|
|
||||||
vBox.AddChild(new StripeBack
|
|
||||||
{
|
|
||||||
HasBottomEdge = false,
|
|
||||||
HasMargins = false,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
ApplyButton
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ApplyButton.OnPressed += OnApplyButtonPressed;
|
|
||||||
|
|
||||||
VSyncCheckBox.Pressed = _cfg.GetCVar(CVars.DisplayVSync);
|
|
||||||
FullscreenCheckBox.Pressed = ConfigIsFullscreen;
|
|
||||||
LightingPresetOption.SelectId(GetConfigLightingQuality());
|
|
||||||
_uiScaleOption.SelectId(GetConfigUIScalePreset(ConfigUIScale));
|
|
||||||
_hudThemeOption.SelectId(_cfg.GetCVar(CCVars.HudTheme));
|
|
||||||
_viewportScaleSlider.Value = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
|
|
||||||
_viewportStretchCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportStretch);
|
|
||||||
_viewportLowResCheckBox.Pressed = !_cfg.GetCVar(CCVars.ViewportScaleRender);
|
|
||||||
|
|
||||||
UpdateViewportScale();
|
|
||||||
UpdateApplyButton();
|
|
||||||
|
|
||||||
AddChild(vBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUIScaleChanged(OptionButton.ItemSelectedEventArgs args)
|
|
||||||
{
|
|
||||||
_uiScaleOption.SelectId(args.Id);
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnHudThemeChanged(OptionButton.ItemSelectedEventArgs args)
|
|
||||||
{
|
|
||||||
_hudThemeOption.SelectId(args.Id);
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
_cfg.SetCVar(CVars.DisplayVSync, VSyncCheckBox.Pressed);
|
|
||||||
SetConfigLightingQuality(LightingPresetOption.SelectedId);
|
|
||||||
if (_hudThemeOption.SelectedId != _cfg.GetCVar(CCVars.HudTheme)) // Don't unnecessarily redraw the HUD
|
|
||||||
{
|
|
||||||
_cfg.SetCVar(CCVars.HudTheme, _hudThemeOption.SelectedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
_cfg.SetCVar(CVars.DisplayWindowMode,
|
|
||||||
(int) (FullscreenCheckBox.Pressed ? WindowMode.Fullscreen : WindowMode.Windowed));
|
|
||||||
_cfg.SetCVar(CVars.DisplayUIScale, UIScaleOptions[_uiScaleOption.SelectedId]);
|
|
||||||
_cfg.SetCVar(CCVars.ViewportStretch, _viewportStretchCheckBox.Pressed);
|
|
||||||
_cfg.SetCVar(CCVars.ViewportFixedScaleFactor, (int) _viewportScaleSlider.Value);
|
|
||||||
_cfg.SetCVar(CCVars.ViewportScaleRender, !_viewportLowResCheckBox.Pressed);
|
|
||||||
_cfg.SaveToFile();
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCheckBoxToggled(BaseButton.ButtonToggledEventArgs args)
|
|
||||||
{
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLightingQualityChanged(OptionButton.ItemSelectedEventArgs args)
|
|
||||||
{
|
|
||||||
LightingPresetOption.SelectId(args.Id);
|
|
||||||
UpdateApplyButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateApplyButton()
|
|
||||||
{
|
|
||||||
var isVSyncSame = VSyncCheckBox.Pressed == _cfg.GetCVar(CVars.DisplayVSync);
|
|
||||||
var isFullscreenSame = FullscreenCheckBox.Pressed == ConfigIsFullscreen;
|
|
||||||
var isLightingQualitySame = LightingPresetOption.SelectedId == GetConfigLightingQuality();
|
|
||||||
var isHudThemeSame = _hudThemeOption.SelectedId == _cfg.GetCVar(CCVars.HudTheme);
|
|
||||||
var isUIScaleSame = MathHelper.CloseTo(UIScaleOptions[_uiScaleOption.SelectedId], ConfigUIScale);
|
|
||||||
var isVPStretchSame = _viewportStretchCheckBox.Pressed == _cfg.GetCVar(CCVars.ViewportStretch);
|
|
||||||
var isVPScaleSame = (int) _viewportScaleSlider.Value == _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
|
|
||||||
var isVPResSame = _viewportLowResCheckBox.Pressed == !_cfg.GetCVar(CCVars.ViewportScaleRender);
|
|
||||||
|
|
||||||
ApplyButton.Disabled = isVSyncSame &&
|
|
||||||
isFullscreenSame &&
|
|
||||||
isLightingQualitySame &&
|
|
||||||
isUIScaleSame &&
|
|
||||||
isVPStretchSame &&
|
|
||||||
isVPScaleSame &&
|
|
||||||
isVPResSame &&
|
|
||||||
isHudThemeSame;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ConfigIsFullscreen =>
|
|
||||||
_cfg.GetCVar(CVars.DisplayWindowMode) == (int) WindowMode.Fullscreen;
|
|
||||||
|
|
||||||
private float ConfigUIScale => _cfg.GetCVar(CVars.DisplayUIScale);
|
|
||||||
|
|
||||||
private int GetConfigLightingQuality()
|
|
||||||
{
|
|
||||||
var val = _cfg.GetCVar(CVars.DisplayLightMapDivider);
|
|
||||||
var soft = _cfg.GetCVar(CVars.DisplaySoftShadows);
|
|
||||||
if (val >= 8)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if ((val >= 2) && !soft)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (val >= 2)
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetConfigLightingQuality(int value)
|
|
||||||
{
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 8);
|
|
||||||
_cfg.SetCVar(CVars.DisplaySoftShadows, false);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 2);
|
|
||||||
_cfg.SetCVar(CVars.DisplaySoftShadows, false);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 2);
|
|
||||||
_cfg.SetCVar(CVars.DisplaySoftShadows, true);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
_cfg.SetCVar(CVars.DisplayLightMapDivider, 1);
|
|
||||||
_cfg.SetCVar(CVars.DisplaySoftShadows, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetConfigUIScalePreset(float value)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < UIScaleOptions.Length; i++)
|
|
||||||
{
|
|
||||||
if (MathHelper.CloseTo(UIScaleOptions[i], value))
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateViewportScale()
|
|
||||||
{
|
|
||||||
_viewportScaleBox.Visible = !_viewportStretchCheckBox.Pressed;
|
|
||||||
_viewportScaleText.Text = Loc.GetString("ui-options-vp-scale", ("scale", _viewportScaleSlider.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,491 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.HUD.UI;
|
|
||||||
using Content.Client.Stylesheets;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.Input;
|
|
||||||
using Robust.Client.UserInterface;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Client.EscapeMenu.UI
|
|
||||||
{
|
|
||||||
public sealed partial class OptionsMenu
|
|
||||||
{
|
|
||||||
private sealed class KeyRebindControl : Control
|
|
||||||
{
|
|
||||||
// List of key functions that must be registered as toggle instead.
|
|
||||||
private static readonly HashSet<BoundKeyFunction> ToggleFunctions = new()
|
|
||||||
{
|
|
||||||
EngineKeyFunctions.ShowDebugMonitors,
|
|
||||||
EngineKeyFunctions.HideUI,
|
|
||||||
};
|
|
||||||
|
|
||||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
|
||||||
|
|
||||||
private BindButton? _currentlyRebinding;
|
|
||||||
|
|
||||||
private readonly Dictionary<BoundKeyFunction, KeyControl> _keyControls =
|
|
||||||
new();
|
|
||||||
|
|
||||||
private readonly List<Action> _deferCommands = new();
|
|
||||||
|
|
||||||
public KeyRebindControl()
|
|
||||||
{
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
Button resetAllButton;
|
|
||||||
var vBox = new VBoxContainer {Margin = new Thickness(2, 0, 0, 0)};
|
|
||||||
AddChild(new VBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new ScrollContainer
|
|
||||||
{
|
|
||||||
VerticalExpand = true,
|
|
||||||
Children = {vBox}
|
|
||||||
},
|
|
||||||
|
|
||||||
new StripeBack
|
|
||||||
{
|
|
||||||
HasBottomEdge = false,
|
|
||||||
HasMargins = false,
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Control {MinSize = (2, 0)},
|
|
||||||
new Label
|
|
||||||
{
|
|
||||||
StyleClasses = {StyleBase.StyleClassLabelSubText},
|
|
||||||
Text = Loc.GetString("ui-options-binds-explanation")
|
|
||||||
},
|
|
||||||
(resetAllButton = new Button
|
|
||||||
{
|
|
||||||
Text = Loc.GetString("ui-options-binds-reset-all"),
|
|
||||||
StyleClasses = {StyleBase.ButtonCaution},
|
|
||||||
HorizontalExpand = true,
|
|
||||||
HorizontalAlignment = HAlignment.Right
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
resetAllButton.OnPressed += _ =>
|
|
||||||
{
|
|
||||||
_deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
_inputManager.ResetAllBindings();
|
|
||||||
_inputManager.SaveToUserData();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var first = true;
|
|
||||||
|
|
||||||
void AddHeader(string headerContents)
|
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
{
|
|
||||||
vBox.AddChild(new Control {MinSize = (0, 8)});
|
|
||||||
}
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
vBox.AddChild(new Label
|
|
||||||
{
|
|
||||||
Text = Loc.GetString(headerContents),
|
|
||||||
FontColorOverride = StyleNano.NanoGold,
|
|
||||||
StyleClasses = {StyleNano.StyleClassLabelKeyText}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddButton(BoundKeyFunction function)
|
|
||||||
{
|
|
||||||
var control = new KeyControl(this, function);
|
|
||||||
vBox.AddChild(control);
|
|
||||||
_keyControls.Add(function, control);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-movement");
|
|
||||||
AddButton(EngineKeyFunctions.MoveUp);
|
|
||||||
AddButton(EngineKeyFunctions.MoveLeft);
|
|
||||||
AddButton(EngineKeyFunctions.MoveDown);
|
|
||||||
AddButton(EngineKeyFunctions.MoveRight);
|
|
||||||
AddButton(EngineKeyFunctions.Walk);
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-interaction-basic");
|
|
||||||
AddButton(EngineKeyFunctions.Use);
|
|
||||||
AddButton(ContentKeyFunctions.WideAttack);
|
|
||||||
AddButton(ContentKeyFunctions.ActivateItemInHand);
|
|
||||||
AddButton(ContentKeyFunctions.ActivateItemInWorld);
|
|
||||||
AddButton(ContentKeyFunctions.Drop);
|
|
||||||
AddButton(ContentKeyFunctions.ExamineEntity);
|
|
||||||
AddButton(ContentKeyFunctions.SwapHands);
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-interaction-adv");
|
|
||||||
AddButton(ContentKeyFunctions.SmartEquipBackpack);
|
|
||||||
AddButton(ContentKeyFunctions.SmartEquipBelt);
|
|
||||||
AddButton(ContentKeyFunctions.ThrowItemInHand);
|
|
||||||
AddButton(ContentKeyFunctions.TryPullObject);
|
|
||||||
AddButton(ContentKeyFunctions.MovePulledObject);
|
|
||||||
AddButton(ContentKeyFunctions.ReleasePulledObject);
|
|
||||||
AddButton(ContentKeyFunctions.Point);
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-ui");
|
|
||||||
AddButton(ContentKeyFunctions.FocusChat);
|
|
||||||
AddButton(ContentKeyFunctions.FocusLocalChat);
|
|
||||||
AddButton(ContentKeyFunctions.FocusRadio);
|
|
||||||
AddButton(ContentKeyFunctions.FocusOOC);
|
|
||||||
AddButton(ContentKeyFunctions.FocusAdminChat);
|
|
||||||
AddButton(ContentKeyFunctions.CycleChatChannelForward);
|
|
||||||
AddButton(ContentKeyFunctions.CycleChatChannelBackward);
|
|
||||||
AddButton(ContentKeyFunctions.OpenCharacterMenu);
|
|
||||||
AddButton(ContentKeyFunctions.OpenContextMenu);
|
|
||||||
AddButton(ContentKeyFunctions.OpenCraftingMenu);
|
|
||||||
AddButton(ContentKeyFunctions.OpenInventoryMenu);
|
|
||||||
AddButton(ContentKeyFunctions.OpenInfo);
|
|
||||||
AddButton(ContentKeyFunctions.OpenActionsMenu);
|
|
||||||
AddButton(ContentKeyFunctions.OpenEntitySpawnWindow);
|
|
||||||
AddButton(ContentKeyFunctions.OpenSandboxWindow);
|
|
||||||
AddButton(ContentKeyFunctions.OpenTileSpawnWindow);
|
|
||||||
AddButton(ContentKeyFunctions.OpenAdminMenu);
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-misc");
|
|
||||||
AddButton(ContentKeyFunctions.TakeScreenshot);
|
|
||||||
AddButton(ContentKeyFunctions.TakeScreenshotNoUI);
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-hotbar");
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar1);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar2);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar3);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar4);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar5);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar6);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar7);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar8);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar9);
|
|
||||||
AddButton(ContentKeyFunctions.Hotbar0);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout1);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout2);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout3);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout4);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout5);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout6);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout7);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout8);
|
|
||||||
AddButton(ContentKeyFunctions.Loadout9);
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-map-editor");
|
|
||||||
AddButton(EngineKeyFunctions.EditorPlaceObject);
|
|
||||||
AddButton(EngineKeyFunctions.EditorCancelPlace);
|
|
||||||
AddButton(EngineKeyFunctions.EditorGridPlace);
|
|
||||||
AddButton(EngineKeyFunctions.EditorLinePlace);
|
|
||||||
AddButton(EngineKeyFunctions.EditorRotateObject);
|
|
||||||
|
|
||||||
AddHeader("ui-options-header-dev");
|
|
||||||
AddButton(EngineKeyFunctions.ShowDebugConsole);
|
|
||||||
AddButton(EngineKeyFunctions.ShowDebugMonitors);
|
|
||||||
AddButton(EngineKeyFunctions.HideUI);
|
|
||||||
|
|
||||||
foreach (var control in _keyControls.Values)
|
|
||||||
{
|
|
||||||
UpdateKeyControl(control);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateKeyControl(KeyControl control)
|
|
||||||
{
|
|
||||||
var activeBinds = _inputManager.GetKeyBindings(control.Function);
|
|
||||||
|
|
||||||
IKeyBinding? bind1 = null;
|
|
||||||
IKeyBinding? bind2 = null;
|
|
||||||
|
|
||||||
if (activeBinds.Count > 0)
|
|
||||||
{
|
|
||||||
bind1 = activeBinds[0];
|
|
||||||
|
|
||||||
if (activeBinds.Count > 1)
|
|
||||||
{
|
|
||||||
bind2 = activeBinds[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
control.BindButton1.Binding = bind1;
|
|
||||||
control.BindButton1.UpdateText();
|
|
||||||
|
|
||||||
control.BindButton2.Binding = bind2;
|
|
||||||
control.BindButton2.UpdateText();
|
|
||||||
|
|
||||||
control.BindButton2.Button.Disabled = activeBinds.Count == 0;
|
|
||||||
control.ResetButton.Disabled = !_inputManager.IsKeyFunctionModified(control.Function);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void EnteredTree()
|
|
||||||
{
|
|
||||||
base.EnteredTree();
|
|
||||||
|
|
||||||
_inputManager.FirstChanceOnKeyEvent += InputManagerOnFirstChanceOnKeyEvent;
|
|
||||||
_inputManager.OnKeyBindingAdded += OnKeyBindAdded;
|
|
||||||
_inputManager.OnKeyBindingRemoved += OnKeyBindRemoved;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ExitedTree()
|
|
||||||
{
|
|
||||||
base.ExitedTree();
|
|
||||||
|
|
||||||
_inputManager.FirstChanceOnKeyEvent -= InputManagerOnFirstChanceOnKeyEvent;
|
|
||||||
_inputManager.OnKeyBindingAdded -= OnKeyBindAdded;
|
|
||||||
_inputManager.OnKeyBindingRemoved -= OnKeyBindRemoved;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnKeyBindRemoved(IKeyBinding obj)
|
|
||||||
{
|
|
||||||
OnKeyBindModified(obj, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnKeyBindAdded(IKeyBinding obj)
|
|
||||||
{
|
|
||||||
OnKeyBindModified(obj, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnKeyBindModified(IKeyBinding bind, bool removal)
|
|
||||||
{
|
|
||||||
if (!_keyControls.TryGetValue(bind.Function, out var keyControl))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removal && _currentlyRebinding?.KeyControl == keyControl)
|
|
||||||
{
|
|
||||||
// Don't do update if the removal was from initiating a rebind.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateKeyControl(keyControl);
|
|
||||||
|
|
||||||
if (_currentlyRebinding == keyControl.BindButton1 || _currentlyRebinding == keyControl.BindButton2)
|
|
||||||
{
|
|
||||||
_currentlyRebinding = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InputManagerOnFirstChanceOnKeyEvent(KeyEventArgs keyEvent, KeyEventType type)
|
|
||||||
{
|
|
||||||
DebugTools.Assert(IsInsideTree);
|
|
||||||
|
|
||||||
if (_currentlyRebinding == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
keyEvent.Handle();
|
|
||||||
|
|
||||||
if (type != KeyEventType.Up)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var key = keyEvent.Key;
|
|
||||||
|
|
||||||
// Figure out modifiers based on key event.
|
|
||||||
// TODO: this won't allow for combinations with keys other than the standard modifier keys,
|
|
||||||
// even though the input system totally supports it.
|
|
||||||
var mods = new Keyboard.Key[3];
|
|
||||||
var i = 0;
|
|
||||||
if (keyEvent.Control && key != Keyboard.Key.Control)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.Control;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyEvent.Shift && key != Keyboard.Key.Shift)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.Shift;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyEvent.Alt && key != Keyboard.Key.Alt)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.Alt;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The input system can only handle 3 modifier keys so if you hold all 4 of the modifier keys
|
|
||||||
// then system gets the shaft, I guess.
|
|
||||||
if (keyEvent.System && i != 3 && key != Keyboard.Key.LSystem && key != Keyboard.Key.RSystem)
|
|
||||||
{
|
|
||||||
mods[i] = Keyboard.Key.LSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
var function = _currentlyRebinding.KeyControl.Function;
|
|
||||||
var bindType = KeyBindingType.State;
|
|
||||||
if (ToggleFunctions.Contains(function))
|
|
||||||
{
|
|
||||||
bindType = KeyBindingType.Toggle;
|
|
||||||
}
|
|
||||||
|
|
||||||
var registration = new KeyBindingRegistration
|
|
||||||
{
|
|
||||||
Function = function,
|
|
||||||
BaseKey = key,
|
|
||||||
Mod1 = mods[0],
|
|
||||||
Mod2 = mods[1],
|
|
||||||
Mod3 = mods[2],
|
|
||||||
Priority = 0,
|
|
||||||
Type = bindType,
|
|
||||||
CanFocus = key == Keyboard.Key.MouseLeft
|
|
||||||
|| key == Keyboard.Key.MouseRight
|
|
||||||
|| key == Keyboard.Key.MouseMiddle,
|
|
||||||
CanRepeat = false
|
|
||||||
};
|
|
||||||
|
|
||||||
_inputManager.RegisterBinding(registration);
|
|
||||||
// OnKeyBindModified will cause _currentlyRebinding to be reset and the UI to update.
|
|
||||||
_inputManager.SaveToUserData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RebindButtonPressed(BindButton button)
|
|
||||||
{
|
|
||||||
if (_currentlyRebinding != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentlyRebinding = button;
|
|
||||||
_currentlyRebinding.Button.Text = Loc.GetString("ui-options-key-prompt");
|
|
||||||
|
|
||||||
if (button.Binding != null)
|
|
||||||
{
|
|
||||||
_deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
// Have to do defer this or else there will be an exception in InputManager.
|
|
||||||
// Because this IS fired from an input event.
|
|
||||||
_inputManager.RemoveBinding(button.Binding);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void FrameUpdate(FrameEventArgs args)
|
|
||||||
{
|
|
||||||
base.FrameUpdate(args);
|
|
||||||
|
|
||||||
if (_deferCommands.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var command in _deferCommands)
|
|
||||||
{
|
|
||||||
command();
|
|
||||||
}
|
|
||||||
|
|
||||||
_deferCommands.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class KeyControl : Control
|
|
||||||
{
|
|
||||||
public readonly BoundKeyFunction Function;
|
|
||||||
public readonly BindButton BindButton1;
|
|
||||||
public readonly BindButton BindButton2;
|
|
||||||
public readonly Button ResetButton;
|
|
||||||
|
|
||||||
public KeyControl(KeyRebindControl parent, BoundKeyFunction function)
|
|
||||||
{
|
|
||||||
Function = function;
|
|
||||||
var name = new Label
|
|
||||||
{
|
|
||||||
Text = Loc.GetString(
|
|
||||||
$"ui-options-function-{CaseConversion.PascalToKebab(function.FunctionName)}"),
|
|
||||||
HorizontalExpand = true,
|
|
||||||
HorizontalAlignment = HAlignment.Left
|
|
||||||
};
|
|
||||||
|
|
||||||
BindButton1 = new BindButton(parent, this, StyleBase.ButtonOpenRight);
|
|
||||||
BindButton2 = new BindButton(parent, this, StyleBase.ButtonOpenLeft);
|
|
||||||
ResetButton = new Button {Text = Loc.GetString("ui-options-bind-reset"), StyleClasses = {StyleBase.ButtonCaution}};
|
|
||||||
|
|
||||||
var hBox = new HBoxContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new Control {MinSize = (5, 0)},
|
|
||||||
name,
|
|
||||||
BindButton1,
|
|
||||||
BindButton2,
|
|
||||||
new Control {MinSize = (10, 0)},
|
|
||||||
ResetButton
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ResetButton.OnPressed += args =>
|
|
||||||
{
|
|
||||||
parent._deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
parent._inputManager.ResetBindingsFor(function);
|
|
||||||
parent._inputManager.SaveToUserData();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
AddChild(hBox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class BindButton : Control
|
|
||||||
{
|
|
||||||
private readonly KeyRebindControl _control;
|
|
||||||
public readonly KeyControl KeyControl;
|
|
||||||
public readonly Button Button;
|
|
||||||
public IKeyBinding? Binding;
|
|
||||||
|
|
||||||
public BindButton(KeyRebindControl control, KeyControl keyControl, string styleClass)
|
|
||||||
{
|
|
||||||
_control = control;
|
|
||||||
KeyControl = keyControl;
|
|
||||||
Button = new Button {StyleClasses = {styleClass}};
|
|
||||||
UpdateText();
|
|
||||||
AddChild(Button);
|
|
||||||
|
|
||||||
Button.OnPressed += args =>
|
|
||||||
{
|
|
||||||
control.RebindButtonPressed(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Button.OnKeyBindDown += ButtonOnOnKeyBindDown;
|
|
||||||
|
|
||||||
MinSize = (200, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ButtonOnOnKeyBindDown(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
if (args.Function == EngineKeyFunctions.UIRightClick)
|
|
||||||
{
|
|
||||||
if (Binding != null)
|
|
||||||
{
|
|
||||||
_control._deferCommands.Add(() =>
|
|
||||||
{
|
|
||||||
_control._inputManager.RemoveBinding(Binding);
|
|
||||||
_control._inputManager.SaveToUserData();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateText()
|
|
||||||
{
|
|
||||||
Button.Text = Binding?.GetKeyString() ?? Loc.GetString("ui-options-unbound");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.EscapeMenu.UI
|
|
||||||
{
|
|
||||||
public sealed partial class OptionsMenu : SS14Window
|
|
||||||
{
|
|
||||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
||||||
[Dependency] private readonly IClydeAudio _clydeAudio = default!;
|
|
||||||
|
|
||||||
public OptionsMenu()
|
|
||||||
{
|
|
||||||
SetSize = MinSize = (800, 450);
|
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
Title = Loc.GetString("ui-options-title");
|
|
||||||
|
|
||||||
GraphicsControl graphicsControl;
|
|
||||||
KeyRebindControl rebindControl;
|
|
||||||
AudioControl audioControl;
|
|
||||||
|
|
||||||
var tabs = new TabContainer
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
(graphicsControl = new GraphicsControl(_configManager, _prototypeManager)),
|
|
||||||
(rebindControl = new KeyRebindControl()),
|
|
||||||
(audioControl = new AudioControl(_configManager, _clydeAudio)),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TabContainer.SetTabTitle(graphicsControl, Loc.GetString("ui-options-tab-graphics"));
|
|
||||||
TabContainer.SetTabTitle(rebindControl, Loc.GetString("ui-options-tab-controls"));
|
|
||||||
TabContainer.SetTabTitle(audioControl, Loc.GetString("ui-options-tab-audio"));
|
|
||||||
|
|
||||||
Contents.AddChild(tabs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10
Content.Client/EscapeMenu/UI/OptionsMenu.xaml
Normal file
10
Content.Client/EscapeMenu/UI/OptionsMenu.xaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<SS14Window xmlns="https://spacestation14.io"
|
||||||
|
xmlns:tabs="clr-namespace:Content.Client.EscapeMenu.UI.Tabs"
|
||||||
|
Title="{Loc 'ui-options-title'}"
|
||||||
|
MinSize="800 450">
|
||||||
|
<TabContainer Name="Tabs">
|
||||||
|
<tabs:GraphicsTab />
|
||||||
|
<tabs:KeyRebindTab />
|
||||||
|
<tabs:AudioTab />
|
||||||
|
</TabContainer>
|
||||||
|
</SS14Window>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user