Skip to content

Commit

Permalink
Merge pull request #3 from flet-dev/s1-lazy-builders
Browse files Browse the repository at this point in the history
S1 lazy builders
  • Loading branch information
FeodorFitsner authored Apr 30, 2022
2 parents 68cb70d + aabe29b commit 6daabb2
Show file tree
Hide file tree
Showing 61 changed files with 1,018 additions and 85 deletions.
12 changes: 11 additions & 1 deletion client/lib/controls/checkbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@ class CheckboxControl extends StatefulWidget {

class _CheckboxControlState extends State<CheckboxControl> {
bool? _value;
final FocusNode _focusNode = FocusNode();

@override
void initState() {
super.initState();
_focusNode.addListener(() {
ws.pageEventFromWeb(
eventTarget: widget.control.id,
eventName: _focusNode.hasFocus ? "focus" : "blur",
eventData: "");
});
}

@override
Expand All @@ -50,6 +57,7 @@ class _CheckboxControlState extends State<CheckboxControl> {
widget.control.attrString("labelPosition", "")!.toLowerCase(),
orElse: () => LabelPosition.right);
bool tristate = widget.control.attrBool("tristate", false)!;
bool autofocus = widget.control.attrBool("autofocus", false)!;
bool disabled = widget.control.isDisabled || widget.parentDisabled;

return StoreConnector<AppState, Function>(
Expand All @@ -66,7 +74,7 @@ class _CheckboxControlState extends State<CheckboxControl> {

onChange(bool? value) {
var svalue = value != null ? value.toString() : "";
debugPrint(svalue);
//debugPrint(svalue);
setState(() {
_value = value;
});
Expand All @@ -83,6 +91,8 @@ class _CheckboxControlState extends State<CheckboxControl> {
}

var checkbox = Checkbox(
autofocus: autofocus,
focusNode: _focusNode,
value: _value,
tristate: tristate,
onChanged: !disabled
Expand Down
30 changes: 30 additions & 0 deletions client/lib/controls/clipboard.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

import '../models/control.dart';

class ClipboardControl extends StatelessWidget {
final Control? parent;
final Control control;

const ClipboardControl({Key? key, this.parent, required this.control})
: super(key: key);

@override
Widget build(BuildContext context) {
debugPrint("Clipboard build: ${control.id}");

var value = control.attrString("value");

if (value != null) {
debugPrint("Clipboard JSON value: $value");

var jv = json.decode(value);
Clipboard.setData(ClipboardData(text: jv["d"] as String?));
}

return const SizedBox.shrink();
}
}
8 changes: 4 additions & 4 deletions client/lib/controls/container.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

import '../models/control.dart';
import '../utils/alignment.dart';
import '../utils/borders.dart';
import 'create_control.dart';
import 'error.dart';
import '../utils/colors.dart';
import '../models/control.dart';
import '../utils/edge_insets.dart';
import 'create_control.dart';
import 'error.dart';

class ContainerControl extends StatelessWidget {
final Control? parent;
Expand All @@ -25,7 +25,7 @@ class ContainerControl extends StatelessWidget {

@override
Widget build(BuildContext context) {
debugPrint("Icon build: ${control.id}");
debugPrint("Container build: ${control.id}");

var bgColor =
HexColor.fromString(context, control.attrString("bgColor", "")!);
Expand Down
36 changes: 31 additions & 5 deletions client/lib/controls/create_control.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import '../models/control_view_model.dart';
import 'alert_dialog.dart';
import 'banner.dart';
import 'checkbox.dart';
import 'clipboard.dart';
import 'column.dart';
import 'container.dart';
import 'dropdown.dart';
Expand Down Expand Up @@ -45,17 +46,22 @@ import 'textfield.dart';
// }

Widget createControl(Control? parent, String id, bool parentDisabled) {
//debugPrint("createControl(): $id");
return StoreConnector<AppState, ControlViewModel>(
distinct: true,
converter: (store) {
//debugPrint("ControlViewModel $id converter");
return ControlViewModel.fromStore(store, id);
},
onWillChange: (prev, next) {
//debugPrint("${next.type} $id will change");
// onWillChange: (prev, next) {
// debugPrint("onWillChange() $id: $prev, $next");
// },
ignoreChange: (state) {
//debugPrint("ignoreChange: $id");
return state.controls[id] == null;
},
builder: (context, controlView) {
//debugPrint("${control.type} ${control.id} builder");
//debugPrint("createControl builder(): $id");
switch (controlView.control.type) {
case ControlType.page:
return PageControl(
Expand All @@ -64,6 +70,8 @@ Widget createControl(Control? parent, String id, bool parentDisabled) {
return TextControl(control: controlView.control);
case ControlType.icon:
return IconControl(control: controlView.control);
case ControlType.clipboard:
return ClipboardControl(control: controlView.control);
case ControlType.image:
return ImageControl(parent: parent, control: controlView.control);
case ControlType.progressRing:
Expand Down Expand Up @@ -205,12 +213,18 @@ Widget createControl(Control? parent, String id, bool parentDisabled) {
}

Widget baseControl(Widget widget, Control? parent, Control control) {
return _expandable(_opacity(widget, parent, control), parent, control);
return _expandable(
_tooltip(_opacity(widget, parent, control), parent, control),
parent,
control);
}

Widget constrainedControl(Widget widget, Control? parent, Control control) {
return _expandable(
_sizedControl(_opacity(widget, parent, control), parent, control),
_sizedControl(
_tooltip(_opacity(widget, parent, control), parent, control),
parent,
control),
parent,
control);
}
Expand All @@ -225,6 +239,18 @@ Widget _opacity(Widget widget, Control? parent, Control control) {
: widget;
}

Widget _tooltip(Widget widget, Control? parent, Control control) {
var tooltip = control.attrString("tooltip");
return tooltip != null
? Tooltip(
message: tooltip,
padding: const EdgeInsets.all(4.0),
child: widget,
waitDuration: const Duration(milliseconds: 800),
)
: widget;
}

Widget _sizedControl(Widget widget, Control? parent, Control control) {
var width = control.attrDouble("width", null);
var height = control.attrDouble("height", null);
Expand Down
15 changes: 15 additions & 0 deletions client/lib/controls/dropdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ class DropdownControl extends StatefulWidget {

class _DropdownControlState extends State<DropdownControl> {
String? _value;
final FocusNode _focusNode = FocusNode();

@override
void initState() {
super.initState();
_focusNode.addListener(() {
ws.pageEventFromWeb(
eventTarget: widget.control.id,
eventName: _focusNode.hasFocus ? "focus" : "blur",
eventData: "");
});
}

@override
Widget build(BuildContext context) {
Expand All @@ -41,6 +53,7 @@ class _DropdownControlState extends State<DropdownControl> {
builder: (context, itemsView) {
debugPrint("Dropdown StoreConnector build: ${widget.control.id}");

bool autofocus = widget.control.attrBool("autofocus", false)!;
bool disabled = widget.control.isDisabled || widget.parentDisabled;

String? value = widget.control.attrString("value");
Expand All @@ -54,6 +67,8 @@ class _DropdownControlState extends State<DropdownControl> {
itemsView.children.where((c) => c.name == "suffix");

var dropDown = DropdownButtonFormField<String>(
autofocus: autofocus,
focusNode: _focusNode,
value: _value,
decoration: buildInputDecoration(
widget.control,
Expand Down
3 changes: 3 additions & 0 deletions client/lib/controls/elevated_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ElevatedButtonControl extends StatelessWidget {
Color? iconColor =
HexColor.fromString(context, control.attrString("iconColor", "")!);
var contentCtrls = children.where((c) => c.name == "content");
bool autofocus = control.attrBool("autofocus", false)!;
bool disabled = control.isDisabled || parentDisabled;

Function()? onPressed = disabled
Expand All @@ -45,6 +46,7 @@ class ElevatedButtonControl extends StatelessWidget {

if (icon != null) {
button = ElevatedButton.icon(
autofocus: autofocus,
onPressed: onPressed,
icon: Icon(
icon,
Expand All @@ -53,6 +55,7 @@ class ElevatedButtonControl extends StatelessWidget {
label: Text(text));
} else if (contentCtrls.isNotEmpty) {
button = ElevatedButton(
autofocus: autofocus,
onPressed: onPressed,
child: createControl(control, contentCtrls.first.id, disabled));
} else {
Expand Down
4 changes: 4 additions & 0 deletions client/lib/controls/floating_action_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class FloatingActionButtonControl extends StatelessWidget {
Color? bgColor =
HexColor.fromString(context, control.attrString("bgColor", "")!);
var contentCtrls = children.where((c) => c.name == "content");
bool autofocus = control.attrBool("autofocus", false)!;
bool disabled = control.isDisabled || parentDisabled;

Function()? onPressed = disabled
Expand All @@ -49,16 +50,19 @@ class FloatingActionButtonControl extends StatelessWidget {
Widget button;
if (contentCtrls.isNotEmpty) {
button = FloatingActionButton(
autofocus: autofocus,
onPressed: onPressed,
child: createControl(control, contentCtrls.first.id, disabled));
} else if (icon != null && text == null) {
button = FloatingActionButton(
autofocus: autofocus,
onPressed: onPressed,
child: Icon(icon),
backgroundColor: bgColor,
);
} else if (icon != null && text != null) {
button = FloatingActionButton.extended(
autofocus: autofocus,
onPressed: onPressed,
label: Text(text),
icon: Icon(icon),
Expand Down
30 changes: 22 additions & 8 deletions client/lib/controls/grid_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,35 @@ class GridViewControl extends StatelessWidget {

final horizontal = control.attrBool("horizontal", false)!;
final runsCount = control.attrInt("runsCount", 1)!;
final maxExtent = control.attrDouble("maxExtent");
final spacing = control.attrDouble("spacing", 10)!;
final runSpacing = control.attrDouble("runSpacing", 10)!;
final padding = parseEdgeInsets(control, "padding");

List<Widget> controls =
children.map((c) => createControl(control, c.id, disabled)).toList();
final childAspectRatio = control.attrDouble("childAspectRatio", 1)!;

List<Control> visibleControls = children.where((c) => c.isVisible).toList();

var gridDelegate = maxExtent == null
? SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: runsCount,
mainAxisSpacing: spacing,
crossAxisSpacing: runSpacing,
childAspectRatio: childAspectRatio)
: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: maxExtent,
mainAxisSpacing: spacing,
crossAxisSpacing: runSpacing,
childAspectRatio: childAspectRatio);

return constrainedControl(
GridView.count(
GridView.builder(
scrollDirection: horizontal ? Axis.horizontal : Axis.vertical,
crossAxisCount: runsCount,
mainAxisSpacing: spacing,
crossAxisSpacing: runSpacing,
padding: padding,
children: controls,
gridDelegate: gridDelegate,
itemCount: visibleControls.length,
itemBuilder: (context, index) {
return createControl(control, visibleControls[index].id, disabled);
},
),
parent,
control);
Expand Down
6 changes: 3 additions & 3 deletions client/lib/controls/icon_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ class IconButtonControl extends StatelessWidget {
Widget build(BuildContext context) {
debugPrint("Button build: ${control.id}");

String? tooltip = control.attrString("tooltip");
IconData? icon = getMaterialIcon(control.attrString("icon", "")!);
Color? iconColor =
HexColor.fromString(context, control.attrString("iconColor", "")!);
double? iconSize = control.attrDouble("iconSize");
var contentCtrls = children.where((c) => c.name == "content");
bool autofocus = control.attrBool("autofocus", false)!;
bool disabled = control.isDisabled || parentDisabled;

Function()? onPressed = disabled
Expand All @@ -47,18 +47,18 @@ class IconButtonControl extends StatelessWidget {

if (icon != null) {
button = IconButton(
autofocus: autofocus,
icon: Icon(
icon,
color: iconColor,
),
iconSize: iconSize,
tooltip: tooltip,
onPressed: onPressed);
} else if (contentCtrls.isNotEmpty) {
button = IconButton(
autofocus: autofocus,
onPressed: onPressed,
iconSize: iconSize,
tooltip: tooltip,
icon: createControl(control, contentCtrls.first.id, disabled));
} else {
return const ErrorControl(
Expand Down
Loading

0 comments on commit 6daabb2

Please sign in to comment.