@@ -24,22 +24,19 @@ namespace Intersect.Client.Interface.Game;
2424
2525public partial class EventWindow : Panel
2626{
27- private readonly IFont ? _defaultFont ;
28-
29- private readonly Panel _promptPanel ;
30- private readonly ImagePanel _faceImage ;
31- private readonly ScrollControl _promptScroller ;
32- private readonly Label _promptTemplateLabel ;
33- private readonly RichLabel _promptLabel ;
34-
35- private readonly Panel _optionsPanel ;
27+ private IFont ? _defaultFont ;
28+ private Panel _promptPanel ;
29+ private ImagePanel _faceImage ;
30+ private ScrollControl _promptScroller ;
31+ private Label _promptTemplateLabel ;
32+ private RichLabel _promptLabel ;
33+ private ScrollControl _optionsPanel ;
3634 private readonly List < Button > _optionButtons = new ( ) ;
37-
38- private readonly bool _typewriting ;
35+ private bool _typewriting ;
3936 private readonly long _typewriterResponseDelay = ClientConfiguration . Instance . TypewriterResponseDelay ;
40- private readonly Typewriter ? _writer ;
41-
37+ private Typewriter ? _writer ;
4238 private readonly Dialog _dialog ;
39+ private static EventWindow ? _instance ;
4340
4441 private EventWindow ( Canvas gameCanvas , Dialog dialog ) : base ( gameCanvas , nameof ( EventWindow ) )
4542 {
@@ -49,24 +46,22 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
4946 _defaultFont = GameContentManager . Current . GetFont ( name : "sourcesansproblack" ) ;
5047
5148 Alignment = [ Alignments . Center ] ;
52- Padding = new Padding ( 16 ) ;
49+ Padding = new Padding ( 12 ) ;
5350
51+ // Create controls first (so JSON can style/layout existing nodes)
5452 _promptPanel = new Panel ( this , nameof ( _promptPanel ) )
5553 {
56- DockChildSpacing = new Padding ( 8 ) , Margin = new Margin ( 16 , 8 , 16 , 8 ) ,
54+ DockChildSpacing = new Padding ( 12 ) ,
5755 } ;
5856
59- _optionsPanel = new Panel ( this , nameof ( _optionsPanel ) )
57+ _optionsPanel = new ScrollControl ( this , nameof ( _optionsPanel ) )
6058 {
61- BackgroundColor = Color . Transparent ,
62- DockChildSpacing = new Padding ( 8 ) ,
63- Margin = new Margin ( 8 , 8 , 8 , 0 ) ,
59+ DockChildSpacing = new Padding ( 4 ) ,
6460 } ;
6561
6662 _faceImage = new ImagePanel ( this , nameof ( _faceImage ) )
6763 {
6864 MaintainAspectRatio = true ,
69- Margin = new Margin ( 8 , 8 , 0 , 8 ) ,
7065 MaximumSize = new Point ( 128 , 128 ) ,
7166 RestrictToParent = true ,
7267 } ;
@@ -88,13 +83,12 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
8883 Dock = Pos . Fill ,
8984 Font = _defaultFont ,
9085 FontSize = 12 ,
91- Padding = new Padding ( 8 ) ,
86+ Padding = new Padding ( 12 ) ,
9287 } ;
9388
94- #region Configure and Display
95-
9689 CreateOptionButtons ( ) ;
9790
91+ // Load JSON to apply layout/templates
9892 try
9993 {
10094 Name = nameof ( EventWindow ) ;
@@ -104,30 +98,47 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
10498 {
10599 ApplicationContext . CurrentContext . Logger ? . LogWarning (
106100 ex ,
107- "Failed to load EventWindow JSON UI, using default layout "
101+ "Failed to load EventWindow JSON UI, using code defaults. "
108102 ) ;
109103 }
110104
105+ ApplyFace ( ) ;
106+ ApplyPromptAndTypewriter ( ) ;
107+ RunOnMainThread ( static @this => @this . _promptScroller . ScrollToTop ( ) , this ) ;
108+
109+ var dimmedBackground = ClientConfiguration . Instance . DimmedEventWindowBackground ;
110+ MakeModal ( dim : dimmedBackground ) ;
111+ BringToFront ( ) ;
112+ Interface . InputBlockingComponents . Add ( this ) ;
113+ ApplicationContext . CurrentContext . Logger ? . LogTrace ( "Event window opened" ) ;
114+ }
115+
116+ private void ApplyFace ( )
117+ {
111118 if ( _dialog . Face is { } faceTextureName )
112119 {
113120 var faceTexture = Globals . ContentManager ? . GetTexture ( TextureType . Face , faceTextureName ) ;
114121 _faceImage . Texture = faceTexture ;
115- if ( faceTexture is not null )
122+
123+ var show = faceTexture is not null ;
124+ _faceImage . IsHidden = ! show ;
125+ _faceImage . IsVisibleInParent = show ;
126+
127+ if ( show )
116128 {
117- _faceImage . IsVisibleInTree = true ;
118129 _faceImage . SizeToContents ( ) ;
119130 }
120- else
121- {
122- _faceImage . IsVisibleInTree = false ;
123- }
124131 }
125132 else
126133 {
127134 _faceImage . Texture = null ;
128- _faceImage . IsVisibleInTree = false ;
135+ _faceImage . IsHidden = true ;
136+ _faceImage . IsVisibleInParent = false ;
129137 }
138+ }
130139
140+ private void ApplyPromptAndTypewriter ( )
141+ {
131142 SkipRender ( ) ;
132143
133144 _promptLabel . ClearText ( ) ;
@@ -143,6 +154,7 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
143154
144155 _typewriting = ClientConfiguration . Instance . TypewriterEnabled &&
145156 Globals . Database ? . TypewriterBehavior != TypewriterBehavior . Off ;
157+
146158 if ( _typewriting )
147159 {
148160 _promptLabel . ClearText ( ) ;
@@ -154,42 +166,29 @@ private EventWindow(Canvas gameCanvas, Dialog dialog) : base(gameCanvas, nameof(
154166 }
155167 ) ;
156168 }
157-
158- RunOnMainThread (
159- static @this =>
160- {
161- @this . _promptScroller . ScrollToTop ( ) ;
162- } ,
163- this
164- ) ;
165-
166- var dimmedBackground = ClientConfiguration . Instance . DimmedEventWindowBackground ;
167- MakeModal ( dim : dimmedBackground ) ;
168- BringToFront ( ) ;
169- Interface . InputBlockingComponents . Add ( this ) ;
170- ApplicationContext . CurrentContext . Logger ? . LogTrace ( "Event window opened" ) ;
171-
172- #endregion Configure and Display
169+ else
170+ {
171+ _writer = null ;
172+ }
173173 }
174174
175175 private void CreateOptionButtons ( )
176176 {
177- // Clear existing buttons
177+ // Clear existing buttons we created
178178 foreach ( var button in _optionButtons )
179179 {
180180 button . Dispose ( ) ;
181181 }
182182
183183 _optionButtons . Clear ( ) ;
184+ _optionsPanel . ClearChildren ( ) ;
184185
185- // Get visible options
186186 var visibleOptions = _dialog . Options . Where ( option => ! string . IsNullOrEmpty ( option ) ) . ToArray ( ) ;
187187 if ( visibleOptions . Length < 1 )
188188 {
189189 visibleOptions = [ Strings . EventWindow . Continue ] ;
190190 }
191191
192- // Create buttons dynamically based on actual options
193192 for ( var optionIndex = 0 ; optionIndex < visibleOptions . Length ; optionIndex ++ )
194193 {
195194 var optionButton = new Button ( _optionsPanel , $ "OptionButton_{ optionIndex } ")
@@ -215,29 +214,9 @@ private void CreateOptionButtons()
215214 }
216215 }
217216
218- protected override void OnMouseClicked ( MouseButton mouseButton , Point mousePosition , bool userAction = true )
219- {
220- base . OnMouseClicked ( mouseButton , mousePosition , userAction ) ;
221-
222- SkipTypewriting ( ) ;
223- }
224-
225- protected override void Dispose ( bool disposing )
226- {
227- EnsureControlRestored ( ) ;
228- base . Dispose ( disposing ) ;
229- }
230-
231- private static EventWindow ? _instance ;
232-
233217 private void Update ( )
234218 {
235- if ( ! IsVisibleInTree || ! _typewriting )
236- {
237- return ;
238- }
239-
240- if ( _writer is null )
219+ if ( ! IsVisibleInTree || ! _typewriting || _writer is null )
241220 {
242221 return ;
243222 }
@@ -246,13 +225,12 @@ private void Update()
246225
247226 foreach ( var optionButton in _optionButtons )
248227 {
249- optionButton . IsVisibleInTree = writerCompleted && ! string . IsNullOrEmpty ( optionButton . Text ) ;
228+ optionButton . IsVisibleInParent = writerCompleted && ! string . IsNullOrEmpty ( optionButton . Text ) ;
250229 }
251230
252231 if ( writerCompleted )
253232 {
254- var disableResponse = Timing . Global . MillisecondsUtc - _writer . DoneAtMilliseconds <
255- _typewriterResponseDelay ;
233+ var disableResponse = Timing . Global . MillisecondsUtc - _writer . DoneAtMilliseconds < _typewriterResponseDelay ;
256234 foreach ( var optionButton in _optionButtons )
257235 {
258236 optionButton . IsDisabled = disableResponse ;
@@ -275,7 +253,6 @@ public static void ShowOrUpdateDialog(Canvas canvas)
275253 {
276254 if ( _instance is { } instance )
277255 {
278- // ApplicationContext.CurrentContext.Logger.LogTrace("Updating previous opened event window");
279256 instance . Update ( ) ;
280257 return ;
281258 }
@@ -308,6 +285,16 @@ public void CloseEventResponse(EventResponseType response)
308285 EnsureDestroyed ( ) ;
309286 }
310287
288+ private void SkipTypewriting ( )
289+ {
290+ if ( _writer ? . IsDone ?? true )
291+ {
292+ return ;
293+ }
294+
295+ _writer . End ( ) ;
296+ }
297+
311298 private void EnsureControlRestored ( )
312299 {
313300 if ( _instance == this )
@@ -333,13 +320,15 @@ private void EnsureDestroyed()
333320 }
334321 }
335322
336- private void SkipTypewriting ( )
323+ protected override void Dispose ( bool disposing )
337324 {
338- if ( _writer ? . IsDone ?? true )
339- {
340- return ;
341- }
325+ EnsureControlRestored ( ) ;
326+ base . Dispose ( disposing ) ;
327+ }
342328
343- _writer . End ( ) ;
329+ protected override void OnMouseClicked ( MouseButton mouseButton , Point mousePosition , bool userAction = true )
330+ {
331+ base . OnMouseClicked ( mouseButton , mousePosition , userAction ) ;
332+ SkipTypewriting ( ) ;
344333 }
345334}
0 commit comments