Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
## 0.0.2

### New Widgets
* **PixelBottomBar** - Navigation bar with pixel-art stepped corners
- Stepped corner styling with customizable pixel size
- Badge support for notification indicators
- Blur effect for translucent backgrounds
- Two indicator styles: `underline` (default) and `highlight`
- Customizable active indicator color (defaults to red)

* **PixelSteppedPanel** - Panel with toggleable stepped corners
- `useSteppedCorners` toggle between pixel-art and smooth rounded corners
- Customizable shadow, border, and background colors
- Pixel-perfect stepped corner rendering via CustomPainter

* **PixelPillPanel** - Pill-shaped panel with multi-step staircase corners
- Configurable `cornerSteps` for rounder or sharper corners
- Same toggle support as PixelSteppedPanel

* **PixelInsetPanel** - Inset panel with 3D bevel effect
- "Pressed in" appearance with inner shadows
- Auto-calculated highlight/shadow colors
- Classic retro game UI style

* **PixelHamburgerIcon** - Animated hamburger menu icon
- Smooth animation between open/closed states
- Pixel-perfect line rendering

### Enhancements
* **PixelButton** - Added `pill` style option for rounded pill-shaped buttons
* **PixelBottomBar** - Default indicator style changed to `underline` with red color

### Documentation
* Added comprehensive dartdoc comments for pub.dev documentation
* Updated README with new widget examples
* Added code examples for all new components

## 0.0.1

* TODO: Describe initial release.
* Initial release
* Core pixel widgets: PixelButton, PixelText, PixelPanel, PixelSlider, PixelToggle, PixelProgressBar
* Visual effects: Pixelate, Bloom, Scanline, Glitch, Noise
* Animations: Fade, Flicker, Jitter, Wave
* PixelTheme for global styling
* Audio integration support
237 changes: 237 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# CLAUDE.md - Pixelify Flutter

## Project Overview
Pixelify Flutter is a retro pixel-art UI component library for Flutter. It provides pixel-style widgets, animations, effects, and utilities for creating nostalgic gaming-inspired interfaces.

## Build & Test Commands
```bash
# Run all tests
flutter test

# Run specific test file
flutter test test/pixelify_flutter_test.dart

# Run tests with coverage
flutter test --coverage

# Build example app for macOS
cd example && flutter build macos

# Run example app
cd example && flutter run -d macos

# Analyze code
flutter analyze

# Format code
dart format lib test
```

## Project Structure
```
pixelify_flutter/
├── lib/
│ ├── pixelify_flutter.dart # Main export file
│ └── src/
│ ├── widgets/ # UI Components
│ │ ├── pixel_button.dart
│ │ ├── pixel_text.dart
│ │ ├── pixel_progress_bar.dart
│ │ ├── pixel_notification_card.dart
│ │ └── pixel_container.dart
│ ├── animations/ # Animation widgets
│ │ ├── fade_animation.dart
│ │ ├── flicker_animation.dart
│ │ ├── jitter_animation.dart
│ │ └── wave_animation.dart
│ ├── effects/ # Visual effects
│ │ ├── pixelate_effect.dart
│ │ ├── scanline_effect.dart
│ │ ├── bloom_effect.dart
│ │ ├── glitch_effect.dart
│ │ └── noise_effect.dart
│ └── utils/ # Utilities
│ ├── pixel_palette.dart
│ ├── dithering.dart
│ ├── shader_loader.dart
│ └── pixel_theme.dart
├── shaders/ # GLSL fragment shaders
│ ├── bloom.frag
│ ├── pixelate.frag
│ └── scanline.frag
├── test/ # Test files
│ ├── pixelify_flutter_test.dart
│ ├── animations_test.dart
│ ├── effects_test.dart
│ └── utils_test.dart
└── example/ # Example app
└── lib/main.dart
```

## Testing Guidelines

### Widget Testing Best Practices

1. **Use specific finders** - Avoid `find.byType(Transform)` which may find multiple widgets from MaterialApp/Scaffold. Use descendant finders:
```dart
expect(
find.descendant(
of: find.byType(MyWidget),
matching: find.byType(Transform),
),
findsOneWidget,
);
```

2. **Handle infinite animations** - Widgets with continuous animations will cause `pumpAndSettle()` to timeout. Use `pump()` with specific duration instead:
```dart
// BAD - will timeout on infinite animations
await tester.pumpAndSettle();

// GOOD - pump specific duration
await tester.pump(const Duration(milliseconds: 100));
```

3. **Disable animations in tests** - For widgets with optional animations, disable them for reliable testing:
```dart
PixelButton(
label: 'TEST',
enableGlowAnimation: false,
enableScanlineAnimation: false,
onPressed: () {},
)
```

4. **Avoid pending timers** - If using `Future.delayed`, ensure tests pump past the delay duration to avoid "Timer is still pending" errors:
```dart
// Widget has 200ms delay
await tester.pump(const Duration(milliseconds: 300)); // Pump past delay
```

5. **Tap the widget, not the text** - For buttons with overlays, tap the widget type rather than text:
```dart
// May fail if text is obscured
await tester.tap(find.text('BUTTON'));

// More reliable
await tester.tap(find.byType(PixelButton));
```

### Animation Widget Patterns

When creating stateful animation widgets:

1. **Track disposal state** to prevent callbacks after dispose:
```dart
class _MyAnimationState extends State<MyAnimation> {
bool _isDisposed = false;

@override
void initState() {
super.initState();
Future.delayed(widget.delay, () {
if (!_isDisposed && mounted) {
_controller.forward();
}
});
}

@override
void dispose() {
_isDisposed = true;
_controller.dispose();
super.dispose();
}
}
```

