Metadata-Version: 2.4
Name: PlayPy
Version: 0.3.0
Summary: PlayPy is a lightweight Python library for creating simple games and interactive applications with ease. It provides a straightforward API for handling graphics, input, and basic game mechanics, making it ideal for beginners and those looking to quickly prototype their ideas.
Author-email: angel <angyv2861@gmail.com>
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: pygame-ce>=2.5.6
Requires-Dist: colorama>=0.4.6
Dynamic: license-file

# PlayPy (0.3.0)

PlayPy is a lightweight Python library for creating games, tools, and interactive applications using a retained-mode UI and scene system built on top of pygame. It focuses on rapid prototyping, composable rendering, and simple but powerful layout primitives.

## Requirements

- Python `>=3.11`
- `pygame(-ce) >=2.6.1`

## Installation

```bash
pip install playpy
```

If that does not work:

```bash
python -m pip install playpy
```

---

# Core Concepts

## Workspace

`Workspace` owns:
- the window
- render loop
- input state
- scene stack
- coroutine scheduler

Key methods:

```python
ws.run()
ws.quit()

ws.queue_scene_change(scene)
ws.queue_scene_push(scene)
ws.queue_scene_pop(scene=None)

ws.step()
```

### Scene Scope

Temporarily push a scene using a context manager:

```python
with ws.scene_scope(scene) as (scn, handle):
    ...
```

Call:

```python
handle.disconnect()
```

to remotely pop the scoped scene.

---

## Layout Values

PlayPy uses two rectangle value types:

### `FRect`
Relative scale values.

```python
plp.FRect(x, y, w, h)
```

### `Rect`
Absolute pixel offsets.

```python
plp.Rect(x, y, w, h)
```

Final element rectangle:

```text
(scale * parent_size) + offset
```

Helpers:

```python
plp.empty_rect()
plp.empty_frect()
plp.full_screen_rect()
```

Rect types are iterable and support multiple constructor overloads.

---

# Parenting

Any `Element` can contain children.

```python
child.parent = parent
```

or:

```python
parent.add_child(child)
```

Relationship helpers:

```python
is_parent_of()
is_child_of()

is_ancestor_of()
is_descendant_of()
```

Properties:

```python
parent
children
ancestors
descendants
```

---

# Rendering System

PlayPy now uses a compositing pipeline.

`Element.draw()` returns a `SurfaceHandler` instead of drawing directly to the workspace.

This enables:
- outlines for arbitrary shapes
- gradients inheriting shape alpha
- subtree compositing
- layered visual effects
- future post-processing support

---

# Elements

## Core Elements

- `Panel`
- `Text`
- `Button`
- `Textbox`
- `Line`
- `Scene`

## Effects

`Effect` is a subclass of `Element` that visually modifies its parent subtree.

Built-in effects:

- `Gradient`
- `ButtonGradient`
- `Outline`
- `BorderRadius`

Effects are ordered using `z`.

Typical layering:

```text
Negative z:
    backgrounds/gradients

Normal z:
    content

Positive z:
    outlines/glows/overlays
```

## Components

`Component`s modify behavior/layout but do not draw.

Built-in components:

- `Padding`
- `Font`
- `Camera`
- `Scrollable`
- `GlobalElement`

Attach/get/remove:

```python
element.set_component(component)

element.get_component(ComponentType)

element.remove_component(ComponentType)
```

or:

```python
component.parent = element
```

---

# Input State

Access input using:

```python
workspace.input
```

Properties:

```python
keys_pressed
key_downs
key_ups

mouse_buttons_pressed
mouse_downs
mouse_ups

mouse_pos
mouse_delta
mouse_wheel

text_input

dt
runtime
quit
```

Helper methods:

```python
key_held()
key_down()
key_up()

mousebutton_held()
mousebutton_down()
mousebutton_up()
```

---

# Hover State

Workspace hover helpers:

```python
is_mouse_top(element)
is_mouse_over(element)

just_hovered(element)
just_unhovered(element)

just_hovered_inclusive(element)
just_unhovered_inclusive(element)
```

Event helpers:

```python
@on_hover(...)
@on_unhover(...)
@while_hovered(...)

@on_hover_inclusive(...)
@on_unhover_inclusive(...)
@while_hovered_inclusive(...)
```

---

# Events

Decorator helpers create `Event` elements.

```python
@plp.on_start(target)
@plp.on_update(target)
@plp.on_quit(target)

@plp.on_scene_change(target)

@plp.create_event(target, condition)
```

Events attached to the main workspace are global by default.

Example:

```python
@plp.on_update(ws)
def tick(w: plp.Workspace):
    if w.input.key_down(plp.Key.ESCAPE):
        w.quit()
```

---

# Coroutines

Event-like functions can yield.

If a handler returns a generator, PlayPy resumes it on future frames.

Example:

```python
def flash(_: plp.Workspace):
    for _ in range(60):
        print("frame")
        yield
```

Supported in:
- event callbacks
- button callbacks
- textbox callbacks
- other event-like handlers

---

# Textbox Features

`Textbox` supports:
- placeholders
- caret blinking
- text confirmation/reverting
- character filtering
- maximum length
- coroutine callbacks

Useful arguments:

```python
is_char_accepted=
on_text_updated=
confirm_on_click_off=
```

Special keys:

```text
Backspace -> remove character
Delete    -> clear text
Return    -> confirm text
Escape    -> revert text
```

---

# Scenes

Scenes support lifecycle hooks:

```python
on_enter()
on_exit()
on_pause()
on_resume()
```

Scene changes are queued internally.

---

# Cameras and Scrolling

`Camera` offsets descendant elements.

`Scrollable` extends camera functionality with built-in scrolling support.

Example:

```python
scrollable = plp.Scrollable()
scrollable.parent = panel
```

---

# Logging

PlayPy replaces standard exceptions/logging with a categorized logging system.

```python
plp.log(severity, category, message)
```

Severities:

```python
plp.Severity.INFO
plp.Severity.WARNING
plp.Severity.ERROR
plp.Severity.CRITICAL
```

`ERROR` and `CRITICAL` are treated as `NoReturn`.
