Skip to content

Commit 03548c5

Browse files
committed
Card control
1 parent 4b70802 commit 03548c5

File tree

7 files changed

+337
-0
lines changed

7 files changed

+337
-0
lines changed

client/lib/controls/card.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:flutter/material.dart';
2+
3+
import '../models/control.dart';
4+
import '../utils/edge_insets.dart';
5+
import 'create_control.dart';
6+
7+
class CardControl extends StatelessWidget {
8+
final Control? parent;
9+
final Control control;
10+
final List<Control> children;
11+
final bool parentDisabled;
12+
13+
const CardControl(
14+
{Key? key,
15+
this.parent,
16+
required this.control,
17+
required this.children,
18+
required this.parentDisabled})
19+
: super(key: key);
20+
21+
@override
22+
Widget build(BuildContext context) {
23+
debugPrint("Card build: ${control.id}");
24+
25+
var contentCtrls =
26+
children.where((c) => c.name == "content" && c.isVisible);
27+
bool disabled = control.isDisabled || parentDisabled;
28+
29+
return constrainedControl(
30+
Card(
31+
elevation: control.attrDouble("elevation"),
32+
margin: parseEdgeInsets(control, "margin"),
33+
child: contentCtrls.isNotEmpty
34+
? createControl(control, contentCtrls.first.id, disabled)
35+
: null),
36+
parent,
37+
control);
38+
}
39+
}

client/lib/controls/create_control.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'card.dart';
12
import 'navigation_rail.dart';
23

