# विंडो स्टैक

> नेविगेशन के पीछे का मॉडल — EventsProcessor का स्टैक, popup बनाम fullscreen, Back बटन और ट्रांज़िशन।

Source: https://crossfly.dev/hi/docs/ui/navigation/the-window-stack — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# विंडो स्टैक

मॉडल को समझना अधिकांश नेविगेशन बग से बचाता है।

## मॉडल (LIFO)
`EventsProcessor` `Window` का एक **स्टैक** बनाए रखता है। शीर्ष विंडो वह है जो **इवेंट प्राप्त करती है और
ऊपर पेंट की जाती है**। नीचे वाली जीवित रहती हैं (नष्ट नहीं होतीं), केवल ढकी रहती हैं।

```
┌─────────────┐  ← topo: recebe toque/teclado, é pintada
│ TelaDetalhe │
├─────────────┤
│ TelaLista   │  ← coberta, viva
├─────────────┤
│ TelaHome    │  ← base
└─────────────┘
```

- `show()` → **push**: `EventsProcessor` में पंजीकृत करता है, `onShow()` को कॉल करता है।
- `hide()` → **pop**: पंजीकरण हटाता है, `onRemove()` को कॉल करता है; नीचे की विंडो शीर्ष पर लौट आती है।

## प्रति विंडो जीवनचक्र
| विधि | कब | उपयोग |
|---|---|---|
| `onShow()` | स्टैक में प्रवेश करने पर | UI असेंबल करना (हमेशा `super.onShow()`) |
| `onReposition()` | आकार बदलने/घुमाने पर | लेआउट पुनर्व्यवस्थित/पुनर्गणना करना |
| `onRemove()` | स्टैक से बाहर निकलने पर | timers, cursors, listeners मुक्त करना |

## Fullscreen बनाम popup
**समान** `Window` क्लास तल स्क्रीन या popup हो सकती है — यह `WindowStyle` पर निर्भर करता है
(`widthRatio`/`heightRatio` < 1 ⇒ popup; [डायलॉग और मोडल](/docs/ui/navigation/dialogs-and-modals) देखें)। Popup
पिछली स्क्रीन के ऊपर रहते हैं (जो पीछे दिखाई देती रहती है)।

## Back बटन (Android) और बाहर टैप करना
- **भौतिक Back बटन** एप्लिकेशन द्वारा कैप्चर किया जाता है और डिफ़ॉल्ट रूप से शीर्ष विंडो का `hide()` करता है।
- `canHide = true` वाले popup में, **बाहर टैप करना** popup को बंद करता है।
- बाहर निकलने को **रोकने** के लिए (उदा.: छोड़ने की पुष्टि), `hide()` होने देने से पहले इरादे को संभालें।

## पूर्ण उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)
स्टैक में push/pop और स्टैक की गई स्क्रीन के `WindowStyle` में कॉन्फ़िगर किए गए एक प्रवेश ट्रांज़िशन को प्रदर्शित करता है।
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

/** चलाने योग्य मुख्य स्क्रीन। launcher (classname) की ओर संकेत करें और चलाएँ: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      add(LAY_AUTO, new Label("Base da pilha (MainWindow)"));

      Button empilhar = new Button("Empilhar tela (push)");
      empilhar.onAction(c -> new TelaEmpilhada().show());   // push: स्टैक के शीर्ष पर आता है
      add(LAY_AUTO, empilhar);
   }
}

/** स्क्रीन जो ट्रांज़िशन के साथ शीर्ष पर आती है और hide() से लौटती है (pop)। */
class TelaEmpilhada extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      // इस विंडो का प्रवेश/निकास ट्रांज़िशन (नीचे वाली पीछे जीवित रहती है)
      getStyle().transition(UIConstants.Transition.SLIDE_LEFT);
      setLayout(new VerticalLayout());

      add(LAY_AUTO, new Label("Topo da pilha — a tela de baixo continua viva"));

      Button voltar = new Button("Voltar (pop)");
      voltar.onAction(c -> hide());   // pop: स्टैक से निकलता है, नीचे वाली शीर्ष पर लौटती है
      add(LAY_AUTO, voltar);
   }
}
```
> नीचे दिए गए अंश **केवल मूल भाग** दिखाते हैं (जो `onShow()` के अंदर जाता है)। चलाने के लिए, उन्हें ऊपर दिए गए `MainWindow` ढाँचे में रखें।

## ट्रांज़िशन
प्रवेश/निकास एनिमेशन `WindowStyle.transition` (`UIConstants.Transition`) से आता है: `NONE`
(डिफ़ॉल्ट), `FADE`, `SLIDE_LEFT/RIGHT/UP/DOWN`, `SCALE`, `SCALE_DOWN`। Pickers डिफ़ॉल्ट रूप से `FADE` का उपयोग करते हैं।
```java
getStyle().transition = UIConstants.Transition.SLIDE_LEFT;   // खुलने पर स्लाइड करता है
```

## अच्छी प्रथाएँ
- नीचे की विंडो के संदर्भ आवश्यकता से अधिक न पकड़ें — `hide()` पर उन्हें एकत्रित होने दें।
- हर `show()` का एक संगत `hide()` होना चाहिए (बिना वापसी के स्क्रीनों को ढेर करने से बचें)।

## सामान्य त्रुटियाँ
- स्थिति को संरक्षित किए बिना `onReposition()` में UI का पुनर्निर्माण करना (स्क्रॉल, चयन)।
- यह मान लेना कि दूसरी खोलने पर नीचे की विंडो नष्ट हो गई — वह जीवित रहती है।

## यह भी देखें
- [स्क्रीनों के बीच नेविगेट करें](/docs/ui/navigation/navigate-between-screens) · [डायलॉग और मोडल](/docs/ui/navigation/dialogs-and-modals)
