Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions package/lib/src/controls/badge.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import '../models/control.dart';
import 'create_control.dart';
import '../utils/transforms.dart';
import '../utils/alignment.dart';
import '../utils/colors.dart';
import '../utils/edge_insets.dart';
import '../utils/text.dart';

class BadgeControl extends StatelessWidget {
final Control? parent;
final Control control;
final List<Control> children;
final bool parentDisabled;

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

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

String? label = control.attrString("labelText");

var contentCtrls =
children.where((c) => c.name == "content" && c.isVisible);
bool disabled = control.isDisabled || parentDisabled;

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

var offsetDetails = parseOffset(control, "offset");

var bgColor = HexColor.fromString(
Theme.of(context), control.attrString("bgColor", "")!);

var textColor = HexColor.fromString(
Theme.of(context), control.attrString("textColor", "")!);

bool isLabelVisible = control.attrBool("isLabelVisible", true)!;
var largeSize = control.attrDouble("largeSize");
var smallSize = control.attrDouble("smallSize");

return baseControl(
context,
Badge(
label: label != null ? Text(label) : null,
isLabelVisible: isLabelVisible,
offset: offsetDetails != null
? Offset(offsetDetails.x, offsetDetails.y)
: null,
alignment: parseAlignment(control, "alignment"),
backgroundColor: bgColor,
largeSize: largeSize,
padding: parseEdgeInsets(control, "padding"),
smallSize: smallSize,
textColor: textColor,
textStyle: parseTextStyle(Theme.of(context), control, "textStyle"),
child: child,
),
parent,
control);
}
}
9 changes: 9 additions & 0 deletions package/lib/src/controls/create_control.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import 'transparent_pointer.dart';
import 'vertical_divider.dart';
import 'window_drag_area.dart';
import 'range_slider.dart';
import 'badge.dart';

Widget createControl(Control? parent, String id, bool parentDisabled,
{Widget? nextChild}) {
Expand Down Expand Up @@ -194,6 +195,14 @@ Widget createWidget(Key? key, ControlViewModel controlView, Control? parent,
case "divider":
return DividerControl(
key: key, parent: parent, control: controlView.control);
case "badge":
return BadgeControl(
key: key,
parent: parent,
control: controlView.control,
children: controlView.children,
parentDisabled: parentDisabled,
);
case "clipboard":
return ClipboardControl(
parent: parent, control: controlView.control, nextChild: nextChild);
Expand Down
1 change: 1 addition & 0 deletions sdk/python/packages/flet-core/src/flet_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,4 @@
from flet_core.view import View
from flet_core.window_drag_area import WindowDragArea
from flet_core.range_slider import RangeSlider
from flet_core.badge import Badge
212 changes: 212 additions & 0 deletions sdk/python/packages/flet-core/src/flet_core/badge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
from typing import Any, Optional

from flet_core.control import Control, OptionalNumber
from flet_core.alignment import Alignment
from flet_core.ref import Ref
from flet_core.types import OffsetValue, PaddingValue
from flet_core.text_style import TextStyle


class Badge(Control):
"""
A Material Design "badge".

Badges are used to show notifications, counts, or status information on navigation items such as NavigationBar or NavigationRail destinations
or a button's icon.

Example:
```
import flet as ft

def main(page: ft.Page):
page.title = "Badges in NavigationBar icons"
page.navigation_bar = ft.NavigationBar(
destinations=[
ft.NavigationDestination(
icon_content=ft.Badge(
content=ft.Icon(ft.icons.EXPLORE),
small_size=10,
),
label="Explore",
),
ft.NavigationDestination(icon=ft.icons.COMMUTE, label="Commute"),
ft.NavigationDestination(
icon_content=ft.Badge(content=ft.Icon(ft.icons.PHONE), text="10")
),
]
)
page.add(ft.Text("Body!"))


ft.app(target=main)



```

-----

Online docs: https://flet.dev/docs/controls/badge
"""

def __init__(
self,
content: Optional[Control] = None,
ref: Optional[Ref] = None,
opacity: OptionalNumber = None,
visible: Optional[bool] = None,
data: Any = None,
#
# Specific
#
text: Optional[str] = None,
offset: OffsetValue = None,
alignment: Optional[Alignment] = None,
bgcolor: Optional[str] = None,
label_visible: Optional[bool] = None,
large_size: OptionalNumber = None,
padding: Optional[PaddingValue] = None,
small_size: OptionalNumber = None,
text_color: Optional[str] = None,
text_style: Optional[TextStyle] = None,
):
Control.__init__(
self,
ref=ref,
opacity=opacity,
visible=visible,
data=data,
)

self.text = text
self.content = content
self.offset = offset
self.alignment = alignment
self.bgcolor = bgcolor
self.label_visible = label_visible
self.large_size = large_size
self.padding = padding
self.small_size = small_size
self.text_color = text_color
self.text_style = text_style

def _get_control_name(self):
return "badge"

def _before_build_command(self):
super()._before_build_command()
self._set_attr_json("offset", self.__offset)
self._set_attr_json("alignment", self.__alignment)
self._set_attr_json("padding", self.__padding)
self._set_attr_json("textStyle", self.__text_style)

def _get_children(self):
children = []
if self.__content is not None:
self.__content._set_attr_internal("n", "content")
children.append(self.__content)
return children

# alignment
@property
def alignment(self) -> Optional[Alignment]:
""":obj:`Alignment`, optional: Align the child control within the container.

Alignment is an instance of `alignment.Alignment` class object with `x` and `y` properties
representing the distance from the center of a rectangle.
"""
return self.__alignment

@alignment.setter
def alignment(self, value: Optional[Alignment]):
self.__alignment = value

# text
@property
def text(self) -> Optional[str]:
return self._get_attr("labelText")

@text.setter
def text(self, value: Optional[str]):
self._set_attr("labelText", value)

# content
@property
def content(self) -> Optional[Control]:
return self.__content

@content.setter
def content(self, value: Optional[Control]):
self.__content = value

# offset
@property
def offset(self) -> OffsetValue:
return self.__offset

@offset.setter
def offset(self, value: OffsetValue):
self.__offset = value

# bgcolor
@property
def bgcolor(self):
return self._get_attr("bgColor")

@bgcolor.setter
def bgcolor(self, value):
self._set_attr("bgColor", value)

# label_visible
@property
def label_visible(self) -> Optional[bool]:
return self._get_attr("isLabelVisible")

@label_visible.setter
def label_visible(self, value: Optional[bool]):
self._set_attr("isLabelVisible", value)

# large_size
@property
def large_size(self) -> OptionalNumber:
return self._get_attr("largeSize")

@large_size.setter
def large_size(self, value: OptionalNumber):
self._set_attr("largeSize", value)

# padding
@property
def padding(self) -> PaddingValue:
return self.__padding

@padding.setter
def padding(self, value: PaddingValue):
self.__padding = value

# small_size
@property
def small_size(self) -> OptionalNumber:
return self._get_attr("smallSize")

@small_size.setter
def small_size(self, value: OptionalNumber):
self._set_attr("smallSize", value)

# text_color
@property
def text_color(self):
return self._get_attr("textColor")

@text_color.setter
def text_color(self, value):
self._set_attr("textColor", value)

# text_style
@property
def text_style(self):
return self.__text_style

@text_style.setter
def text_style(self, value: Optional[TextStyle]):
self.__text_style = value