mirror of
https://github.com/wgh136/pixes.git
synced 2025-09-27 04:57:23 +00:00
195 lines
4.6 KiB
Dart
195 lines
4.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'pair.dart';
|
|
|
|
class SimpleController extends StateController{
|
|
final void Function()? refresh_;
|
|
|
|
SimpleController({this.refresh_});
|
|
|
|
@override
|
|
void refresh() {
|
|
(refresh_ ?? super.refresh)();
|
|
}
|
|
}
|
|
|
|
abstract class StateController{
|
|
static final _controllers = <StateControllerWrapped>[];
|
|
|
|
static T put<T extends StateController>(T controller, {Object? tag, bool autoRemove = false}){
|
|
_controllers.add(StateControllerWrapped(controller, autoRemove, tag));
|
|
return controller;
|
|
}
|
|
|
|
static T putIfNotExists<T extends StateController>(T controller, {Object? tag, bool autoRemove = false}){
|
|
return findOrNull<T>(tag: tag) ?? put(controller, tag: tag, autoRemove: autoRemove);
|
|
}
|
|
|
|
static T find<T extends StateController>({Object? tag}){
|
|
try {
|
|
return _controllers.lastWhere((element) =>
|
|
element.controller is T
|
|
&& (tag == null || tag == element.tag)).controller as T;
|
|
}
|
|
catch(e){
|
|
throw StateError("${T.runtimeType} with tag $tag Not Found");
|
|
}
|
|
}
|
|
|
|
static T? findOrNull<T extends StateController>({Object? tag}){
|
|
try {
|
|
return _controllers.lastWhere((element) =>
|
|
element.controller is T
|
|
&& (tag == null || tag == element.tag)).controller as T;
|
|
}
|
|
catch(e){
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static void remove<T>([Object? tag, bool check = false]){
|
|
for(int i=_controllers.length-1; i>=0; i--){
|
|
var element = _controllers[i];
|
|
if(element.controller is T && (tag == null || tag == element.tag)){
|
|
if(check && !element.autoRemove){
|
|
continue;
|
|
}
|
|
_controllers.removeAt(i);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static SimpleController putSimpleController(void Function() onUpdate, Object? tag, {void Function()? refresh}){
|
|
var controller = SimpleController(refresh_: refresh);
|
|
controller.stateUpdaters.add(Pair(null, onUpdate));
|
|
_controllers.add(StateControllerWrapped(controller, false, tag));
|
|
return controller;
|
|
}
|
|
|
|
List<Pair<Object?, void Function()>> stateUpdaters = [];
|
|
|
|
void update([List<Object>? ids]){
|
|
if(ids == null){
|
|
for(var element in stateUpdaters){
|
|
element.right();
|
|
}
|
|
}else{
|
|
for(var element in stateUpdaters){
|
|
if(ids.contains(element.left)) {
|
|
element.right();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void dispose(){
|
|
_controllers.removeWhere((element) => element.controller == this);
|
|
}
|
|
|
|
void refresh(){
|
|
update();
|
|
}
|
|
}
|
|
|
|
class StateControllerWrapped{
|
|
StateController controller;
|
|
bool autoRemove;
|
|
Object? tag;
|
|
|
|
StateControllerWrapped(this.controller, this.autoRemove, this.tag);
|
|
}
|
|
|
|
|
|
class StateBuilder<T extends StateController> extends StatefulWidget {
|
|
const StateBuilder({super.key, this.init, this.dispose, this.initState, this.tag,
|
|
required this.builder, this.id});
|
|
|
|
final T? init;
|
|
|
|
final void Function(T controller)? dispose;
|
|
|
|
final void Function(T controller)? initState;
|
|
|
|
final Object? tag;
|
|
|
|
final Widget Function(T controller) builder;
|
|
|
|
Widget builderWrapped(StateController controller){
|
|
return builder(controller as T);
|
|
}
|
|
|
|
void initStateWrapped(StateController controller){
|
|
return initState?.call(controller as T);
|
|
}
|
|
|
|
void disposeWrapped(StateController controller){
|
|
return dispose?.call(controller as T);
|
|
}
|
|
|
|
final Object? id;
|
|
|
|
@override
|
|
State<StateBuilder> createState() => _StateBuilderState<T>();
|
|
}
|
|
|
|
class _StateBuilderState<T extends StateController> extends State<StateBuilder> {
|
|
late T controller;
|
|
|
|
@override
|
|
void initState() {
|
|
if(widget.init != null) {
|
|
StateController.put(widget.init!, tag: widget.tag, autoRemove: true);
|
|
}
|
|
try {
|
|
controller = StateController.find<T>(tag: widget.tag);
|
|
}
|
|
catch(e){
|
|
throw "Controller Not Found";
|
|
}
|
|
controller.stateUpdaters.add(Pair(widget.id, () {
|
|
if(mounted){
|
|
setState(() {});
|
|
}
|
|
}));
|
|
widget.initStateWrapped(controller);
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
widget.disposeWrapped(controller);
|
|
StateController.remove<T>(widget.tag, true);
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) => widget.builderWrapped(controller);
|
|
}
|
|
|
|
abstract class StateWithController<T extends StatefulWidget> extends State<T>{
|
|
late final SimpleController _controller;
|
|
|
|
void refresh(){
|
|
_controller.update();
|
|
}
|
|
|
|
@override
|
|
@mustCallSuper
|
|
void initState() {
|
|
_controller = StateController.putSimpleController(() => setState(() {}), tag, refresh: refresh);
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
@mustCallSuper
|
|
void dispose() {
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void update(){
|
|
_controller.update();
|
|
}
|
|
|
|
Object? get tag;
|
|
} |