# Widget2D API Reference

**Package:** `com.amanotes.widget2d` | **Version:** 2.1.5 | **Namespace:** `Amanotes.Core`

Responsive UI system for automatic component resizing based on size changes.

---

## Core Classes

### `Widget2D`

Core component for responsive UI elements that automatically resizes attached components.

```csharp
public class Widget2D : MonoBehaviour
{
    public Vector2 size { get; set; }        // Widget size (triggers refresh on set)
    public Vector2 pivot { get; set; }       // Pivot point (0,0 to 1,1)
    public float width { get; set; }         // Shorthand for size.x
    public float height { get; set; }        // Shorthand for size.y
    
    public void Refresh();                   // Manually trigger update
}
```

**Supported Components:**
- Widget2D (nested widgets)
- RectTransform (UI elements)
- SpriteRenderer (2D sprites)
- BoxCollider (physics colliders)
- TextMeshPro / TextMeshProUGUI (requires TMPro package)

**Example:**
```csharp
var widget = GetComponent<Widget2D>();
widget.size = new Vector2(100, 50);
widget.pivot = new Vector2(0.5f, 0.5f); // Center pivot
widget.Refresh();
```

---

### `Screen2D`

Extends Widget2D with automatic screen adaptation.

```csharp
public class Screen2D : Widget2D
{
    [SerializeField] [Range(0f, 1f)] 
    private float fitWidthToHeight;          // 0=fit width, 1=fit height
    
    public void Init();                      // Initialize screen adaptation
}
```

**Example:**
```csharp
var screen = GetComponent<Screen2D>();
screen.size = new Vector2(1080, 1920); // Portrait reference
screen.Init(); // Screen now adapts to resolution changes

// fitWidthToHeight = 0: Width fixed, height adjusts
// fitWidthToHeight = 1: Height fixed, width adjusts
```

---

### `SpriteRendererWidget`

Specialized Widget2D for sprites with padding, fill amount, and sliced sprite support.

```csharp
public class SpriteRendererWidget : Widget2D
{
    public SpriteRenderer target { get; }
    
    [SerializeField] private Vector4 paddingPixels;      // Left, bottom, right, top
    [SerializeField] private float adjustScale;          // Scale multiplier (0.1-20)
    [SerializeField] private float fillAmount;           // Fill amount (0-1)
    [SerializeField] private Direction fillDirection;    // Right, Left, Up, Down
    
    public void SetProgress(float value);                // Set fill amount and enable/disable
}
```

**Example:**
```csharp
// Progress bar
var healthBar = GetComponent<SpriteRendererWidget>();
healthBar.size = new Vector2(200, 20);
healthBar.fillDirection = Direction.Right;
healthBar.SetProgress(0.75f); // 75% filled
```

---

### `WidgetTransform`

Advanced responsive layout that follows a source widget with alignment, scaling, and size control.

```csharp
public class WidgetTransform : MonoBehaviour, ISizeListener
{
    public Widget2D source;                  // Source widget to follow
    
    // Alignment (0-1, typically)
    public float alignX;                     // 0=left, 0.5=center, 1=right
    public float alignY;                     // 0=bottom, 0.5=center, 1=top
    
    // Scale (0-2)
    public float scaleX;
    public float scaleY;
    
    // Size percentage (0-2)
    public float sizePercentX;               // Width as % of source
    public float sizePercentY;               // Height as % of source
    
    // Size delta
    public float sizeX;                      // Width offset
    public float sizeY;                      // Height offset
    
    // Handlers
    public SizeHandler size;
    public ScaleHandler scale;
    public AlignHandler align;
    
    public void SetSource(Widget2D w);
    public void Refresh();
}
```

**Example:**
```csharp
// Center child at 80% of parent size
var transform = GetComponent<WidgetTransform>();
transform.SetSource(parentWidget);
transform.alignX = 0.5f;
transform.alignY = 0.5f;
transform.sizePercentX = 0.8f;
transform.sizePercentY = 0.8f;
```

---

## Interfaces

### `ISizeListener`

Interface for components that respond to widget size changes.

```csharp
public interface ISizeListener
{
    void OnResize(Vector2 size);             // Called when widget size changes
}
```

**Implementation:**
```csharp
public class CustomListener : MonoBehaviour, ISizeListener
{
    public void OnResize(Vector2 size)
    {
        Debug.Log($"Widget resized to: {size}");
        UpdateLayout(size);
    }
}
```

---

## Utility Classes

### `WidgetHandler`

Static utility for component resizing with extensible handler system.

```csharp
public static class WidgetHandler
{
    public static bool IsSupported(Type typeT);
    public static bool IsSupported(Component c);
    public static WidgetHandler GetHandler(Type type);
    public static void RegisterHandler<T>(Func<T, Vector2> getter, Action<T, Vector2> setter);
    public static Vector2 GetComponentSize(Component component);
    public static void SetComponentSize(Component component, Vector2 size);
    public static void SetComponentSize(Component component, Vector2 size, bool useZ, Vector2 pivot);
    public static void SetSize(List<Component> components, Vector2 size);
    public static void SetSize(List<Component> components, Size2D size2D);
}
```

**Custom Handler:**
```csharp
// Register custom component handler
WidgetHandler.RegisterHandler<MyCustomRenderer>(
    renderer => renderer.bounds.size,
    (renderer, size) => renderer.SetBounds(size)
);
```

---

### `Size2D`

Internal data structure for Widget2D.

