diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd2d0ae..4a7285e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,16 @@
+## 5.6.0
+November 15, 2024
+- Introduce setBuilder() in every Controller. Will rebuild with every setState() call.
+- Replacing stateSet(WidgetBuilder? builder) with the name, setBuilder in class, StateX and AppStateX
+- class StateXController now includes mixin, ChangeNotifier and ListenableWidgetBuilderMixin
+
## 5.5.0
-Octobter 14, 2024
+October 14, 2024
- AppStateX class now has the notifyClientsInBuild parameter. Defaults to true.
- Notify any dependencies when calling for a rebuild
+ This then notifies any dependencies when calling for a rebuild.
- The runInitAsync() function in every StateX object
- now allows their initAsync() functions to be conditionally called wit every rebuild.
+ now allows their initAsync() functions to be conditionally called with every rebuild.
## 5.4.0
October 07, 2024
@@ -21,8 +27,8 @@ October 05, 2024
## 5.2.3
October 04, 2024
-- Removed 'default' Error Handler mistakenly left in Production.
-- Removed 'default' Error Widget Builder mistakenly left in Production.
+- *BUGFIX* Removed 'default' Error Handler mistakenly left in Production.
+- *BUGFIX* Removed 'default' Error Widget Builder mistakenly left in Production.
- User Error Handler, onError(), in part08_app_statex.dart.
- If onError() is not overridden, Flutter's own Error Handler is called.
- New getter, stateErrorHandled, can be set true by user.
diff --git a/doc/03_controllers.md b/doc/03_controllers.md
index ffe1d67..956dd74 100644
--- a/doc/03_controllers.md
+++ b/doc/03_controllers.md
@@ -29,7 +29,7 @@ If not, you're actually impeding Flutter’s general functionality and degrading
The less that changes, the better.
Use the keyword, final, for variables assigned only once.
Better still, use the keyword, const, if you know the property's value
-before compile-time will never change.
+ will never change before compile-time.
As your app runs, Flutter is calling those widgets over and over again.
“There is no imperative changing of the UI itself (like widget.setText)—you change the state,
@@ -38,19 +38,18 @@ and the UI rebuilds from scratch.”
— flutter.dev Start thinking declaratively
Now, I suspect in the beginning, all your ‘mutable’ code was going into your State class.
-A reasonable idea at first glance.
After all, you always want ready access to the State object and its setState() function.
-However, that can make for a rather large and unmanageable Dart file
-placing all the business logic and such under one State class.
-I quickly found, more often than not, placing such code in a separate Dart file in a separate class made for a better approach.
+However, that can make for a very large and unmanageable Dart file
+placing all the business logic one State class.
+I quickly found placing such code in a separate Dart file in a separate class made for a better approach.
You're explicitly separating the app's interface from its business rules.
-Looking how Flutter implemented such an approach already using Controllers in widgets,
-I created the 'State Object Controller' class.
+Flutter already implemented such an approach using Controllers in many widgets,
+I've done the same by creating the 'State Object Controller' class.
-Again, however, when working with Flutter, you always need reliable access to a particular State object so to call its setState() function
-(other developer's choose instead the StatefulElement’s markNeedsBuild() function).
-Doing so ‘rebuilds’ that portion of the screen involving that State object and reflects the changes made.
-That means the State Object controller would need access to its designated State object.
+When working with Flutter, you always need reliable access to a particular State object so to call its setState() function
+(other developer's instead call the StatefulElement’s markNeedsBuild() function).
+This ‘rebuilds’ that portion of the screen involving that State object.
+The State Object controller needs ready access to its designated State object.
@@ -59,8 +58,8 @@ That means the State Object controller would need access to its designated State
Through the course of an app’s lifecycle,
a controller can be assigned to any number of StateX objects.
A StateXController object works with ‘the last’ State object it’s been assigned to
-but keeps a reference of any and all State objects it’s previously worked with in the Widget tree.
-When a screen closes (i.e. the current StateX object is disposed of), the controller returns back to the previous StateX it was assigned to.
+but keeps a reference all the State objects it’s previously worked with.
+When a screen closes (i.e. the current StateX object is disposed of), the controller returns back to its previous StateX.
This allows, for example, for one controller to sustain the app’s business rules for the duration of the running app
conveying that logic across any number of screens (i.e. any number of StateX objects).
@@ -75,7 +74,7 @@ while its controllers are concerned with everything else.
Show By Example
-Here is a gist file for you to download and follow along: statex_counter_app.dart
+Here is a gist file for you to download and follow along: statex_counter_app.dart
As you see in the first screenshot below, the traditional State class has been replaced with the class, StateX,
and takes in a StateXController object named, YourController.
@@ -87,11 +86,11 @@ However, note there’s no setState() function call.
It’s in the controller and called in the con.onPressed() function.
-| [statex_counter_app.dart](https://gist.github.com/Andrious/e7d3ce3b8dcd5495978690a24ae5c3d6#file-statex_counter_app-dart-L24) | [statex_counter_app.dart](https://gist.github.com/Andrious/e7d3ce3b8dcd5495978690a24ae5c3d6#file-statex_counter_app-dart-L39) |
+| [statex_counter_app.dart](https://gist.github.com/Andrious/c68d9f4edcc5e2344a3f50e49b269f2e#file-statex_counter_app-dart-L24) | [statex_counter_app.dart](https://gist.github.com/Andrious/e7d3ce3b8dcd5495978690a24ae5c3d6#file-statex_counter_app-dart-L39) |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------:|
Set Control
diff --git a/example/lib/src/another_app/controller.dart b/example/lib/src/another_app/controller_another_app.dart
similarity index 51%
rename from example/lib/src/another_app/controller.dart
rename to example/lib/src/another_app/controller_another_app.dart
index 730b1a9..9bebf22 100644
--- a/example/lib/src/another_app/controller.dart
+++ b/example/lib/src/another_app/controller_another_app.dart
@@ -1,13 +1,12 @@
-// Copyright 2022 Andrious Solutions Ltd. All rights reserved.
+// Copyright 2024 Andrious Solutions Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
///
/// Export libraries concerned with the App's 'Event Handling' (the Business Logic)
///
-export 'package:example/src/another_app/home/controller.dart';
-export 'package:example/src/another_app/home/gridview/controller.dart';
+export 'package:state_extended/state_extended.dart' show StateXController;
-export 'package:example/src/another_app/utils/controller.dart';
+export '/src/another_app/home/controller_home.dart';
-export 'package:state_extended/state_extended.dart' show StateXController;
+export '/src/another_app/utils/controller_utils.dart';
diff --git a/example/lib/src/another_app/home/controller/home_controller.dart b/example/lib/src/another_app/home/controller/home_controller.dart
index 32675ab..7b90dd2 100644
--- a/example/lib/src/another_app/home/controller/home_controller.dart
+++ b/example/lib/src/another_app/home/controller/home_controller.dart
@@ -5,9 +5,9 @@
/// The Controller for this app's Home Page StatefulWidget.
///
-import '/src/another_app/controller.dart';
+import '/src/another_app/controller_another_app.dart';
-import '/src/another_app/view.dart';
+import '/src/another_app/view_another_app.dart';
///
class HomeController extends StateXController {
diff --git a/example/lib/src/another_app/home/controller.dart b/example/lib/src/another_app/home/controller_home.dart
similarity index 57%
rename from example/lib/src/another_app/home/controller.dart
rename to example/lib/src/another_app/home/controller_home.dart
index 69e00d7..27482c6 100644
--- a/example/lib/src/another_app/home/controller.dart
+++ b/example/lib/src/another_app/home/controller_home.dart
@@ -5,6 +5,8 @@
/// Export libraries concerned with the Home Page's 'Event Handling' (the Business Logic)
///
-export 'package:example/src/another_app/home/controller/home_controller.dart';
+export '/src/another_app/home/controller/home_controller.dart';
-export 'package:example/src/another_app/home/inherited/controller.dart';
+export '/src/another_app/home/gridview/controller_gridview.dart';
+
+export '/src/another_app/home/inherited/controller_inherited.dart';
diff --git a/example/lib/src/another_app/home/gridview/controller/image_api_controller.dart b/example/lib/src/another_app/home/gridview/controller/image_api_controller.dart
index 7e6887a..51b71b4 100644
--- a/example/lib/src/another_app/home/gridview/controller/image_api_controller.dart
+++ b/example/lib/src/another_app/home/gridview/controller/image_api_controller.dart
@@ -6,15 +6,14 @@
///
import 'dart:async';
-import 'dart:convert' show json;
-import 'package:example/src/another_app/home/gridview/view.dart';
+import 'dart:convert' show json;
-import 'package:example/src/controller.dart';
+import 'package:http/http.dart' as http;
-import 'package:example/src/view.dart';
+import '/src/another_app/controller_another_app.dart';
-import 'package:http/http.dart' as http;
+import '/src/another_app/view_another_app.dart';
/// This is the 'image API' State Object Controller.
class ImageAPIController extends StateXController {
diff --git a/example/lib/src/another_app/home/gridview/controller.dart b/example/lib/src/another_app/home/gridview/controller_gridview.dart
similarity index 75%
rename from example/lib/src/another_app/home/gridview/controller.dart
rename to example/lib/src/another_app/home/gridview/controller_gridview.dart
index 3d53158..fcf053b 100644
--- a/example/lib/src/another_app/home/gridview/controller.dart
+++ b/example/lib/src/another_app/home/gridview/controller_gridview.dart
@@ -5,8 +5,6 @@
/// All the SOC's used in this app's GridView widget
/// SOC stands for State Object Controllers.
///
-export '/src/another_app/home/controller.dart';
-
export '/src/another_app/home/gridview/controller/image_api_controller.dart';
-export '/src/another_app/home/gridview/images/controller.dart';
+export '/src/another_app/home/gridview/images/controller_images.dart';
diff --git a/example/lib/src/another_app/home/gridview/images/controller/bird_controller.dart b/example/lib/src/another_app/home/gridview/images/controller/bird_controller.dart
index 59b2993..23c923d 100644
--- a/example/lib/src/another_app/home/gridview/images/controller/bird_controller.dart
+++ b/example/lib/src/another_app/home/gridview/images/controller/bird_controller.dart
@@ -5,7 +5,7 @@
///
///
-import 'package:example/src/controller.dart';
+import '/src/another_app/controller_another_app.dart';
/// This SOC is associated with the Bird images and works with
/// InheritBird StatefulWidget and the InheritedWidget, _BirdInherited
diff --git a/example/lib/src/another_app/home/gridview/images/controller/cat_controller.dart b/example/lib/src/another_app/home/gridview/images/controller/cat_controller.dart
index 3606501..2d1bab5 100644
--- a/example/lib/src/another_app/home/gridview/images/controller/cat_controller.dart
+++ b/example/lib/src/another_app/home/gridview/images/controller/cat_controller.dart
@@ -2,7 +2,7 @@
///
///
-import 'package:example/src/controller.dart';
+import '/src/another_app/controller_another_app.dart';
///
class CatController extends InheritController {
diff --git a/example/lib/src/another_app/home/gridview/images/controller/dog_controller.dart b/example/lib/src/another_app/home/gridview/images/controller/dog_controller.dart
index a709107..f2dcf8d 100644
--- a/example/lib/src/another_app/home/gridview/images/controller/dog_controller.dart
+++ b/example/lib/src/another_app/home/gridview/images/controller/dog_controller.dart
@@ -2,7 +2,7 @@
///
///
-import 'package:example/src/controller.dart';
+import '/src/another_app/controller_another_app.dart';
///
class DogController extends InheritController {
diff --git a/example/lib/src/another_app/home/gridview/images/controller/fox_controller.dart b/example/lib/src/another_app/home/gridview/images/controller/fox_controller.dart
index e811786..3cac81e 100644
--- a/example/lib/src/another_app/home/gridview/images/controller/fox_controller.dart
+++ b/example/lib/src/another_app/home/gridview/images/controller/fox_controller.dart
@@ -2,7 +2,7 @@
///
///
-import 'package:example/src/controller.dart';
+import '/src/another_app/controller_another_app.dart';
///
class FoxController extends InheritController {
diff --git a/example/lib/src/another_app/home/gridview/images/controller.dart b/example/lib/src/another_app/home/gridview/images/controller_images.dart
similarity index 100%
rename from example/lib/src/another_app/home/gridview/images/controller.dart
rename to example/lib/src/another_app/home/gridview/images/controller_images.dart
diff --git a/example/lib/src/another_app/home/gridview/images/view/random_bird.dart b/example/lib/src/another_app/home/gridview/images/view/random_bird.dart
index 6971048..6db7c64 100644
--- a/example/lib/src/another_app/home/gridview/images/view/random_bird.dart
+++ b/example/lib/src/another_app/home/gridview/images/view/random_bird.dart
@@ -5,9 +5,9 @@
/// This widget works with the free Bird API.
///
-import 'package:example/src/another_app/controller.dart';
+import '/src/another_app/controller_another_app.dart';
-import 'package:example/src/another_app/view.dart';
+import '/src/another_app/view_another_app.dart';
///
class RandomBird extends StatefulWidget {
@@ -28,4 +28,17 @@ class _RandomBirdState extends ImageAPIStateX {
path: 'api/v2/random/animal/bird',
),
);
+
+ /// Place a breakpoint on this build() function and see how things work.
+ @override
+ // ignore: unnecessary_overrides
+ Widget build(BuildContext context) => super.build(context);
+
+ @override
+ // ignore: unnecessary_overrides
+ Widget buildF(BuildContext context) => super.buildF(context);
+
+ @override
+ // ignore: unnecessary_overrides
+ Widget builder(context) => super.builder(context);
}
diff --git a/example/lib/src/another_app/home/gridview/images/view/random_cat.dart b/example/lib/src/another_app/home/gridview/images/view/random_cat.dart
index 298fb02..f948d2e 100644
--- a/example/lib/src/another_app/home/gridview/images/view/random_cat.dart
+++ b/example/lib/src/another_app/home/gridview/images/view/random_cat.dart
@@ -4,9 +4,10 @@
///
/// This widget works with the free Cat API.
///
-import 'package:example/src/another_app/controller.dart';
-import 'package:example/src/another_app/view.dart';
+import '/src/another_app/controller_another_app.dart';
+
+import '/src/another_app/view_another_app.dart';
///
class RandomCat extends StatefulWidget {
@@ -27,4 +28,8 @@ class _RandomCatState extends ImageAPIStateX {
path: 'api/v2/random/animal/cat',
),
);
+
+ /// Supply a 'splash screen' while the FutureBuilder is processing.
+ @override
+ Widget? onSplashScreen(BuildContext context) => const SplashScreen();
}
diff --git a/example/lib/src/another_app/home/gridview/images/view/random_dog.dart b/example/lib/src/another_app/home/gridview/images/view/random_dog.dart
index f274204..e15a50e 100644
--- a/example/lib/src/another_app/home/gridview/images/view/random_dog.dart
+++ b/example/lib/src/another_app/home/gridview/images/view/random_dog.dart
@@ -5,9 +5,9 @@
/// This widget works with the free Dog API.
///
-import 'package:example/src/another_app/controller.dart';
+import '/src/another_app/controller_another_app.dart';
-import 'package:example/src/another_app/view.dart';
+import '/src/another_app/view_another_app.dart';
///
class RandomDog extends StatefulWidget {
diff --git a/example/lib/src/another_app/home/gridview/images/view/random_fox.dart b/example/lib/src/another_app/home/gridview/images/view/random_fox.dart
index c8ad075..a62f764 100644
--- a/example/lib/src/another_app/home/gridview/images/view/random_fox.dart
+++ b/example/lib/src/another_app/home/gridview/images/view/random_fox.dart
@@ -5,9 +5,9 @@
/// This widget works with the free Fox API.
///
-import 'package:example/src/another_app/controller.dart';
+import '/src/another_app/controller_another_app.dart';
-import 'package:example/src/another_app/view.dart';
+import '/src/another_app/view_another_app.dart';
///
class RandomFox extends StatefulWidget {
diff --git a/example/lib/src/another_app/home/gridview/images/view.dart b/example/lib/src/another_app/home/gridview/images/view_images.dart
similarity index 100%
rename from example/lib/src/another_app/home/gridview/images/view.dart
rename to example/lib/src/another_app/home/gridview/images/view_images.dart
diff --git a/example/lib/src/another_app/home/gridview/view.dart b/example/lib/src/another_app/home/gridview/view_gridview.dart
similarity index 53%
rename from example/lib/src/another_app/home/gridview/view.dart
rename to example/lib/src/another_app/home/gridview/view_gridview.dart
index cbe395c..3ab0193 100644
--- a/example/lib/src/another_app/home/gridview/view.dart
+++ b/example/lib/src/another_app/home/gridview/view_gridview.dart
@@ -1,6 +1,6 @@
///
///
///
-export '/src/another_app/home/gridview/images/view.dart';
+export '/src/another_app/home/gridview/images/view_images.dart';
export '/src/another_app/home/gridview/view/image_api.dart';
diff --git a/example/lib/src/another_app/home/inherited/controller.dart b/example/lib/src/another_app/home/inherited/controller_inherited.dart
similarity index 100%
rename from example/lib/src/another_app/home/inherited/controller.dart
rename to example/lib/src/another_app/home/inherited/controller_inherited.dart
diff --git a/example/lib/src/another_app/home/inherited/view/inherit_bird.dart b/example/lib/src/another_app/home/inherited/view/inherit_bird.dart
index ae223d0..ba7bd06 100644
--- a/example/lib/src/another_app/home/inherited/view/inherit_bird.dart
+++ b/example/lib/src/another_app/home/inherited/view/inherit_bird.dart
@@ -5,9 +5,9 @@
/// Contains the InheritedWidget for updating the Bird Image widgets.
///
-import '/src/another_app/controller.dart';
+import '/src/controller.dart';
-import '/src/another_app/view.dart';
+import '/src/view.dart';
///
class InheritBird extends StatefulWidget {
diff --git a/example/lib/src/another_app/home/inherited/view/inherit_cat.dart b/example/lib/src/another_app/home/inherited/view/inherit_cat.dart
index 8d9e0da..28cd658 100644
--- a/example/lib/src/another_app/home/inherited/view/inherit_cat.dart
+++ b/example/lib/src/another_app/home/inherited/view/inherit_cat.dart
@@ -5,9 +5,9 @@
/// Stores the InheritedWidget used to update the Cat images.
///
-import '/src/another_app/controller.dart';
+import '/src/controller.dart';
-import '/src/another_app/view.dart';
+import '/src/view.dart';
/// This StatefulWidget stores an InheritedWidget
class InheritCat extends StatefulWidget {
diff --git a/example/lib/src/another_app/home/inherited/view/inherit_dog.dart b/example/lib/src/another_app/home/inherited/view/inherit_dog.dart
index 66757c7..50ae550 100644
--- a/example/lib/src/another_app/home/inherited/view/inherit_dog.dart
+++ b/example/lib/src/another_app/home/inherited/view/inherit_dog.dart
@@ -5,9 +5,9 @@
/// This StatefulWidget works with the 'Dog' InheritedWidget
///
-import '/src/another_app/controller.dart';
+import '/src/controller.dart';
-import '/src/another_app/view.dart';
+import '/src/view.dart';
/// This StatefulWidget stores an InheritedWidget
class InheritDog extends StatefulWidget {
diff --git a/example/lib/src/another_app/home/inherited/view/inherit_fox.dart b/example/lib/src/another_app/home/inherited/view/inherit_fox.dart
index 088685b..e3f9b51 100644
--- a/example/lib/src/another_app/home/inherited/view/inherit_fox.dart
+++ b/example/lib/src/another_app/home/inherited/view/inherit_fox.dart
@@ -5,9 +5,9 @@
/// This StatefulWidget works with the Fox InheritedWidget.
///
-import '/src/another_app/controller.dart';
+import '/src/another_app/controller_another_app.dart';
-import '/src/another_app/view.dart';
+import '/src/another_app/view_another_app.dart';
/// This StatefulWidget stores an InheritedWidget
class InheritFox extends StatefulWidget {
diff --git a/example/lib/src/another_app/home/inherited/view.dart b/example/lib/src/another_app/home/inherited/view_inherited.dart
similarity index 100%
rename from example/lib/src/another_app/home/inherited/view.dart
rename to example/lib/src/another_app/home/inherited/view_inherited.dart
diff --git a/example/lib/src/another_app/home/view/home_page.dart b/example/lib/src/another_app/home/view/home_page.dart
index 6a62dae..2b2e0b0 100644
--- a/example/lib/src/another_app/home/view/home_page.dart
+++ b/example/lib/src/another_app/home/view/home_page.dart
@@ -4,11 +4,10 @@
///
/// The StatefulWidget representing the app's Home Page.
///
-import '/src/another_app/home/view.dart';
-import '/src/controller.dart';
+import '/src/another_app/controller_another_app.dart';
-import '/src/view.dart';
+import '/src/another_app/view_another_app.dart';
/// The Home page
class HomePage extends StatefulWidget {
diff --git a/example/lib/src/another_app/home/view.dart b/example/lib/src/another_app/home/view_home.dart
similarity index 66%
rename from example/lib/src/another_app/home/view.dart
rename to example/lib/src/another_app/home/view_home.dart
index 0db031d..81348de 100644
--- a/example/lib/src/another_app/home/view.dart
+++ b/example/lib/src/another_app/home/view_home.dart
@@ -5,8 +5,8 @@
/// Export libraries concerned with the Home Page's Interface
///
-export 'package:example/src/another_app/home/gridview/view.dart';
+export 'package:example/src/another_app/home/gridview/view_gridview.dart';
-export 'package:example/src/another_app/home/inherited/view.dart';
+export 'package:example/src/another_app/home/inherited/view_inherited.dart';
export 'package:example/src/another_app/home/view/home_page.dart';
diff --git a/example/lib/src/another_app/utils/controller.dart b/example/lib/src/another_app/utils/controller_utils.dart
similarity index 100%
rename from example/lib/src/another_app/utils/controller.dart
rename to example/lib/src/another_app/utils/controller_utils.dart
diff --git a/example/lib/src/another_app/view.dart b/example/lib/src/another_app/view.dart
deleted file mode 100644
index 5a49222..0000000
--- a/example/lib/src/another_app/view.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2022 Andrious Solutions Ltd. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-///
-/// Export libraries concerned with the App's 'View' (the Interface)
-///
-export 'package:example/src/another_app/home/gridview/view.dart';
-
-export 'package:example/src/another_app/home/view.dart';
-
-export 'package:flutter/material.dart' hide StateSetter;
-
-export 'package:state_extended/state_extended.dart' show StateIn, StateX;
diff --git a/example/lib/src/another_app/view_another_app.dart b/example/lib/src/another_app/view_another_app.dart
new file mode 100644
index 0000000..0cc01d8
--- /dev/null
+++ b/example/lib/src/another_app/view_another_app.dart
@@ -0,0 +1,14 @@
+// Copyright 2024 Andrious Solutions Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// ///
+// /// Export libraries concerned with the App's 'View' (the Interface)
+
+export 'package:flutter/material.dart';
+
+export 'package:state_extended/state_extended.dart'show StateX;
+
+export '/src/another_app/home/view_home.dart';
+
+export '/src/view.dart' show SplashScreen;
+
diff --git a/example/lib/src/controller.dart b/example/lib/src/controller.dart
index a265ac8..e128036 100644
--- a/example/lib/src/controller.dart
+++ b/example/lib/src/controller.dart
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-export '/src/another_app/controller.dart';
+export 'package:state_extended/state_extended.dart' show StateXController;
+
+export '/src/another_app/controller_another_app.dart';
export '/src/controller/app/app_controller.dart';
export '/src/controller/app/common/events_controller.dart';
-export '/src/controller/home/_controller.dart';
+export '/src/controller/home/_controller_home.dart';
diff --git a/example/lib/src/controller/home/_controller.dart b/example/lib/src/controller/home/_controller_home.dart
similarity index 100%
rename from example/lib/src/controller/home/_controller.dart
rename to example/lib/src/controller/home/_controller_home.dart
diff --git a/example/lib/src/view.dart b/example/lib/src/view.dart
index 9c26b33..6b8942d 100644
--- a/example/lib/src/view.dart
+++ b/example/lib/src/view.dart
@@ -6,11 +6,12 @@
export 'package:flutter/cupertino.dart' show CupertinoSwitch;
-/// StateSetter is also defined in state_extended.dart
-export 'package:flutter/material.dart' hide StateSetter;
+export 'package:flutter/material.dart';
export 'package:state_extended/state_extended.dart';
+export '/src/another_app/view_another_app.dart';
+
export '/src/view/app/common/class_name_mixin.dart';
export '/src/view/app/common/events_state.dart';
diff --git a/example/lib/src/view/home/page_01.dart b/example/lib/src/view/home/page_01.dart
index 090af0d..555d54b 100644
--- a/example/lib/src/view/home/page_01.dart
+++ b/example/lib/src/view/home/page_01.dart
@@ -24,11 +24,12 @@ class Page1State extends StateX with EventsStateMixin {
controller: Controller(),
useInherited: Controller().useInherited,
) {
+ _con = controller as Controller;
// Add some additional controllers if you like
addList([AnotherController(), YetAnotherController(), WordPairsTimer()]);
_timer = controllerByType()!;
}
-
+ late Controller _con;
late WordPairsTimer _timer;
/// The counter
@@ -93,11 +94,9 @@ class Page1State extends StateX with EventsStateMixin {
// Note, returns null if not found.
anotherController = rootState.controllerByType();
- /// Note, this controller is present for the life of the app.
/// InheritedWidget switch will reset count, but the controller can saves the count
- final con = controller as Controller;
- count = con.page1Count;
- con.page1Count = 0;
+ count = _con.page1Count;
+ _con.page1Count = 0;
}
///
@@ -119,7 +118,7 @@ class Page1State extends StateX with EventsStateMixin {
),
),
Flexible(
- child: stateSet(
+ child: setBuilder(
// Will build this one lone widget
(context) => Text(
'$count',
@@ -157,22 +156,19 @@ class Page1State extends StateX with EventsStateMixin {
mainAxisSize: MainAxisSize.min,
children: [
const Text('Use built-in InheritedWidget'),
- Builder(builder: (context) {
- final con = controller as Controller;
- return CupertinoSwitch(
- key: const Key('InheritedSwitch'),
- value: con.useInherited,
- onChanged: (v) {
- // Save the setting
- con.useInherited = v;
- // Save the count
- con.page1Count = count;
- // Both access the 'first' StateX object
- firstState?.setState(() {});
- rootState?.setState(() {});
- },
- );
- }),
+ CupertinoSwitch(
+ key: const Key('InheritedSwitch'),
+ value: _con.useInherited,
+ onChanged: (v) {
+ // Save the setting
+ _con.useInherited = v;
+ // Save the count
+ _con.page1Count = count;
+ // Both access the 'first' StateX object
+ firstState?.setState(() {});
+ rootState?.setState(() {});
+ },
+ ),
],
),
],
diff --git a/example/lib/src/view/home/page_02.dart b/example/lib/src/view/home/page_02.dart
index c10e85b..f337445 100644
--- a/example/lib/src/view/home/page_02.dart
+++ b/example/lib/src/view/home/page_02.dart
@@ -1,26 +1,22 @@
-// Copyright 2022 Andrious Solutions Ltd. All rights reserved.
+// Copyright 2024 Andrious Solutions Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'package:example/src/view/home/run_state_mixins.dart';
-
import '/src/controller.dart';
import '/src/view.dart';
-/// The second page displayed in this app.
+///
class Page2 extends StatefulWidget {
///
const Page2({super.key});
@override
- State createState() => Page2State();
+ State createState() => Page2State();
}
-/// This works with a separate 'data source'
-/// It a separate data source, and so the count is never reset to zero.
-class Page2State extends StateX {
- //with EventsStateMixin {
+///
+class Page2State extends StateX with EventsStateMixin {
/// Define an InheritedWidget to be inserted above this Widget on the Widget tree.
/// showBinding: Print in console when Binding events are triggered.
Page2State() : super(controller: Controller(), printEvents: true) {
@@ -99,61 +95,114 @@ class Page2State extends StateX {
assert(rootState is AppStateX, "Should be the 'root' state object.");
}
- /// Ignore BuildPage(). It's just a generic StatelessWidget to quickly produce a screen.
@override
- Widget builder(BuildContext context) => BuildPage(
- label: '2',
- count: con.data,
- counter: con.onPressed,
- row: (context) => [
- /// Page button for Page 1
- Flexible(
- child: ElevatedButton(
- key: const Key('Page 1'),
- style: flatButtonStyle,
- onPressed: () {
- Navigator.pop(context);
- },
- child: const Text(
- 'Page 1',
- ),
+ Widget build(BuildContext context) => Scaffold(
+ appBar: AppBar(
+ title: const Text('Three-page example'),
+ ),
+ persistentFooterButtons: [
+ ElevatedButton(
+ key: const Key('Page 1 Counter'),
+ style: flatButtonStyle,
+ onPressed: () {
+ final con = controller!;
+ // Retrieve specific State object (thus it can't be private)
+ Page1State state = con.ofState()!;
+ // Retrieve State object by its StatefulWidget (will have to cast)
+ state = con.stateOf() as Page1State;
+ state.count++;
+ state.setState(() {});
+ },
+ child: const Text('Page 1 Counter'),
+ ),
+ ],
+ floatingActionButton: FloatingActionButton(
+ key: const Key('+'),
+ onPressed: con.onPressed,
+ child: const Icon(Icons.add),
+ ),
+ body: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Padding(
+ padding: EdgeInsets.only(top: 100),
+ child: Text("You're on page:"),
+ ),
+ const Flexible(
+ child: Text(
+ '2',
+ style: TextStyle(fontSize: 48),
+ ),
+ ),
+ const Flexible(
+ child: Padding(
+ padding: EdgeInsets.only(top: 50),
+ child: Text(
+ 'You have pushed the button this many times:',
),
),
+ ),
+ Flexible(
+ child: Text(
+ '${con.data}',
+ style: Theme.of(context).textTheme.headlineMedium,
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(bottom: 100),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ /// Page button for Page 1
+ Flexible(
+ child: ElevatedButton(
+ key: const Key('Page 1'),
+ style: flatButtonStyle,
+ onPressed: () {
+ Navigator.pop(context);
+ },
+ child: const Text(
+ 'Page 1',
+ ),
+ ),
+ ),
- /// Page button for Page 3
- Flexible(
- child: ElevatedButton(
- key: const Key('Page 3'),
- style: flatButtonStyle,
- onPressed: () async {
- //
- await Navigator.push(
- context,
- MaterialPageRoute(
- builder: (BuildContext context) => const Page3()));
-
- /// A good habit to get into. Refresh the screen again.
- /// In this case, to show the count may have changed.
- setState(() {});
- },
- child: const Text(
- 'Page 3',
+ /// Page button for Page 3
+ Flexible(
+ child: ElevatedButton(
+ key: const Key('Page 3'),
+ style: flatButtonStyle,
+ onPressed: () async {
+ //
+ await Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) =>
+ const Page3()));
+
+ /// A good habit to get into. Refresh the screen again.
+ /// In this case, to show the count may have changed.
+ setState(() {});
+ },
+ child: const Text(
+ 'Page 3',
+ ),
+ ),
),
- ),
+ ],
),
- ],
- column: (context) => [
- const Flexible(child: Text("Has a 'data source' to save the count")),
- ],
- persistentFooterButtons: [
- ElevatedButton(
- key: const Key('Page 1 Counter'),
- style: flatButtonStyle,
- onPressed: onPressed,
- child: const Text('Page 1 Counter'),
- ),
- ],
- );
+ ),
+ const Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Flexible(child: Text("Has a 'data source' to save the count")),
+ ],
+ ),
+ ],
+ ),
+ );
/// Supply a public method to be accessed in Page 3.
/// Calling another State object's function for demonstration purposes
@@ -166,4 +215,4 @@ class Page2State extends StateX {
state.count++;
state.setState(() {});
}
-}
+}
\ No newline at end of file
diff --git a/example/lib/src/view/home/page_03.dart b/example/lib/src/view/home/page_03.dart
index c8cac35..18be434 100644
--- a/example/lib/src/view/home/page_03.dart
+++ b/example/lib/src/view/home/page_03.dart
@@ -1,26 +1,31 @@
-// Copyright 2022 Andrious Solutions Ltd. All rights reserved.
+// Copyright 2024 Andrious Solutions Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import '/src/another_app/view.dart' as i;
-
import '/src/controller.dart';
import '/src/view.dart';
-/// The third page displayed in this app.
+///
class Page3 extends StatefulWidget {
- /// You can instantiate the State Controller in the StatefulWidget;
+ ///
const Page3({super.key});
@override
- State createState() => _Page3State();
+ State createState() => Page3State();
}
-class _Page3State extends StateX with EventsStateMixin {
- // Use built-in InheritedWidget
- _Page3State() : super(useInherited: true);
- //
+///
+class Page3State extends StateX with EventsStateMixin {
+ /// Use built-in InheritedWidget
+ Page3State() : super(controller: Controller(), useInherited: true) {
+ /// Cast to type, Controller
+ con = controller as Controller;
+ }
+
+ /// The controller reference property
+ late Controller con;
+ ///
int count = 0;
// Place a breakpoint here from your favorite IDE and see how it works.
@@ -36,105 +41,135 @@ class _Page3State extends StateX with EventsStateMixin {
/// You could use the builder() function here instead
/// It'll behave has the build() function
@override
- Widget builder(BuildContext context) {
- // Comment out this line, and the counter is suddenly not working
- // state() is a widget that depends on the State InheritedWidget
- // it will rebuild but only if the InheritedWidget is called again by notifyClients()
- return stateSet(_builder);
- // That's because _build() is never called again by the InheritedWidget.
- return _builder(context);
- }
-
- Widget _builder(BuildContext context) => _buildPage3(
- count: count,
- newKey: () {
- // Both do the same thing!
- firstState?.setState(() {});
- rootState?.setState(() {});
- },
- counter: () {
- count++;
- notifyClients();
- },
- page1counter: () {
- // Merely instantiating the StatefulWidget to call its function.
- var state = Controller().ofState()!;
- state = Controller().stateOf()! as Page2State;
- state.onPressed();
- },
- page2counter: () {
- Controller().onPressed();
- },
- );
-
- /// Ignore this function. Study the features above instead.
- Widget _buildPage3({
- int count = 0,
- required void Function() counter,
- required void Function() newKey,
- required void Function() page1counter,
- required void Function() page2counter,
- }) =>
- BuildPage(
- label: '3',
- count: count,
- counter: counter,
- column: (_) => [
- Flexible(
- child: ElevatedButton(
- key: const Key('New Key'),
- onPressed: newKey,
- child: const Text('New Key for Page 1'),
+ Widget builder(BuildContext context) => Scaffold(
+ appBar: AppBar(
+ title: const Text('Three-page example'),
+ ),
+ body: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Padding(
+ padding: EdgeInsets.only(top: 100),
+ child: Text("You're on page:"),
+ ),
+ const Flexible(
+ child: Text(
+ '3',
+ style: TextStyle(fontSize: 48),
+ ),
+ ),
+ const Flexible(
+ child: Padding(
+ padding: EdgeInsets.only(top: 50),
+ child: Text(
+ 'You have pushed the button this many times:',
+ ),
+ ),
),
- ),
- Row(children: [
- const SizedBox(width: 5),
Flexible(
- child: ElevatedButton(
- key: const Key('InheritedWidget example'),
- onPressed: () async {
- await Navigator.push(
- lastState!.context,
- MaterialPageRoute(
- builder: (BuildContext context) => const i.HomePage()),
- );
- },
- child: const Text("'InheritedWidget' example"),
+ child: con.setBuilder(
+ (context) => Text(
+ '$count',
+ style: Theme.of(context).textTheme.headlineMedium,
+ ),
),
),
- ]),
- ],
- row: (BuildContext context) => [
- Flexible(
- child: ElevatedButton(
- key: const Key('Page 1'),
- onPressed: () {
- Navigator.of(context)
- ..pop()
- ..pop();
- },
- child: const Text('Page 1'),
+ Padding(
+ padding: const EdgeInsets.only(bottom: 100),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ Flexible(
+ child: ElevatedButton(
+ key: const Key('Page 1'),
+ onPressed: () {
+ Navigator.of(context)
+ ..pop()
+ ..pop();
+ },
+ child: const Text('Page 1'),
+ ),
+ ),
+ Flexible(
+ child: ElevatedButton(
+ key: const Key('Page 2'),
+ onPressed: () {
+ Navigator.pop(context);
+ },
+ child: const Text('Page 2'),
+ ),
+ ),
+ ],
+ ),
),
- ),
- Flexible(
- child: ElevatedButton(
- key: const Key('Page 2'),
- onPressed: () {
- Navigator.pop(context);
- },
- child: const Text('Page 2'),
+ Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Flexible(
+ child: ElevatedButton(
+ key: const Key('New Key'),
+ onPressed: () {
+ // Both do the same thing!
+ firstState?.setState(() {});
+ rootState?.setState(() {});
+ },
+ child: const Text('New Key for Page 1'),
+ ),
+ ),
+ Row(children: [
+ const SizedBox(width: 5),
+ Flexible(
+ child: ElevatedButton(
+ key: const Key('InheritedWidget example'),
+ onPressed: () async {
+ await Navigator.push(
+ lastState!.context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => const HomePage(),
+ ),
+ );
+ },
+ child: const Text("'InheritedWidget' example"),
+ ),
+ ),
+ ]),
+ ],
),
- ),
- ],
- persistentFooterButtons: [
+ ],
+ ),
+ floatingActionButton: FloatingActionButton(
+ key: const Key('+'),
+ onPressed: () {
+ count++;
+ con.setState((){});
+ },
+ child: const Icon(Icons.add),
+ ),
+ persistentFooterButtons: [
ElevatedButton(
key: const Key('Page 1 Counter'),
- onPressed: page1counter,
+ onPressed: () {
+ // Return State object by its type or by its StatefulWidget Type
+ // Both returns null if not found.
+ var page2State = con.ofState();
+ final stateX = con.stateOf();
+
+ if(stateX != null && stateX is Page2State){
+ // ignore: unnecessary_cast
+ page2State = stateX as Page2State;
+ }
+ // Merely instantiating the StatefulWidget to call its function.
+ page2State?.onPressed();
+ },
child: const Text('Page 1 Counter'),
),
ElevatedButton(
key: const Key('Page 2 Counter'),
- onPressed: page2counter,
+ onPressed: () {
+ con.onPressed();
+ },
child: const Text('Page 2 Counter'),
),
],
diff --git a/lib/part06_inherited_widget_state_mixin.dart b/lib/part06_inherited_widget_state_mixin.dart
index 7eefaee..e853ad9 100644
--- a/lib/part06_inherited_widget_state_mixin.dart
+++ b/lib/part06_inherited_widget_state_mixin.dart
@@ -87,11 +87,15 @@ mixin InheritedWidgetStateMixin on State {
/// Called when the State's InheritedWidget is called again
/// This 'widget function' will be called again.
- Widget stateSet(WidgetBuilder? widgetFunc) {
- widgetFunc ??= (_) => const SizedBox.shrink();
+ Widget setBuilder(WidgetBuilder? builder) => stateSet(builder);
+ /// Called when the State's InheritedWidget is called again
+ /// This 'widget function' will be called again.
+ //@Deprecated('Use statBuilder() instead.')
+ Widget stateSet(WidgetBuilder? builder) {
+ builder ??= (_) => const SizedBox.shrink();
return useInherited && this is StateX
- ? _SetStateXWidget(stateX: this as StateX, widgetFunc: widgetFunc)
- : widgetFunc(context);
+ ? _SetStateXWidget(stateX: this as StateX, builder: builder)
+ : builder(context);
}
/// Copy particular properties from the 'previous' StateX
diff --git a/lib/part08_app_statex.dart b/lib/part08_app_statex.dart
index 9977951..adf0f61 100644
--- a/lib/part08_app_statex.dart
+++ b/lib/part08_app_statex.dart
@@ -226,17 +226,12 @@ abstract class AppStateX extends StateX
var appResponse = await super.didRequestAppExit();
//
if (appResponse == AppExitResponse.exit) {
- //
final list = statesList(reversed: true, remove: this);
// Loop through all the StateX objects
for (final StateX state in list) {
- //
try {
- //
if (state.mounted && !state._deactivated) {
- //
final response = await state.didRequestAppExit();
-
if (response == AppExitResponse.cancel) {
// Cancel and do not exit the application.
appResponse == response;
@@ -336,10 +331,15 @@ abstract class AppStateX extends StateX
/// Called when the State's InheritedWidget is called again
/// This 'widget function' will be called again.
@override
+ Widget setBuilder(WidgetBuilder? widgetFunc) => stateSet(widgetFunc);
+ /// Called when the State's InheritedWidget is called again
+ /// This 'widget function' will be called again.
+ @override
+// @Deprecated('Use stateBuilder() instead.')
Widget stateSet(WidgetBuilder? widgetFunc) {
widgetFunc ??=
(_) => const SizedBox.shrink(); // Display 'nothing' if not provided
- return _SetStateXWidget(stateX: this, widgetFunc: widgetFunc);
+ return _SetStateXWidget(stateX: this, builder: widgetFunc);
}
/// Catch any errors in the App
@@ -565,14 +565,14 @@ class _SetStateXWidget extends StatelessWidget {
///
const _SetStateXWidget({
required this.stateX,
- required this.widgetFunc,
+ required this.builder,
});
final StateX stateX;
- final WidgetBuilder widgetFunc;
+ final WidgetBuilder builder;
@override
Widget build(BuildContext context) {
stateX.dependOnInheritedWidget(context);
- return widgetFunc(context);
+ return builder(context);
}
}
diff --git a/lib/part13_statex_controller.dart b/lib/part13_statex_controller.dart
index fe9dc97..1734a4d 100644
--- a/lib/part13_statex_controller.dart
+++ b/lib/part13_statex_controller.dart
@@ -12,7 +12,14 @@ part of 'state_extended.dart';
/// {@category Get started}
/// {@category Event handling}
/// {@category State Object Controller}
-class StateXController with SetStateMixin, StateListener, RootState, AsyncOps {
+class StateXController
+ with
+ ChangeNotifier,
+ SetStateMixin,
+ ListenableWidgetBuilderMixin,
+ StateListener,
+ RootState,
+ AsyncOps {
/// Optionally supply a State object to 'link' to this object.
/// Thus, assigned as 'current' StateX for this object
StateXController([StateX? state]) {
@@ -47,6 +54,14 @@ class StateXController with SetStateMixin, StateListener, RootState, AsyncOps {
/// The current StateX object.
StateX? get state => _stateX;
+ /// Call a State object's setState()
+ /// and notify any listeners
+ @override
+ void setState(VoidCallback fn) {
+ super.setState(fn);
+ notifyListeners();
+ }
+
/// Link a widget to an InheritedWidget
bool dependOnInheritedWidget(BuildContext? context) =>
_stateX?.dependOnInheritedWidget(context) ?? false;
diff --git a/lib/part14_listenable_widget_builder_mixin.dart b/lib/part14_listenable_widget_builder_mixin.dart
new file mode 100644
index 0000000..942fd19
--- /dev/null
+++ b/lib/part14_listenable_widget_builder_mixin.dart
@@ -0,0 +1,109 @@
+// Copyright 2024 Andrious Solutions Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+part of 'state_extended.dart';
+
+/// setBuilder(WidgetBuilder? builder) rebuilds with every setState() call.
+///
+/// dartdoc:
+/// {@category StateX class}
+/// {@category State Object Controller}
+mixin ListenableWidgetBuilderMixin {
+
+ /// Returns a widget from builder assuming the current object is a [Listenable]
+ /// const SizedBox.shrink() otherwise
+ Widget setBuilder(WidgetBuilder? builder) {
+ if (builder != null) {
+ _widgetBuilderUsed = true;
+ }
+ return _ListenableWidgetBuilder(
+ listenable: this,
+ builder: builder,
+ );
+ }
+
+ /// A flag. Noting if the function above is ever used.
+ bool get setBuilderUsed => _widgetBuilderUsed;
+ bool _widgetBuilderUsed = false;
+}
+
+/// Creates a widget that rebuilds when the given listenable calls.
+/// notifyListeners() function
+class _ListenableWidgetBuilder extends StatefulWidget {
+ /// The arguments is not required.
+ const _ListenableWidgetBuilder({
+ this.listenable,
+ this.builder,
+ });
+
+ /// Checked in State object if, in fact, a Listenable
+ final dynamic listenable;
+
+ /// Supply a Widget builder
+ final WidgetBuilder? builder;
+
+ /// Subclasses typically do not override this method.
+ @override
+ State createState() => _ListenableState();
+
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty('listenable', listenable));
+ }
+}
+
+//
+class _ListenableState extends State<_ListenableWidgetBuilder> {
+ @override
+ void initState() {
+ super.initState();
+ // May be actually be a Listenable
+ if (widget.builder != null && widget.listenable is Listenable) {
+ widgetBuilder = widget.builder!;
+ listenable = widget.listenable;
+ listenable?.addListener(_callBuild);
+ } else {
+ // A widget must be provided. Even if it's nothing
+ widgetBuilder = (_) => const SizedBox.shrink();
+ }
+ }
+
+ // Possibly not provided
+ Listenable? listenable;
+ // A Widget will be returned no matter what is provided.
+ late WidgetBuilder widgetBuilder;
+
+ @override
+ void didUpdateWidget(_ListenableWidgetBuilder oldWidget) {
+ super.didUpdateWidget(oldWidget);
+ // Possibly a O(2) expense if oldWidget == widget
+ if (oldWidget.listenable is Listenable) {
+ oldWidget.listenable?.removeListener(_callBuild);
+ }
+ if (widget.listenable is Listenable) {
+ widget.listenable?.addListener(_callBuild);
+ }
+ }
+
+ @override
+ void dispose() {
+ listenable?.removeListener(_callBuild);
+ listenable = null;
+ super.dispose();
+ }
+
+ void _callBuild() {
+ //
+ if (!mounted) {
+ return;
+ }
+ setState(() {
+ // Call the build() function again
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) => widgetBuilder.call(context);
+}
diff --git a/lib/part14_set_state_mixin.dart b/lib/part15_set_state_mixin.dart
similarity index 98%
rename from lib/part14_set_state_mixin.dart
rename to lib/part15_set_state_mixin.dart
index cb99fa5..2075730 100644
--- a/lib/part14_set_state_mixin.dart
+++ b/lib/part15_set_state_mixin.dart
@@ -10,7 +10,7 @@ part of 'state_extended.dart';
/// dartdoc:
/// {@category State Object Controller}
mixin SetStateMixin {
- /// Provide the setState() function to external actors
+ /// Calls the 'current' State object's setState() function if any.
void setState(VoidCallback fn) => _stateX?.setState(fn);
/// Retrieve the State object by its StatefulWidget. Returns null if not found.
diff --git a/lib/part15_controllers_by_id_mixin.dart b/lib/part16_controllers_by_id_mixin.dart
similarity index 100%
rename from lib/part15_controllers_by_id_mixin.dart
rename to lib/part16_controllers_by_id_mixin.dart
diff --git a/lib/part16_root_state_mixin.dart b/lib/part17_root_state_mixin.dart
similarity index 100%
rename from lib/part16_root_state_mixin.dart
rename to lib/part17_root_state_mixin.dart
diff --git a/lib/part17_record_exception_mixin.dart b/lib/part18_record_exception_mixin.dart
similarity index 100%
rename from lib/part17_record_exception_mixin.dart
rename to lib/part18_record_exception_mixin.dart
diff --git a/lib/part18_async_ops_mixin.dart b/lib/part19_async_ops_mixin.dart
similarity index 100%
rename from lib/part18_async_ops_mixin.dart
rename to lib/part19_async_ops_mixin.dart
diff --git a/lib/part19_uuid.dart b/lib/part20_uuid.dart
similarity index 100%
rename from lib/part19_uuid.dart
rename to lib/part20_uuid.dart
diff --git a/lib/state_extended.dart b/lib/state_extended.dart
index aa655bf..95460fe 100644
--- a/lib/state_extended.dart
+++ b/lib/state_extended.dart
@@ -72,20 +72,23 @@ part 'part12_set_state.dart';
/// class StateXController: dependOnInheritedWidget(), notifyClients()
part 'part13_statex_controller.dart';
+/// [Listenable] widget builder
+part 'part14_listenable_widget_builder_mixin.dart';
+
/// For StateXController, setState(), stateOf(), ofState(), firstState, and lastState
-part 'part14_set_state_mixin.dart';
+part 'part15_set_state_mixin.dart';
/// State object's controllerByType(), controllerById(), rootCon
-part 'part15_controllers_by_id_mixin.dart';
+part 'part16_controllers_by_id_mixin.dart';
/// The 'Root' State object: lastContext, dataObject and inDebugMode
-part 'part16_root_state_mixin.dart';
+part 'part17_root_state_mixin.dart';
/// Record an exception in a State object
-part 'part17_record_exception_mixin.dart';
+part 'part18_record_exception_mixin.dart';
/// Supply the Async API: initAsync() and onAsyncError()
-part 'part18_async_ops_mixin.dart';
+part 'part19_async_ops_mixin.dart';
/// A UUID generator, useful for generating unique IDs.
-part 'part19_uuid.dart';
+part 'part20_uuid.dart';
diff --git a/pubspec.lock b/pubspec.lock
index 805c1a5..c9a6254 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -279,10 +279,10 @@ packages:
dependency: transitive
description:
name: typed_data
- sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
+ sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
- version: "1.3.2"
+ version: "1.4.0"
universal_platform:
dependency: "direct main"
description:
@@ -303,10 +303,10 @@ packages:
dependency: transitive
description:
name: vm_service
- sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
+ sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
- version: "14.2.4"
+ version: "14.2.5"
webdriver:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 3a3d319..1ab0b4b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: state_extended
description: This class extends the capabilities of Flutter's State class and includes a controller.
-version: 5.5.0
+version: 5.6.0
homepage: https://www.andrioussolutions.com
repository: https://github.com/AndriousSolutions/state_extended