Skip to content

Commit a0b9159

Browse files
authored
Fix #2768: Restore/Refactor of EventWindow
Refactor EventWindow to use a dynamic List for option buttons and improve button creation logic. Also restores the ability to use .json file templates for event Dialogues.
1 parent 32d3daf commit a0b9159

File tree

1 file changed

+64
-68
lines changed

1 file changed

+64
-68
lines changed

Intersect.Client.Core/Interface/Game/EventWindow.cs

Lines changed: 64 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Intersect.Client.Core;
12
using Intersect.Client.Core.Controls;
23
using Intersect.Client.Entities.Events;
34
using Intersect.Client.Framework.Content;
@@ -26,14 +27,13 @@ public partial class EventWindow : Panel
2627
private readonly IFont? _defaultFont;
2728

2829
private readonly Panel _promptPanel;
29-
3030
private readonly ImagePanel _faceImage;
3131
private readonly ScrollControl _promptScroller;
3232
private readonly Label _promptTemplateLabel;
3333
private readonly RichLabel _promptLabel;
3434

3535
private readonly Panel _optionsPanel;
36-
private readonly Button[] _optionButtons = new Button[4];
36+
private readonly List<Button> _optionButtons = new();
3737

3838
private readonly bool _typewriting;
3939
private readonly long _typewriterResponseDelay = ClientConfiguration.Instance.TypewriterResponseDelay;
@@ -49,53 +49,22 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
4949
_defaultFont = GameContentManager.Current.GetFont(name: "sourcesansproblack");
5050

5151
Alignment = [Alignments.Center];
52-
MinimumSize = new Point(520, 180);
53-
MaximumSize = new Point(720, 520);
5452
Padding = new Padding(16);
5553

5654
_promptPanel = new Panel(this, nameof(_promptPanel))
5755
{
58-
Dock = Pos.Fill,
59-
DockChildSpacing = new Padding(8),
56+
DockChildSpacing = new Padding(8), Margin = new Margin(16, 8, 16, 8),
6057
};
6158

6259
_optionsPanel = new Panel(this, nameof(_optionsPanel))
6360
{
6461
BackgroundColor = Color.Transparent,
65-
Dock = Pos.Bottom,
6662
DockChildSpacing = new Padding(8),
67-
Margin = new Margin(0, 8, 0, 0),
63+
Margin = new Margin(8, 8, 8, 0),
6864
};
6965

70-
for (var optionIndex = 0; optionIndex < 4; ++optionIndex)
71-
{
72-
var optionButton = new Button(_optionsPanel, $"{nameof(_optionButtons)}[{optionIndex}]")
73-
{
74-
Dock = Pos.Top,
75-
Font = _defaultFont,
76-
FontSize = 12,
77-
UserData = (EventResponseType)(optionIndex + 1),
78-
};
79-
optionButton.Clicked += (sender, _) =>
80-
{
81-
if (sender.UserData is not EventResponseType eventResponseType)
82-
{
83-
return;
84-
}
85-
86-
CloseEventResponse(eventResponseType);
87-
};
88-
_optionButtons[optionIndex] = optionButton;
89-
}
90-
91-
_optionsPanel.PostLayout.Enqueue(
92-
ResizeOptionsPanelToChildren,
93-
_optionsPanel
94-
);
95-
96-
_faceImage = new ImagePanel(_promptPanel, nameof(_faceImage))
66+
_faceImage = new ImagePanel(this, nameof(_faceImage))
9767
{
98-
Dock = Pos.Left,
9968
MaintainAspectRatio = true,
10069
Margin = new Margin(8, 8, 0, 8),
10170
MaximumSize = new Point(128, 128),
@@ -122,13 +91,26 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
12291
Padding = new Padding(8),
12392
};
12493

125-
_promptPanel.SizeToChildren(recursive: true);
126-
12794
#region Configure and Display
12895

