Skip to content

Commit 344f199

Browse files
committed
fix: allow to replace a specific view instance
1 parent 8fa1cdc commit 344f199

1 file changed

Lines changed: 71 additions & 3 deletions

File tree

Assets/PurrUI/Runtime/ViewStack.cs

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,70 @@ public T Replace<T>() where T : MonoView
341341
return (T)Replace(prefab);
342342
}
343343

344+
/// <summary>
345+
/// Replaces the specified instance in the stack with a new window instantiated from the provided prefab.
346+
/// The old instance plays its exit transition while the new one plays its enter transition.
347+
/// The new window takes the same position in the stack as the old one.
348+
/// </summary>
349+
public MonoView Replace(MonoView instance, MonoView prefab)
350+
{
351+
if (!Application.isPlaying)
352+
return null;
353+
354+
if (prefab == null)
355+
{
356+
Debug.LogError("[WindowStack] Provided prefab is null.", this);
357+
return null;
358+
}
359+
360+
int idx = _stack.IndexOf(instance);
361+
362+
if (idx == -1)
363+
{
364+
Debug.LogError("[WindowStack] The provided window instance is not in the stack.", this);
365+
return null;
366+
}
367+
368+
// If it's the top window, use the regular Replace method
369+
if (idx == _stack.Count - 1)
370+
return Replace(prefab);
371+
372+
// Remove the instance at its position
373+
_stack.RemoveAt(idx);
374+
instance.OnPopped();
375+
instance.parentStack = null;
376+
377+
var exitTransition = instance.ExitTransition();
378+
if (exitTransition != null)
379+
{
380+
instance.canvasGroup.blocksRaycasts = false;
381+
StartCoroutine(RunExitTransition(instance, exitTransition));
382+
}
383+
else
384+
{
385+
instance.DestroyMe();
386+
}
387+
388+
// Insert new instance at the same position
389+
return InsertIntoStack(prefab, idx);
390+
}
391+
392+
/// <summary>
393+
/// Replaces the specified instance in the stack with a new window of the specified type.
394+
/// The old instance plays its exit transition while the new one plays its enter transition.
395+
/// The new window takes the same position in the stack as the old one.
396+
/// </summary>
397+
public T Replace<T>(MonoView instance) where T : MonoView
398+
{
399+
if (!TryGet<T>(out var prefab))
400+
{
401+
Debug.LogError($"[WindowStack] No window prefab of type `{typeof(T)}` found in WindowPrefabs.", this);
402+
return null;
403+
}
404+
405+
return (T)Replace(instance, prefab);
406+
}
407+
344408
/// <summary>
345409
/// Moves the specified instance to the top of the stack. If the instance is not in the stack, does nothing.
346410
/// </summary>
@@ -402,11 +466,15 @@ private void RemoveTop()
402466

403467
private MonoView AddToStack(MonoView prefab)
404468
{
405-
var idx = _stack.Count;
469+
return InsertIntoStack(prefab, _stack.Count);
470+
}
471+
472+
private MonoView InsertIntoStack(MonoView prefab, int idx)
473+
{
406474
var instance = Instantiate(prefab, _parent);
407-
_stack.Add(instance);
475+
_stack.Insert(idx, instance);
408476
instance.Initialize(this);
409-
instance.UpdateOrder(idx + _orderOffset);
477+
UpdateOrder(idx);
410478
instance.OnPushed();
411479

412480
var transition = instance.EnterTransition();

0 commit comments

Comments
 (0)