Skip to content

Commit e2d71e6

Browse files
Misc control improvements - S1 (#144)
* TextField and Dropdown formatting Fix #108, #132, #134, #100, #101 * Switch Flutter to master channel * Fix Flutter tests * Fixed dropdown text style for windows * Switch Flutter to dev channel * Allow partial theme and other JSON prop updates Fix #77 * Changing app host/IP binding Fix #98 * Fix #138: page.width and page.height are 0 on the first page load * Fix #137 scroll=hidden support * Fix #140: Container on_click callback breaks containers without explicit size * Long press support for buttons, container and listtile Fix #135 * Fixed long press event handlers for buttons * Gradients support in Container Close #123 * Fix container gradient * ButtonStyle POC - python side * ButtonStyle partially works * ButtonStyle almost done * Python files cleanup * All buttons have style * iconbutton.selected added * Fixed entry controls focus() method * Some cleanup * Fix elevated button style
1 parent de65939 commit e2d71e6

Some content is hidden

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

67 files changed

+1487
-275
lines changed

.appveyor.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ for:
9595
install:
9696
- ps: .\ci\install_flutter.ps1
9797
- set PATH=C:\flutter\bin;%PATH%
98-
- flutter --version
98+
- flutter channel dev
99+
- flutter upgrade
99100

100101
build_script:
101102
- cd client
@@ -138,7 +139,8 @@ for:
138139
- curl https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_3.0.3-stable.zip -o flutter_macos_stable.zip
139140
- unzip -qq flutter_macos_stable.zip
140141
- export PATH="$PATH:`pwd`/flutter/bin"
141-
- flutter --version
142+
- flutter channel dev
143+
- flutter upgrade
142144
- flutter config --enable-macos-desktop
143145
- flutter doctor
144146

@@ -172,8 +174,9 @@ for:
172174
install:
173175
# Flutter SDK
174176
- sudo snap install flutter --classic
177+
- flutter channel dev
178+
- flutter upgrade
175179
- flutter sdk-path
176-
- flutter --version
177180

178181
build_script:
179182
- cd client
@@ -207,7 +210,8 @@ for:
207210
- curl https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_3.0.3-stable.zip -o flutter_macos_stable.zip
208211
- unzip -qq flutter_macos_stable.zip
209212
- export PATH="$PATH:`pwd`/flutter/bin"
210-
- flutter --version
213+
- flutter channel dev
214+
- flutter upgrade
211215
- flutter doctor
212216

213217
build_script:
@@ -249,8 +253,9 @@ for:
249253
install:
250254
# Flutter SDK
251255
- sudo snap install flutter --classic
256+
- flutter channel dev
257+
- flutter upgrade
252258
- flutter sdk-path
253-
- flutter --version
254259

255260
# Go and GoReleaser
256261
- gvm install go${GO_VERSION} -B

client/.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
/build/
3333

3434
# Web related
35-
lib/generated_plugin_registrant.dart
3635

3736
# Symbolication related
3837
app.*.symbols
@@ -46,4 +45,4 @@ app.*.map.json
4645
/android/app/release
4746

4847
# Ruby
49-
vendor/
48+
vendor/

client/lib/actions.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class PageReconnectingAction {
2626

2727
class PageSizeChangeAction {
2828
final Size newPageSize;
29-
PageSizeChangeAction(this.newPageSize);
29+
final WindowMediaData? wmd;
30+
PageSizeChangeAction(this.newPageSize, this.wmd);
3031
}
3132

3233
class SetPageRouteAction {

client/lib/controls/alert_dialog.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ class _AlertDialogControlState extends State<AlertDialogControl> {
6969
actions: actionCtrls
7070
.map((c) => createControl(widget.control, c.id, disabled))
7171
.toList(),
72-
actionsPadding:
73-
parseEdgeInsets(widget.control, "actionsPadding") ?? EdgeInsets.zero,
72+
actionsPadding: parseEdgeInsets(widget.control, "actionsPadding"),
7473
actionsAlignment: actionsAlignment,
7574
);
7675
}

client/lib/controls/container.dart

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import '../utils/alignment.dart';
55
import '../utils/borders.dart';
66
import '../utils/colors.dart';
77
import '../utils/edge_insets.dart';
8+
import '../utils/gradient.dart';
89
import '../web_socket_client.dart';
910
import 'create_control.dart';
1011

@@ -32,30 +33,43 @@ class ContainerControl extends StatelessWidget {
3233
children.where((c) => c.name == "content" && c.isVisible);
3334
bool ink = control.attrBool("ink", false)!;
3435
bool onClick = control.attrBool("onclick", false)!;
36+
bool onLongPress = control.attrBool("onLongPress", false)!;
3537
bool disabled = control.isDisabled || parentDisabled;
3638

3739
var boxDecor = BoxDecoration(
3840
color: bgColor,
41+
gradient: parseGradient(Theme.of(context), control, "gradient"),
3942
border: parseBorder(Theme.of(context), control, "border"),
4043
borderRadius: parseBorderRadius(control, "borderRadius"));
4144

4245
Widget? child = contentCtrls.isNotEmpty
4346
? createControl(control, contentCtrls.first.id, disabled)
4447
: null;
4548

46-
if (onClick && ink) {
49+
if ((onClick || onLongPress) && ink) {
4750
return constrainedControl(
4851
Container(
4952
margin: parseEdgeInsets(control, "margin"),
5053
child: Ink(
5154
child: InkWell(
52-
onTap: () {
53-
debugPrint("Container ${control.id} clicked!");
54-
ws.pageEventFromWeb(
55-
eventTarget: control.id,
56-
eventName: "click",
57-
eventData: control.attrs["data"] ?? "");
58-
},
55+
onTap: onClick
56+
? () {
57+
debugPrint("Container ${control.id} clicked!");
58+
ws.pageEventFromWeb(
59+
eventTarget: control.id,
60+
eventName: "click",
61+
eventData: control.attrs["data"] ?? "");
62+
}
63+
: null,
64+
onLongPress: onLongPress
65+
? () {
66+
debugPrint("Container ${control.id} long pressed!");
67+
ws.pageEventFromWeb(
68+
eventTarget: control.id,
69+
eventName: "long_press",
70+
eventData: control.attrs["data"] ?? "");
71+
}
72+
: null,
5973
child: Container(
6074
child: child,
6175
padding: parseEdgeInsets(control, "padding"),
@@ -67,33 +81,41 @@ class ContainerControl extends StatelessWidget {
6781
parent,
6882
control);
6983
} else {
70-
var container = constrainedControl(
71-
Container(
72-
padding: parseEdgeInsets(control, "padding"),
73-
margin: parseEdgeInsets(control, "margin"),
74-
alignment: parseAlignment(control, "alignment"),
75-
decoration: boxDecor,
76-
child: child),
77-
parent,
78-
control);
79-
if (onClick) {
80-
return MouseRegion(
84+
Widget container = Container(
85+
padding: parseEdgeInsets(control, "padding"),
86+
margin: parseEdgeInsets(control, "margin"),
87+
alignment: parseAlignment(control, "alignment"),
88+
decoration: boxDecor,
89+
child: child);
90+
91+
if (onClick || onLongPress) {
92+
container = MouseRegion(
8193
cursor: SystemMouseCursors.click,
8294
child: GestureDetector(
8395
child: container,
84-
onTapDown: (details) {
85-
debugPrint("Container ${control.id} clicked!");
86-
ws.pageEventFromWeb(
87-
eventTarget: control.id,
88-
eventName: "click",
89-
eventData: control.attrString("data", "")! +
90-
"${details.localPosition.dx}:${details.localPosition.dy} ${details.globalPosition.dx}:${details.globalPosition.dy}");
91-
},
96+
onTapDown: onClick
97+
? (details) {
98+
debugPrint("Container ${control.id} clicked!");
99+
ws.pageEventFromWeb(
100+
eventTarget: control.id,
101+
eventName: "click",
102+
eventData: control.attrString("data", "")! +
103+
"${details.localPosition.dx}:${details.localPosition.dy} ${details.globalPosition.dx}:${details.globalPosition.dy}");
104+
}
105+
: null,
106+
onLongPress: onLongPress
107+
? () {
108+
debugPrint("Container ${control.id} clicked!");
109+
ws.pageEventFromWeb(
110+
eventTarget: control.id,
111+
eventName: "long_press",
112+
eventData: control.attrs["data"] ?? "");
113+
}
114+
: null,
92115
),
93116
);
94-
} else {
95-
return container;
96117
}
118+
return constrainedControl(container, parent, control);
97119
}
98120
}
99121
}

client/lib/controls/dropdown.dart

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import '../models/app_state.dart';
88
import '../models/control.dart';
99
import '../models/control_children_view_model.dart';
1010
import '../protocol/update_control_props_payload.dart';
11+
import '../utils/borders.dart';
12+
import '../utils/colors.dart';
1113
import '../web_socket_client.dart';
1214
import 'create_control.dart';
1315
import 'form_field.dart';
@@ -30,12 +32,16 @@ class DropdownControl extends StatefulWidget {
3032

3133
class _DropdownControlState extends State<DropdownControl> {
3234
String? _value;
35+
bool _focused = false;
3336
final FocusNode _focusNode = FocusNode();
3437

3538
@override
3639
void initState() {
3740
super.initState();
3841
_focusNode.addListener(() {
42+
setState(() {
43+
_focused = _focusNode.hasFocus;
44+
});
3945
ws.pageEventFromWeb(
4046
eventTarget: widget.control.id,
4147
eventName: _focusNode.hasFocus ? "focus" : "blur",
@@ -58,6 +64,21 @@ class _DropdownControlState extends State<DropdownControl> {
5864
bool autofocus = widget.control.attrBool("autofocus", false)!;
5965
bool disabled = widget.control.isDisabled || widget.parentDisabled;
6066

67+
var textSize = widget.control.attrDouble("textSize");
68+
69+
var color = HexColor.fromString(
70+
Theme.of(context), widget.control.attrString("color", "")!);
71+
var focusedColor = HexColor.fromString(Theme.of(context),
72+
widget.control.attrString("focusedColor", "")!);
73+
74+
TextStyle? textStyle;
75+
if (textSize != null || color != null || focusedColor != null) {
76+
textStyle = TextStyle(
77+
fontSize: textSize,
78+
color: (_focused ? focusedColor ?? color : color) ??
79+
Theme.of(context).colorScheme.onSurface);
80+
}
81+
6182
var items = itemsView.children
6283
.where((c) => c.name == null)
6384
.map<DropdownMenuItem<String>>(
@@ -96,15 +117,21 @@ class _DropdownControlState extends State<DropdownControl> {
96117
}
97118
}
98119

120+
var borderRadius = parseBorderRadius(widget.control, "borderRadius");
121+
99122
Widget dropDown = DropdownButtonFormField<String>(
123+
style: textStyle,
100124
autofocus: autofocus,
101125
focusNode: _focusNode,
102126
value: _value,
127+
borderRadius: borderRadius,
103128
decoration: buildInputDecoration(
129+
context,
104130
widget.control,
105131
prefixControls.isNotEmpty ? prefixControls.first : null,
106132
suffixControls.isNotEmpty ? suffixControls.first : null,
107-
null),
133+
null,
134+
_focused),
108135
onChanged: (String? value) {
109136
debugPrint("Dropdown selected value: $value");
110137
setState(() {

client/lib/controls/elevated_button.dart

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:flet_view/utils/buttons.dart';
12
import 'package:flutter/material.dart';
23

34
import '../models/control.dart';
@@ -47,23 +48,39 @@ class ElevatedButtonControl extends StatelessWidget {
4748
eventData: control.attrs["data"] ?? "");
4849
};
4950

51+
Function()? onLongPress = disabled
52+
? null
53+
: () {
54+
debugPrint("Button ${control.id} long pressed!");
55+
ws.pageEventFromWeb(
56+
eventTarget: control.id,
57+
eventName: "long_press",
58+
eventData: control.attrs["data"] ?? "");
59+
};
60+
5061
ElevatedButton? button;
51-
ButtonStyle? style;
5262

53-
if (color != null || bgcolor != null || elevation != null) {
54-
style = ElevatedButton.styleFrom(
55-
// Foreground color
56-
onPrimary: color,
57-
// Background color
58-
primary: bgcolor,
59-
).copyWith(elevation: ButtonStyleButton.allOrNull(elevation));
60-
}
63+
var theme = Theme.of(context);
64+
65+
var style = parseButtonStyle(Theme.of(context), control, "style",
66+
defaultForegroundColor: theme.colorScheme.primary,
67+
defaultBackgroundColor: theme.colorScheme.surface,
68+
defaultOverlayColor: theme.colorScheme.primary.withOpacity(0.08),
69+
defaultShadowColor: theme.colorScheme.shadow,
70+
defaultSurfaceTintColor: theme.colorScheme.surfaceTint,
71+
defaultElevation: 1,
72+
defaultPadding: const EdgeInsets.symmetric(horizontal: 8),
73+
defaultBorderSide: BorderSide.none,
74+
defaultShape: theme.useMaterial3
75+
? const StadiumBorder()
76+
: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)));
6177

6278
if (icon != null) {
6379
button = ElevatedButton.icon(
6480
style: style,
6581
autofocus: autofocus,
6682
onPressed: onPressed,
83+
onLongPress: onLongPress,
6784
icon: Icon(
6885
icon,
6986
color: iconColor,
@@ -74,10 +91,14 @@ class ElevatedButtonControl extends StatelessWidget {
7491
style: style,
7592
autofocus: autofocus,
7693
onPressed: onPressed,
94+
onLongPress: onLongPress,
7795
child: createControl(control, contentCtrls.first.id, disabled));
7896
} else {
79-
button =
80-
ElevatedButton(style: style, onPressed: onPressed, child: Text(text));
97+
button = ElevatedButton(
98+
style: style,
99+
onPressed: onPressed,
100+
onLongPress: onLongPress,
101+
child: Text(text));
81102
}
82103

83104
return constrainedControl(button, parent, control);

0 commit comments

Comments
 (0)