Skip to content

Commit c0a0705

Browse files
committed
Merge remote-tracking branch 'origin/v1' into v1
2 parents 6febd58 + 63d7284 commit c0a0705

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+918
-593
lines changed

.appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ skip_commits:
1010

1111
environment:
1212
python_stack: python 3.12
13-
FLUTTER_VERSION: 3.27.4
13+
FLUTTER_VERSION: 3.29.2
1414
GITHUB_TOKEN:
1515
secure: 9SKIwc3VSfYJ5IChvNR74hQprJ0DRmcV9pPX+8KyE6IXIdfMsX6ikeUmMhJGRu3ztkZaF45jmU7Xn/6tauXQXhDBxK1N8kFHFSAnq6LjUXyhS0TZKX/H+jDozBeVbCXp
1616
TWINE_USERNAME: __token__

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Flet changelog
22

3+
## 0.27.6
4+
5+
* Fix `flet build`: allow dependencies with commas ([#5033](https://github.com/flet-dev/flet/issues/5033))
6+
* Show app startup screen by default ([#5036](https://github.com/flet-dev/flet/issues/5036))
7+
* fix: `Textfield` cursor position changes when modifying field content in `on_change` ([#5019](https://github.com/flet-dev/flet/issues/5019))
8+
* Remove deperecated `Control.update_async()` method ([#5005](https://github.com/flet-dev/flet/issues/5005))
9+
* fix: incorrect positioning of non-FAB controls assigned to page.floating_action_button ([#5049](https://github.com/flet-dev/flet/issues/5049))
10+
311
## 0.27.5
412

513
* Added `FletApp.showAppStartupScreen` and `FletApp.appStartupScreenMessage` properties.

packages/flet/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# 0.27.6
2+
3+
* Fix `flet build`: allow dependencies with commas ([#5033](https://github.com/flet-dev/flet/issues/5033))
4+
* Show app startup screen by default ([#5036](https://github.com/flet-dev/flet/issues/5036))
5+
* fix: `Textfield` cursor position changes when modifying field content in `on_change` ([#5019](https://github.com/flet-dev/flet/issues/5019))
6+
* Remove deperecated `Control.update_async()` method ([#5005](https://github.com/flet-dev/flet/issues/5005))
7+
* fix: incorrect positioning of non-FAB controls assigned to page.floating_action_button ([#5049](https://github.com/flet-dev/flet/issues/5049))
8+
19
# 0.27.5
210

311
* Added `FletApp.showAppStartupScreen` and `FletApp.appStartupScreenMessage` properties.

packages/flet/lib/src/controls/alert_dialog.dart

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '../utils/edge_insets.dart';
99
import '../utils/others.dart';
1010
import '../utils/text.dart';
1111
import '../widgets/error.dart';
12+
import 'control_widget.dart';
1213

1314
class AlertDialogControl extends StatefulWidget {
1415
final Control control;
@@ -47,12 +48,12 @@ class _AlertDialogControlState extends State<AlertDialogControl> {
4748
}
4849

4950
Widget _createAlertDialog() {
50-
var titleControl = widget.control.buildWidget("title");
51-
var contentControl = widget.control.buildWidget("content");
52-
var actionControls = widget.control.buildWidgets("actions");
51+
var titleControl = widget.control.get("title");
52+
var contentWidget = widget.control.buildWidget("content");
53+
var actionWidgets = widget.control.buildWidgets("actions");
5354
if (titleControl == null &&
54-
contentControl == null &&
55-
actionControls.isEmpty) {
55+
contentWidget == null &&
56+
actionWidgets.isEmpty) {
5657
return const ErrorControl(
5758
"AlertDialog has nothing to display. Provide at minimum one of the following: title, content, actions");
5859
}
@@ -63,12 +64,16 @@ class _AlertDialogControlState extends State<AlertDialogControl> {
6364
parseClip(widget.control.getString("clipBehavior"), Clip.none)!;
6465

6566
return AlertDialog(
66-
title: titleControl,
67+
title: titleControl is Control
68+
? ControlWidget(control: titleControl)
69+
: titleControl is String
70+
? Text(titleControl)
71+
: null,
6772
titlePadding: parseEdgeInsets(widget.control, "title_padding"),
68-
content: contentControl,
73+
content: contentWidget,
6974
contentPadding: parseEdgeInsets(widget.control, "content_padding",
7075
const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0))!,
71-
actions: actionControls,
76+
actions: actionWidgets,
7277
actionsPadding: parseEdgeInsets(widget.control, "actions_padding"),
7378
actionsAlignment: actionsAlignment,
7479
shape: parseOutlinedBorder(widget.control, "shape"),

packages/flet/lib/src/controls/app_bar.dart_

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22

33
import '../models/control.dart';
44
import '../utils/borders.dart';
5+
import '../utils/edge_insets.dart';
56
import '../utils/others.dart';
67
import '../utils/text.dart';
78
import '../utils/theme.dart';
@@ -90,6 +91,7 @@ class AppBarControl extends StatelessWidget
9091
toolbarOpacity: control.getDouble("toolbarOpacity", 1)!,
9192
toolbarTextStyle:
9293
parseTextStyle(Theme.of(context), control, "toolbarTextStyle"),
94+
actionsPadding: parseEdgeInsets(control, "actionsPadding"),
9395
);
9496
return baseControl(context, appBar, parent, control);
9597
});

packages/flet/lib/src/controls/checkbox.dart_

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:collection/collection.dart';
12
import 'package:flutter/material.dart';
23

34
import '../flet_control_backend.dart';
@@ -19,13 +20,15 @@ class CheckboxControl extends StatefulWidget {
1920
final bool parentDisabled;
2021
final bool? parentAdaptive;
2122
final FletControlBackend backend;
23+
final List<Control> children;
2224

2325
const CheckboxControl(
2426
{super.key,
2527
this.parent,
2628
required this.control,
2729
required this.parentDisabled,
2830
required this.parentAdaptive,
31+
required this.children,
2932
required this.backend});
3033

3134
@override
@@ -81,7 +84,10 @@ class _CheckboxControlState extends State<CheckboxControl> with FletStoreMixin {
8184

8285
return withPagePlatform((context, platform) {
8386
bool? adaptive =
84-
widget.control.getBool("adaptive") ?? widget.parentAdaptive;
87+
widget.control.attrBool("adaptive") ?? widget.parentAdaptive;
88+
bool disabled = widget.control.isDisabled || widget.parentDisabled;
89+
double? width = widget.control.attrDouble("width");
90+
double? height = widget.control.attrDouble("height");
8591

8692
if (adaptive == true &&
8793
(platform == TargetPlatform.iOS ||
@@ -91,18 +97,13 @@ class _CheckboxControlState extends State<CheckboxControl> with FletStoreMixin {
9197
parentDisabled: widget.parentDisabled,
9298
backend: widget.backend);
9399
}
94-
95-
String label = widget.control.getString("label", "")!;
100+
var label = widget.children.firstWhereOrNull((c) => c.isVisible);
101+
String labelStr = widget.control.attrString("label", "")!;
96102
LabelPosition labelPosition = parseLabelPosition(
97-
widget.control.getString("labelPosition"), LabelPosition.right)!;
98-
_tristate = widget.control.getBool("tristate", false)!;
99-
bool autofocus = widget.control.getBool("autofocus", false)!;
100-
101-
bool disabled = widget.control.disabled || widget.parentDisabled;
102-
103-
debugPrint("Checkbox build: ${widget.control.id}");
104-
105-
bool? value = widget.control.getBool("value", _tristate ? null : false);
103+
widget.control.attrString("labelPosition"), LabelPosition.right)!;
104+
_tristate = widget.control.attrBool("tristate", false)!;
105+
bool autofocus = widget.control.attrBool("autofocus", false)!;
106+
bool? value = widget.control.attrBool("value", _tristate ? null : false);
106107
if (_value != value) {
107108
_value = value;
108109
}
@@ -117,25 +118,25 @@ class _CheckboxControlState extends State<CheckboxControl> with FletStoreMixin {
117118
autofocus: autofocus,
118119
focusNode: _focusNode,
119120
value: _value,
120-
isError: widget.control.getBool("isError", false)!,
121-
semanticLabel: widget.control.getString("semanticsLabel"),
121+
isError: widget.control.attrBool("isError", false)!,
122+
semanticLabel: widget.control.attrString("semanticsLabel"),
122123
shape: parseOutlinedBorder(widget.control, "shape"),
123124
side: parseWidgetStateBorderSide(
124125
Theme.of(context), widget.control, "borderSide"),
125-
splashRadius: widget.control.getDouble("splashRadius"),
126-
activeColor: widget.control.getColor("activeColor", context),
127-
focusColor: widget.control.getColor("focusColor", context),
128-
hoverColor: widget.control.getColor("hoverColor", context),
126+
splashRadius: widget.control.attrDouble("splashRadius"),
127+
activeColor: widget.control.attrColor("activeColor", context),
128+
focusColor: widget.control.attrColor("focusColor", context),
129+
hoverColor: widget.control.attrColor("hoverColor", context),
129130
overlayColor: parseWidgetStateColor(
130131
Theme.of(context), widget.control, "overlayColor"),
131-
checkColor: widget.control.getColor("checkColor", context),
132+
checkColor: widget.control.attrColor("checkColor", context),
132133
fillColor: parseWidgetStateColor(
133134
Theme.of(context), widget.control, "fillColor"),
134135
tristate: _tristate,
135136
visualDensity:
136-
parseVisualDensity(widget.control.getString("visualDensity")),
137+
parseVisualDensity(widget.control.attrString("visualDensity")),
137138
mouseCursor:
138-
parseMouseCursor(widget.control.getString("mouseCursor")),
139+
parseMouseCursor(widget.control.attrString("mouseCursor")),
139140
onChanged: !disabled
140141
? (bool? value) {
141142
_onChange(value);
@@ -147,19 +148,36 @@ class _CheckboxControlState extends State<CheckboxControl> with FletStoreMixin {
147148
});
148149

149150
Widget result = checkbox;
150-
if (label != "") {
151-
var labelWidget = disabled
152-
? Text(label, style: labelStyle)
153-
: MouseRegion(
154-
cursor: SystemMouseCursors.click,
155-
child: Text(label, style: labelStyle));
151+
if (label != null || (labelStr != "")) {
152+
Widget? labelWidget;
153+
if (label != null) {
154+
labelWidget =
155+
createControl(widget.control, label.id, disabled);
156+
} else {
157+
labelWidget = disabled
158+
? Text(labelStr, style: labelStyle)
159+
: MouseRegion(
160+
cursor: SystemMouseCursors.click,
161+
child: Text(labelStr, style: labelStyle));
162+
}
163+
156164
result = MergeSemantics(
157165
child: GestureDetector(
158166
onTap: !disabled ? _toggleValue : null,
159167
child: labelPosition == LabelPosition.right
160168
? Row(children: [checkbox, labelWidget])
161169
: Row(children: [labelWidget, checkbox])));
162170
}
171+
if (width != null || height != null) {
172+
result = SizedBox(
173+
width: width,
174+
height: height,
175+
child: FittedBox(
176+
fit: BoxFit.fill,
177+
child: result,
178+
),
179+
);
180+
}
163181

164182
return constrainedControl(context, result, widget.parent, widget.control);
165183
});

packages/flet/lib/src/controls/cupertino_action_sheet_action.dart_

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
22

33
import '../flet_control_backend.dart';
44
import '../models/control.dart';
5+
import '../utils/mouse.dart';
56
import 'create_control.dart';
67
import 'error.dart';
78

@@ -44,6 +45,7 @@ class CupertinoActionSheetActionControl extends StatelessWidget {
4445
backend.triggerControlEvent(control.id, "click");
4546
}
4647
},
48+
mouseCursor: parseMouseCursor(control.attrString("mouseCursor")),
4749
child: contentCtrls.isNotEmpty
4850
? createControl(control, contentCtrls.first.id, disabled,
4951
parentAdaptive: parentAdaptive)

packages/flet/lib/src/controls/cupertino_app_bar.dart_

Lines changed: 76 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,54 +26,87 @@ class CupertinoAppBarControl extends StatelessWidget
2626
@override
2727
Widget build(BuildContext context) {
2828
debugPrint("CupertinoAppBar build: ${control.id}");
29+
var large = control.attrBool("large", false)!;
2930

30-
var leadingCtrls = children.where((c) => c.name == "leading" && c.visible);
31+
var leadingCtrls =
32+
children.where((c) => c.name == "leading" && c.isVisible);
3133

32-
// if the material AppBar was used with adaptive=True, AppBar.title will be used as middle control
33-
var middleCtrls = children
34-
.where((c) => (c.name == "middle" || c.name == "title") && c.visible);
34+
// "middle" is deprecated in v0.27.0 and will be removed in v0.30.0, use "title" instead
35+
var titleCtrls = children
36+
.where((c) => (c.name == "title" || c.name == "middle") && c.isVisible);
3537

3638
// if the material AppBar was used with adaptive=True, AppBar.actions[0] will be used as trailing control
3739
var trailingCtrls = children.where(
38-
(c) => (c.name == "trailing" || c.name == "action") && c.visible);
40+
(c) => (c.name == "trailing" || c.name == "action") && c.isVisible);
3941

40-
var bar = CupertinoNavigationBar(
41-
leading: leadingCtrls.isNotEmpty
42-
? createControl(control, leadingCtrls.first.id, control.disabled,
43-
parentAdaptive: parentAdaptive)
44-
: null,
45-
automaticallyImplyLeading:
46-
control.getBool("automaticallyImplyLeading", true)!,
47-
automaticallyImplyMiddle:
48-
control.getBool("automaticallyImplyMiddle", true)!,
49-
transitionBetweenRoutes:
50-
control.getBool("transitionBetweenRoutes", true)!,
51-
border: parseBorder(Theme.of(context), control, "border"),
52-
previousPageTitle: control.getString("previousPageTitle"),
53-
padding: parseEdgeInsetsDirectional(control, "padding"),
54-
backgroundColor: control.getColor("bgcolor", context),
55-
automaticBackgroundVisibility:
56-
control.getBool("automaticBackgroundVisibility", true)!,
57-
enableBackgroundFilterBlur:
58-
control.getBool("backgroundFilterBlur", true)!,
59-
brightness: parseBrightness(control.getString("brightness")),
60-
middle: middleCtrls.isNotEmpty
61-
? createControl(control, middleCtrls.first.id, control.disabled,
62-
parentAdaptive: parentAdaptive)
63-
: null,
64-
trailing: trailingCtrls.length == 1
65-
? createControl(control, trailingCtrls.first.id, control.disabled,
66-
parentAdaptive: parentAdaptive)
67-
: trailingCtrls.length > 1
68-
? Row(
69-
mainAxisSize: MainAxisSize.min,
70-
children: trailingCtrls
71-
.map((c) => createControl(control, c.id, control.disabled,
72-
parentAdaptive: parentAdaptive))
73-
.toList(),
74-
)
75-
: null,
76-
);
42+
var leading = leadingCtrls.isNotEmpty
43+
? createControl(control, leadingCtrls.first.id, control.isDisabled,
44+
parentAdaptive: parentAdaptive)
45+
: null;
46+
47+
var automaticallyImplyLeading =
48+
control.attrBool("automaticallyImplyLeading", true)!;
49+
var automaticallyImplyTitle =
50+
control.attrBool("automaticallyImplyTitle", control.attrBool("automaticallyImplyMiddle", true)!)!;
51+
var transitionBetweenRoutes =
52+
control.attrBool("transitionBetweenRoutes", true)!;
53+
var border = parseBorder(Theme.of(context), control, "border");
54+
var previousPageTitle = control.attrString("previousPageTitle");
55+
var padding = parseEdgeInsetsDirectional(control, "padding");
56+
var backgroundColor = control.attrColor("bgcolor", context);
57+
var automaticBackgroundVisibility =
58+
control.attrBool("automaticBackgroundVisibility", true)!;
59+
var enableBackgroundFilterBlur =
60+
control.attrBool("backgroundFilterBlur", true)!;
61+
var brightness = parseBrightness(control.attrString("brightness"));
62+
var title = titleCtrls.isNotEmpty
63+
? createControl(control, titleCtrls.first.id, control.isDisabled,
64+
parentAdaptive: parentAdaptive)
65+
: null;
66+
var trailing = trailingCtrls.length == 1
67+
? createControl(control, trailingCtrls.first.id, control.isDisabled,
68+
parentAdaptive: parentAdaptive)
69+
: trailingCtrls.length > 1
70+
? Row(
71+
mainAxisSize: MainAxisSize.min,
72+
children: trailingCtrls
73+
.map((c) => createControl(control, c.id, control.isDisabled,
74+
parentAdaptive: parentAdaptive))
75+
.toList(),
76+
)
77+
: null;
78+
79+
var bar = large
80+
? CupertinoNavigationBar.large(
81+
leading: leading,
82+
automaticallyImplyLeading: automaticallyImplyLeading,
83+
transitionBetweenRoutes: transitionBetweenRoutes,
84+
border: border,
85+
previousPageTitle: previousPageTitle,
86+
padding: padding,
87+
backgroundColor: backgroundColor,
88+
automaticBackgroundVisibility: automaticBackgroundVisibility,
89+
enableBackgroundFilterBlur: enableBackgroundFilterBlur,
90+
brightness: brightness,
91+
trailing: trailing,
92+
largeTitle: title,
93+
automaticallyImplyTitle: automaticallyImplyTitle,
94+
)
95+
: CupertinoNavigationBar(
96+
leading: leading,
97+
automaticallyImplyLeading: automaticallyImplyLeading,
98+
automaticallyImplyMiddle: automaticallyImplyTitle,
99+
transitionBetweenRoutes: transitionBetweenRoutes,
100+
border: border,
101+
previousPageTitle: previousPageTitle,
102+
padding: padding,
103+
backgroundColor: backgroundColor,
104+
automaticBackgroundVisibility: automaticBackgroundVisibility,
105+
enableBackgroundFilterBlur: enableBackgroundFilterBlur,
106+
brightness: brightness,
107+
middle: title,
108+
trailing: trailing,
109+
);
77110
return baseControl(context, bar, parent, control);
78111
}
79112

@@ -85,7 +118,7 @@ class CupertinoAppBarControl extends StatelessWidget
85118
@override
86119
bool shouldFullyObstruct(BuildContext context) {
87120
final Color backgroundColor = CupertinoDynamicColor.maybeResolve(
88-
control.getColor("bgcolor", context), context) ??
121+
control.attrColor("bgcolor", context), context) ??
89122
CupertinoTheme.of(context).barBackgroundColor;
90123
return backgroundColor.alpha == 0xFF;
91124
}

packages/flet/lib/src/controls/cupertino_button.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ class CupertinoButtonControl extends StatelessWidget {
150150
pressedOpacity: pressedOpacity,
151151
alignment: alignment,
152152
minSize: minSize,
153+
autofocus: control.getBool("autofocus", false)!,
154+
focusColor: control.getColor("focus_color", context),
153155
onLongPress: !control.disabled
154156
? () {
155157
FletBackend.of(context)

0 commit comments

Comments
 (0)