Skip to content

Commit

Permalink
Badge control (#2037)
Browse files Browse the repository at this point in the history
* Badge initial commit

* label and content properties

* offset property

* alignment property

* bgcolor property

* label_visible property

* fixed label bug; small_size, large_size, text_color properties

* text_style property

* removed commented code

* example for Badge

* removed comments
  • Loading branch information
InesaFitsner authored Nov 6, 2023
1 parent b709ff8 commit 45a9356
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 0 deletions.
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

0 comments on commit 45a9356

Please sign in to comment.