yokutango-mobile-reader/lib/screens/practise/kanji.dart

152 lines
4.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:signature/signature.dart';
import '../../models/data_entry.dart';
import '../../components/navigation_buttons.dart';
class KanjiPage extends StatefulWidget {
final KanjiEntry entry;
final Function() onNextCard;
final Function() onPreviousCard;
final bool showDrawingPanel;
final bool showStrokeOrder;
final int? index;
const KanjiPage({
required this.entry,
required this.onNextCard,
required this.onPreviousCard,
this.showDrawingPanel = false,
this.showStrokeOrder = false,
this.index,
super.key,
});
@override
_KanjiPageState createState() => _KanjiPageState();
}
class _KanjiPageState extends State<KanjiPage> {
final focusNode = FocusNode();
bool isPressed = false;
late final controller = SignatureController(
penColor: Theme.of(context).textTheme.bodyMedium?.color ?? Colors.black,
);
@override
void initState() {
focusNode.requestFocus();
super.initState();
}
@override
void dispose() {
focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return RawKeyboardListener(
focusNode: focusNode,
onKey: (event) {
if (event.isKeyPressed(LogicalKeyboardKey.enter) || event.isKeyPressed(LogicalKeyboardKey.space)) {
if (widget.showDrawingPanel) return;
if (isPressed) {
controller.clear();
widget.onNextCard();
}
setState(() => isPressed = !isPressed);
}
},
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (widget.showDrawingPanel) return;
if (isPressed) {
controller.clear();
widget.onNextCard();
}
setState(() => isPressed = !isPressed);
},
child: Stack(
alignment: Alignment.center,
fit: StackFit.expand,
children: [
if (widget.showDrawingPanel) ...[
const SizedBox(width: 20),
Signature(
controller: controller,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
)
],
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
widget.entry.kana.join('\n'),
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(width: 20),
const Divider(thickness: 5),
const SizedBox(width: 20),
Text(
widget.entry.kanji,
style: isPressed
? Theme.of(context).textTheme.headlineLarge
: Theme.of(context)
.textTheme
.headlineLarge
?.merge(const TextStyle(color: Colors.transparent)),
),
const SizedBox(width: 20),
const Divider(thickness: 5),
if (widget.showDrawingPanel) ...[
const SizedBox(width: 20),
Row(
children: [
const Expanded(child: SizedBox()),
IconButton(
iconSize: 40,
onPressed: controller.clear,
icon: const Icon(Icons.delete),
)
],
)
]
],
),
Positioned(
bottom: 40,
child: NavigationButtons(
middleText:
widget.index == null ? 'N' : (widget.index! + 1).toString(),
onMiddlePressed: () {
if (isPressed) {
controller.clear();
widget.onNextCard();
}
setState(() => isPressed = !isPressed);
},
onNextCard: () => setState(() {
if (isPressed) {
controller.clear();
widget.onNextCard();
}
setState(() => isPressed = !isPressed);
}),
onPreviousCard: () => setState(() {
controller.clear();
isPressed = false;
widget.onPreviousCard();
}),
),
)
],
),
),
);
}
}