```csharp
public class Size2D
{
    public Vector2 _size;                    // Internal size storage
    public Vector2 pivot;                    // Pivot point (0,0 to 1,1)
    public bool useZ;                        // false=XY plane, true=XZ plane
    public GizmoMode gizmoMode;              // None, Selected, Always
    public Color gizmoColor;                 // Gizmo color in editor
}
```

---

## Transform Handlers

### `SizeHandler`

Controls size behavior with axis filtering and percentage-based sizing.

```csharp
public class SizeHandler
{
    public AxisFilter axis;                  // None, X, Y, XY
    public bool keepRatio;                   // Maintain aspect ratio
    public float percentX;                   // Width percentage (0-2)
    public float percentY;                   // Height percentage (0-2)
    public Vector2 sizeDelta;                // Size offset
}
```

---

### `ScaleHandler`

Controls scale behavior with fit/fill modes.

```csharp
public class ScaleHandler
{
    public AxisFilter axis;                  // None, X, Y, XY
    public bool keepRatio;                   // Maintain aspect ratio
    public float scaleX;                     // Horizontal scale (0-2)
    public float scaleY;                     // Vertical scale (0-2)
    public float fitParameter;               // 0=fit, 1=fill
}
```

---

### `AlignHandler`

Controls alignment behavior with offsets.

```csharp
public class AlignHandler
{
    public AxisFilter axis;                  // None, X, Y, XY
    public float alignX;                     // Horizontal alignment (-1 to 2)
    public float alignY;                     // Vertical alignment (-1 to 2)
    public Vector2 offset;                   // Position offset
    public Vector2 selfAlign;                // Self-alignment offset
}
```

---

## Extension Methods

### BoxCollider Extensions

```csharp
public static void SetSize(this BoxCollider c, Vector2 size, Vector2 pivot = default);
public static void SetSize(this BoxCollider c, Vector2 size, bool useZ, Vector2 pivot = default);
```

### SpriteRenderer Extensions

```csharp
public static SpriteRenderer SetSize(this SpriteRenderer sr, Vector2 size, bool allowScale = true);
public static SpriteRenderer SetSizeInPixel(this SpriteRenderer sr, int w, int h, bool allowScale = true);
public static SpriteRenderer UniformScale(this SpriteRenderer sr, Vector2 size, float fillRatio = 0);
```

### Transform Extensions

```csharp
public static Transform UniformScale(this Transform t, Vector2 orgSize, Vector2 size, float fillRatio = 0);
```

**Example:**
```csharp
// Fit mode - shows entire sprite
spriteRenderer.UniformScale(new Vector2(100, 50), 0.0f);

// Fill mode - fills entire area
spriteRenderer.UniformScale(new Vector2(100, 50), 1.0f);
```

---

## Enums

### `AxisFilter`

```csharp
[Flags]
public enum AxisFilter
{
    None = 0,      // No axes
    X = 1,         // X axis only
    Y = 2,         // Y axis only
    XY = X | Y     // Both axes
}
```

### `Direction`

```csharp
public enum Direction
{
    Right,    // Fill left to right
    Left,     // Fill right to left
    Up,       // Fill bottom to top
    Down      // Fill top to bottom
}
```

### `GizmoMode`

```csharp
public enum GizmoMode
{
    None,       // Never draw gizmos
    Selected,   // Draw when selected
    Always      // Always draw gizmos
}
```

---

## Common Patterns

### Pattern 1: Full-Screen Widget

```csharp
// When to use: Root widget for screen adaptation
var screen = gameObject.AddComponent<Screen2D>();
screen.size = new Vector2(1080, 1920);
screen.Init();
```

### Pattern 2: Centered Child

```csharp
// When to use: Center widget within parent
var transform = GetComponent<WidgetTransform>();
transform.SetSource(parentWidget);
transform.alignX = 0.5f;
transform.alignY = 0.5f;
transform.sizePercentX = 0.8f;
transform.sizePercentY = 0.8f;
```

### Pattern 3: Progress Bar

```csharp
// When to use: Visual progress indicator
var progressBar = GetComponent<SpriteRendererWidget>();
progressBar.size = new Vector2(300, 40);
progressBar.fillDirection = Direction.Right;
progressBar.SetProgress(currentProgress); // 0-1
```

### Pattern 4: Responsive Scaling

```csharp
// When to use: Scale to fit screen with padding
var transform = GetComponent<WidgetTransform>();
transform.SetSource(screenWidget);
transform.scale.keepRatio = true;
transform.scale.fitParameter = 0.0f; // Fit mode
transform.scaleX = 0.9f; // 90% for padding
transform.scaleY = 0.9f;
```

### Pattern 5: Custom Size Listener

```csharp
// When to use: Custom layout logic on resize
public class AdaptiveContent : MonoBehaviour, ISizeListener
{
    public void OnResize(Vector2 size)
    {
        float itemWidth = size.x / itemsPerRow;
        UpdateItemSizes(itemWidth);
    }
}
```

### Pattern 6: Multi-Component Widget

```csharp
// When to use: Auto-resize multiple components
var widget = gameObject.AddComponent<Widget2D>();
widget.size = new Vector2(100, 50);

// Add components - widget auto-detects and resizes
gameObject.AddComponent<SpriteRenderer>();
gameObject.AddComponent<BoxCollider>();

widget.Refresh();
```

---

## See Also

- [Widget2D README](../README.md)
- [Widget2D Responsive Patterns](Widget2D-Responsive-Patterns.md)
