From ce81760ae45eb2f33e672f9c36a2a6ffa967f682 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 4 Mar 2024 07:40:07 +0100 Subject: [PATCH 01/10] CupertinoDatePicker: initial commit --- .../flet/lib/src/controls/create_control.dart | 8 +- .../src/controls/cupertino_date_picker.dart | 121 ++++++++ .../flet-core/src/flet_core/__init__.py | 5 + .../src/flet_core/cupertino_date_picker.py | 265 ++++++++++++++++++ 4 files changed, 398 insertions(+), 1 deletion(-) create mode 100644 packages/flet/lib/src/controls/cupertino_date_picker.dart create mode 100644 sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py diff --git a/packages/flet/lib/src/controls/create_control.dart b/packages/flet/lib/src/controls/create_control.dart index 0a9627123..72b592eaa 100644 --- a/packages/flet/lib/src/controls/create_control.dart +++ b/packages/flet/lib/src/controls/create_control.dart @@ -38,6 +38,7 @@ import 'cupertino_button.dart'; import 'cupertino_checkbox.dart'; import 'cupertino_context_menu.dart'; import 'cupertino_context_menu_action.dart'; +import 'cupertino_date_picker.dart'; import 'cupertino_dialog_action.dart'; import 'cupertino_list_tile.dart'; import 'cupertino_navigation_bar.dart'; @@ -500,7 +501,12 @@ Widget createWidget( return DatePickerControl( parent: parent, control: controlView.control, - children: controlView.children, + parentDisabled: parentDisabled, + backend: backend); + case "cupertinodatepicker": + return CupertinoDatePickerControl( + parent: parent, + control: controlView.control, parentDisabled: parentDisabled, backend: backend); case "timepicker": diff --git a/packages/flet/lib/src/controls/cupertino_date_picker.dart b/packages/flet/lib/src/controls/cupertino_date_picker.dart new file mode 100644 index 000000000..bfe1d4b5d --- /dev/null +++ b/packages/flet/lib/src/controls/cupertino_date_picker.dart @@ -0,0 +1,121 @@ +import 'package:collection/collection.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../flet_control_backend.dart'; +import '../models/control.dart'; +import '../utils/colors.dart'; + +class CupertinoDatePickerControl extends StatefulWidget { + final Control? parent; + final Control control; + final bool parentDisabled; + final FletControlBackend backend; + + const CupertinoDatePickerControl( + {super.key, + this.parent, + required this.control, + required this.parentDisabled, + required this.backend}); + + @override + State createState() => + _CupertinoDatePickerControlState(); +} + +class _CupertinoDatePickerControlState + extends State { + static const double _kItemExtent = 32.0; + + @override + Widget build(BuildContext context) { + debugPrint("CupertinoDatePicker build: ${widget.control.id}"); + + bool lastOpen = widget.control.state["open"] ?? false; + + var open = widget.control.attrBool("open", false)!; + bool showDayOfWeek = widget.control.attrBool("showDayOfWeek", false)!; + Color? bgcolor = HexColor.fromString( + Theme.of(context), widget.control.attrString("bgcolor", "")!); + DateTime? value = widget.control.attrDateTime("value"); + DateTime? firstDate = widget.control.attrDateTime("firstDate"); + DateTime? lastDate = widget.control.attrDateTime("lastDate"); + DateTime? currentDate = widget.control.attrDateTime("currentDate"); + int minimumYear = widget.control.attrInt("minimumYear", 1)!; + int? maximumYear = widget.control.attrInt("maximumYear"); + double itemExtent = widget.control.attrDouble("itemExtent", _kItemExtent)!; + int minuteInterval = widget.control.attrInt("minuteInterval", 1)!; + bool use24hFormat = widget.control.attrBool("use24hFormat", false)!; + + DatePickerDateOrder? dateOrder = DatePickerDateOrder.values + .firstWhereOrNull((a) => + a.name.toLowerCase() == + widget.control.attrString("dateOrder", "")!.toLowerCase()); + CupertinoDatePickerMode datePickerMode = CupertinoDatePickerMode.values + .firstWhere( + (a) => + a.name.toLowerCase() == + widget.control.attrString("datePickerMode", "")!.toLowerCase(), + orElse: () => CupertinoDatePickerMode.dateAndTime); + + void onClosed(DateTime? dateValue) { + String stringValue; + String eventName; + if (dateValue == null) { + stringValue = + value?.toIso8601String() ?? currentDate?.toIso8601String() ?? ""; + eventName = "dismiss"; + } else { + stringValue = dateValue.toIso8601String(); + eventName = "change"; + } + widget.control.state["open"] = false; + widget.backend.updateControlState( + widget.control.id, {"value": stringValue, "open": "false"}); + widget.backend + .triggerControlEvent(widget.control.id, eventName, stringValue); + } + + Widget createSelectDateDialog() { + Widget dialog = CupertinoDatePicker( + initialDateTime: value ?? currentDate, + showDayOfWeek: showDayOfWeek, + minimumDate: firstDate ?? DateTime(1900), + maximumDate: lastDate ?? DateTime(2050), + backgroundColor: bgcolor, + minimumYear: minimumYear, + maximumYear: maximumYear, + itemExtent: itemExtent, + minuteInterval: minuteInterval, + use24hFormat: use24hFormat, + dateOrder: dateOrder, + mode: datePickerMode, + onDateTimeChanged: (DateTime value) { + String stringValue = value.toIso8601String(); + widget.backend + .updateControlState(widget.control.id, {"value": stringValue}); + widget.backend + .triggerControlEvent(widget.control.id, "change", stringValue); + }, + ); + + return dialog; + } + + if (open && (open != lastOpen)) { + widget.control.state["open"] = open; + + WidgetsBinding.instance.addPostFrameCallback((_) { + showDialog( + useRootNavigator: false, + context: context, + builder: (context) => createSelectDateDialog()).then((result) { + debugPrint("pickDate() completed"); + onClosed(result); + }); + }); + } + return const SizedBox.shrink(); + } +} diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index 2688e958a..a12bbbba5 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -75,6 +75,11 @@ from flet_core.cupertino_checkbox import CupertinoCheckbox from flet_core.cupertino_context_menu import CupertinoContextMenu from flet_core.cupertino_context_menu_action import CupertinoContextMenuAction +from flet_core.cupertino_date_picker import ( + CupertinoDatePicker, + CupertinoDatePickerDateOrder, + CupertinoDatePickerMode, +) from flet_core.cupertino_dialog_action import CupertinoDialogAction from flet_core.cupertino_filled_button import CupertinoFilledButton from flet_core.cupertino_list_tile import CupertinoListTile diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py new file mode 100644 index 000000000..8b9e34b4b --- /dev/null +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py @@ -0,0 +1,265 @@ +from datetime import date, datetime +from enum import Enum +from typing import Any, Optional, Union + +from flet_core.control import Control, OptionalNumber +from flet_core.ref import Ref +from flet_core.types import ResponsiveNumber + +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal + + +class CupertinoDatePickerMode(Enum): + TIME = "time" + DATE = "date" + DATE_AND_TIME = "dateAndTime" + MONTH_YEAR = "monthYear" + + +class CupertinoDatePickerDateOrder(Enum): + DAY_MONTH_YEAR = "dmy" + MONTH_YEAR_DAY = "mdy" + YEAR_MONTH_DAY = "ymd" + YEAR_DAY_MONTH = "ydm" + + +class CupertinoDatePicker(Control): + """ + + + ----- + + Online docs: https://flet.dev/docs/controls/date_picker + """ + + def __init__( + self, + open: bool = False, + value: Optional[datetime] = None, + first_date: Optional[datetime] = None, + last_date: Optional[datetime] = None, + current_date: Optional[datetime] = None, + bgcolor: Optional[str] = None, + minute_interval: Optional[int] = None, + minimum_year: Optional[int] = None, + maximum_year: Optional[int] = None, + item_extent: OptionalNumber = None, + use_24h_format: Optional[bool] = None, + date_picker_mode: Optional[CupertinoDatePickerMode] = None, + date_order: Optional[CupertinoDatePickerDateOrder] = None, + on_change=None, + on_dismiss=None, + # + # ConstrainedControl + # + ref: Optional[Ref] = None, + expand: Optional[Union[bool, int]] = None, + expand_loose: Optional[bool] = None, + col: Optional[ResponsiveNumber] = None, + opacity: OptionalNumber = None, + tooltip: Optional[str] = None, + visible: Optional[bool] = None, + disabled: Optional[bool] = None, + data: Any = None, + ): + Control.__init__( + self, + ref=ref, + expand=expand, + expand_loose=expand_loose, + col=col, + opacity=opacity, + tooltip=tooltip, + visible=visible, + disabled=disabled, + data=data, + ) + self.value = value + self.bgcolor = bgcolor + self.minute_interval = minute_interval + self.maximum_year = maximum_year + self.minimum_year = minimum_year + self.item_extent = item_extent + self.first_date = first_date + self.use_24h_format = use_24h_format + self.last_date = last_date + self.current_date = current_date + self.date_picker_mode = date_picker_mode + self.date_order = date_order + self.on_change = on_change + self.on_dismiss = on_dismiss + self.open = open + + def _get_control_name(self): + return "cupertinodatepicker" + + def before_update(self): + super().before_update() + + def pick_date(self): + self.open = True + self.update() + + # open + @property + def open(self) -> Optional[bool]: + return self._get_attr("open", data_type="bool", def_value=False) + + @open.setter + def open(self, value: Optional[bool]): + self._set_attr("open", value) + + # value + @property + def value(self) -> Optional[datetime]: + value_string = self._get_attr("value", def_value=None) + return datetime.fromisoformat(value_string) if value_string else None + + @value.setter + def value(self, value: Optional[Union[datetime, str]]): + if isinstance(value, (date, datetime)): + value = value.isoformat() + self._set_attr("value", value) + + # first_date + @property + def first_date(self) -> Optional[datetime]: + value_string = self._get_attr("firstDate", def_value=None) + return ( + datetime.fromisoformat(value_string) if value_string is not None else None + ) + + @first_date.setter + def first_date(self, value: Optional[Union[datetime, str]]): + if isinstance(value, (date, datetime)): + value = value.isoformat() + self._set_attr("firstDate", value) + + # last_date + @property + def last_date(self) -> Optional[datetime]: + value_string = self._get_attr("lastDate", def_value=None) + return ( + datetime.fromisoformat(value_string) if value_string is not None else None + ) + + @last_date.setter + def last_date(self, value: Optional[Union[datetime, str]]): + if isinstance(value, (date, datetime)): + value = value.isoformat() + self._set_attr("lastDate", value) + + # current_date + @property + def current_date(self) -> Optional[datetime]: + value_string = self._get_attr("currentDate", def_value=None) + return ( + datetime.fromisoformat(value_string) if value_string is not None else None + ) + + @current_date.setter + def current_date(self, value: Optional[Union[datetime, str]]): + if isinstance(value, (date, datetime)): + value = value.isoformat() + self._set_attr("currentDate", value) + + # bgcolor + @property + def bgcolor(self) -> Optional[str]: + return self._get_attr("bgcolor") + + @bgcolor.setter + def bgcolor(self, value: Optional[str]): + self._set_attr("bgcolor", value) + + # item_extent + @property + def item_extent(self) -> OptionalNumber: + return self._get_attr("itemExtent", data_type="float", def_value=32.0) + + @item_extent.setter + def item_extent(self, value: OptionalNumber): + self._set_attr("itemExtent", value) + + # min_year + @property + def min_year(self) -> Optional[int]: + return self._get_attr("minYear", data_type="int", def_value=1) + + @min_year.setter + def min_year(self, value: Optional[int]): + self._set_attr("minYear", value) + + # max_year + @property + def max_year(self) -> Optional[int]: + return self._get_attr("maxYear", data_type="int") + + @max_year.setter + def max_year(self, value: Optional[int]): + self._set_attr("maxYear", value) + + # minute_interval + @property + def minute_interval(self) -> Optional[int]: + return self._get_attr("minuteInterval", data_type="int", def_value=1) + + @minute_interval.setter + def minute_interval(self, value: Optional[int]): + self._set_attr("minuteInterval", value) + + # use_24h_format + @property + def use_24h_format(self) -> Optional[int]: + return self._get_attr("use24hFormat", data_type="bool", def_value=False) + + @use_24h_format.setter + def use_24h_format(self, value: Optional[int]): + self._set_attr("use24hFormat", value) + + # date_picker_mode + @property + def date_picker_mode(self) -> Optional[CupertinoDatePickerMode]: + return self.__date_picker_mode + + @date_picker_mode.setter + def date_picker_mode(self, value: Optional[CupertinoDatePickerMode]): + self.__date_picker_mode = value + self._set_attr( + "datePickerMode", + value.value if isinstance(value, CupertinoDatePickerMode) else value, + ) + + # date_order + @property + def date_order(self) -> Optional[CupertinoDatePickerDateOrder]: + return self.__date_order + + @date_order.setter + def date_order(self, value: Optional[CupertinoDatePickerDateOrder]): + self.__date_order = value + self._set_attr( + "dateOrder", + value.value if isinstance(value, CupertinoDatePickerDateOrder) else value, + ) + + # on_change + @property + def on_change(self): + return self._get_event_handler("change") + + @on_change.setter + def on_change(self, handler): + self._add_event_handler("change", handler) + + # on_dismiss + @property + def on_dismiss(self): + return self._get_event_handler("dismiss") + + @on_dismiss.setter + def on_dismiss(self, handler): + self._add_event_handler("dismiss", handler) From d9272045ec9770be0a43cc44d391d5980a4b901d Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 4 Mar 2024 07:40:36 +0100 Subject: [PATCH 02/10] DatePicker: reformat --- .../flet/lib/src/controls/date_picker.dart | 2 - .../flet-core/src/flet_core/date_picker.py | 86 +++++++------------ 2 files changed, 32 insertions(+), 56 deletions(-) diff --git a/packages/flet/lib/src/controls/date_picker.dart b/packages/flet/lib/src/controls/date_picker.dart index 137be3340..27417c6f1 100644 --- a/packages/flet/lib/src/controls/date_picker.dart +++ b/packages/flet/lib/src/controls/date_picker.dart @@ -8,7 +8,6 @@ import 'form_field.dart'; class DatePickerControl extends StatefulWidget { final Control? parent; final Control control; - final List children; final bool parentDisabled; final FletControlBackend backend; @@ -16,7 +15,6 @@ class DatePickerControl extends StatefulWidget { {super.key, this.parent, required this.control, - required this.children, required this.parentDisabled, required this.backend}); diff --git a/sdk/python/packages/flet-core/src/flet_core/date_picker.py b/sdk/python/packages/flet-core/src/flet_core/date_picker.py index 08f966e83..9a39a0439 100644 --- a/sdk/python/packages/flet-core/src/flet_core/date_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/date_picker.py @@ -4,7 +4,6 @@ from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref -from flet_core.text_style import TextStyle from flet_core.textfield import KeyboardType from flet_core.types import ResponsiveNumber from flet_core.utils import deprecated @@ -35,42 +34,42 @@ class DatePicker(Control): Depending on the `date_picker_entry_mode`, it will show either a Calendar or an Input (TextField) for picking a date. - Example: - ``` - import datetime - import flet as ft + Example: + ``` + import datetime + import flet as ft - def main(page: ft.Page): - def change_date(e): - print(f"Date picker changed, value is {date_picker.value}") + def main(page: ft.Page): + def change_date(e): + print(f"Date picker changed, value is {date_picker.value}") - def date_picker_dismissed(e): - print(f"Date picker dismissed, value is {date_picker.value}") + def date_picker_dismissed(e): + print(f"Date picker dismissed, value is {date_picker.value}") - date_picker = ft.DatePicker( - on_change=change_date, - on_dismiss=date_picker_dismissed, - first_date=datetime.datetime(2023, 10, 1), - last_date=datetime.datetime(2024, 10, 1), - ) + date_picker = ft.DatePicker( + on_change=change_date, + on_dismiss=date_picker_dismissed, + first_date=datetime.datetime(2023, 10, 1), + last_date=datetime.datetime(2024, 10, 1), + ) - page.overlay.append(date_picker) + page.overlay.append(date_picker) - date_button = ft.ElevatedButton( - "Pick date", - icon=ft.icons.CALENDAR_MONTH, - on_click=lambda _: date_picker.pick_date(), - ) + date_button = ft.ElevatedButton( + "Pick date", + icon=ft.icons.CALENDAR_MONTH, + on_click=lambda _: date_picker.pick_date(), + ) - page.add(date_button) + page.add(date_button) - ft.app(target=main) - ``` + ft.app(target=main) + ``` - ----- + ----- - Online docs: https://flet.dev/docs/controls/date_picker + Online docs: https://flet.dev/docs/controls/datepicker """ def __init__( @@ -79,12 +78,10 @@ def __init__( value: Optional[datetime] = None, first_date: Optional[datetime] = None, last_date: Optional[datetime] = None, - text_style: Optional[TextStyle] = None, current_date: Optional[datetime] = None, keyboard_type: Optional[KeyboardType] = None, date_picker_mode: Optional[DatePickerMode] = None, date_picker_entry_mode: Optional[DatePickerEntryMode] = None, - # locale: Optional[str] = None, help_text: Optional[str] = None, cancel_text: Optional[str] = None, confirm_text: Optional[str] = None, @@ -134,7 +131,6 @@ def __init__( self.error_invalid_text = error_invalid_text self.date_picker_mode = date_picker_mode self.date_picker_entry_mode = date_picker_entry_mode - self.text_style = text_style self.field_hint_text = field_hint_text self.field_label_text = field_label_text self.switch_to_calendar_icon = switch_to_calendar_icon @@ -186,10 +182,7 @@ def value(self, value: Optional[Union[datetime, str]]): @property def first_date(self) -> Optional[datetime]: value_string = self._get_attr("firstDate", def_value=None) - if value_string is None: - return None - else: - return datetime.fromisoformat(value_string) + return datetime.fromisoformat(value_string) if value_string is not None else None @first_date.setter def first_date(self, value: Optional[Union[datetime, str]]): @@ -201,10 +194,7 @@ def first_date(self, value: Optional[Union[datetime, str]]): @property def last_date(self) -> Optional[datetime]: value_string = self._get_attr("lastDate", def_value=None) - if value_string is None: - return None - else: - return datetime.fromisoformat(value_string) + return datetime.fromisoformat(value_string) if value_string is not None else None @last_date.setter def last_date(self, value: Optional[Union[datetime, str]]): @@ -216,10 +206,7 @@ def last_date(self, value: Optional[Union[datetime, str]]): @property def current_date(self) -> Optional[datetime]: value_string = self._get_attr("currentDate", def_value=None) - if value_string is None: - return None - else: - return datetime.fromisoformat(value_string) + return datetime.fromisoformat(value_string) if value_string is not None else None @current_date.setter def current_date(self, value: Optional[Union[datetime, str]]): @@ -227,15 +214,6 @@ def current_date(self, value: Optional[Union[datetime, str]]): value = value.isoformat() self._set_attr("currentDate", value) - # # locale - # @property - # def locale(self) -> Optional[str]: - # return self._get_attr("locale", def_value=None) - - # @locale.setter - # def locale(self, value: Optional[str]): - # self._set_attr("locale", value) - # field_hint_text @property def field_hint_text(self) -> Optional[str]: @@ -307,7 +285,7 @@ def keyboard_type(self) -> Optional[KeyboardType]: @keyboard_type.setter def keyboard_type(self, value: Optional[KeyboardType]): self.__keyboard_type = value - self._set_attr("keyboardType", value.value if value is not None else None) + self._set_attr("keyboardType", value.value if isinstance(value, KeyboardType) else value) # date_picker_mode @property @@ -317,7 +295,7 @@ def date_picker_mode(self) -> Optional[DatePickerMode]: @date_picker_mode.setter def date_picker_mode(self, value: Optional[DatePickerMode]): self.__date_picker_mode = value - self._set_attr("datePickerMode", value.value if value is not None else None) + self._set_attr("datePickerMode", value.value if isinstance(value, DatePickerMode) else value) # date_picker_entry_mode @property @@ -328,7 +306,7 @@ def date_picker_entry_mode(self) -> Optional[DatePickerEntryMode]: def date_picker_entry_mode(self, value: Optional[DatePickerEntryMode]): self.__date_picker_entry_mode = value self._set_attr( - "datePickerEntryMode", value.value if value is not None else None + "datePickerEntryMode", value.value if isinstance(value, DatePickerEntryMode) else value ) # switch_to_calendar_icon From 2a199a038e99d3d18ed72f8a1ff70574b6001c2f Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 4 Mar 2024 07:40:54 +0100 Subject: [PATCH 03/10] CupertinoTimerPicker: cleanup --- .../flet-core/src/flet_core/cupertino_timer_picker.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py index 7db04538a..3f3c80024 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py @@ -1,15 +1,8 @@ from enum import Enum -from typing import Any, Optional, Union +from typing import Any, Optional from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref -from flet_core.types import ( - AnimationValue, - OffsetValue, - ResponsiveNumber, - RotateValue, - ScaleValue, -) class CupertinoTimerPickerMode(Enum): From 68f1425d3b7fd696097a1fcf9131115e086fd94b Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 5 Mar 2024 06:41:35 +0100 Subject: [PATCH 04/10] CupertinoDatePicker can be embedded in CupertinoBottomSheet --- .../src/controls/cupertino_date_picker.dart | 83 +++++------------- .../src/flet_core/cupertino_date_picker.py | 86 +++++++++++-------- .../src/flet_core/cupertino_timer_picker.py | 11 ++- 3 files changed, 82 insertions(+), 98 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_date_picker.dart b/packages/flet/lib/src/controls/cupertino_date_picker.dart index bfe1d4b5d..830f9da08 100644 --- a/packages/flet/lib/src/controls/cupertino_date_picker.dart +++ b/packages/flet/lib/src/controls/cupertino_date_picker.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/colors.dart'; +import 'create_control.dart'; class CupertinoDatePickerControl extends StatefulWidget { final Control? parent; @@ -32,9 +33,6 @@ class _CupertinoDatePickerControlState Widget build(BuildContext context) { debugPrint("CupertinoDatePicker build: ${widget.control.id}"); - bool lastOpen = widget.control.state["open"] ?? false; - - var open = widget.control.attrBool("open", false)!; bool showDayOfWeek = widget.control.attrBool("showDayOfWeek", false)!; Color? bgcolor = HexColor.fromString( Theme.of(context), widget.control.attrString("bgcolor", "")!); @@ -59,63 +57,28 @@ class _CupertinoDatePickerControlState widget.control.attrString("datePickerMode", "")!.toLowerCase(), orElse: () => CupertinoDatePickerMode.dateAndTime); - void onClosed(DateTime? dateValue) { - String stringValue; - String eventName; - if (dateValue == null) { - stringValue = - value?.toIso8601String() ?? currentDate?.toIso8601String() ?? ""; - eventName = "dismiss"; - } else { - stringValue = dateValue.toIso8601String(); - eventName = "change"; - } - widget.control.state["open"] = false; - widget.backend.updateControlState( - widget.control.id, {"value": stringValue, "open": "false"}); - widget.backend - .triggerControlEvent(widget.control.id, eventName, stringValue); - } - - Widget createSelectDateDialog() { - Widget dialog = CupertinoDatePicker( - initialDateTime: value ?? currentDate, - showDayOfWeek: showDayOfWeek, - minimumDate: firstDate ?? DateTime(1900), - maximumDate: lastDate ?? DateTime(2050), - backgroundColor: bgcolor, - minimumYear: minimumYear, - maximumYear: maximumYear, - itemExtent: itemExtent, - minuteInterval: minuteInterval, - use24hFormat: use24hFormat, - dateOrder: dateOrder, - mode: datePickerMode, - onDateTimeChanged: (DateTime value) { - String stringValue = value.toIso8601String(); - widget.backend - .updateControlState(widget.control.id, {"value": stringValue}); - widget.backend - .triggerControlEvent(widget.control.id, "change", stringValue); - }, - ); - - return dialog; - } - - if (open && (open != lastOpen)) { - widget.control.state["open"] = open; + Widget dialog = CupertinoDatePicker( + initialDateTime: value ?? currentDate, + showDayOfWeek: showDayOfWeek, + minimumDate: firstDate ?? DateTime(1900), + maximumDate: lastDate ?? DateTime(2050), + backgroundColor: bgcolor, + minimumYear: minimumYear, + maximumYear: maximumYear, + itemExtent: itemExtent, + minuteInterval: minuteInterval, + use24hFormat: use24hFormat, + dateOrder: dateOrder, + mode: datePickerMode, + onDateTimeChanged: (DateTime value) { + String stringValue = value.toIso8601String(); + widget.backend + .updateControlState(widget.control.id, {"value": stringValue}); + widget.backend + .triggerControlEvent(widget.control.id, "change", stringValue); + }, + ); - WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog( - useRootNavigator: false, - context: context, - builder: (context) => createSelectDateDialog()).then((result) { - debugPrint("pickDate() completed"); - onClosed(result); - }); - }); - } - return const SizedBox.shrink(); + return constrainedControl(context, dialog, widget.parent, widget.control); } } diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py index 8b9e34b4b..5ee15c4d1 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py @@ -2,9 +2,16 @@ from enum import Enum from typing import Any, Optional, Union -from flet_core.control import Control, OptionalNumber +from flet_core.constrained_control import ConstrainedControl +from flet_core.control import OptionalNumber from flet_core.ref import Ref -from flet_core.types import ResponsiveNumber +from flet_core.types import ( + AnimationValue, + OffsetValue, + ResponsiveNumber, + RotateValue, + ScaleValue, +) try: from typing import Literal @@ -26,18 +33,17 @@ class CupertinoDatePickerDateOrder(Enum): YEAR_DAY_MONTH = "ydm" -class CupertinoDatePicker(Control): +class CupertinoDatePicker(ConstrainedControl): """ - + An iOS-styled date picker. ----- - Online docs: https://flet.dev/docs/controls/date_picker + Online docs: https://flet.dev/docs/controls/cupertinodatepicker """ def __init__( self, - open: bool = False, value: Optional[datetime] = None, first_date: Optional[datetime] = None, last_date: Optional[datetime] = None, @@ -51,27 +57,62 @@ def __init__( date_picker_mode: Optional[CupertinoDatePickerMode] = None, date_order: Optional[CupertinoDatePickerDateOrder] = None, on_change=None, - on_dismiss=None, # # ConstrainedControl # ref: Optional[Ref] = None, - expand: Optional[Union[bool, int]] = None, + key: Optional[str] = None, + width: OptionalNumber = None, + height: OptionalNumber = None, + left: OptionalNumber = None, + top: OptionalNumber = None, + right: OptionalNumber = None, + bottom: OptionalNumber = None, + expand: Union[None, bool, int] = None, expand_loose: Optional[bool] = None, col: Optional[ResponsiveNumber] = None, opacity: OptionalNumber = None, + rotate: RotateValue = None, + scale: ScaleValue = None, + offset: OffsetValue = None, + aspect_ratio: OptionalNumber = None, + animate_opacity: AnimationValue = None, + animate_size: AnimationValue = None, + animate_position: AnimationValue = None, + animate_rotation: AnimationValue = None, + animate_scale: AnimationValue = None, + animate_offset: AnimationValue = None, + on_animation_end=None, tooltip: Optional[str] = None, visible: Optional[bool] = None, disabled: Optional[bool] = None, data: Any = None, ): - Control.__init__( + ConstrainedControl.__init__( self, ref=ref, + key=key, + width=width, + height=height, + left=left, + top=top, + right=right, + bottom=bottom, expand=expand, expand_loose=expand_loose, col=col, opacity=opacity, + rotate=rotate, + scale=scale, + offset=offset, + aspect_ratio=aspect_ratio, + animate_opacity=animate_opacity, + animate_size=animate_size, + animate_position=animate_position, + animate_rotation=animate_rotation, + animate_scale=animate_scale, + animate_offset=animate_offset, + on_animation_end=on_animation_end, tooltip=tooltip, visible=visible, disabled=disabled, @@ -90,28 +131,10 @@ def __init__( self.date_picker_mode = date_picker_mode self.date_order = date_order self.on_change = on_change - self.on_dismiss = on_dismiss - self.open = open def _get_control_name(self): return "cupertinodatepicker" - def before_update(self): - super().before_update() - - def pick_date(self): - self.open = True - self.update() - - # open - @property - def open(self) -> Optional[bool]: - return self._get_attr("open", data_type="bool", def_value=False) - - @open.setter - def open(self, value: Optional[bool]): - self._set_attr("open", value) - # value @property def value(self) -> Optional[datetime]: @@ -254,12 +277,3 @@ def on_change(self): @on_change.setter def on_change(self, handler): self._add_event_handler("change", handler) - - # on_dismiss - @property - def on_dismiss(self): - return self._get_event_handler("dismiss") - - @on_dismiss.setter - def on_dismiss(self, handler): - self._add_event_handler("dismiss", handler) diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py index 85ce371ae..ee37edd66 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py @@ -1,9 +1,16 @@ from enum import Enum -from typing import Any, Optional +from typing import Any, Optional, Union from flet_core.constrained_control import ConstrainedControl -from flet_core.control import Control, OptionalNumber +from flet_core.control import OptionalNumber from flet_core.ref import Ref +from flet_core.types import ( + AnimationValue, + OffsetValue, + ResponsiveNumber, + RotateValue, + ScaleValue, +) class CupertinoTimerPickerMode(Enum): From 52cedeef6579ec68236a8b41cb1c3f5961156222 Mon Sep 17 00:00:00 2001 From: TheEthicalBoy <98978078+ndonkoHenri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:34:24 +0100 Subject: [PATCH 05/10] fix DateOrder --- .../packages/flet-core/src/flet_core/cupertino_date_picker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py index 5ee15c4d1..023b7282d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py @@ -28,7 +28,7 @@ class CupertinoDatePickerMode(Enum): class CupertinoDatePickerDateOrder(Enum): DAY_MONTH_YEAR = "dmy" - MONTH_YEAR_DAY = "mdy" + MONTH_YEAR_DAY = "myd" YEAR_MONTH_DAY = "ymd" YEAR_DAY_MONTH = "ydm" From fb908cae4f21d42c6d6a2b1e286cbf07836d8418 Mon Sep 17 00:00:00 2001 From: TheEthicalBoy <98978078+ndonkoHenri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:43:00 +0000 Subject: [PATCH 06/10] remove current_date + catch assertion errors --- .../src/controls/cupertino_date_picker.dart | 13 +++++++----- .../src/flet_core/cupertino_date_picker.py | 20 ++++--------------- .../flet_core/cupertino_segmented_button.py | 1 + 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_date_picker.dart b/packages/flet/lib/src/controls/cupertino_date_picker.dart index 830f9da08..2ee6e4cf7 100644 --- a/packages/flet/lib/src/controls/cupertino_date_picker.dart +++ b/packages/flet/lib/src/controls/cupertino_date_picker.dart @@ -39,7 +39,6 @@ class _CupertinoDatePickerControlState DateTime? value = widget.control.attrDateTime("value"); DateTime? firstDate = widget.control.attrDateTime("firstDate"); DateTime? lastDate = widget.control.attrDateTime("lastDate"); - DateTime? currentDate = widget.control.attrDateTime("currentDate"); int minimumYear = widget.control.attrInt("minimumYear", 1)!; int? maximumYear = widget.control.attrInt("maximumYear"); double itemExtent = widget.control.attrDouble("itemExtent", _kItemExtent)!; @@ -57,11 +56,12 @@ class _CupertinoDatePickerControlState widget.control.attrString("datePickerMode", "")!.toLowerCase(), orElse: () => CupertinoDatePickerMode.dateAndTime); - Widget dialog = CupertinoDatePicker( - initialDateTime: value ?? currentDate, + try { + Widget dialog = CupertinoDatePicker( + initialDateTime: value, showDayOfWeek: showDayOfWeek, - minimumDate: firstDate ?? DateTime(1900), - maximumDate: lastDate ?? DateTime(2050), + minimumDate: firstDate, + maximumDate: lastDate, backgroundColor: bgcolor, minimumYear: minimumYear, maximumYear: maximumYear, @@ -78,6 +78,9 @@ class _CupertinoDatePickerControlState .triggerControlEvent(widget.control.id, "change", stringValue); }, ); + } catch (e) { + return ErrorControl(e.toString()); + } return constrainedControl(context, dialog, widget.parent, widget.control); } diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py index 023b7282d..4c4a62eeb 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py @@ -47,7 +47,6 @@ def __init__( value: Optional[datetime] = None, first_date: Optional[datetime] = None, last_date: Optional[datetime] = None, - current_date: Optional[datetime] = None, bgcolor: Optional[str] = None, minute_interval: Optional[int] = None, minimum_year: Optional[int] = None, @@ -127,7 +126,6 @@ def __init__( self.first_date = first_date self.use_24h_format = use_24h_format self.last_date = last_date - self.current_date = current_date self.date_picker_mode = date_picker_mode self.date_order = date_order self.on_change = on_change @@ -175,20 +173,6 @@ def last_date(self, value: Optional[Union[datetime, str]]): value = value.isoformat() self._set_attr("lastDate", value) - # current_date - @property - def current_date(self) -> Optional[datetime]: - value_string = self._get_attr("currentDate", def_value=None) - return ( - datetime.fromisoformat(value_string) if value_string is not None else None - ) - - @current_date.setter - def current_date(self, value: Optional[Union[datetime, str]]): - if isinstance(value, (date, datetime)): - value = value.isoformat() - self._set_attr("currentDate", value) - # bgcolor @property def bgcolor(self) -> Optional[str]: @@ -205,6 +189,8 @@ def item_extent(self) -> OptionalNumber: @item_extent.setter def item_extent(self, value: OptionalNumber): + if value is not None and value<0: + raise ValueError("item_extent must be greater than 0") self._set_attr("itemExtent", value) # min_year @@ -232,6 +218,8 @@ def minute_interval(self) -> Optional[int]: @minute_interval.setter def minute_interval(self, value: Optional[int]): + if value is not None and (value < 0 or 60 % value != 0): + raise ValueError("minute_interval must be a positive integer factor of 60") self._set_attr("minuteInterval", value) # use_24h_format diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py index b973843fe..5d2419087 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py @@ -15,6 +15,7 @@ class CupertinoSegmentedButton(ConstrainedControl): """ + An iOS-style segmented button. ----- From 5cbb164d2f79d0df11701b3cbbf7b378006a2424 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Wed, 6 Mar 2024 06:43:02 +0100 Subject: [PATCH 07/10] fix try catch --- .../src/controls/cupertino_date_picker.dart | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_date_picker.dart b/packages/flet/lib/src/controls/cupertino_date_picker.dart index 2ee6e4cf7..88e713a51 100644 --- a/packages/flet/lib/src/controls/cupertino_date_picker.dart +++ b/packages/flet/lib/src/controls/cupertino_date_picker.dart @@ -6,6 +6,7 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/colors.dart'; import 'create_control.dart'; +import 'error.dart'; class CupertinoDatePickerControl extends StatefulWidget { final Control? parent; @@ -56,30 +57,31 @@ class _CupertinoDatePickerControlState widget.control.attrString("datePickerMode", "")!.toLowerCase(), orElse: () => CupertinoDatePickerMode.dateAndTime); + Widget dialog; try { - Widget dialog = CupertinoDatePicker( - initialDateTime: value, - showDayOfWeek: showDayOfWeek, - minimumDate: firstDate, - maximumDate: lastDate, - backgroundColor: bgcolor, - minimumYear: minimumYear, - maximumYear: maximumYear, - itemExtent: itemExtent, - minuteInterval: minuteInterval, - use24hFormat: use24hFormat, - dateOrder: dateOrder, - mode: datePickerMode, - onDateTimeChanged: (DateTime value) { - String stringValue = value.toIso8601String(); - widget.backend - .updateControlState(widget.control.id, {"value": stringValue}); - widget.backend - .triggerControlEvent(widget.control.id, "change", stringValue); - }, - ); + dialog = CupertinoDatePicker( + initialDateTime: value, + showDayOfWeek: showDayOfWeek, + minimumDate: firstDate, + maximumDate: lastDate, + backgroundColor: bgcolor, + minimumYear: minimumYear, + maximumYear: maximumYear, + itemExtent: itemExtent, + minuteInterval: minuteInterval, + use24hFormat: use24hFormat, + dateOrder: dateOrder, + mode: datePickerMode, + onDateTimeChanged: (DateTime value) { + String stringValue = value.toIso8601String(); + widget.backend + .updateControlState(widget.control.id, {"value": stringValue}); + widget.backend + .triggerControlEvent(widget.control.id, "change", stringValue); + }, + ); } catch (e) { - return ErrorControl(e.toString()); + return ErrorControl("CupertinoDatePicker Error: ${e.toString()}"); } return constrainedControl(context, dialog, widget.parent, widget.control); From 8c80433591a0595243df51d45a99242ef57d8889 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Wed, 6 Mar 2024 07:18:15 +0100 Subject: [PATCH 08/10] uniform action buttons --- .../cupertino_action_sheet_action.dart | 15 ++++--- .../cupertino_context_menu_action.dart | 9 ++-- .../cupertino_action_sheet_action.py | 45 ++++++++++++------- .../cupertino_context_menu_action.py | 34 +++++++------- 4 files changed, 61 insertions(+), 42 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_action_sheet_action.dart b/packages/flet/lib/src/controls/cupertino_action_sheet_action.dart index 1add3d261..28517a3d6 100644 --- a/packages/flet/lib/src/controls/cupertino_action_sheet_action.dart +++ b/packages/flet/lib/src/controls/cupertino_action_sheet_action.dart @@ -27,6 +27,7 @@ class CupertinoActionSheetActionControl extends StatelessWidget { debugPrint("CupertinoActionSheetActionControl build: ${control.id}"); bool disabled = control.isDisabled || parentDisabled; + String text = control.attrString("text", "")!; var contentCtrls = children.where((c) => c.name == "content" && c.isVisible); if (contentCtrls.isEmpty) { @@ -37,13 +38,17 @@ class CupertinoActionSheetActionControl extends StatelessWidget { return constrainedControl( context, CupertinoActionSheetAction( - isDefaultAction: control.attrBool("default", false)!, - isDestructiveAction: control.attrBool("destructive", false)!, + isDefaultAction: control.attrBool("isDefaultAction", false)!, + isDestructiveAction: control.attrBool("isDestructiveAction", false)!, onPressed: () { - backend.triggerControlEvent(control.id, "click", ""); + if (!disabled) { + backend.triggerControlEvent(control.id, "click"); + } }, - child: createControl(control, contentCtrls.first.id, disabled, - parentAdaptive: parentAdaptive), + child: contentCtrls.isNotEmpty + ? createControl(control, contentCtrls.first.id, disabled, + parentAdaptive: parentAdaptive) + : Text(text), ), parent, control); diff --git a/packages/flet/lib/src/controls/cupertino_context_menu_action.dart b/packages/flet/lib/src/controls/cupertino_context_menu_action.dart index 5faaedebf..743578d2f 100644 --- a/packages/flet/lib/src/controls/cupertino_context_menu_action.dart +++ b/packages/flet/lib/src/controls/cupertino_context_menu_action.dart @@ -54,10 +54,13 @@ class _CupertinoContextMenuActionControlState : Text(text, overflow: TextOverflow.ellipsis)); return CupertinoContextMenuAction( - isDefaultAction: widget.control.attrBool("default", false)!, - isDestructiveAction: widget.control.attrBool("destructive", false)!, + isDefaultAction: widget.control.attrBool("isDefaultAction", false)!, + isDestructiveAction: + widget.control.attrBool("isDestructiveAction", false)!, onPressed: () { - widget.backend.triggerControlEvent(widget.control.id, "click", ""); + if (!disabled) { + widget.backend.triggerControlEvent(widget.control.id, "click"); + } }, trailingIcon: trailingIcon, child: child, diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_action_sheet_action.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_action_sheet_action.py index 49c848aeb..3bb5b35fc 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_action_sheet_action.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_action_sheet_action.py @@ -23,9 +23,10 @@ class CupertinoActionSheetAction(ConstrainedControl): def __init__( self, - content: Control, - default: Optional[bool] = None, - destructive: Optional[bool] = None, + text: Optional[str] = None, + content: Optional[Control] = None, + is_default_action: Optional[bool] = None, + is_destructive_action: Optional[bool] = None, on_click=None, # # ConstrainedControl @@ -89,9 +90,10 @@ def __init__( data=data, ) + self.text = text self.content = content - self.default = default - self.destructive = destructive + self.is_default_action = is_default_action + self.is_destructive_action = is_destructive_action self.on_click = on_click def _get_control_name(self): @@ -107,23 +109,32 @@ def _get_children(self): children.append(self.__content) return children - # default + # text @property - def default(self) -> Optional[bool]: - return self._get_attr("default", data_type="bool", def_value=False) + def text(self): + return self._get_attr("text") - @default.setter - def default(self, value: Optional[bool]): - self._set_attr("default", value) + @text.setter + def text(self, value): + self._set_attr("text", value) - # destructive + # is_default_action @property - def destructive(self) -> Optional[bool]: - return self._get_attr("destructive", data_type="bool", def_value=False) + def is_default_action(self) -> Optional[bool]: + return self._get_attr("isDefaultAction") - @destructive.setter - def destructive(self, value: Optional[bool]): - self._set_attr("destructive", value) + @is_default_action.setter + def is_default_action(self, value: Optional[bool]): + self._set_attr("isDefaultAction", value) + + # is_destructive_action + @property + def is_destructive_action(self) -> Optional[bool]: + return self._get_attr("isDestructiveAction") + + @is_destructive_action.setter + def is_destructive_action(self, value: Optional[bool]): + self._set_attr("isDestructiveAction", value) # content @property diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_context_menu_action.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_context_menu_action.py index 2faf342ef..0b1b11a1a 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_context_menu_action.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_context_menu_action.py @@ -16,11 +16,11 @@ class CupertinoContextMenuAction(AdaptiveControl): def __init__( self, - content: Optional[Control] = None, text: Optional[str] = None, + content: Optional[Control] = None, + is_default_action: Optional[bool] = None, + is_destructive_action: Optional[bool] = None, trailing_icon: Optional[str] = None, - default: Optional[bool] = None, - destructive: Optional[bool] = None, on_click=None, # # Control @@ -41,8 +41,8 @@ def __init__( AdaptiveControl.__init__(self, adaptive=adaptive) - self.default = default - self.destructive = destructive + self.is_default_action = is_default_action + self.is_destructive_action = is_destructive_action self.content = content self.trailing_icon = trailing_icon self.on_click = on_click @@ -54,23 +54,23 @@ def _get_control_name(self): def _get_children(self): return [self.__content] if self.__content else [] - # default + # is_default_action @property - def default(self) -> Optional[bool]: - return self._get_attr("default", data_type="bool", def_value=False) + def is_default_action(self) -> Optional[bool]: + return self._get_attr("isDefaultAction", data_type="bool", def_value=False) - @default.setter - def default(self, value: Optional[bool]): - self._set_attr("default", value) + @is_default_action.setter + def is_default_action(self, value: Optional[bool]): + self._set_attr("isDefaultAction", value) - # destructive + # is_destructive_action @property - def destructive(self) -> Optional[bool]: - return self._get_attr("destructive", data_type="bool", def_value=False) + def is_destructive_action(self) -> Optional[bool]: + return self._get_attr("isDestructiveAction", data_type="bool", def_value=False) - @destructive.setter - def destructive(self, value: Optional[bool]): - self._set_attr("destructive", value) + @is_destructive_action.setter + def is_destructive_action(self, value: Optional[bool]): + self._set_attr("isDestructiveAction", value) # trailing_icon @property From 3d1a867da38b228b69e8f0d0953fe63b50181bd8 Mon Sep 17 00:00:00 2001 From: TheEthicalBoy <98978078+ndonkoHenri@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:21:07 +0000 Subject: [PATCH 09/10] remove Container.on_tap --- packages/flet/lib/src/controls/container.dart | 20 ++++--------------- .../flet-core/src/flet_core/container.py | 20 ++----------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/packages/flet/lib/src/controls/container.dart b/packages/flet/lib/src/controls/container.dart index f9c59cb69..6e53d700b 100644 --- a/packages/flet/lib/src/controls/container.dart +++ b/packages/flet/lib/src/controls/container.dart @@ -66,7 +66,6 @@ class ContainerControl extends StatelessWidget with FletStoreMixin { children.where((c) => c.name == "content" && c.isVisible); bool ink = control.attrBool("ink", false)!; bool onClick = control.attrBool("onclick", false)!; - bool onTap = control.attrBool("ontap", false)!; String url = control.attrString("url", "")!; String? urlTarget = control.attrString("urlTarget"); bool onLongPress = control.attrBool("onLongPress", false)!; @@ -146,7 +145,7 @@ class ContainerControl extends StatelessWidget with FletStoreMixin { Widget? result; - if ((onTap || onClick || url != "" || onLongPress || onHover) && + if ((onClick || url != "" || onLongPress || onHover) && ink && !disabled) { var ink = Material( @@ -156,12 +155,7 @@ class ContainerControl extends StatelessWidget with FletStoreMixin { // Dummy callback to enable widget // see https://github.com/flutter/flutter/issues/50116#issuecomment-582047374 // and https://github.com/flutter/flutter/blob/eed80afe2c641fb14b82a22279d2d78c19661787/packages/flutter/lib/src/material/ink_well.dart#L1125-L1129 - onTap: onTap - ? () { - debugPrint("Container ${control.id} Tap!"); - backend.triggerControlEvent(control.id, "tap", ""); - } - : null, + onTap: onHover ? () {} : null, onTapDown: onClick || url != "" ? (details) { debugPrint("Container ${control.id} clicked!"); @@ -257,10 +251,10 @@ class ContainerControl extends StatelessWidget with FletStoreMixin { : null, child: child); - if ((onTap || onClick || onLongPress || onHover || url != "") && + if ((onClick || onLongPress || onHover || url != "") && !disabled) { result = MouseRegion( - cursor: onTap || onClick || url != "" + cursor: onClick || url != "" ? SystemMouseCursors.click : MouseCursor.defer, onEnter: onHover @@ -278,12 +272,6 @@ class ContainerControl extends StatelessWidget with FletStoreMixin { } : null, child: GestureDetector( - onTap: onTap - ? () { - debugPrint("Container ${control.id} onTap!"); - backend.triggerControlEvent(control.id, "ontap", ""); - } - : null, onTapDown: onClick || url != "" ? (details) { debugPrint("Container ${control.id} clicked!"); diff --git a/sdk/python/packages/flet-core/src/flet_core/container.py b/sdk/python/packages/flet-core/src/flet_core/container.py index 2642c491b..90cf7999d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/container.py +++ b/sdk/python/packages/flet-core/src/flet_core/container.py @@ -118,7 +118,6 @@ def __init__( url_target: Optional[str] = None, theme: Optional[Theme] = None, theme_mode: Optional[ThemeMode] = None, - on_release=None, on_click=None, on_long_press=None, on_hover=None, @@ -165,8 +164,6 @@ def convert_container_tap_event_data(e): d = json.loads(e.data) return ContainerTapEvent(**d) - self.__on_release = EventHandler(convert_container_tap_event_data) - self._add_event_handler("tap", self.__on_release.get_handler()) self.__on_click = EventHandler(convert_container_tap_event_data) self._add_event_handler("click", self.__on_click.get_handler()) @@ -195,7 +192,6 @@ def convert_container_tap_event_data(e): self.url_target = url_target self.theme = theme self.theme_mode = theme_mode - self.on_release = on_release self.on_click = on_click self.on_long_press = on_long_press self.on_hover = on_hover @@ -472,16 +468,6 @@ def theme_mode(self, value: Optional[ThemeMode]): self.__theme_mode = value self._set_attr("themeMode", value.value if value is not None else None) - # on_release - @property - def on_release(self): - return self._get_event_handler("tap") - - @on_release.setter - def on_release(self, handler): - self._add_event_handler("tap", handler) - self._set_attr("onTap", True if handler is not None else None) - # on_click @property def on_click(self): @@ -490,10 +476,8 @@ def on_click(self): @on_click.setter def on_click(self, handler): self.__on_click.subscribe(handler) - if handler is not None: - self._set_attr("onclick", True) - else: - self._set_attr("onclick", None) + self._set_attr("onClick", True if handler is not None else None) + # on_long_press @property From e66acc477bd143e0d8cd7fc08aaceb79097651e3 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Wed, 6 Mar 2024 09:53:43 -0800 Subject: [PATCH 10/10] Remove unused imports --- .../flet-core/src/flet_core/cupertino_date_picker.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py index 4c4a62eeb..87ec49125 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_date_picker.py @@ -13,11 +13,6 @@ ScaleValue, ) -try: - from typing import Literal -except ImportError: - from typing_extensions import Literal - class CupertinoDatePickerMode(Enum): TIME = "time" @@ -189,7 +184,7 @@ def item_extent(self) -> OptionalNumber: @item_extent.setter def item_extent(self, value: OptionalNumber): - if value is not None and value<0: + if value is not None and value < 0: raise ValueError("item_extent must be greater than 0") self._set_attr("itemExtent", value)