2. **Initialize lists before use** - Don't use `late` for lists that might be accessed before initialization:
```dart
// BAD - can cause LateInitializationError
late List<Offset> _points;

// GOOD - initialize empty
List<Offset> _points = [];
```

3. **Check mounted in post-frame callbacks**:
```dart
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
// Safe to call setState
setState(() { /* ... */ });
});
```

### Layout Debugging

For RenderFlex overflow errors:

1. **Account for borders** - Container borders reduce available inner space:
```dart
// If container has border width 1, inner width is totalWidth - 2
final double innerWidth = segments * (segmentWidth + margin);
final double totalWidth = innerWidth + 2; // +2 for border
```

2. **Use Clip.hardEdge** for Stack children that might overflow:
```dart
Stack(
clipBehavior: Clip.hardEdge,
children: [...],
)
```

## Key APIs

### PixelButton
```dart
PixelButton(
label: 'CLICK',
onPressed: () {},
color: Colors.blue,
outlineColor: Colors.black,
pixelEdgeThickness: 3.0,
enableGlowAnimation: true,
enableScanlineAnimation: true,
)
```

### PixelProgressBar
```dart
PixelProgressBar(
progress: 0.5,
style: PixelProgressBarStyle.segmented, // segmented, smooth, iconFilled
segments: 15,
fillColor: Colors.cyanAccent,
showScanlines: true,
showGlow: true,
)
```

### GlitchEffect
```dart
GlitchEffect(
intensity: 0.3,
frequency: const Duration(milliseconds: 200),
child: Text('GLITCH'),
)
```

### NoiseEffect
```dart
NoiseEffect(
intensity: 0.2,
density: 2000,
animate: true,
color: Colors.white,
)
```

## Shader Notes

Fragment shaders are in `/shaders/` directory. Key considerations:

1. **Array size must match initialization**: `float weights[5] = float[](...)`
2. **Use proper GLSL ES precision**: `precision highp float;`
3. **Shader loading is async** - handle loading states in widgets
79 changes: 77 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ A comprehensive Flutter package for creating retro pixel-art style UI components
## ✨ Features

### 🎨 Pixel Widgets
- **PixelButton** - Interactive buttons with hover effects, sound support, and scanline animations
- **PixelButton** - Interactive buttons with hover effects, sound support, pill style, and scanline animations
- **PixelText** - Text with multiple retro effects (flicker, glitch, scanline, pixelate)
- **PixelPanel** - Containers with various retro styles (CRT, paper grain, glowing borders)
- **PixelSteppedPanel** - Panels with pixel-art stepped corners (toggleable)
- **PixelPillPanel** - Pill-shaped panels with multi-step staircase corners
- **PixelInsetPanel** - Inset panels with 3D bevel effect
- **PixelBottomBar** - Navigation bar with stepped corners, badges, blur, and indicator styles
- **PixelSlider** - Segmented sliders with pixel-perfect styling
- **PixelToggle** - Toggle switches with blinking and flip animations
- **PixelProgressBar** - Progress indicators with segmented, smooth, and icon-filled styles
- **PixelTextField** - Input fields with retro styling
- **PixelShimmer** - Loading shimmer effects with pixelated overlays
- **PixelHamburgerIcon** - Animated hamburger menu icon with pixel styling

### 🎭 Visual Effects
- **Pixelate Effect** - Shader-based pixelation with customizable pixel size
Expand All @@ -42,7 +47,7 @@ Add this to your package's `pubspec.yaml` file:

```yaml
dependencies:
pixelify_flutter: ^0.0.1
pixelify_flutter: ^0.0.2
audioplayers: ^6.5.0 # For sound effects
```

Expand Down Expand Up @@ -241,6 +246,76 @@ PixelPanel(
)
```

### 📦 PixelSteppedPanel

Panels with pixel-art stepped corners that can toggle between stepped and smooth rounded corners.

```dart
// Basic stepped panel
PixelSteppedPanel(
useSteppedCorners: true,
backgroundColor: Color(0xFF2A2D3A),
borderColor: Color(0xFF4A4E65),
child: Text('PRESIDENTIAL BRIEFING'),
)

// Pill-shaped panel with staircase corners
PixelPillPanel(
useSteppedCorners: true,
cornerSteps: 4,
backgroundColor: Color(0xFF3D4155),
borderColor: Color(0xFF6A6E85),
child: Text('SELECT YOUR RESPONSE'),
)

// Inset panel with 3D bevel effect
PixelInsetPanel(
useSteppedCorners: true,
backgroundColor: Color(0xFF1A1C24),
borderColor: Color(0xFF3D4155),
child: Text('STATISTICS'),
)
```

### 🧭 PixelBottomBar

Navigation bar with pixel-art stepped corners, badge support, blur effect, and customizable indicator styles.

```dart
PixelBottomBar(
icons: [
Icons.home,
Icons.search,
Icons.notifications,
Icons.person,
],
labels: ['Home', 'Search', 'Alerts', 'Profile'],
currentIndex: selectedIndex,
onTap: (index) => setState(() => selectedIndex = index),
backgroundColor: Color(0xFF1A1C2C),
activeColor: Colors.cyanAccent,
inactiveColor: Colors.grey,
indicatorStyle: PixelBottomBarIndicatorStyle.underline,
activeIndicatorColor: Colors.redAccent,
badges: {2: '5'}, // Show badge on Alerts tab
useBlur: true,
)
```

### ☰ PixelHamburgerIcon

Animated hamburger menu icon with pixel styling.

```dart
PixelHamburgerIcon(
isOpen: isMenuOpen,
onTap: () => setState(() => isMenuOpen = !isMenuOpen),
color: Colors.cyanAccent,
size: 32,
pixelSize: 3,
)
```

## 🎨 Effects & Animations

### Wrapper Widgets
Expand Down
Loading