5d772389d6
Reine Verschiebung per Dart part/part-of (keine Umbenennung, keine Logikänderung) - settings_modal.dart schrumpft von 5541 auf 270 Zeilen. Verifiziert per automatisiertem Blockvergleich gegen das Original und flutter analyze (Baseline unverändert: 1 bekannter Hinweis). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
188 lines
6.5 KiB
Dart
188 lines
6.5 KiB
Dart
part of '../settings_modal.dart';
|
|
|
|
class _AppearanceSection extends StatelessWidget {
|
|
final PyramidTheme pt;
|
|
final bool isDark;
|
|
final int accentIdx;
|
|
final double radius;
|
|
final double density;
|
|
final double motion;
|
|
final WidgetRef ref;
|
|
|
|
const _AppearanceSection({
|
|
required this.pt,
|
|
required this.isDark,
|
|
required this.accentIdx,
|
|
required this.radius,
|
|
required this.density,
|
|
required this.motion,
|
|
required this.ref,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
_SectionTitle(
|
|
title: 'Erscheinungsbild',
|
|
subtitle: 'Gestalte Pyramid nach deinem Geschmack.',
|
|
pt: pt),
|
|
_SettingsGroup(title: 'Theme', pt: pt, children: [
|
|
_SettingsRow(
|
|
title: 'Farbmodus',
|
|
desc: 'Hell oder dunkel',
|
|
pt: pt,
|
|
control: _SegControl(
|
|
options: const ['Dunkel', 'Hell'],
|
|
selected: isDark ? 0 : 1,
|
|
pt: pt,
|
|
onSelect: (i) {
|
|
final dark = i == 0;
|
|
ref.read(themeModeProvider.notifier).state = dark;
|
|
saveThemePrefs(isDark: dark);
|
|
},
|
|
),
|
|
),
|
|
_Divider(pt: pt),
|
|
_SettingsRow(
|
|
title: 'Akzentfarbe',
|
|
desc: 'Farbe für Hervorhebungen und Buttons',
|
|
pt: pt,
|
|
control: Row(
|
|
children: accentPresets.asMap().entries.map((e) {
|
|
final i = e.key;
|
|
final preset = e.value;
|
|
final isActive = accentIdx == i;
|
|
return GestureDetector(
|
|
onTap: () {
|
|
ref.read(accentProvider.notifier).state = i;
|
|
saveThemePrefs(accentIdx: i);
|
|
},
|
|
child: AnimatedContainer(
|
|
duration: const Duration(milliseconds: 150),
|
|
width: 22,
|
|
height: 22,
|
|
margin: const EdgeInsets.only(right: 6),
|
|
decoration: BoxDecoration(
|
|
color: preset.color,
|
|
shape: BoxShape.circle,
|
|
border: isActive ? Border.all(color: Colors.white, width: 2) : null,
|
|
boxShadow: isActive
|
|
? [BoxShadow(color: preset.color.withAlpha(100), blurRadius: 8)]
|
|
: null,
|
|
),
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
),
|
|
]),
|
|
const SizedBox(height: 20),
|
|
_SettingsGroup(title: 'Form & Bewegung', pt: pt, children: [
|
|
_SettingsRow(
|
|
title: 'Eckenrundung',
|
|
desc: '${radius.round()} px',
|
|
pt: pt,
|
|
control: SizedBox(
|
|
width: 150,
|
|
child: SliderTheme(
|
|
data: SliderThemeData(
|
|
activeTrackColor: pt.accent,
|
|
thumbColor: pt.accent,
|
|
inactiveTrackColor: pt.border,
|
|
trackHeight: 3,
|
|
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 6),
|
|
),
|
|
child: Slider(
|
|
value: radius,
|
|
min: 4,
|
|
max: 20,
|
|
onChanged: (v) {
|
|
ref.read(radiusProvider.notifier).state = v;
|
|
saveThemePrefs(radius: v);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
_Divider(pt: pt),
|
|
_SettingsRow(
|
|
title: 'Animationen',
|
|
desc: '${(motion * 100).round()}%',
|
|
pt: pt,
|
|
control: SizedBox(
|
|
width: 150,
|
|
child: SliderTheme(
|
|
data: SliderThemeData(
|
|
activeTrackColor: pt.accent,
|
|
thumbColor: pt.accent,
|
|
inactiveTrackColor: pt.border,
|
|
trackHeight: 3,
|
|
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 6),
|
|
),
|
|
child: Slider(
|
|
value: motion,
|
|
min: 0,
|
|
max: 1,
|
|
onChanged: (v) {
|
|
ref.read(motionProvider.notifier).state = v;
|
|
saveThemePrefs(motion: v);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
]),
|
|
const SizedBox(height: 20),
|
|
_SettingsGroup(title: 'Vorschau', pt: pt, children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
height: 100,
|
|
decoration: BoxDecoration(
|
|
color: pt.bg3,
|
|
borderRadius: BorderRadius.circular(pt.rBase),
|
|
border: Border.all(color: pt.border),
|
|
),
|
|
child: const Center(child: PyramidLoader(size: 70, useLottie: true)),
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text('Lottie', style: TextStyle(color: pt.fgMuted, fontSize: 11)),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
height: 100,
|
|
decoration: BoxDecoration(
|
|
color: pt.bg3,
|
|
borderRadius: BorderRadius.circular(pt.rBase),
|
|
border: Border.all(color: pt.border),
|
|
),
|
|
child: const Center(child: PyramidLoader(size: 70, useLottie: false)),
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text('SVG', style: TextStyle(color: pt.fgMuted, fontSize: 11)),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
]),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|