34
import 'package:flutter/material.dart';
@@ -154,6 +155,12 @@ Widget createControl(Control? parent, String id, bool parentDisabled) {
154155
control: controlView.control,
155156
children: controlView.children,
156157
parentDisabled: parentDisabled);
158+
case ControlType.card:
159+
return CardControl(
160+
parent: parent,
161+
control: controlView.control,
162+
children: controlView.children,
163+
parentDisabled: parentDisabled);
157164
case ControlType.listView:
158165
return ListViewControl(
159166
parent: parent,

client/lib/models/control_type.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ enum ControlType {
22
alertDialog,
33
appBar,
44
banner,
5+
card,
56
checkbox,
67
circleAvatar,
78
clipboard,
@@ -16,6 +17,7 @@ enum ControlType {
1617
icon,
1718
iconButton,
1819
image,
20+
listTile,
1921
listView,
2022
navigationRail,
2123
navigationRailDestination,

sdk/python/flet/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from flet.alert_dialog import AlertDialog
22
from flet.app_bar import AppBar
33
from flet.banner import Banner
4+
from flet.card import Card
45
from flet.checkbox import Checkbox
56
from flet.circle_avatar import CircleAvatar
67
from flet.column import Column
@@ -17,6 +18,7 @@
1718
from flet.icon import Icon
1819
from flet.icon_button import IconButton
1920
from flet.image import Image
21+
from flet.list_tile import ListTile
2022
from flet.list_view import ListView
2123
from flet.navigation_rail import NavigationRail, NavigationRailDestination
2224
from flet.outlined_button import OutlinedButton

sdk/python/flet/card.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
from typing import Optional, Union
2+
3+
from beartype import beartype
4+
5+
from flet import border_radius, margin, padding
6+
from flet.alignment import Alignment
7+
from flet.border import Border
8+
from flet.border_radius import BorderRadius
9+
from flet.constrained_control import ConstrainedControl
10+
from flet.control import BorderStyle, Control, MarginValue, OptionalNumber, PaddingValue
11+
from flet.ref import Ref
12+
13+
try:
14+
from typing import Literal
15+
except:
16+
from typing_extensions import Literal
17+
18+
19+
class Card(ConstrainedControl):
20+
def __init__(
21+
self,
22+
ref: Ref = None,
23+
width: OptionalNumber = None,
24+
height: OptionalNumber = None,
25+
expand: Union[bool, int] = None,
26+
opacity: OptionalNumber = None,
27+
tooltip: str = None,
28+
visible: bool = None,
29+
disabled: bool = None,
30+
data: any = None,
31+
#
32+
# Specific
33+
#
34+
content: Control = None,
35+
margin: MarginValue = None,
36+
elevation: OptionalNumber = None,
37+
):
38+
ConstrainedControl.__init__(
39+
self,
40+
ref=ref,
41+
width=width,
42+
height=height,
43+
expand=expand,
44+
opacity=opacity,
45+
tooltip=tooltip,
46+
visible=visible,
47+
disabled=disabled,
48+
data=data,
49+
)
50+
51+
self.content = content
52+
self.margin = margin
53+
self.elevation = elevation
54+
55+
def _get_control_name(self):
56+
return "card"
57+
58+
def _get_children(self):
59+
children = []
60+
if self.__content != None:
61+
self.__content._set_attr_internal("n", "content")
62+
children.append(self.__content)
63+
return children
64+
65+
# margin
66+
@property
67+
def margin(self):
68+
return self.__margin
69+
70+
@margin.setter
71+
@beartype
72+
def margin(self, value: MarginValue):
73+
self.__margin = value
74+
if value and isinstance(value, (int, float)):
75+
value = margin.all(value)
76+
self._set_attr_json("margin", value)
77+
78+
# elevation
79+
@property
80+
def elevation(self) -> OptionalNumber:
81+
return self._get_attr("elevation")
82+
83+
@elevation.setter
84+
@beartype
85+
def elevation(self, value: OptionalNumber):
86+
self._set_attr("elevation", value)
87+
88+
# content
89+
@property
90+
def content(self):
91+
return self.__content
92+
93+
@content.setter
94+
@beartype
95+
def content(self, value: Optional[Control]):
96+
self.__content = value

sdk/python/flet/list_tile.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
from typing import Optional, Union
2+
3+
from beartype import beartype
4+
5+
from flet import padding
6+
from flet.constrained_control import ConstrainedControl
7+
from flet.control import Control, OptionalNumber, PaddingValue
8+
from flet.ref import Ref
9+
10+
11+
class ListTile(ConstrainedControl):
12+
def __init__(
13+
self,
14+
text: str = None,
15+
ref: Ref = None,
16+
width: OptionalNumber = None,
17+
height: OptionalNumber = None,
18+
expand: Union[bool, int] = None,
19+
opacity: OptionalNumber = None,
20+
tooltip: str = None,
21+
visible: bool = None,
22+
disabled: bool = None,
23+
data: any = None,
24+
#
25+
# Specific
26+
#
27+
content_padding: PaddingValue = None,
28+
leading: Control = None,
29+
title: Control = None,
30+
subtitle: Control = None,
31+
trailing: Control = None,
32+
is_three_line: bool = None,
33+
selected: bool = None,
34+
autofocus: bool = None,
35+
on_click=None,
36+
):
37+
ConstrainedControl.__init__(
38+
self,
39+
ref=ref,
40+
width=width,
41+
height=height,
42+
expand=expand,
43+
opacity=opacity,
44+
tooltip=tooltip,
45+
visible=visible,
46+
disabled=disabled,
47+
data=data,
48+
)
49+
50+
self.content_padding = content_padding
51+
self.leading = leading
52+
self.title = title
53+
self.subtitle = subtitle
54+
self.trailing = trailing
55+
self.is_three_line = is_three_line
56+
self.selected = selected
57+
self.autofocus = autofocus
58+
self.on_click = on_click
59+
60+
def _get_control_name(self):
61+
return "listtile"
62+
63+
def _get_children(self):
64+
children = []
65+
if self.__leading:
66+
self.__leading._set_attr_internal("n", "leading")
67+
children.append(self.__leading)
68+
if self.__title:
69+
self.__title._set_attr_internal("n", "title")
70+
children.append(self.__title)
71+
if self.__subtitle:
72+
self.__subtitle._set_attr_internal("n", "subtitle")
73+
children.append(self.__subtitle)
74+
if self.__trailing:
75+
self.__trailing._set_attr_internal("n", "trailing")
76+
children.append(self.__trailing)
77+
return children
78+
79+
# content_padding
80+
@property
81+
def content_padding(self):
82+
return self.__content_padding
83+
84+
@content_padding.setter
85+
@beartype
86+
def content_padding(self, value: PaddingValue):
87+
self.__content_padding = value
88+
if value and isinstance(value, (int, float)):
89+
value = padding.all(value)
90+
self._set_attr_json("contentPadding", value)
91+
92+
# leading
93+
@property
94+
def leading(self):
95+
return self.__leading
96+
97+
@leading.setter
98+
@beartype
99+
def leading(self, value: Optional[Control]):
100+
self.__leading = value
101+
102+
# title
103+
@property
104+
def title(self):
105+
return self.__title
106+
107+
@title.setter
108+
@beartype
109+
def title(self, value: Optional[Control]):
110+
self.__title = value
111+
112+
# subtitle
113+
@property
114+
def subtitle(self):
115+
return self.__subtitle
116+
117+
@subtitle.setter
118+
@beartype
119+
def subtitle(self, value: Optional[Control]):
120+
self.__subtitle = value
121+
122+
# trailing
123+
@property
124+
def trailing(self):
125+
return self.__trailing
126+
127+
@trailing.setter
128+
@beartype
129+
def trailing(self, value: Optional[Control]):
130+
self.__trailing = value
131+
132+
# is_three_line
133+
@property
134+
def is_three_line(self):
135+
return self._get_attr("isThreeLine", data_type="bool", def_value=False)
136+
137+
@is_three_line.setter
138+
@beartype
139+
def is_three_line(self, value: Optional[bool]):
140+
self._set_attr("isThreeLine", value)
141+
142+
# selected
143+
@property
144+
def selected(self):
145+
return self._get_attr("selected", data_type="bool", def_value=False)
146+
147+
@selected.setter
148+
@beartype
149+
def selected(self, value: Optional[bool]):
150+
self._set_attr("selected", value)
151+
152+
# autofocus
153+
@property
154+
def autofocus(self):
155+
return self._get_attr("autofocus", data_type="bool", def_value=False)
156+
157+
@autofocus.setter
158+
@beartype
159+
def autofocus(self, value: Optional[bool]):
160+
self._set_attr("autofocus", value)
161+
162+
# on_click
163+
@property
164+
def on_click(self):
165+
return self._get_event_handler("click")
166+
167+
@on_click.setter
168+
def on_click(self, handler):
169+
self._add_event_handler("click", handler)

sdk/python/playground/card-test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import flet
2+
from flet import Card, Container, Text
3+
4+
5+
def main(page):
6+
page.title = "Card Examples"
7+
# page.theme_mode = "dark"
8+
page.add(
9+
Card(
10+
content=Container(
11+
content=Text("A regular card with padded content"), padding=10
12+
),
13+
margin=0,
14+
),
15+
Card(
16+
content=Container(content=Text("A card with custom elevation"), padding=10),
17+
elevation=5,
18+
),
19+
)
20+
21+
22+
flet.app(name="test1", port=8550, target=main, view=flet.WEB_BROWSER)

0 commit comments

Comments
 (0)