2025-03-11 21:17:14 +08:00

163 lines
4.2 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:lamiter/Class/Question/question.dart';
import 'package:lamiter/Class/Question/question_layout_attributes.dart';
import 'package:lamiter/Component/tfq_title.dart';
import 'package:lamiter/Extension/build_context.dart';
import 'package:lamiter/Provider/Form/form_provider.dart';
import 'package:lamiter/Provider/Language/language_provider.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class TFQ<T extends FormProvider> extends Question<bool> {
final GlobalKey<TFQLayoutState> TFQKey = GlobalKey<TFQLayoutState>();
final TFQLayoutAttributes attributes;
TFQ({
super.key,
required super.id,
required super.required,
super.answer = false,
required this.attributes,
});
@override
void setAnswerLayout(bool? _answer) {
if (_answer == null) return;
answer = _answer;
TFQKey.currentState?.setAnswer(_answer);
}
@override
void lockAnswerLayouot() {
TFQKey.currentState?.lockAnswer();
}
@override
bool isAnswerRequiredAndLegal() {
return true;
}
@override
Widget build(BuildContext context) {
void layoutSetAnswer(bool? layoutAnswer) {
answer = layoutAnswer;
context.read<T>().refresh();
}
return _Layout(
key: TFQKey,
attributes: attributes,
setAnswer: layoutSetAnswer,
);
}
}
class TFQLayoutAttributes extends QuestionLayoutAttributes {
final IconData? trueIcon;
final IconData? falseIcon;
TFQLayoutAttributes({
super.title,
required super.required,
this.trueIcon,
this.falseIcon,
});
}
class _Layout extends StatefulWidget {
// True or false question
final TFQLayoutAttributes attributes;
final Function(bool?) setAnswer;
const _Layout({
super.key,
required this.attributes,
required this.setAnswer,
});
@override
State<_Layout> createState() => TFQLayoutState();
}
class TFQLayoutState extends State<_Layout> with AutomaticKeepAliveClientMixin {
bool _answer = false;
bool _readOnly = false;
late Icon _trueIconDisplay;
late Icon _falseIconDisplay;
@override
void initState() {
super.initState();
_trueIconDisplay = Icon(widget.attributes.trueIcon);
_falseIconDisplay = Icon(widget.attributes.falseIcon);
}
void setAnswer(bool? b) {
_answer = b ?? false;
widget.setAnswer(b); // form notifier
_trueIconDisplay = Icon(
widget.attributes.trueIcon,
color: context.inverseSurface.withOpacity(_answer ? 1 : 0.35),
);
_falseIconDisplay = Icon(
widget.attributes.falseIcon,
color: context.inverseSurface.withOpacity(_answer ? 0.35 : 1),
);
setState(() {});
}
void lockAnswer() {
_readOnly = true;
setState(() {});
}
@override
Widget build(BuildContext context) {
super.build(context);
final languageProvider = Provider.of<LanguageProvider>(context);
return Form(
child: Container(
padding: EdgeInsets.only(bottom: 6.sp),
decoration: BoxDecoration(border: Border(bottom: context.QBorderSide)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TFQTitle(
title: languageProvider
.getLocaleString(widget.attributes.title ?? ''),
readOnly: _readOnly,
required: widget.attributes.required,
),
Row(
children: [
_falseIconDisplay,
CupertinoSwitch(
// This bool value toggles the switch.
value: _answer,
trackColor: widget.attributes.falseIcon == null
? context.primary
: CupertinoColors.destructiveRed,
activeColor: widget.attributes.falseIcon == null
? CupertinoColors.activeGreen
: CupertinoColors.activeBlue,
onChanged: (bool? value) {
if (_readOnly) return;
setAnswer(value);
},
),
_trueIconDisplay
],
),
],
),
),
);
}
@override
bool get wantKeepAlive => true;
}