ghini 25.12.25030926
ghini: ^25.12.25030926 copied to clipboard
A compact Flutter utility kit for colored debugging and tools.
example/lib/main.dart
// example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:ghini/ghini.dart'; // 包含 PCLayout0, GhiniTheme, GhiniPageHolder
void main() async {
await pcInit(); // 1. 必须先初始化窗口引擎
runApp(const GalleryApp());
}
class GalleryApp extends StatefulWidget {
const GalleryApp({super.key});
@override
State<GalleryApp> createState() => _GalleryAppState();
}
class _GalleryAppState extends State<GalleryApp> {
final ValueNotifier<ThemeMode> _themeMode = ValueNotifier(ThemeMode.light);
final ValueNotifier<int> _navIndex = ValueNotifier(0);
// 2. 组件注册表:在此处添加新写的 Demo
final _demos = [
(icon: Icons.palette_outlined, label: '色彩系统', widget: const GhiniPageHolder('Palette Visualization')),
(icon: Icons.window, label: '布局占位', widget: const GhiniPageHolder('Layout Test')),
(icon: Icons.text_fields, label: '排版演示', widget: const Center(child: Text('Typography Coming Soon3'))),
];
@override
void dispose() {
_themeMode.dispose();
_navIndex.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<ThemeMode>(
valueListenable: _themeMode,
builder: (context, mode, _) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Ghini Kit',
themeMode: mode,
theme: GhiniTheme.light(),
darkTheme: GhiniTheme.dark(),
home: ValueListenableBuilder<int>(
valueListenable: _navIndex,
builder: (context, currentIndex, child) {
return PCLayout0(
title: 'Ghini Gallery',
// trayIcon: 'assets/app_icon',
sidebarWidth: 220,
// Logo 区域
sidebarLogo: Container(
height: 60,
alignment: Alignment.centerLeft,
padding: const EdgeInsets.only(left: 24),
child: Row(
children: [
Icon(Icons.widgets, color: Theme.of(context).colorScheme.primary),
const SizedBox(width: 12),
const Text('Ghini Kit', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
],
),
),
// 菜单区域:将 Demos 映射为按钮
sidebarMenu: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Column(
children: _demos.asMap().entries.map((e) {
final isSelected = e.key == currentIndex;
final colorScheme = Theme.of(context).colorScheme;
return Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Material(
color: isSelected ? colorScheme.primaryContainer : Colors.transparent,
borderRadius: BorderRadius.circular(8),
child: InkWell(
borderRadius: BorderRadius.circular(8),
splashColor: colorScheme.primary.withValues(alpha: 0.3),
hoverColor: colorScheme.onSurface.withValues(alpha: 0.1),
onTap: () => _navIndex.value = e.key,
child: Container(
height: 40,
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(
children: [
Icon(
e.value.icon,
size: 20,
color: isSelected ? colorScheme.onSecondaryContainer : colorScheme.onSurfaceVariant,
),
const SizedBox(width: 12),
Text(
e.value.label,
style: TextStyle(
color: isSelected
? colorScheme.onSecondaryContainer
: colorScheme.onSurfaceVariant,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
),
),
],
),
),
),
),
);
}).toList(),
),
),
// 底部区域:放置主题切换开关
sidebarBottom: Container(
padding: const EdgeInsets.all(16),
child: Card(
color: Theme.of(context).colorScheme.surfaceContainerHigh,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
const Icon(Icons.brightness_4, size: 20),
const SizedBox(width: 8),
Expanded(child: Text('深色模式', style: Theme.of(context).textTheme.bodySmall)),
// 修正:移除 visualDensity,若需更小可用 Transform.scale 包裹
Transform.scale(
scale: 0.8, // 可选:让开关稍微小一点以适应侧边栏
child: Switch(
value: mode == ThemeMode.dark,
onChanged: (val) => _themeMode.value = val ? ThemeMode.dark : ThemeMode.light,
),
),
],
),
),
),
),
// 核心内容区
body: _demos[currentIndex].widget,
);
},
),
);
},
);
}
}