multiple updates
- colour theme implemented. ThemeService based global switching for future light detection triggers - test flipflop service for various fun - navigator widget class with state switching
This commit is contained in:
59
pi/ui/lib/widgets/navigator_widget.dart
Normal file
59
pi/ui/lib/widgets/navigator_widget.dart
Normal file
@@ -0,0 +1,59 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/config_service.dart';
|
||||
|
||||
/// Displays the navigator character with emotion support.
|
||||
///
|
||||
/// Use a GlobalKey to control emotions from parent:
|
||||
/// ```dart
|
||||
/// final _navigatorKey = GlobalKey<NavigatorWidgetState>();
|
||||
/// NavigatorWidget(key: _navigatorKey)
|
||||
/// // Later:
|
||||
/// _navigatorKey.currentState?.setEmotion('happy');
|
||||
/// ```
|
||||
class NavigatorWidget extends StatefulWidget {
|
||||
const NavigatorWidget({super.key});
|
||||
|
||||
@override
|
||||
State<NavigatorWidget> createState() => NavigatorWidgetState();
|
||||
}
|
||||
|
||||
class NavigatorWidgetState extends State<NavigatorWidget> {
|
||||
String _emotion = 'default';
|
||||
|
||||
/// Change the displayed emotion.
|
||||
/// Image file must exist at: {assetsPath}/navigator/{navigator}/{emotion}.png
|
||||
void setEmotion(String emotion) {
|
||||
if (emotion != _emotion) {
|
||||
setState(() => _emotion = emotion);
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset to default emotion
|
||||
void reset() => setEmotion('default');
|
||||
|
||||
/// Current emotion
|
||||
String get emotion => _emotion;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final config = ConfigService.instance;
|
||||
final basePath = '${config.assetsPath}/navigator/${config.navigator}';
|
||||
|
||||
return Image.file(
|
||||
File('$basePath/$_emotion.png'),
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
// Fallback: try default.png if specific emotion missing
|
||||
if (_emotion != 'default') {
|
||||
return Image.file(
|
||||
File('$basePath/default.png'),
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (_, __, ___) => const SizedBox.shrink(),
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../theme/app_theme.dart';
|
||||
|
||||
/// A labeled stat display box for the dashboard
|
||||
class StatBox extends StatelessWidget {
|
||||
final String label;
|
||||
@@ -9,18 +11,22 @@ class StatBox extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = AppTheme.of(context);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 100,
|
||||
color: theme.foreground,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
label,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Colors.grey,
|
||||
fontSize: 80,
|
||||
color: theme.subdued,
|
||||
letterSpacing: 1,
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user