96+
CreateOptionButtons();
97+
98+
try
99+
{
100+
Name = nameof(EventWindow);
101+
LoadJsonUi(GameContentManager.UI.InGame, Graphics.Renderer.GetResolutionString());
102+
}
103+
catch (Exception ex)
104+
{
105+
ApplicationContext.CurrentContext.Logger?.LogWarning(
106+
ex,
107+
"Failed to load EventWindow JSON UI, using default layout"
108+
);
109+
}
110+
129111
if (_dialog.Face is { } faceTextureName)
130112
{
131-
var faceTexture = Globals.ContentManager.GetTexture(TextureType.Face, faceTextureName);
113+
var faceTexture = Globals.ContentManager?.GetTexture(TextureType.Face, faceTextureName);
132114
_faceImage.Texture = faceTexture;
133115
if (faceTexture is not null)
134116
{
@@ -146,29 +128,6 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
146128
_faceImage.IsVisibleInTree = false;
147129
}
148130

149-
var visibleOptions = _dialog.Options.Where(option => !string.IsNullOrEmpty(option)).ToArray();
150-
if (visibleOptions.Length < 1)
151-
{
152-
visibleOptions = [Strings.EventWindow.Continue];
153-
}
154-
155-
for (var optionIndex = 0; optionIndex < _optionButtons.Length; ++optionIndex)
156-
{
157-
var optionButton = _optionButtons[optionIndex];
158-
if (optionIndex < visibleOptions.Length)
159-
{
160-
optionButton.Text = visibleOptions[optionIndex];
161-
optionButton.IsVisibleInTree = true;
162-
}
163-
else
164-
{
165-
optionButton.IsVisibleInTree = false;
166-
}
167-
}
168-
169-
// Name = $"{nameof(EventWindow)}_{Math.Max(1, visibleOptions.Length)}";
170-
// LoadJsonUi(GameContentManager.UI.InGame, Graphics.Renderer?.GetResolutionString());
171-
172131
SkipRender();
173132

174133
_promptLabel.ClearText();
@@ -180,11 +139,10 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
180139
}
181140

182141
_promptLabel.ForceImmediateRebuild();
183-
184142
_ = _promptLabel.SizeToChildren();
185143

186144
_typewriting = ClientConfiguration.Instance.TypewriterEnabled &&
187-
Globals.Database.TypewriterBehavior != TypewriterBehavior.Off;
145+
Globals.Database?.TypewriterBehavior != TypewriterBehavior.Off;
188146
if (_typewriting)
189147
{
190148
_promptLabel.ClearText();
@@ -200,7 +158,6 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
200158
RunOnMainThread(
201159
static @this =>
202160
{
203-
@this.SizeToChildren(recursive: true);
204161
@this._promptScroller.ScrollToTop();
205162
},
206163
this
@@ -209,14 +166,52 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
209166
MakeModal(dim: true);
210167
BringToFront();
211168
Interface.InputBlockingComponents.Add(this);
212-
ApplicationContext.CurrentContext.Logger.LogTrace("Event window opened");
169+
ApplicationContext.CurrentContext.Logger?.LogTrace("Event window opened");
213170

214171
#endregion Configure and Display
215172
}
216173

217-
private static void ResizeOptionsPanelToChildren(Panel optionsPanel)
174+
private void CreateOptionButtons()
218175
{
219-
optionsPanel.SizeToChildren(new SizeToChildrenArgs(Recurse: true));
176+
// Clear existing buttons
177+
foreach (var button in _optionButtons)
178+
{
179+
button.Dispose();
180+
}
181+
182+
_optionButtons.Clear();
183+
184+
// Get visible options
185+
var visibleOptions = _dialog.Options.Where(option => !string.IsNullOrEmpty(option)).ToArray();
186+
if (visibleOptions.Length < 1)
187+
{
188+
visibleOptions = [Strings.EventWindow.Continue];
189+
}
190+
191+
// Create buttons dynamically based on actual options
192+
for (var optionIndex = 0; optionIndex < visibleOptions.Length; optionIndex++)
193+
{
194+
var optionButton = new Button(_optionsPanel, $"OptionButton_{optionIndex}")
195+
{
196+
Dock = Pos.Bottom,
197+
Font = _defaultFont,
198+
FontSize = 12,
199+
Text = visibleOptions[optionIndex],
200+
UserData = (EventResponseType)(optionIndex + 1),
201+
};
202+
203+
optionButton.Clicked += (sender, _) =>
204+
{
205+
if (sender.UserData is not EventResponseType eventResponseType)
206+
{
207+
return;
208+
}
209+
210+
CloseEventResponse(eventResponseType);
211+
};
212+
213+
_optionButtons.Add(optionButton);
214+
}
220215
}
221216

222217
protected override void OnMouseClicked(MouseButton mouseButton, Point mousePosition, bool userAction = true)
@@ -318,6 +313,7 @@ private void EnsureControlRestored()
318313
{
319314
_instance = null;
320315
}
316+
321317
_ = Interface.InputBlockingComponents.Remove(this);
322318
RemoveModal();
323319
}

0 commit comments

Comments
 (0)