@@ -109,32 +109,9 @@ public MonoView Push(MonoView prefab)
109109 }
110110
111111 if ( _stack . Count > 0 )
112- {
113- var currentTop = _stack [ ^ 1 ] ;
114- currentTop . MoveToBackground ( ) ;
115- }
116-
117- var idx = _stack . Count ;
118- var instance = Instantiate ( prefab , _parent ) ;
119- _stack . Add ( instance ) ;
120- instance . Initialize ( this ) ;
121- instance . UpdateOrder ( idx + _orderOffset ) ;
122- instance . OnPushed ( ) ;
112+ _stack [ ^ 1 ] . MoveToBackground ( ) ;
123113
124- var transition = instance . EnterTransition ( ) ;
125- if ( transition != null )
126- {
127- instance . canvasGroup . interactable = false ;
128- instance . canvasGroup . blocksRaycasts = false ;
129- StartCoroutine ( RunEnterTransition ( instance , transition ) ) ;
130- ApplyCulling ( false ) ;
131- }
132- else
133- {
134- ApplyCulling ( true ) ;
135- }
136-
137- return instance ;
114+ return AddToStack ( prefab ) ;
138115 }
139116
140117 private void UpdateVisibility ( )
@@ -233,8 +210,6 @@ private IEnumerator RunUncullTransition(MonoView view, IEnumerator transition)
233210 /// The prefab must be included in the WindowPrefabs collection.
234211 /// If no prefab of that type is found, logs an error and does nothing.
235212 /// </summary>
236- /// <typeparam name="T"></typeparam>
237- /// <returns></returns>
238213 public T Push < T > ( ) where T : MonoView
239214 {
240215 if ( ! TryGet < T > ( out var prefab ) )
@@ -243,34 +218,7 @@ public T Push<T>() where T : MonoView
243218 return null ;
244219 }
245220
246- var idx = _stack . Count ;
247-
248- if ( idx > 0 )
249- {
250- var currentTop = _stack [ idx - 1 ] ;
251- currentTop . MoveToBackground ( ) ;
252- }
253-
254- var instance = Instantiate ( prefab , _parent ) ;
255- _stack . Add ( instance ) ;
256- instance . Initialize ( this ) ;
257- instance . UpdateOrder ( idx + _orderOffset ) ;
258- instance . OnPushed ( ) ;
259-
260- var transition = instance . EnterTransition ( ) ;
261- if ( transition != null )
262- {
263- instance . canvasGroup . interactable = false ;
264- instance . canvasGroup . blocksRaycasts = false ;
265- StartCoroutine ( RunEnterTransition ( instance , transition ) ) ;
266- ApplyCulling ( false ) ;
267- }
268- else
269- {
270- ApplyCulling ( true ) ;
271- }
272-
273- return instance ;
221+ return ( T ) Push ( prefab ) ;
274222 }
275223
276224 /// <summary>
@@ -284,21 +232,7 @@ public void Pop()
284232 return ;
285233 }
286234
287- var topView = _stack [ ^ 1 ] ;
288- _stack . RemoveAt ( _stack . Count - 1 ) ;
289- topView . OnPopped ( ) ;
290-
291- var transition = topView . ExitTransition ( ) ;
292- if ( transition != null )
293- {
294- topView . canvasGroup . interactable = false ;
295- topView . canvasGroup . blocksRaycasts = false ;
296- StartCoroutine ( RunExitTransition ( topView , transition ) ) ;
297- }
298- else
299- {
300- topView . DestroyMe ( ) ;
301- }
235+ RemoveTop ( ) ;
302236
303237 if ( _stack . Count > 0 )
304238 {
@@ -359,6 +293,41 @@ public void Pop(MonoView instance)
359293 UpdateVisibility ( ) ;
360294 }
361295
296+ /// <summary>
297+ /// Replaces the top window with a new window instantiated from the provided prefab.
298+ /// The old top plays its exit transition while the new one plays its enter transition.
299+ /// Views below are not affected (no unnecessary uncull/re-cull).
300+ /// </summary>
301+ public MonoView Replace ( MonoView prefab )
302+ {
303+ if ( prefab == null )
304+ {
305+ Debug . LogError ( "[WindowStack] Provided prefab is null." , this ) ;
306+ return null ;
307+ }
308+
309+ if ( _stack . Count > 0 )
310+ RemoveTop ( ) ;
311+
312+ return AddToStack ( prefab ) ;
313+ }
314+
315+ /// <summary>
316+ /// Replaces the top window with a new window of the specified type.
317+ /// The old top plays its exit transition while the new one plays its enter transition.
318+ /// Views below are not affected (no unnecessary uncull/re-cull).
319+ /// </summary>
320+ public T Replace < T > ( ) where T : MonoView
321+ {
322+ if ( ! TryGet < T > ( out var prefab ) )
323+ {
324+ Debug . LogError ( $ "[WindowStack] No window prefab of type `{ typeof ( T ) } ` found in WindowPrefabs.", this ) ;
325+ return null ;
326+ }
327+
328+ return ( T ) Replace ( prefab ) ;
329+ }
330+
362331 /// <summary>
363332 /// Moves the specified instance to the top of the stack. If the instance is not in the stack, does nothing.
364333 /// </summary>
@@ -398,6 +367,50 @@ public void MoveToTop<T>() where T : MonoView
398367 }
399368 }
400369
370+ private void RemoveTop ( )
371+ {
372+ var topView = _stack [ ^ 1 ] ;
373+ _stack . RemoveAt ( _stack . Count - 1 ) ;
374+ topView . OnPopped ( ) ;
375+
376+ var transition = topView . ExitTransition ( ) ;
377+ if ( transition != null )
378+ {
379+ topView . canvasGroup . interactable = false ;
380+ topView . canvasGroup . blocksRaycasts = false ;
381+ StartCoroutine ( RunExitTransition ( topView , transition ) ) ;
382+ }
383+ else
384+ {
385+ topView . DestroyMe ( ) ;
386+ }
387+ }
388+
389+ private MonoView AddToStack ( MonoView prefab )
390+ {
391+ var idx = _stack . Count ;
392+ var instance = Instantiate ( prefab , _parent ) ;
393+ _stack . Add ( instance ) ;
394+ instance . Initialize ( this ) ;
395+ instance . UpdateOrder ( idx + _orderOffset ) ;
396+ instance . OnPushed ( ) ;
397+
398+ var transition = instance . EnterTransition ( ) ;
399+ if ( transition != null )
400+ {
401+ instance . canvasGroup . interactable = false ;
402+ instance . canvasGroup . blocksRaycasts = false ;
403+ StartCoroutine ( RunEnterTransition ( instance , transition ) ) ;
404+ ApplyCulling ( false ) ;
405+ }
406+ else
407+ {
408+ ApplyCulling ( true ) ;
409+ }
410+
411+ return instance ;
412+ }
413+
401414 private IEnumerator RunEnterTransition ( MonoView view , IEnumerator transition )
402415 {
403416 yield return transition ;
0 commit comments