From 0ec33947bfd54ae5082af0cb71d02cfb2ef71ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Larivi=C3=A8re?= Date: Wed, 13 Nov 2024 18:22:18 +0100 Subject: [PATCH 1/6] Clean up code for Mvu & Component split . --- Directory.Packages.props | 16 +- Fabulous.MauiControls.sln | 6 + src/Fabulous.MauiControls/Attributes.fs | 196 +++++----- .../Fabulous.MauiControls.fsproj | 177 ++++++--- .../Views/Application.fs | 302 --------------- .../Application/Application.Component.fs | 102 ++++++ .../Views/Application/Application.Mvu.fs | 101 +++++ .../Views/Application/Application.fs | 121 ++++++ .../Cells/EntryCell/EntryCell.Component.fs | 36 ++ .../Views/Cells/EntryCell/EntryCell.Mvu.fs | 37 ++ .../Views/Cells/{ => EntryCell}/EntryCell.fs | 52 --- .../Views/Cells/SwitchCell.fs | 64 ---- .../Cells/SwitchCell/SwitchCell.Component.fs | 22 ++ .../Views/Cells/SwitchCell/SwitchCell.Mvu.fs | 23 ++ .../Views/Cells/SwitchCell/SwitchCell.fs | 33 ++ .../Views/Cells/_Cell.fs | 118 ------ .../Views/Cells/_Cell/Cell.Component.fs | 38 ++ .../Views/Cells/_Cell/Cell.Mvu.fs | 38 ++ .../Views/Cells/_Cell/Cell.fs | 58 +++ .../CollectionView.Component.fs | 19 + .../CollectionView/CollectionView.Mvu.fs | 18 + .../{ => CollectionView}/CollectionView.fs | 22 -- .../ListView/ListView.Component.fs | 78 ++++ .../Collections/ListView/ListView.Mvu.fs | 78 ++++ .../Collections/{ => ListView}/ListView.fs | 140 ------- .../Views/Collections/_ItemsView.fs | 136 ------- .../_ItemsView/ItemsView.Component.fs | 41 +++ .../Collections/_ItemsView/ItemsView.Mvu.fs | 41 +++ .../Views/Collections/_ItemsView/ItemsView.fs | 70 ++++ .../Views/Controls/Button/Button.Component.fs | 40 ++ .../Views/Controls/Button/Button.Mvu.fs | 41 +++ .../Views/Controls/{ => Button}/Button.fs | 62 ---- .../Views/Controls/CheckBox.fs | 60 --- .../Controls/CheckBox/CheckBox.Component.fs | 21 ++ .../Views/Controls/CheckBox/CheckBox.Mvu.fs | 23 ++ .../Views/Controls/CheckBox/CheckBox.fs | 30 ++ .../Views/Controls/DatePicker.fs | 250 ------------- .../DatePicker/DatePicker.Component.fs | 72 ++++ .../Controls/DatePicker/DatePicker.Mvu.fs | 75 ++++ .../Views/Controls/DatePicker/DatePicker.fs | 118 ++++++ .../Views/Controls/Editor/Editor.Component.fs | 31 ++ .../Views/Controls/Editor/Editor.Mvu.fs | 31 ++ .../Views/Controls/{ => Editor}/Editor.fs | 42 --- .../Views/Controls/Entry/Entry.Component.fs | 31 ++ .../Views/Controls/Entry/Entry.Mvu.fs | 32 ++ .../Views/Controls/{ => Entry}/Entry.fs | 42 --- .../Views/Controls/GraphicsView.fs | 167 --------- .../GraphicsView/GraphicsView.Component.fs | 78 ++++ .../Controls/GraphicsView/GraphicsView.Mvu.fs | 78 ++++ .../Controls/GraphicsView/GraphicsView.fs | 24 ++ .../Views/Controls/ImageButton.fs | 345 ------------------ .../ImageButton/ImageButton.Component.fs | 126 +++++++ .../Controls/ImageButton/ImageButton.Mvu.fs | 126 +++++++ .../Views/Controls/ImageButton/ImageButton.fs | 117 ++++++ .../Views/Controls/Picker/Picker.Component.fs | 26 ++ .../Views/Controls/Picker/Picker.Mvu.fs | 26 ++ .../Views/Controls/{ => Picker}/Picker.fs | 44 +-- .../RadioButton/RadioButton.Component.fs | 43 +++ .../Controls/RadioButton/RadioButton.Mvu.fs | 42 +++ .../Controls/{ => RadioButton}/RadioButton.fs | 70 ---- .../Controls/SearchBar/SearchBar.Component.fs | 23 ++ .../Views/Controls/SearchBar/SearchBar.Mvu.fs | 23 ++ .../Controls/{ => SearchBar}/SearchBar.fs | 32 -- .../Views/Controls/Slider/Slider.Component.fs | 47 +++ .../Views/Controls/Slider/Slider.Mvu.fs | 47 +++ .../Views/Controls/{ => Slider}/Slider.fs | 76 +--- .../Controls/Stepper/Stepper.Component.fs | 24 ++ .../Views/Controls/Stepper/Stepper.Mvu.fs | 25 ++ .../Views/Controls/{ => Stepper}/Stepper.fs | 34 -- .../Views/Controls/Switch/Switch.Component.fs | 21 ++ .../Views/Controls/Switch/Switch.Mvu.fs | 21 ++ .../Views/Controls/{ => Switch}/Switch.fs | 28 -- .../TimePicker/TimePicker.Component.fs | 22 ++ .../Controls/TimePicker/TimePicker.Mvu.fs | 22 ++ .../Controls/{ => TimePicker}/TimePicker.fs | 28 -- .../Controls/WebView/WebView.Component.fs | 28 ++ .../Views/Controls/WebView/WebView.Mvu.fs | 28 ++ .../Views/Controls/{ => WebView}/WebView.fs | 40 -- .../_InputView/InputView.Component.fs | 8 + .../Controls/_InputView/InputView.Mvu.fs | 8 + .../InputView.fs} | 8 - .../DragGestureRecognizer.fs | 77 ---- .../DragGestureRecognizer.Component.fs | 30 ++ .../DragGestureRecognizer.Mvu.fs | 37 ++ .../DragGestureRecognizer.fs | 29 ++ .../DropGestureRecognizer.fs | 101 ----- .../DropGestureRecognizer.Component.fs | 40 ++ .../DropGestureRecognizer.Mvu.fs | 51 +++ .../DropGestureRecognizer.fs | 30 ++ .../PanGestureRecognizer.Component.fs | 17 + .../PanGestureRecognizer.Mvu.fs | 20 + .../PanGestureRecognizer.fs | 25 +- .../PinchGestureRecognizer.fs | 45 --- .../PinchGestureRecognizer.Component.fs | 17 + .../PinchGestureRecognizer.Mvu.fs | 21 ++ .../PinchGestureRecognizer.fs | 20 + .../SwipeGestureRecognizer.Component.fs | 21 ++ .../SwipeGestureRecognizer.Mvu.fs | 21 ++ .../SwipeGestureRecognizer.fs | 26 -- .../TapGestureRecognizer.Component.fs | 16 + .../TapGestureRecognizer.Mvu.fs | 16 + .../TapGestureRecognizer.fs | 20 - .../Views/Layouts/FlexLayout.fs | 2 - .../Views/Layouts/RefreshView.fs | 71 ---- .../RefreshView/RefreshView.Component.fs | 27 ++ .../Layouts/RefreshView/RefreshView.Mvu.fs | 27 ++ .../Views/Layouts/RefreshView/RefreshView.fs | 32 ++ .../ScrollView/ScrollView.Component.fs | 18 + .../Layouts/ScrollView/ScrollView.Mvu.fs | 18 + .../Layouts/{ => ScrollView}/ScrollView.fs | 20 - .../Layouts/SwipeItem/SwipeItem.Component.fs | 16 + .../Views/Layouts/SwipeItem/SwipeItem.Mvu.fs | 17 + .../Layouts/{ => SwipeItem}/SwipeItem.fs | 20 - .../Views/Layouts/SwipeView.fs | 174 --------- .../Layouts/SwipeView/SwipeView.Component.fs | 58 +++ .../Views/Layouts/SwipeView/SwipeView.Mvu.fs | 58 +++ .../Views/Layouts/SwipeView/SwipeView.fs | 74 ++++ .../MenuFlyoutItem.Component.fs | 12 + .../MenuFlyoutItem/MenuFlyoutItem.Mvu.fs | 13 + .../{ => MenuFlyoutItem}/MenuFlyoutItem.fs | 16 - .../MenuItems/MenuItem/MenuItem.Component.fs | 17 + .../Views/MenuItems/MenuItem/MenuItem.Mvu.fs | 18 + .../MenuItems/{ => MenuItem}/MenuItem.fs | 29 +- .../ToolbarItem/ToolbarItem.Component.fs | 13 + .../MenuItems/ToolbarItem/ToolbarItem.Mvu.fs | 13 + .../{ => ToolbarItem}/ToolbarItem.fs | 16 - .../ContentPage/ContentPage.Component.fs | 17 + .../Pages/ContentPage/ContentPage.Mvu.fs | 17 + .../Pages/{ => ContentPage}/ContentPage.fs | 22 +- .../Pages/FlyoutPage/FlyoutPage.Component.fs | 30 ++ .../Views/Pages/FlyoutPage/FlyoutPage.Mvu.fs | 30 ++ .../Pages/{ => FlyoutPage}/FlyoutPage.fs | 46 +-- .../NavigationPage.Component.fs | 30 ++ .../NavigationPage/NavigationPage.Mvu.fs | 28 ++ .../{ => NavigationPage}/NavigationPage.fs | 44 +-- .../Views/Pages/_MultiPageOfPage.fs | 116 ------ .../MultiPageOfPage.Component.fs | 59 +++ .../_MultiPageOfPage/MultiPageOfPage.Mvu.fs | 60 +++ .../Pages/_MultiPageOfPage/MultiPageOfPage.fs | 11 + .../Views/Pages/_Page/Page.Component.fs | 42 +++ .../Views/Pages/_Page/Page.Mvu.fs | 42 +++ .../Views/Pages/{_Page.fs => _Page/Page.fs} | 68 ---- .../Geometries/RoundRectangleGeometry.fs | 1 - src/Fabulous.MauiControls/Views/Window.fs | 220 ----------- .../Views/Window/Window.Component.fs | 72 ++++ .../Views/Window/Window.Mvu.fs | 72 ++++ .../Views/Window/Window.fs | 94 +++++ .../{_Element.fs => _Element/Element.Mvu.fs} | 18 +- .../Views/_Element/Element.fs | 22 ++ .../_VisualElement/VisualElement.Component.fs | 70 ++++ .../Views/_VisualElement/VisualElement.Mvu.fs | 81 ++++ .../VisualElement.fs} | 134 ------- 152 files changed, 4383 insertions(+), 3611 deletions(-) delete mode 100644 src/Fabulous.MauiControls/Views/Application.fs create mode 100644 src/Fabulous.MauiControls/Views/Application/Application.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Application/Application.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs rename src/Fabulous.MauiControls/Views/Cells/{ => EntryCell}/EntryCell.fs (58%) delete mode 100644 src/Fabulous.MauiControls/Views/Cells/SwitchCell.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs delete mode 100644 src/Fabulous.MauiControls/Views/Cells/_Cell.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs create mode 100644 src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Mvu.fs rename src/Fabulous.MauiControls/Views/Collections/{ => CollectionView}/CollectionView.fs (81%) create mode 100644 src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs rename src/Fabulous.MauiControls/Views/Collections/{ => ListView}/ListView.fs (54%) delete mode 100644 src/Fabulous.MauiControls/Views/Collections/_ItemsView.fs create mode 100644 src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Button/Button.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Button/Button.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => Button}/Button.fs (75%) delete mode 100644 src/Fabulous.MauiControls/Views/Controls/CheckBox.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.fs delete mode 100644 src/Fabulous.MauiControls/Views/Controls/DatePicker.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => Editor}/Editor.fs (71%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => Entry}/Entry.fs (77%) delete mode 100644 src/Fabulous.MauiControls/Views/Controls/GraphicsView.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.fs delete mode 100644 src/Fabulous.MauiControls/Views/Controls/ImageButton.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => Picker}/Picker.fs (74%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => RadioButton}/RadioButton.fs (61%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => SearchBar}/SearchBar.fs (72%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => Slider}/Slider.fs (54%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => Stepper}/Stepper.fs (50%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => Switch}/Switch.fs (50%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => TimePicker}/TimePicker.fs (77%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{ => WebView}/WebView.fs (71%) create mode 100644 src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Mvu.fs rename src/Fabulous.MauiControls/Views/Controls/{_InputView.fs => _InputView/InputView.fs} (91%) delete mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.fs delete mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Mvu.fs rename src/Fabulous.MauiControls/Views/GestureRecognizers/{ => PanGestureRecognizer}/PanGestureRecognizer.fs (50%) delete mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs rename src/Fabulous.MauiControls/Views/GestureRecognizers/{ => SwipeGestureRecognizer}/SwipeGestureRecognizer.fs (57%) create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Mvu.fs rename src/Fabulous.MauiControls/Views/GestureRecognizers/{ => TapGestureRecognizer}/TapGestureRecognizer.fs (53%) delete mode 100644 src/Fabulous.MauiControls/Views/Layouts/RefreshView.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs rename src/Fabulous.MauiControls/Views/Layouts/{ => ScrollView}/ScrollView.fs (83%) create mode 100644 src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Mvu.fs rename src/Fabulous.MauiControls/Views/Layouts/{ => SwipeItem}/SwipeItem.fs (62%) delete mode 100644 src/Fabulous.MauiControls/Views/Layouts/SwipeView.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs create mode 100644 src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Mvu.fs rename src/Fabulous.MauiControls/Views/MenuItems/{ => MenuFlyoutItem}/MenuFlyoutItem.fs (62%) create mode 100644 src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Mvu.fs rename src/Fabulous.MauiControls/Views/MenuItems/{ => MenuItem}/MenuItem.fs (67%) create mode 100644 src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Mvu.fs rename src/Fabulous.MauiControls/Views/MenuItems/{ => ToolbarItem}/ToolbarItem.fs (69%) create mode 100644 src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs rename src/Fabulous.MauiControls/Views/Pages/{ => ContentPage}/ContentPage.fs (66%) create mode 100644 src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Mvu.fs rename src/Fabulous.MauiControls/Views/Pages/{ => FlyoutPage}/FlyoutPage.fs (55%) create mode 100644 src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs rename src/Fabulous.MauiControls/Views/Pages/{ => NavigationPage}/NavigationPage.fs (88%) delete mode 100644 src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Pages/_Page/Page.Mvu.fs rename src/Fabulous.MauiControls/Views/Pages/{_Page.fs => _Page/Page.fs} (71%) delete mode 100644 src/Fabulous.MauiControls/Views/Window.fs create mode 100644 src/Fabulous.MauiControls/Views/Window/Window.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Window/Window.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Window/Window.fs rename src/Fabulous.MauiControls/Views/{_Element.fs => _Element/Element.Mvu.fs} (53%) create mode 100644 src/Fabulous.MauiControls/Views/_Element/Element.fs create mode 100644 src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs rename src/Fabulous.MauiControls/Views/{_VisualElement.fs => _VisualElement/VisualElement.fs} (80%) diff --git a/Directory.Packages.props b/Directory.Packages.props index a635c2d..74f2295 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,18 +7,18 @@ - - + + - - - - - - + + + + + + \ No newline at end of file diff --git a/Fabulous.MauiControls.sln b/Fabulous.MauiControls.sln index 7eeb56e..3b4d4b6 100644 --- a/Fabulous.MauiControls.sln +++ b/Fabulous.MauiControls.sln @@ -57,6 +57,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ComponentNavigation", "samp EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Calculator", "samples\Calculator\Calculator.fsproj", "{E24F96A8-B1FF-45AA-A7D9-379F3F88F422}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabulous", "..\Fabulous\src\Fabulous\Fabulous.fsproj", "{A5D5A010-8A72-4B4F-8266-8D25FD9662B7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -140,6 +142,10 @@ Global {66532A61-1BB8-4BD1-A281-A160ABB0EFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU {66532A61-1BB8-4BD1-A281-A160ABB0EFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU {66532A61-1BB8-4BD1-A281-A160ABB0EFE7}.Release|Any CPU.Build.0 = Release|Any CPU + {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {67FB01A1-1A3E-4A3B-83DC-7D63B56FB1A1} = {35A6823C-8312-4F92-818A-5117BB31A569} diff --git a/src/Fabulous.MauiControls/Attributes.fs b/src/Fabulous.MauiControls/Attributes.fs index 5fe534e..78aab45 100644 --- a/src/Fabulous.MauiControls/Attributes.fs +++ b/src/Fabulous.MauiControls/Attributes.fs @@ -157,100 +157,102 @@ module Attributes = bindableObject.ClearValue(bindableProperty) else bindableObject.SetValue(bindableProperty, value)) - - /// Update both a property and its related event. - /// This definition makes sure that the event is only raised when the property is changed by the user, - /// and not when the property is set by the code - let defineBindableWithEvent<'data, 'args> - name - (bindableProperty: BindableProperty) - (getEvent: obj -> IEvent, 'args>) - : SimpleScalarAttributeDefinition> = - - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun oldValueOpt (newValueOpt: MsgValueEventData<'data, 'args> voption) node -> - let target = node.Target :?> BindableObject - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the event - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> target.ClearValue(bindableProperty) - - | ValueSome curr -> - // Clean up the old event handler if any - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - target.SetValue(bindableProperty, curr.Value) - - // Set the new event handler - let event = getEvent target - - let handler = - event.Subscribe(fun args -> - let (MsgValue r) = curr.Event args - Dispatcher.dispatch node r) - - node.SetHandler(name, handler)) - ) - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } - - /// Update both a property and its related event. - /// This definition makes sure that the event is only raised when the property is changed by the user, - /// and not when the property is set by the code - let defineBindableWithEventNoDispatch<'data, 'args> - name - (bindableProperty: BindableProperty) - (getEvent: obj -> IEvent, 'args>) - : SimpleScalarAttributeDefinition> = - - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun oldValueOpt (newValueOpt: ValueEventData<'data, 'args> voption) node -> - let target = node.Target :?> BindableObject - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the event - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> target.ClearValue(bindableProperty) - - | ValueSome curr -> - // Clean up the old event handler if any - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - target.SetValue(bindableProperty, curr.Value) - - // Set the new event handler - let event = getEvent target - - let handler = event.Subscribe(curr.Event) - - node.SetHandler(name, handler)) - ) - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } + + module Mvu = + /// Update both a property and its related event. + /// This definition makes sure that the event is only raised when the property is changed by the user, + /// and not when the property is set by the code + let defineBindableWithEvent<'data, 'args> + name + (bindableProperty: BindableProperty) + (getEvent: obj -> IEvent, 'args>) + : SimpleScalarAttributeDefinition> = + + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun oldValueOpt (newValueOpt: MsgValueEventData<'data, 'args> voption) node -> + let target = node.Target :?> BindableObject + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the event + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> target.ClearValue(bindableProperty) + + | ValueSome curr -> + // Clean up the old event handler if any + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + target.SetValue(bindableProperty, curr.Value) + + // Set the new event handler + let event = getEvent target + + let handler = + event.Subscribe(fun args -> + let (MsgValue r) = curr.Event args + Dispatcher.dispatch node r) + + node.SetHandler(name, handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } + + module Component = + /// Update both a property and its related event. + /// This definition makes sure that the event is only raised when the property is changed by the user, + /// and not when the property is set by the code + let defineBindableWithEvent<'data, 'args> + name + (bindableProperty: BindableProperty) + (getEvent: obj -> IEvent, 'args>) + : SimpleScalarAttributeDefinition> = + + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun oldValueOpt (newValueOpt: ValueEventData<'data, 'args> voption) node -> + let target = node.Target :?> BindableObject + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the event + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> target.ClearValue(bindableProperty) + + | ValueSome curr -> + // Clean up the old event handler if any + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + target.SetValue(bindableProperty, curr.Value) + + // Set the new event handler + let event = getEvent target + + let handler = event.Subscribe(curr.Event) + + node.SetHandler(name, handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } diff --git a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj index 1581771..1318fd5 100644 --- a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj +++ b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj @@ -1,6 +1,6 @@ - false + true net8.0 true @@ -28,7 +28,8 @@ - + + @@ -38,31 +39,67 @@ - + + + - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + - + + + @@ -97,51 +134,101 @@ - + + + - + + + - + + + - + + + - - - + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + - - + + + + + + - - + + + + + + diff --git a/src/Fabulous.MauiControls/Views/Application.fs b/src/Fabulous.MauiControls/Views/Application.fs deleted file mode 100644 index ae9d557..0000000 --- a/src/Fabulous.MauiControls/Views/Application.fs +++ /dev/null @@ -1,302 +0,0 @@ -namespace Fabulous.Maui - -open System -open System.Collections.Generic -open System.Runtime.CompilerServices -open Fabulous -open Fabulous.Maui -open Fabulous.StackAllocatedCollections -open Microsoft.Maui.Controls -open Microsoft.Maui.ApplicationModel - -type IFabApplication = - inherit IFabElement - -type FabApplication() = - inherit Application() - - let start = Event() - let sleep = Event() - let resume = Event() - let appLinkRequestReceived = Event, Uri>() - - let windows = List() - - member this.Windows = windows - member this.EditableWindows = windows - - [] - member _.Start = start.Publish - - override this.OnStart() = start.Trigger(this, EventArgs()) - - [] - member _.Sleep = sleep.Publish - - override this.OnSleep() = sleep.Trigger(this, EventArgs()) - - [] - member _.Resume = resume.Publish - - override this.OnResume() = resume.Trigger(this, EventArgs()) - - [] - member _.AppLinkRequestReceived = appLinkRequestReceived.Publish - - override this.OnAppLinkRequestReceived(uri) = - appLinkRequestReceived.Trigger(this, uri) - - override this.CreateWindow(activationState) = - if windows.Count > 0 then - windows[0] - else - base.CreateWindow(activationState) - - override this.OpenWindow(window) = - windows.Add(window) - base.OpenWindow(window) - - override this.CloseWindow(window) = - windows.Remove(window) |> ignore - base.CloseWindow(window) - -module Application = - let WidgetKey = Widgets.register() - - let MainPage = - Attributes.definePropertyWidget "Application_MainPage" (fun target -> (target :?> Application).MainPage :> obj) (fun target value -> - (target :?> Application).MainPage <- value) - - let ModalPoppedMsg = - Attributes.defineEvent "Application_ModalPoppedMsg" (fun target -> (target :?> Application).ModalPopped) - - let ModalPoppedFn = - Attributes.defineEventNoDispatch "Application_ModalPoppedFn" (fun target -> (target :?> Application).ModalPopped) - - let ModalPoppingMsg = - Attributes.defineEvent "Application_ModalPoppingMsg" (fun target -> (target :?> Application).ModalPopping) - - let ModalPoppingFn = - Attributes.defineEventNoDispatch "Application_ModalPoppingFn" (fun target -> (target :?> Application).ModalPopping) - - let ModalPushedMsg = - Attributes.defineEvent "Application_ModalPushedMsg" (fun target -> (target :?> Application).ModalPushed) - - let ModalPushedFn = - Attributes.defineEventNoDispatch "Application_ModalPushedFn" (fun target -> (target :?> Application).ModalPushed) - - let ModalPushingMsg = - Attributes.defineEvent "Application_ModalPushingMsg" (fun target -> (target :?> Application).ModalPushing) - - let ModalPushingFn = - Attributes.defineEventNoDispatch "Application_ModalPushingFn" (fun target -> (target :?> Application).ModalPushing) - - let RequestedThemeChangedMsg = - Attributes.defineEvent "Application_RequestedThemeChangedMsg" (fun target -> (target :?> Application).RequestedThemeChanged) - - let RequestedThemeChangedFn = - Attributes.defineEventNoDispatch "Application_RequestedThemeChangedFn" (fun target -> - (target :?> Application).RequestedThemeChanged) - - let ResumeMsg = - Attributes.defineEventNoArg "Application_ResumeMsg" (fun target -> (target :?> FabApplication).Resume) - - let ResumeFn = - Attributes.defineEventNoArgNoDispatch "Application_ResumeFn" (fun target -> (target :?> FabApplication).Resume) - - let SleepMsg = - Attributes.defineEventNoArg "Application_SleepMsg" (fun target -> (target :?> FabApplication).Sleep) - - let SleepFn = - Attributes.defineEventNoArgNoDispatch "Application_SleepFn" (fun target -> (target :?> FabApplication).Sleep) - - let StartMsg = - Attributes.defineEventNoArg "Application_StartMsg" (fun target -> (target :?> FabApplication).Start) - - let StartFn = - Attributes.defineEventNoArgNoDispatch "Application_StartFn" (fun target -> (target :?> FabApplication).Start) - - let AppLinkRequestReceivedMsg = - Attributes.defineEvent "Application_AppLinkRequestReceivedMsg" (fun target -> (target :?> FabApplication).AppLinkRequestReceived) - - let AppLinkRequestReceivedFn = - Attributes.defineEventNoDispatch "Application_AppLinkRequestReceivedFn" (fun target -> (target :?> FabApplication).AppLinkRequestReceived) - - let UserAppTheme = - Attributes.defineEnum "Application_UserAppTheme" (fun _ newValueOpt node -> - let application = node.Target :?> Application - - let value = - match newValueOpt with - | ValueNone -> AppTheme.Unspecified - | ValueSome v -> v - - application.UserAppTheme <- value) - - let Windows = - Attributes.defineListWidgetCollection "Application_Windows" (fun target -> (target :?> FabApplication).EditableWindows) - -[] -module ApplicationBuilders = - type Fabulous.Maui.View with - - /// Create an Application widget with a main page - /// The main page widget - static member inline Application(mainPage: WidgetBuilder<'msg, #IFabPage>) = - WidgetHelpers.buildWidgets<'msg, IFabApplication> Application.WidgetKey [| Application.MainPage.WithValue(mainPage.Compile()) |] - - /// Create an Application widget with a list of windows - static member inline Application<'msg, 'itemMarker when 'msg: equality and 'itemMarker :> IFabWindow>() = - CollectionBuilder<'msg, IFabApplication, 'itemMarker>(Application.WidgetKey, Application.Windows) - -[] -type ApplicationModifiers = - /// Listen for the ModalPopped event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPopped(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPoppedEventArgs -> 'msg) = - this.AddScalar(Application.ModalPoppedMsg.WithValue(fn)) - - /// Listen for the ModalPopped event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPopped(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPoppedEventArgs -> unit) = - this.AddScalar(Application.ModalPoppedFn.WithValue(fn)) - - /// Listen for the ModalPopping event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPopping(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPoppingEventArgs -> 'msg) = - this.AddScalar(Application.ModalPoppingMsg.WithValue(fn)) - - /// Listen for the ModalPopping event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPopping(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPoppingEventArgs -> unit) = - this.AddScalar(Application.ModalPoppingFn.WithValue(fn)) - - /// Listen for the ModalPushed event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPushed(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPushedEventArgs -> 'msg) = - this.AddScalar(Application.ModalPushedMsg.WithValue(fn)) - - /// Listen for the ModalPushed event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPushed(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPushedEventArgs -> unit) = - this.AddScalar(Application.ModalPushedFn.WithValue(fn)) - - /// Listen for the ModalPushing event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPushing(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPushingEventArgs -> 'msg) = - this.AddScalar(Application.ModalPushingMsg.WithValue(fn)) - - /// Listen for the ModalPushing event - /// Current widget - /// Message to dispatch - [] - static member inline onModalPushing(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPushingEventArgs -> unit) = - this.AddScalar(Application.ModalPushingFn.WithValue(fn)) - - /// Listen for the Resume event - /// Current widget - /// Message to dispatch - [] - static member inline onResume(this: WidgetBuilder<'msg, #IFabApplication>, msg: 'msg) = - this.AddScalar(Application.ResumeMsg.WithValue(MsgValue(msg))) - - /// Listen for the Resume event - /// Current widget - /// Function to execute - [] - static member inline onResume(this: WidgetBuilder<'msg, #IFabApplication>, fn: unit -> unit) = - this.AddScalar(Application.ResumeFn.WithValue(fn)) - - /// Listen for the Start event - /// Current widget - /// Message to dispatch - [] - static member inline onStart(this: WidgetBuilder<'msg, #IFabApplication>, msg: 'msg) = - this.AddScalar(Application.StartMsg.WithValue(MsgValue(msg))) - - /// Listen for the Start event - /// Current widget - /// Function to execute - [] - static member inline onStart(this: WidgetBuilder<'msg, #IFabApplication>, fn: unit -> unit) = - this.AddScalar(Application.StartFn.WithValue(fn)) - - /// Listen for the Sleep event - /// Current widget - /// Message to dispatch - [] - static member inline onSleep(this: WidgetBuilder<'msg, #IFabApplication>, msg: 'msg) = - this.AddScalar(Application.SleepMsg.WithValue(MsgValue(msg))) - - /// Listen for the Sleep event - /// Current widget - /// Function to execute - [] - static member inline onSleep(this: WidgetBuilder<'msg, #IFabApplication>, fn: unit -> unit) = - this.AddScalar(Application.SleepFn.WithValue(fn)) - - /// Listen for the RequestedThemeChanged event - /// Current widget - /// Message to dispatch - [] - static member inline onRequestedThemeChanged(this: WidgetBuilder<'msg, #IFabApplication>, fn: AppTheme -> 'msg) = - this.AddScalar(Application.RequestedThemeChangedMsg.WithValue(fun args -> fn args.RequestedTheme |> box)) - - /// Listen for the RequestedThemeChanged event - /// Current widget - /// Message to dispatch - [] - static member inline onRequestedThemeChanged(this: WidgetBuilder<'msg, #IFabApplication>, fn: AppTheme -> unit) = - this.AddScalar(Application.RequestedThemeChangedFn.WithValue(fun args -> fn args.RequestedTheme)) - - /// Listen for the AppLinkRequestReceived event - /// Current widget - /// Message to dispatch - [] - static member inline onAppLinkRequestReceived(this: WidgetBuilder<'msg, #IFabApplication>, fn: Uri -> 'msg) = - this.AddScalar(Application.AppLinkRequestReceivedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the AppLinkRequestReceived event - /// Current widget - /// Message to dispatch - [] - static member inline onAppLinkRequestReceived(this: WidgetBuilder<'msg, #IFabApplication>, fn: Uri -> unit) = - this.AddScalar(Application.AppLinkRequestReceivedFn.WithValue(fun args -> fn args)) - - /// Set the user app theme - /// Current widget - /// The user app theme - [] - static member inline userAppTheme(this: WidgetBuilder<'msg, #IFabApplication>, value: AppTheme) = - this.AddScalar(Application.UserAppTheme.WithValue(value)) - - /// Link a ViewRef to access the direct Application control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabApplication>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) - -[] -type ApplicationYieldExtensions = - [] - static member inline Yield<'msg, 'marker, 'itemType when 'msg: equality and 'marker :> IFabApplication and 'itemType :> IFabWindow> - ( - _: CollectionBuilder<'msg, 'marker, IFabWindow>, - x: WidgetBuilder<'msg, 'itemType> - ) : Content<'msg> = - { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Application/Application.Component.fs b/src/Fabulous.MauiControls/Views/Application/Application.Component.fs new file mode 100644 index 0000000..aeb14bf --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Application/Application.Component.fs @@ -0,0 +1,102 @@ +namespace Fabulous.Maui + +open System +open System.Runtime.CompilerServices +open Fabulous +open Fabulous.Maui +open Microsoft.Maui.Controls +open Microsoft.Maui.ApplicationModel + +module ApplicationComponent = + let ModalPopped = + Attributes.Component.defineEvent "ApplicationComponent_ModalPopped" (fun target -> (target :?> Application).ModalPopped) + + let ModalPopping = + Attributes.Component.defineEvent "ApplicationComponent_ModalPopping" (fun target -> (target :?> Application).ModalPopping) + + let ModalPushed = + Attributes.Component.defineEvent "ApplicationComponent_ModalPushed" (fun target -> (target :?> Application).ModalPushed) + + let ModalPushing = + Attributes.Component.defineEvent "ApplicationComponent_ModalPushing" (fun target -> (target :?> Application).ModalPushing) + + let RequestedThemeChanged = + Attributes.Component.defineEvent "ApplicationComponent_RequestedThemeChanged" (fun target -> + (target :?> Application).RequestedThemeChanged) + + let Resume = + Attributes.Component.defineEventNoArg "ApplicationComponent_Resume" (fun target -> (target :?> FabApplication).Resume) + + let Sleep = + Attributes.Component.defineEventNoArg "ApplicationComponent_Sleep" (fun target -> (target :?> FabApplication).Sleep) + + let Start = + Attributes.Component.defineEventNoArg "ApplicationComponent_Start" (fun target -> (target :?> FabApplication).Start) + + let AppLinkRequestReceived = + Attributes.Component.defineEvent "ApplicationComponent_AppLinkRequestReceived" (fun target -> (target :?> FabApplication).AppLinkRequestReceived) + +[] +type ApplicationComponentModifiers = + /// Listen for the ModalPopped event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPopped(this: WidgetBuilder, fn: ModalPoppedEventArgs -> unit) = + this.AddScalar(ApplicationComponent.ModalPopped.WithValue(fn)) + + /// Listen for the ModalPopping event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPopping(this: WidgetBuilder, fn: ModalPoppingEventArgs -> unit) = + this.AddScalar(ApplicationComponent.ModalPopping.WithValue(fn)) + + /// Listen for the ModalPushed event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPushed(this: WidgetBuilder, fn: ModalPushedEventArgs -> unit) = + this.AddScalar(ApplicationComponent.ModalPushed.WithValue(fn)) + + /// Listen for the ModalPushing event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPushing(this: WidgetBuilder, fn: ModalPushingEventArgs -> unit) = + this.AddScalar(ApplicationComponent.ModalPushing.WithValue(fn)) + + /// Listen for the Resume event + /// Current widget + /// Function to execute + [] + static member inline onResume(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ApplicationComponent.Resume.WithValue(fn)) + + /// Listen for the Start event + /// Current widget + /// Function to execute + [] + static member inline onStart(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ApplicationComponent.Start.WithValue(fn)) + + /// Listen for the Sleep event + /// Current widget + /// Function to execute + [] + static member inline onSleep(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ApplicationComponent.Sleep.WithValue(fn)) + + /// Listen for the RequestedThemeChanged event + /// Current widget + /// Message to dispatch + [] + static member inline onRequestedThemeChanged(this: WidgetBuilder, fn: AppTheme -> unit) = + this.AddScalar(ApplicationComponent.RequestedThemeChanged.WithValue(fun args -> fn args.RequestedTheme)) + + /// Listen for the AppLinkRequestReceived event + /// Current widget + /// Message to dispatch + [] + static member inline onAppLinkRequestReceived(this: WidgetBuilder, fn: Uri -> unit) = + this.AddScalar(ApplicationComponent.AppLinkRequestReceived.WithValue(fn) ) diff --git a/src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs b/src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs new file mode 100644 index 0000000..797a0c9 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs @@ -0,0 +1,101 @@ +namespace Fabulous.Maui + +open System +open System.Runtime.CompilerServices +open Fabulous +open Fabulous.Maui +open Microsoft.Maui.Controls +open Microsoft.Maui.ApplicationModel + +module ApplicationMvu = + let ModalPopped = + Attributes.Mvu.defineEvent "ApplicationMvu_ModalPopped" (fun target -> (target :?> Application).ModalPopped) + + let ModalPopping = + Attributes.Mvu.defineEvent "ApplicationMvu_ModalPopping" (fun target -> (target :?> Application).ModalPopping) + + let ModalPushed = + Attributes.Mvu.defineEvent "ApplicationMvu_ModalPushed" (fun target -> (target :?> Application).ModalPushed) + + let ModalPushing = + Attributes.Mvu.defineEvent "ApplicationMvu_ModalPushing" (fun target -> (target :?> Application).ModalPushing) + + let RequestedThemeChanged = + Attributes.Mvu.defineEvent "ApplicationMvu_RequestedThemeChanged" (fun target -> (target :?> Application).RequestedThemeChanged) + + let Resume = + Attributes.Mvu.defineEventNoArg "ApplicationMvu_Resume" (fun target -> (target :?> FabApplication).Resume) + + let Sleep = + Attributes.Mvu.defineEventNoArg "ApplicationMvu_Sleep" (fun target -> (target :?> FabApplication).Sleep) + + let Start = + Attributes.Mvu.defineEventNoArg "ApplicationMvu_Start" (fun target -> (target :?> FabApplication).Start) + + let AppLinkRequestReceived = + Attributes.Mvu.defineEvent "ApplicationMvu_AppLinkRequestReceived" (fun target -> (target :?> FabApplication).AppLinkRequestReceived) + +[] +type ApplicationMvuModifiers = + /// Listen for the ModalPopped event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPopped(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPoppedEventArgs -> 'msg) = + this.AddScalar(ApplicationMvu.ModalPopped.WithValue(fn)) + + /// Listen for the ModalPopping event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPopping(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPoppingEventArgs -> 'msg) = + this.AddScalar(ApplicationMvu.ModalPopping.WithValue(fn)) + + /// Listen for the ModalPushed event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPushed(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPushedEventArgs -> 'msg) = + this.AddScalar(ApplicationMvu.ModalPushed.WithValue(fn)) + + /// Listen for the ModalPushing event + /// Current widget + /// Message to dispatch + [] + static member inline onModalPushing(this: WidgetBuilder<'msg, #IFabApplication>, fn: ModalPushingEventArgs -> 'msg) = + this.AddScalar(ApplicationMvu.ModalPushing.WithValue(fn)) + + /// Listen for the Resume event + /// Current widget + /// Message to dispatch + [] + static member inline onResume(this: WidgetBuilder<'msg, #IFabApplication>, msg: 'msg) = + this.AddScalar(ApplicationMvu.Resume.WithValue(MsgValue(msg))) + + /// Listen for the Start event + /// Current widget + /// Message to dispatch + [] + static member inline onStart(this: WidgetBuilder<'msg, #IFabApplication>, msg: 'msg) = + this.AddScalar(ApplicationMvu.Start.WithValue(MsgValue(msg))) + + /// Listen for the Sleep event + /// Current widget + /// Message to dispatch + [] + static member inline onSleep(this: WidgetBuilder<'msg, #IFabApplication>, msg: 'msg) = + this.AddScalar(ApplicationMvu.Sleep.WithValue(MsgValue(msg))) + + /// Listen for the RequestedThemeChanged event + /// Current widget + /// Message to dispatch + [] + static member inline onRequestedThemeChanged(this: WidgetBuilder<'msg, #IFabApplication>, fn: AppTheme -> 'msg) = + this.AddScalar(ApplicationMvu.RequestedThemeChanged.WithValue(fun args -> fn args.RequestedTheme |> box)) + + /// Listen for the AppLinkRequestReceived event + /// Current widget + /// Message to dispatch + [] + static member inline onAppLinkRequestReceived(this: WidgetBuilder<'msg, #IFabApplication>, fn: Uri -> 'msg) = + this.AddScalar(ApplicationMvu.AppLinkRequestReceived.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/Application/Application.fs b/src/Fabulous.MauiControls/Views/Application/Application.fs new file mode 100644 index 0000000..f4dbea0 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Application/Application.fs @@ -0,0 +1,121 @@ +namespace Fabulous.Maui + +open System +open System.Collections.Generic +open System.Runtime.CompilerServices +open Fabulous +open Fabulous.Maui +open Fabulous.StackAllocatedCollections +open Microsoft.Maui.Controls +open Microsoft.Maui.ApplicationModel + +type IFabApplication = + inherit IFabElement + +type FabApplication() = + inherit Application() + + let start = Event() + let sleep = Event() + let resume = Event() + let appLinkRequestReceived = Event, Uri>() + + let windows = List() + + member this.Windows = windows + member this.EditableWindows = windows + + [] + member _.Start = start.Publish + + override this.OnStart() = start.Trigger(this, EventArgs()) + + [] + member _.Sleep = sleep.Publish + + override this.OnSleep() = sleep.Trigger(this, EventArgs()) + + [] + member _.Resume = resume.Publish + + override this.OnResume() = resume.Trigger(this, EventArgs()) + + [] + member _.AppLinkRequestReceived = appLinkRequestReceived.Publish + + override this.OnAppLinkRequestReceived(uri) = + appLinkRequestReceived.Trigger(this, uri) + + override this.CreateWindow(activationState) = + if windows.Count > 0 then + windows[0] + else + base.CreateWindow(activationState) + + override this.OpenWindow(window) = + windows.Add(window) + base.OpenWindow(window) + + override this.CloseWindow(window) = + windows.Remove(window) |> ignore + base.CloseWindow(window) + +module Application = + let WidgetKey = Widgets.register() + + let MainPage = + Attributes.definePropertyWidget "Application_MainPage" (fun target -> (target :?> Application).MainPage :> obj) (fun target value -> + (target :?> Application).MainPage <- value) + + let UserAppTheme = + Attributes.defineEnum "Application_UserAppTheme" (fun _ newValueOpt node -> + let application = node.Target :?> Application + + let value = + match newValueOpt with + | ValueNone -> AppTheme.Unspecified + | ValueSome v -> v + + application.UserAppTheme <- value) + + let Windows = + Attributes.defineListWidgetCollection "Application_Windows" (fun target -> (target :?> FabApplication).EditableWindows) + +[] +module ApplicationBuilders = + type Fabulous.Maui.View with + + /// Create an Application widget with a main page + /// The main page widget + static member inline Application(mainPage: WidgetBuilder<'msg, #IFabPage>) = + WidgetHelpers.buildWidgets<'msg, IFabApplication> Application.WidgetKey [| Application.MainPage.WithValue(mainPage.Compile()) |] + + /// Create an Application widget with a list of windows + static member inline Application<'msg, 'itemMarker when 'msg: equality and 'itemMarker :> IFabWindow>() = + CollectionBuilder<'msg, IFabApplication, 'itemMarker>(Application.WidgetKey, Application.Windows) + +[] +type ApplicationModifiers = + /// Set the user app theme + /// Current widget + /// The user app theme + [] + static member inline userAppTheme(this: WidgetBuilder<'msg, #IFabApplication>, value: AppTheme) = + this.AddScalar(Application.UserAppTheme.WithValue(value)) + + /// Link a ViewRef to access the direct Application control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabApplication>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) + +[] +type ApplicationYieldExtensions = + [] + static member inline Yield<'msg, 'marker, 'itemType when 'msg: equality and 'marker :> IFabApplication and 'itemType :> IFabWindow> + ( + _: CollectionBuilder<'msg, 'marker, IFabWindow>, + x: WidgetBuilder<'msg, 'itemType> + ) : Content<'msg> = + { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs new file mode 100644 index 0000000..94f9fe8 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs @@ -0,0 +1,36 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module EntryCellComponent = + let OnCompleted = + Attributes.Component.defineEventNoArg "EntryCellComponent_Completed" (fun target -> (target :?> EntryCell).Completed) + + let TextWithEvent = + Attributes.Component.defineBindableWithEvent "EntryCellComponent_TextChanged" EntryCell.TextProperty (fun target -> (target :?> FabEntryCell).TextChanged) + +[] +module EntryCellComponentBuilders = + type Fabulous.Maui.View with + + /// Create an EntryCell with a label, a text, and listen to text changes + /// The label value + /// The text value + /// Message to dispatch + static member inline EntryCell(label: string, text: string, onTextChanged: string -> unit) = + WidgetBuilder( + EntryCell.WidgetKey, + EntryCell.Label.WithValue(label), + EntryCellComponent.TextWithEvent.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) + ) + +[] +type EntryCellComponentModifiers = + /// Listen to the Completed event + /// Current widget + /// Function to execute + [] + static member inline onCompleted(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(EntryCellComponent.OnCompleted.WithValue(fn)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs new file mode 100644 index 0000000..2290f63 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs @@ -0,0 +1,37 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module EntryCellMvu = + let OnCompleted = + Attributes.Mvu.defineEventNoArg "EntryCellMvu_Completed" (fun target -> (target :?> EntryCell).Completed) + + let TextWithEvent = + Attributes.Mvu.defineBindableWithEvent "EntryCellMvu_TextChanged" EntryCell.TextProperty (fun target -> (target :?> FabEntryCell).TextChanged) + +[] +module EntryCellMvuBuilders = + type Fabulous.Maui.View with + + /// Create an EntryCell with a label, a text, and listen to text changes + /// The label value + /// The text value + /// Message to dispatch + static member inline EntryCell(label: string, text: string, onTextChanged: string -> 'msg) = + WidgetBuilder<'msg, IFabEntryCell>( + EntryCell.WidgetKey, + EntryCell.Label.WithValue(label), + EntryCellMvu.TextWithEvent.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) + ) + +[] +type EntryCellMvuModifiers = + + /// Listen to the Completed event + /// Current widget + /// Message to dispatch + [] + static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntryCell>, msg: 'msg) = + this.AddScalar(EntryCellMvu.OnCompleted.WithValue(MsgValue(msg))) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Cells/EntryCell.fs b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.fs similarity index 58% rename from src/Fabulous.MauiControls/Views/Cells/EntryCell.fs rename to src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.fs index 7dac65d..11771ee 100644 --- a/src/Fabulous.MauiControls/Views/Cells/EntryCell.fs +++ b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.fs @@ -46,50 +46,12 @@ module EntryCell = let LabelColor = Attributes.defineBindableColor EntryCell.LabelColorProperty - let OnCompletedMsg = - Attributes.defineEventNoArg "EntryCell_CompletedMsg" (fun target -> (target :?> EntryCell).Completed) - - let OnCompletedFn = - Attributes.defineEventNoArgNoDispatch "EntryCell_CompletedFn" (fun target -> (target :?> EntryCell).Completed) - let Placeholder = Attributes.defineBindableWithEquality EntryCell.PlaceholderProperty - let TextWithEventMsg = - Attributes.defineBindableWithEvent "EntryCell_TextChangedMsg" EntryCell.TextProperty (fun target -> (target :?> FabEntryCell).TextChanged) - - let TextWithEventFn = - Attributes.defineBindableWithEventNoDispatch "EntryCell_TextChangedFn" EntryCell.TextProperty (fun target -> (target :?> FabEntryCell).TextChanged) - let VerticalTextAlignment = Attributes.defineBindableEnum EntryCell.VerticalTextAlignmentProperty -[] -module EntryCellBuilders = - type Fabulous.Maui.View with - - /// Create an EntryCell with a label, a text, and listen to text changes - /// The label value - /// The text value - /// Message to dispatch - static member inline EntryCell(label: string, text: string, onTextChanged: string -> 'msg) = - WidgetBuilder<'msg, IFabEntryCell>( - EntryCell.WidgetKey, - EntryCell.Label.WithValue(label), - EntryCell.TextWithEventMsg.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) - ) - - /// Create an EntryCell with a label, a text, and listen to text changes - /// The label value - /// The text value - /// Message to dispatch - static member inline EntryCell(label: string, text: string, onTextChanged: string -> unit) = - WidgetBuilder<'msg, IFabEntryCell>( - EntryCell.WidgetKey, - EntryCell.Label.WithValue(label), - EntryCell.TextWithEventFn.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) - ) - [] type EntryCellModifiers = /// Set the horizontal text alignment @@ -113,20 +75,6 @@ type EntryCellModifiers = static member inline labelColor(this: WidgetBuilder<'msg, #IFabEntryCell>, value: Color) = this.AddScalar(EntryCell.LabelColor.WithValue(value)) - /// Listen to the Completed event - /// Current widget - /// Message to dispatch - [] - static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntryCell>, msg: 'msg) = - this.AddScalar(EntryCell.OnCompletedMsg.WithValue(MsgValue(msg))) - - /// Listen to the Completed event - /// Current widget - /// Function to execute - [] - static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntryCell>, fn: unit -> unit) = - this.AddScalar(EntryCell.OnCompletedFn.WithValue(fn)) - /// Set the placeholder text /// Current widget /// The placeholder diff --git a/src/Fabulous.MauiControls/Views/Cells/SwitchCell.fs b/src/Fabulous.MauiControls/Views/Cells/SwitchCell.fs deleted file mode 100644 index 7e52c69..0000000 --- a/src/Fabulous.MauiControls/Views/Cells/SwitchCell.fs +++ /dev/null @@ -1,64 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls -open Microsoft.Maui.Graphics - -type IFabSwitchCell = - inherit IFabCell - -module SwitchCell = - let WidgetKey = Widgets.register() - - let OnColor = Attributes.defineBindableColor SwitchCell.OnColorProperty - - let OnWithEventMsg = - Attributes.defineBindableWithEvent "SwitchCell_OnChangedMsg" SwitchCell.OnProperty (fun target -> (target :?> SwitchCell).OnChanged) - - let OnWithEventFn = - Attributes.defineBindableWithEventNoDispatch "SwitchCell_OnChangedFn" SwitchCell.OnProperty (fun target -> (target :?> SwitchCell).OnChanged) - - let Text = Attributes.defineBindableWithEquality SwitchCell.TextProperty - -[] -module SwitchCellBuilders = - type Fabulous.Maui.View with - - /// Create a SwitchCell with a text, a toggle state, and listen to toggle state changes - /// The text value - /// The toggle state value - /// Change callback - static member inline SwitchCell(text: string, value: bool, onChanged: bool -> 'msg) = - WidgetBuilder<'msg, IFabSwitchCell>( - SwitchCell.WidgetKey, - SwitchCell.OnWithEventMsg.WithValue(MsgValueEventData.create value (fun (args: ToggledEventArgs) -> onChanged args.Value)), - SwitchCell.Text.WithValue(text) - ) - - /// Create a SwitchCell with a text, a toggle state, and listen to toggle state changes - /// The text value - /// The toggle state value - /// Change callback - static member inline SwitchCell(text: string, value: bool, onChanged: bool -> unit) = - WidgetBuilder<'msg, IFabSwitchCell>( - SwitchCell.WidgetKey, - SwitchCell.OnWithEventFn.WithValue(ValueEventData.create value (fun (args: ToggledEventArgs) -> onChanged args.Value)), - SwitchCell.Text.WithValue(text) - ) - -[] -type SwitchCellModifiers = - /// Set the color of the on state - /// Current widget - /// The color of the on state in the light theme. - [] - static member inline colorOn(this: WidgetBuilder<'msg, #IFabSwitchCell>, value: Color) = - this.AddScalar(SwitchCell.OnColor.WithValue(value)) - - /// Link a ViewRef to access the direct SwitchCell control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabSwitchCell>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs new file mode 100644 index 0000000..75b5f73 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs @@ -0,0 +1,22 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SwitchCellComponent = + let OnWithEvent = + Attributes.Component.defineBindableWithEvent "SwitchCellComponent_OnChanged" SwitchCell.OnProperty (fun target -> (target :?> SwitchCell).OnChanged) + +[] +module SwitchCellComponentBuilders = + type Fabulous.Maui.View with + /// Create a SwitchCell with a text, a toggle state, and listen to toggle state changes + /// The text value + /// The toggle state value + /// Change callback + static member inline SwitchCell(text: string, value: bool, onChanged: bool -> unit) = + WidgetBuilder<'msg, IFabSwitchCell>( + SwitchCell.WidgetKey, + SwitchCellComponent.OnWithEvent.WithValue(ValueEventData.create value (fun (args: ToggledEventArgs) -> onChanged args.Value)), + SwitchCell.Text.WithValue(text) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs new file mode 100644 index 0000000..7625779 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs @@ -0,0 +1,23 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SwitchCellMvu = + let OnWithEvent = + Attributes.Mvu.defineBindableWithEvent "SwitchCellMvu_OnChanged" SwitchCell.OnProperty (fun target -> (target :?> SwitchCell).OnChanged) + +[] +module SwitchCellBuilders = + type Fabulous.Maui.View with + + /// Create a SwitchCell with a text, a toggle state, and listen to toggle state changes + /// The text value + /// The toggle state value + /// Change callback + static member inline SwitchCell(text: string, value: bool, onChanged: bool -> 'msg) = + WidgetBuilder<'msg, IFabSwitchCell>( + SwitchCell.WidgetKey, + SwitchCellMvu.OnWithEvent.WithValue(MsgValueEventData.create value (fun (args: ToggledEventArgs) -> onChanged args.Value)), + SwitchCell.Text.WithValue(text) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs new file mode 100644 index 0000000..67f0969 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs @@ -0,0 +1,33 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Fabulous.ScalarAttributeDefinitions +open Microsoft.Maui.Controls +open Microsoft.Maui.Graphics + +type IFabSwitchCell = + inherit IFabCell + +module SwitchCell = + let WidgetKey = Widgets.register() + + let OnColor = Attributes.defineBindableColor SwitchCell.OnColorProperty + + let Text : SimpleScalarAttributeDefinition = Attributes.defineBindableWithEquality SwitchCell.TextProperty + +[] +type SwitchCellModifiers = + /// Set the color of the on state + /// Current widget + /// The color of the on state in the light theme. + [] + static member inline colorOn(this: WidgetBuilder<'msg, #IFabSwitchCell>, value: Color) = + this.AddScalar(SwitchCell.OnColor.WithValue(value)) + + /// Link a ViewRef to access the direct SwitchCell control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabSwitchCell>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/Cells/_Cell.fs b/src/Fabulous.MauiControls/Views/Cells/_Cell.fs deleted file mode 100644 index 1955574..0000000 --- a/src/Fabulous.MauiControls/Views/Cells/_Cell.fs +++ /dev/null @@ -1,118 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Fabulous.StackAllocatedCollections -open Microsoft.Maui.Controls - -type IFabCell = - inherit IFabElement - -module Cell = - let AppearingMsg = - Attributes.defineEventNoArg "Cell_AppearingMsg" (fun target -> (target :?> Cell).Appearing) - - let AppearingFn = - Attributes.defineEventNoArgNoDispatch "Cell_AppearingFn" (fun target -> (target :?> Cell).Appearing) - - let DisappearingMsg = - Attributes.defineEventNoArg "Cell_DisappearingMsg" (fun target -> (target :?> Cell).Disappearing) - - let DisappearingFn = - Attributes.defineEventNoArgNoDispatch "Cell_DisappearingFn" (fun target -> (target :?> Cell).Disappearing) - - let Height = - Attributes.defineFloat "Cell_Height" (fun _ newValueOpt node -> - let cell = node.Target :?> Cell - - let value = - match newValueOpt with - | ValueNone -> cell.Height - | ValueSome v -> v - - cell.Height <- value) - - let IsEnabled = Attributes.defineBindableBool Cell.IsEnabledProperty - - let TappedMsg = - Attributes.defineEventNoArg "Cell_TappedMsg" (fun target -> (target :?> Cell).Tapped) - - let TappedFn = - Attributes.defineEventNoArgNoDispatch "Cell_TappedFn" (fun target -> (target :?> Cell).Tapped) - - let ContextActions = - Attributes.defineListWidgetCollection "Cell_ContextActions" (fun target -> (target :?> Cell).ContextActions) - -[] -type CellModifiers = - /// Set a value that indicates whether the cell is enabled - /// Current widget - /// true if the cell is enabled; otherwise, false - [] - static member inline isEnabled(this: WidgetBuilder<'msg, #IFabCell>, value: bool) = - this.AddScalar(Cell.IsEnabled.WithValue(value)) - - /// Set the desired height override of this widget - /// Current widget - /// The height this widget desires to be - [] - static member inline height(this: WidgetBuilder<'msg, #IFabCell>, value: float) = - this.AddScalar(Cell.Height.WithValue(value)) - - /// Listen to the Appearing event - /// Current widget - /// Message to dispatch - [] - static member inline onAppearing(this: WidgetBuilder<'msg, #IFabCell>, msg: 'msg) = - this.AddScalar(Cell.AppearingMsg.WithValue(MsgValue(msg))) - - /// Listen to the Appearing event - /// Current widget - /// Function to execute - [] - static member inline onAppearing(this: WidgetBuilder<'msg, #IFabCell>, fn: unit -> unit) = - this.AddScalar(Cell.AppearingFn.WithValue(fn)) - - /// Listen to the Disappearing event - /// Current widget - /// Message to dispatch - [] - static member inline onDisappearing(this: WidgetBuilder<'msg, #IFabCell>, msg: 'msg) = - this.AddScalar(Cell.DisappearingMsg.WithValue(MsgValue(msg))) - - /// Listen to the Disappearing event - /// Current widget - /// Function to execute - [] - static member inline onDisappearing(this: WidgetBuilder<'msg, #IFabCell>, fn: unit -> unit) = - this.AddScalar(Cell.DisappearingFn.WithValue(fn)) - - /// Listen to the Tapped event - /// Current widget - /// Message to dispatch - [] - static member inline onTapped(this: WidgetBuilder<'msg, #IFabCell>, msg: 'msg) = - this.AddScalar(Cell.TappedMsg.WithValue(MsgValue(msg))) - - /// Listen to the Tapped event - /// Current widget - /// Function to execute - [] - static member inline onTapped(this: WidgetBuilder<'msg, #IFabCell>, fn: unit -> unit) = - this.AddScalar(Cell.TappedFn.WithValue(fn)) - - /// Set the context actions of the cell - /// Current widget - [] - static member inline contextActions<'msg, 'marker when 'msg: equality and 'marker :> IFabCell>(this: WidgetBuilder<'msg, 'marker>) = - WidgetHelpers.buildAttributeCollection<'msg, 'marker, IFabMenuItem> Cell.ContextActions this - -[] -type CellYieldExtensions = - [] - static member inline Yield<'msg, 'marker, 'itemType when 'msg: equality and 'marker :> IFabCell and 'itemType :> IFabMenuItem> - ( - _: AttributeCollectionBuilder<'msg, 'marker, IFabMenuItem>, - x: WidgetBuilder<'msg, 'itemType> - ) : Content<'msg> = - { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Component.fs b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Component.fs new file mode 100644 index 0000000..8b9acbb --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Component.fs @@ -0,0 +1,38 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module CellComponent = + let Appearing = + Attributes.Component.defineEventNoArg "CellComponent_Appearing" (fun target -> (target :?> Cell).Appearing) + + let Disappearing = + Attributes.Component.defineEventNoArg "CellComponent_Disappearing" (fun target -> (target :?> Cell).Disappearing) + + let Tapped = + Attributes.Component.defineEventNoArg "CellComponent_Tapped" (fun target -> (target :?> Cell).Tapped) + +[] +type CellComponentModifiers = + /// Listen to the Appearing event + /// Current widget + /// Function to execute + [] + static member inline onAppearing(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(CellComponent.Appearing.WithValue(fn)) + + /// Listen to the Disappearing event + /// Current widget + /// Function to execute + [] + static member inline onDisappearing(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(CellComponent.Disappearing.WithValue(fn)) + + /// Listen to the Tapped event + /// Current widget + /// Function to execute + [] + static member inline onTapped(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(CellComponent.Tapped.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Mvu.fs b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Mvu.fs new file mode 100644 index 0000000..291101e --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.Mvu.fs @@ -0,0 +1,38 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module CellMvu = + let Appearing = + Attributes.Mvu.defineEventNoArg "CellMvu_Appearing" (fun target -> (target :?> Cell).Appearing) + + let Disappearing = + Attributes.Mvu.defineEventNoArg "CellMvu_Disappearing" (fun target -> (target :?> Cell).Disappearing) + + let Tapped = + Attributes.Mvu.defineEventNoArg "CellMvu_Tapped" (fun target -> (target :?> Cell).Tapped) + +[] +type CellMvuModifiers = + /// Listen to the Appearing event + /// Current widget + /// Message to dispatch + [] + static member inline onAppearing(this: WidgetBuilder<'msg, #IFabCell>, msg: 'msg) = + this.AddScalar(CellMvu.Appearing.WithValue(MsgValue(msg))) + + /// Listen to the Disappearing event + /// Current widget + /// Message to dispatch + [] + static member inline onDisappearing(this: WidgetBuilder<'msg, #IFabCell>, msg: 'msg) = + this.AddScalar(CellMvu.Disappearing.WithValue(MsgValue(msg))) + + /// Listen to the Tapped event + /// Current widget + /// Message to dispatch + [] + static member inline onTapped(this: WidgetBuilder<'msg, #IFabCell>, msg: 'msg) = + this.AddScalar(CellMvu.Tapped.WithValue(MsgValue(msg))) diff --git a/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs new file mode 100644 index 0000000..87fd99a --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs @@ -0,0 +1,58 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Fabulous.StackAllocatedCollections +open Microsoft.Maui.Controls + +type IFabCell = + inherit IFabElement + +module Cell = + let Height = + Attributes.defineFloat "Cell_Height" (fun _ newValueOpt node -> + let cell = node.Target :?> Cell + + let value = + match newValueOpt with + | ValueNone -> cell.Height + | ValueSome v -> v + + cell.Height <- value) + + let IsEnabled = Attributes.defineBindableBool Cell.IsEnabledProperty + + let ContextActions = + Attributes.defineListWidgetCollection "Cell_ContextActions" (fun target -> (target :?> Cell).ContextActions) + +[] +type CellModifiers = + /// Set a value that indicates whether the cell is enabled + /// Current widget + /// true if the cell is enabled; otherwise, false + [] + static member inline isEnabled(this: WidgetBuilder<'msg, #IFabCell>, value: bool) = + this.AddScalar(Cell.IsEnabled.WithValue(value)) + + /// Set the desired height override of this widget + /// Current widget + /// The height this widget desires to be + [] + static member inline height(this: WidgetBuilder<'msg, #IFabCell>, value: float) = + this.AddScalar(Cell.Height.WithValue(value)) + + /// Set the context actions of the cell + /// Current widget + [] + static member inline contextActions<'msg, 'marker when 'msg: equality and 'marker :> IFabCell>(this: WidgetBuilder<'msg, 'marker>) = + WidgetHelpers.buildAttributeCollection<'msg, 'marker, IFabMenuItem> Cell.ContextActions this + +[] +type CellYieldExtensions = + [] + static member inline Yield<'msg, 'marker, 'itemType when 'msg: equality and 'marker :> IFabCell and 'itemType :> IFabMenuItem> + ( + _: AttributeCollectionBuilder<'msg, 'marker, IFabMenuItem>, + x: WidgetBuilder<'msg, 'itemType> + ) : Content<'msg> = + { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Component.fs b/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Component.fs new file mode 100644 index 0000000..19282fa --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Component.fs @@ -0,0 +1,19 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module CollectionViewComponent = + let SelectionChanged = + Attributes.Component.defineEvent "CollectionViewComponent_SelectionChanged" (fun target -> + (target :?> CollectionView).SelectionChanged) + +[] +type CollectionViewComponentModifiers = + /// Listen for the SelectionChanged event + /// Current widget + /// Message to dispatch + [] + static member inline onSelectionChanged(this: WidgetBuilder, fn: SelectionChangedEventArgs -> unit) = + this.AddScalar(CollectionViewComponent.SelectionChanged.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Mvu.fs b/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Mvu.fs new file mode 100644 index 0000000..53a9f5e --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.Mvu.fs @@ -0,0 +1,18 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module CollectionViewMvu = + let SelectionChanged = + Attributes.Mvu.defineEvent "CollectionViewMvu_SelectionChanged" (fun target -> (target :?> CollectionView).SelectionChanged) + +[] +type CollectionViewMvuModifiers = + /// Listen for the SelectionChanged event + /// Current widget + /// Message to dispatch + [] + static member inline onSelectionChanged(this: WidgetBuilder<'msg, #IFabCollectionView>, fn: SelectionChangedEventArgs -> 'msg) = + this.AddScalar(CollectionViewMvu.SelectionChanged.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/Collections/CollectionView.fs b/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.fs similarity index 81% rename from src/Fabulous.MauiControls/Views/Collections/CollectionView.fs rename to src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.fs index e28762a..7a13ff9 100644 --- a/src/Fabulous.MauiControls/Views/Collections/CollectionView.fs +++ b/src/Fabulous.MauiControls/Views/Collections/CollectionView/CollectionView.fs @@ -2,7 +2,6 @@ namespace Fabulous.Maui open System.Runtime.CompilerServices open Fabulous -open Microsoft.Maui open Microsoft.Maui.Controls type IFabCollectionView = @@ -48,13 +47,6 @@ module CollectionView = let ItemSizingStrategy = Attributes.defineBindableEnum CollectionView.ItemSizingStrategyProperty - let SelectionChangedMsg = - Attributes.defineEvent "CollectionView_SelectionChangedMsg" (fun target -> (target :?> CollectionView).SelectionChanged) - - let SelectionChangedFn = - Attributes.defineEventNoDispatch "CollectionView_SelectionChangedFn" (fun target -> - (target :?> CollectionView).SelectionChanged) - let SelectionMode = Attributes.defineBindableEnum CollectionView.SelectionModeProperty @@ -101,20 +93,6 @@ type CollectionViewModifiers = static member inline itemSizingStrategy(this: WidgetBuilder<'msg, #IFabCollectionView>, value: ItemSizingStrategy) = this.AddScalar(CollectionView.ItemSizingStrategy.WithValue(value)) - /// Listen for the SelectionChanged event - /// Current widget - /// Message to dispatch - [] - static member inline onSelectionChanged(this: WidgetBuilder<'msg, #IFabCollectionView>, fn: SelectionChangedEventArgs -> 'msg) = - this.AddScalar(CollectionView.SelectionChangedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the SelectionChanged event - /// Current widget - /// Message to dispatch - [] - static member inline onSelectionChanged(this: WidgetBuilder<'msg, #IFabCollectionView>, fn: SelectionChangedEventArgs -> unit) = - this.AddScalar(CollectionView.SelectionChangedFn.WithValue(fn)) - /// Set the selection mode /// Current widget /// The selection mode diff --git a/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs new file mode 100644 index 0000000..bdef156 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs @@ -0,0 +1,78 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ListViewComponent = + let ItemAppearing = + Attributes.Component.defineEvent "ListViewComponent_ItemAppearing" (fun target -> (target :?> ListView).ItemAppearing) + + let ItemDisappearing = + Attributes.Component.defineEvent "ListViewComponent_ItemDisappearing" (fun target -> (target :?> ListView).ItemDisappearing) + + let ItemSelected = + Attributes.Component.defineEvent "ListViewComponent_ItemSelected" (fun target -> (target :?> ListView).ItemSelected) + + let ItemTapped = + Attributes.Component.defineEvent "ListViewComponent_ItemTapped" (fun target -> (target :?> ListView).ItemTapped) + + let Refreshing = + Attributes.Component.defineEventNoArg "ListViewComponent_Refreshing" (fun target -> (target :?> ListView).Refreshing) + + let Scrolled = + Attributes.Component.defineEvent "ListViewComponent_Scrolled" (fun target -> (target :?> ListView).Scrolled) + + let ScrollToRequested = + Attributes.Component.defineEvent "ListViewComponent_ScrollToRequested" (fun target -> (target :?> ListView).ScrollToRequested) + +[] +type ListViewComponentModifiers = + /// Listen for the ItemAppearing event + /// Current widget + /// Message to dispatch + [] + static member inline onItemAppearing(this: WidgetBuilder, fn: ItemVisibilityEventArgs -> unit) = + this.AddScalar(ListViewComponent.ItemAppearing.WithValue(fn)) + + /// Listen for the ItemDisappearing event + /// Current widget + /// Message to dispatch + [] + static member inline onItemDisappearing(this: WidgetBuilder, fn: ItemVisibilityEventArgs -> unit) = + this.AddScalar(ListViewComponent.ItemDisappearing.WithValue(fn)) + + /// Listen for the ItemTapped event + /// Current widget + /// Message to dispatch + [] + static member inline onItemTapped(this: WidgetBuilder, fn: int -> unit) = + this.AddScalar(ListViewComponent.ItemTapped.WithValue(fun args -> fn args.ItemIndex)) + + /// Listen for the ItemSelected event + /// Current widget + /// Message to dispatch + [] + static member inline onItemSelected(this: WidgetBuilder, fn: int -> unit) = + this.AddScalar(ListViewComponent.ItemSelected.WithValue(fun args -> fn args.SelectedItemIndex)) + + /// Listen for the Refreshing event + /// Current widget + /// Function to execute + [] + static member inline onRefreshing(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ListViewComponent.Refreshing.WithValue(fn)) + + /// Listen for the Scrolled event + /// Current widget + /// Message to dispatch + [] + static member inline onScrolled(this: WidgetBuilder, fn: ScrolledEventArgs -> unit) = + this.AddScalar(ListViewComponent.Scrolled.WithValue(fn)) + + /// Listen for the ScrollToRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onScrollToRequested(this: WidgetBuilder, fn: ScrollToRequestedEventArgs -> unit) = + this.AddScalar(ListViewComponent.ScrollToRequested.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs new file mode 100644 index 0000000..b621227 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs @@ -0,0 +1,78 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ListViewMvu = + let ItemAppearing = + Attributes.Mvu.defineEvent "ListViewMvu_ItemAppearing" (fun target -> (target :?> ListView).ItemAppearing) + + let ItemDisappearing = + Attributes.Mvu.defineEvent "ListViewMvu_ItemDisappearing" (fun target -> (target :?> ListView).ItemDisappearing) + + let ItemSelected = + Attributes.Mvu.defineEvent "ListViewMvu_ItemSelected" (fun target -> (target :?> ListView).ItemSelected) + + let ItemTapped = + Attributes.Mvu.defineEvent "ListViewMvu_ItemTapped" (fun target -> (target :?> ListView).ItemTapped) + + let Refreshing = + Attributes.Mvu.defineEventNoArg "ListViewMvu_Refreshing" (fun target -> (target :?> ListView).Refreshing) + + let Scrolled = + Attributes.Mvu.defineEvent "ListViewMvu_Scrolled" (fun target -> (target :?> ListView).Scrolled) + + let ScrollToRequested = + Attributes.Mvu.defineEvent "ListViewMvu_ScrollToRequested" (fun target -> (target :?> ListView).ScrollToRequested) + +[] +type ListViewMvuModifiers = + /// Listen for the ItemAppearing event + /// Current widget + /// Message to dispatch + [] + static member inline onItemAppearing(this: WidgetBuilder<'msg, #IFabListView>, fn: ItemVisibilityEventArgs -> 'msg) = + this.AddScalar(ListViewMvu.ItemAppearing.WithValue(fun args -> fn args |> box)) + + /// Listen for the ItemDisappearing event + /// Current widget + /// Message to dispatch + [] + static member inline onItemDisappearing(this: WidgetBuilder<'msg, #IFabListView>, fn: ItemVisibilityEventArgs -> 'msg) = + this.AddScalar(ListViewMvu.ItemDisappearing.WithValue(fun args -> fn args |> box)) + + /// Listen for the ItemTapped event + /// Current widget + /// Message to dispatch + [] + static member inline onItemTapped(this: WidgetBuilder<'msg, #IFabListView>, fn: int -> 'msg) = + this.AddScalar(ListViewMvu.ItemTapped.WithValue(fun args -> fn args.ItemIndex |> box)) + + /// Listen for the ItemSelected event + /// Current widget + /// Message to dispatch + [] + static member inline onItemSelected(this: WidgetBuilder<'msg, #IFabListView>, fn: int -> 'msg) = + this.AddScalar(ListViewMvu.ItemSelected.WithValue(fun args -> fn args.SelectedItemIndex |> box)) + + /// Listen for the Refreshing event + /// Current widget + /// Message to dispatch + [] + static member inline onRefreshing(this: WidgetBuilder<'msg, #IFabListView>, msg: 'msg) = + this.AddScalar(ListViewMvu.Refreshing.WithValue(MsgValue(msg))) + + /// Listen for the Scrolled event + /// Current widget + /// Message to dispatch + [] + static member inline onScrolled(this: WidgetBuilder<'msg, #IFabListView>, fn: ScrolledEventArgs -> 'msg) = + this.AddScalar(ListViewMvu.Scrolled.WithValue(fun args -> fn args |> box)) + + /// Listen for the ScrollToRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onScrollToRequested(this: WidgetBuilder<'msg, #IFabListView>, fn: ScrollToRequestedEventArgs -> 'msg) = + this.AddScalar(ListViewMvu.ScrollToRequested.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/Collections/ListView.fs b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.fs similarity index 54% rename from src/Fabulous.MauiControls/Views/Collections/ListView.fs rename to src/Fabulous.MauiControls/Views/Collections/ListView/ListView.fs index 00b1615..f1d19ee 100644 --- a/src/Fabulous.MauiControls/Views/Collections/ListView.fs +++ b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.fs @@ -53,39 +53,9 @@ module ListView = let IsRefreshing = Attributes.defineBindableBool ListView.IsRefreshingProperty - let ItemAppearingMsg = - Attributes.defineEvent "ListView_ItemAppearingMsg" (fun target -> (target :?> ListView).ItemAppearing) - - let ItemAppearingFn = - Attributes.defineEventNoDispatch "ListView_ItemAppearingFn" (fun target -> (target :?> ListView).ItemAppearing) - - let ItemDisappearingMsg = - Attributes.defineEvent "ListView_ItemDisappearingMsg" (fun target -> (target :?> ListView).ItemDisappearing) - - let ItemDisappearingFn = - Attributes.defineEventNoDispatch "ListView_ItemDisappearingFn" (fun target -> (target :?> ListView).ItemDisappearing) - - let ItemSelectedMsg = - Attributes.defineEvent "ListView_ItemSelectedMsg" (fun target -> (target :?> ListView).ItemSelected) - - let ItemSelectedFn = - Attributes.defineEventNoDispatch "ListView_ItemSelectedFn" (fun target -> (target :?> ListView).ItemSelected) - - let ItemTappedMsg = - Attributes.defineEvent "ListView_ItemTappedMsg" (fun target -> (target :?> ListView).ItemTapped) - - let ItemTappedFn = - Attributes.defineEvent "ListView_ItemTappedFn" (fun target -> (target :?> ListView).ItemTapped) - let RefreshControlColor = Attributes.defineBindableColor ListView.RefreshControlColorProperty - let RefreshingMsg = - Attributes.defineEventNoArg "ListView_RefreshingMsg" (fun target -> (target :?> ListView).Refreshing) - - let RefreshingFn = - Attributes.defineEventNoArgNoDispatch "ListView_RefreshingFn" (fun target -> (target :?> ListView).Refreshing) - let RowHeight = Attributes.defineBindableInt ListView.RowHeightProperty let SelectionMode = @@ -96,18 +66,6 @@ module ListView = let SeparatorVisibility = Attributes.defineBindableEnum ListView.SeparatorVisibilityProperty - let ScrolledMsg = - Attributes.defineEvent "ListView_ScrolledMsg" (fun target -> (target :?> ListView).Scrolled) - - let ScrolledFn = - Attributes.defineEventNoDispatch "ListView_ScrolledFn" (fun target -> (target :?> ListView).Scrolled) - - let ScrollToRequestedMsg = - Attributes.defineEvent "ListView_ScrollToRequestedMsg" (fun target -> (target :?> ListView).ScrollToRequested) - - let ScrollToRequestedFn = - Attributes.defineEventNoDispatch "ListView_ScrollToRequestedFn" (fun target -> (target :?> ListView).ScrollToRequested) - let VerticalScrollBarVisibility = Attributes.defineBindableEnum ListView.VerticalScrollBarVisibilityProperty @@ -175,104 +133,6 @@ type ListViewModifiers = static member inline isRefreshing(this: WidgetBuilder<'msg, #IFabListView>, value: bool) = this.AddScalar(ListView.IsRefreshing.WithValue(value)) - /// Listen for the ItemAppearing event - /// Current widget - /// Message to dispatch - [] - static member inline onItemAppearing(this: WidgetBuilder<'msg, #IFabListView>, fn: ItemVisibilityEventArgs -> 'msg) = - this.AddScalar(ListView.ItemAppearingMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the ItemAppearing event - /// Current widget - /// Message to dispatch - [] - static member inline onItemAppearing(this: WidgetBuilder<'msg, #IFabListView>, fn: ItemVisibilityEventArgs -> unit) = - this.AddScalar(ListView.ItemAppearingFn.WithValue(fn)) - - /// Listen for the ItemDisappearing event - /// Current widget - /// Message to dispatch - [] - static member inline onItemDisappearing(this: WidgetBuilder<'msg, #IFabListView>, fn: ItemVisibilityEventArgs -> 'msg) = - this.AddScalar(ListView.ItemDisappearingMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the ItemDisappearing event - /// Current widget - /// Message to dispatch - [] - static member inline onItemDisappearing(this: WidgetBuilder<'msg, #IFabListView>, fn: ItemVisibilityEventArgs -> unit) = - this.AddScalar(ListView.ItemDisappearingFn.WithValue(fn)) - - /// Listen for the ItemTapped event - /// Current widget - /// Message to dispatch - [] - static member inline onItemTapped(this: WidgetBuilder<'msg, #IFabListView>, fn: int -> 'msg) = - this.AddScalar(ListView.ItemTappedMsg.WithValue(fun args -> fn args.ItemIndex |> box)) - - /// Listen for the ItemTapped event - /// Current widget - /// Message to dispatch - [] - static member inline onItemTapped(this: WidgetBuilder<'msg, #IFabListView>, fn: int -> unit) = - this.AddScalar(ListView.ItemTappedFn.WithValue(fun args -> fn args.ItemIndex)) - - /// Listen for the ItemSelected event - /// Current widget - /// Message to dispatch - [] - static member inline onItemSelected(this: WidgetBuilder<'msg, #IFabListView>, fn: int -> 'msg) = - this.AddScalar(ListView.ItemSelectedMsg.WithValue(fun args -> fn args.SelectedItemIndex |> box)) - - /// Listen for the ItemSelected event - /// Current widget - /// Message to dispatch - [] - static member inline onItemSelected(this: WidgetBuilder<'msg, #IFabListView>, fn: int -> unit) = - this.AddScalar(ListView.ItemSelectedFn.WithValue(fun args -> fn args.SelectedItemIndex)) - - /// Listen for the Refreshing event - /// Current widget - /// Message to dispatch - [] - static member inline onRefreshing(this: WidgetBuilder<'msg, #IFabListView>, msg: 'msg) = - this.AddScalar(ListView.RefreshingMsg.WithValue(MsgValue(msg))) - - /// Listen for the Refreshing event - /// Current widget - /// Function to execute - [] - static member inline onRefreshing(this: WidgetBuilder<'msg, #IFabListView>, fn: unit -> unit) = - this.AddScalar(ListView.RefreshingFn.WithValue(fn)) - - /// Listen for the Scrolled event - /// Current widget - /// Message to dispatch - [] - static member inline onScrolled(this: WidgetBuilder<'msg, #IFabListView>, fn: ScrolledEventArgs -> 'msg) = - this.AddScalar(ListView.ScrolledMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the Scrolled event - /// Current widget - /// Message to dispatch - [] - static member inline onScrolled(this: WidgetBuilder<'msg, #IFabListView>, fn: ScrolledEventArgs -> unit) = - this.AddScalar(ListView.ScrolledFn.WithValue(fn)) - - /// Listen for the ScrollToRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onScrollToRequested(this: WidgetBuilder<'msg, #IFabListView>, fn: ScrollToRequestedEventArgs -> 'msg) = - this.AddScalar(ListView.ScrollToRequestedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the ScrollToRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onScrollToRequested(this: WidgetBuilder<'msg, #IFabListView>, fn: ScrollToRequestedEventArgs -> unit) = - this.AddScalar(ListView.ScrollToRequestedFn.WithValue(fn)) - /// Set the refresh control color /// Current widget /// The refresh control color diff --git a/src/Fabulous.MauiControls/Views/Collections/_ItemsView.fs b/src/Fabulous.MauiControls/Views/Collections/_ItemsView.fs deleted file mode 100644 index 2d8da54..0000000 --- a/src/Fabulous.MauiControls/Views/Collections/_ItemsView.fs +++ /dev/null @@ -1,136 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui -open Microsoft.Maui.Controls - -type IFabItemsView = - inherit IFabView - -module ItemsView = - let EmptyView = Attributes.defineBindableWidget ItemsView.EmptyViewProperty - - let HorizontalScrollBarVisibility = - Attributes.defineBindableEnum ItemsView.HorizontalScrollBarVisibilityProperty - - let ItemsSource = - Attributes.defineSimpleScalar - "ItemsView_ItemsSource" - (fun a b -> ScalarAttributeComparers.equalityCompare a.OriginalItems b.OriginalItems) - (fun _ newValueOpt node -> - let itemsView = node.Target :?> ItemsView - - match newValueOpt with - | ValueNone -> - itemsView.ClearValue(ItemsView.ItemTemplateProperty) - itemsView.ClearValue(ItemsView.ItemsSourceProperty) - | ValueSome value -> - itemsView.SetValue(ItemsView.ItemTemplateProperty, WidgetDataTemplateSelector(node, unbox >> value.Template)) - - itemsView.SetValue(ItemsView.ItemsSourceProperty, value.OriginalItems)) - - let ItemsUpdatingScrollMode = - Attributes.defineBindableEnum ItemsView.ItemsUpdatingScrollModeProperty - - let RemainingItemsThreshold = - Attributes.defineBindableInt ItemsView.RemainingItemsThresholdProperty - - let RemainingItemsThresholdReachedMsg = - Attributes.defineEventNoArg "ItemsView_RemainingItemsThresholdReachedMsg" (fun target -> (target :?> ItemsView).RemainingItemsThresholdReached) - - let RemainingItemsThresholdReachedFn = - Attributes.defineEventNoArgNoDispatch "ItemsView_RemainingItemsThresholdReachedFn" (fun target -> (target :?> ItemsView).RemainingItemsThresholdReached) - - let ScrolledMsg = - Attributes.defineEvent "ItemsView_ScrolledMsg" (fun target -> (target :?> ItemsView).Scrolled) - - let ScrolledFn = - Attributes.defineEventNoDispatch "ItemsView_ScrolledFn" (fun target -> (target :?> ItemsView).Scrolled) - - let ScrollToRequestedMsg = - Attributes.defineEvent "ItemsView_ScrolledRequestedMsg" (fun target -> (target :?> ItemsView).ScrollToRequested) - - let ScrollToRequestedFn = - Attributes.defineEventNoDispatch "ItemsView_ScrolledRequestedFn" (fun target -> (target :?> ItemsView).ScrollToRequested) - - let VerticalScrollBarVisibility = - Attributes.defineBindableEnum ItemsView.VerticalScrollBarVisibilityProperty - -[] -type ItemsViewModifiers = - /// Set the empty view widget - /// Current widget - /// The empty view widget - [] - static member inline emptyView(this: WidgetBuilder<'msg, #IFabItemsView>, content: WidgetBuilder<'msg, #IFabView>) = - this.AddWidget(ItemsView.EmptyView.WithValue(content.Compile())) - - /// Set the visibility of the horizontal scroll bar - /// Current widget - /// true if the horizontal scroll is enabled; otherwise, false - [] - static member inline horizontalScrollBarVisibility(this: WidgetBuilder<'msg, #IFabItemsView>, value: ScrollBarVisibility) = - this.AddScalar(ItemsView.HorizontalScrollBarVisibility.WithValue(value)) - - /// Set the items updating scroll mode - /// Current widget - /// The items updating scroll mode - [] - static member inline itemsUpdatingScrollMode(this: WidgetBuilder<'msg, #IFabItemsView>, value: ItemsUpdatingScrollMode) = - this.AddScalar(ItemsView.ItemsUpdatingScrollMode.WithValue(value)) - - /// Listen for the Scrolled event - /// Current widget - /// Message to dispatch - [] - static member inline onScrolled(this: WidgetBuilder<'msg, #IFabItemsView>, fn: ItemsViewScrolledEventArgs -> 'msg) = - this.AddScalar(ItemsView.ScrolledMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the Scrolled event - /// Current widget - /// Message to dispatch - [] - static member inline onScrolled(this: WidgetBuilder<'msg, #IFabItemsView>, fn: ItemsViewScrolledEventArgs -> unit) = - this.AddScalar(ItemsView.ScrolledFn.WithValue(fn)) - - /// Listen for the ScrollToRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onScrollToRequested(this: WidgetBuilder<'msg, #IFabItemsView>, fn: ScrollToRequestEventArgs -> 'msg) = - this.AddScalar(ItemsView.ScrollToRequestedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the ScrollToRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onScrollToRequested(this: WidgetBuilder<'msg, #IFabItemsView>, fn: ScrollToRequestEventArgs -> unit) = - this.AddScalar(ItemsView.ScrollToRequestedFn.WithValue(fn)) - - /// Set the threshold of items not yet visible in the list at which the RemainingItemsThresholdReached event will be fired - /// Current widget - /// The threshold of items not yet visible in the list - /// Message to dispatch - [] - static member inline remainingItemsThreshold(this: WidgetBuilder<'msg, #IFabItemsView>, value: int, onThresholdReached: 'msg) = - this - .AddScalar(ItemsView.RemainingItemsThreshold.WithValue(value)) - .AddScalar(ItemsView.RemainingItemsThresholdReachedMsg.WithValue(MsgValue(onThresholdReached))) - - /// Set the threshold of items not yet visible in the list at which the RemainingItemsThresholdReached event will be fired - /// Current widget - /// The threshold of items not yet visible in the list - /// Message to dispatch - [] - static member inline remainingItemsThreshold(this: WidgetBuilder<'msg, #IFabItemsView>, value: int, onThresholdReached: unit -> unit) = - this - .AddScalar(ItemsView.RemainingItemsThreshold.WithValue(value)) - .AddScalar(ItemsView.RemainingItemsThresholdReachedFn.WithValue(onThresholdReached)) - - /// Set the visibility of the vertical scroll bar - /// Current widget - /// true if the vertical scroll is enabled; otherwise, false - [] - static member inline verticalScrollBarVisibility(this: WidgetBuilder<'msg, #IFabItemsView>, value: ScrollBarVisibility) = - this.AddScalar(ItemsView.VerticalScrollBarVisibility.WithValue(value)) diff --git a/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs new file mode 100644 index 0000000..66a4494 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs @@ -0,0 +1,41 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ItemsViewComponent = + let RemainingItemsThresholdReached = + Attributes.Component.defineEventNoArg "ItemsViewComponent_RemainingItemsThresholdReached" (fun target -> (target :?> ItemsView).RemainingItemsThresholdReached) + + let Scrolled = + Attributes.Component.defineEvent "ItemsViewComponent_Scrolled" (fun target -> (target :?> ItemsView).Scrolled) + + let ScrollToRequested = + Attributes.Component.defineEvent "ItemsViewComponent_ScrolledRequested" (fun target -> (target :?> ItemsView).ScrollToRequested) + +[] +type ItemsViewComponentModifiers = + /// Listen for the Scrolled event + /// Current widget + /// Message to dispatch + [] + static member inline onScrolled(this: WidgetBuilder, fn: ItemsViewScrolledEventArgs -> unit) = + this.AddScalar(ItemsViewComponent.Scrolled.WithValue(fn)) + + /// Listen for the ScrollToRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onScrollToRequested(this: WidgetBuilder, fn: ScrollToRequestEventArgs -> unit) = + this.AddScalar(ItemsViewComponent.ScrollToRequested.WithValue(fn)) + + /// Set the threshold of items not yet visible in the list at which the RemainingItemsThresholdReached event will be fired + /// Current widget + /// The threshold of items not yet visible in the list + /// Message to dispatch + [] + static member inline remainingItemsThreshold(this: WidgetBuilder, value: int, onThresholdReached: unit -> unit) = + this + .AddScalar(ItemsView.RemainingItemsThreshold.WithValue(value)) + .AddScalar(ItemsViewComponent.RemainingItemsThresholdReached.WithValue(onThresholdReached)) diff --git a/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Mvu.fs b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Mvu.fs new file mode 100644 index 0000000..0a2a10f --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Mvu.fs @@ -0,0 +1,41 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ItemsViewMvu = + let RemainingItemsThresholdReached = + Attributes.Mvu.defineEventNoArg "ItemsViewMvu_RemainingItemsThresholdReached" (fun target -> (target :?> ItemsView).RemainingItemsThresholdReached) + + let Scrolled = + Attributes.Mvu.defineEvent "ItemsViewMvu_Scrolled" (fun target -> (target :?> ItemsView).Scrolled) + + let ScrollToRequested = + Attributes.Mvu.defineEvent "ItemsViewMvu_ScrolledRequested" (fun target -> (target :?> ItemsView).ScrollToRequested) + +[] +type ItemsViewMvuModifiers = + /// Listen for the Scrolled event + /// Current widget + /// Message to dispatch + [] + static member inline onScrolled(this: WidgetBuilder<'msg, #IFabItemsView>, fn: ItemsViewScrolledEventArgs -> 'msg) = + this.AddScalar(ItemsViewMvu.Scrolled.WithValue(fun args -> fn args |> box)) + + /// Listen for the ScrollToRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onScrollToRequested(this: WidgetBuilder<'msg, #IFabItemsView>, fn: ScrollToRequestEventArgs -> 'msg) = + this.AddScalar(ItemsViewMvu.ScrollToRequested.WithValue(fun args -> fn args |> box)) + + /// Set the threshold of items not yet visible in the list at which the RemainingItemsThresholdReached event will be fired + /// Current widget + /// The threshold of items not yet visible in the list + /// Message to dispatch + [] + static member inline remainingItemsThreshold(this: WidgetBuilder<'msg, #IFabItemsView>, value: int, onThresholdReached: 'msg) = + this + .AddScalar(ItemsView.RemainingItemsThreshold.WithValue(value)) + .AddScalar(ItemsViewMvu.RemainingItemsThresholdReached.WithValue(MsgValue(onThresholdReached))) diff --git a/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.fs b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.fs new file mode 100644 index 0000000..979c05c --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.fs @@ -0,0 +1,70 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui +open Microsoft.Maui.Controls + +type IFabItemsView = + inherit IFabView + +module ItemsView = + let EmptyView = Attributes.defineBindableWidget ItemsView.EmptyViewProperty + + let HorizontalScrollBarVisibility = + Attributes.defineBindableEnum ItemsView.HorizontalScrollBarVisibilityProperty + + let ItemsSource = + Attributes.defineSimpleScalar + "ItemsView_ItemsSource" + (fun a b -> ScalarAttributeComparers.equalityCompare a.OriginalItems b.OriginalItems) + (fun _ newValueOpt node -> + let itemsView = node.Target :?> ItemsView + + match newValueOpt with + | ValueNone -> + itemsView.ClearValue(ItemsView.ItemTemplateProperty) + itemsView.ClearValue(ItemsView.ItemsSourceProperty) + | ValueSome value -> + itemsView.SetValue(ItemsView.ItemTemplateProperty, WidgetDataTemplateSelector(node, unbox >> value.Template)) + + itemsView.SetValue(ItemsView.ItemsSourceProperty, value.OriginalItems)) + + let ItemsUpdatingScrollMode = + Attributes.defineBindableEnum ItemsView.ItemsUpdatingScrollModeProperty + + let RemainingItemsThreshold = + Attributes.defineBindableInt ItemsView.RemainingItemsThresholdProperty + + let VerticalScrollBarVisibility = + Attributes.defineBindableEnum ItemsView.VerticalScrollBarVisibilityProperty + +[] +type ItemsViewModifiers = + /// Set the empty view widget + /// Current widget + /// The empty view widget + [] + static member inline emptyView(this: WidgetBuilder<'msg, #IFabItemsView>, content: WidgetBuilder<'msg, #IFabView>) = + this.AddWidget(ItemsView.EmptyView.WithValue(content.Compile())) + + /// Set the visibility of the horizontal scroll bar + /// Current widget + /// true if the horizontal scroll is enabled; otherwise, false + [] + static member inline horizontalScrollBarVisibility(this: WidgetBuilder<'msg, #IFabItemsView>, value: ScrollBarVisibility) = + this.AddScalar(ItemsView.HorizontalScrollBarVisibility.WithValue(value)) + + /// Set the items updating scroll mode + /// Current widget + /// The items updating scroll mode + [] + static member inline itemsUpdatingScrollMode(this: WidgetBuilder<'msg, #IFabItemsView>, value: ItemsUpdatingScrollMode) = + this.AddScalar(ItemsView.ItemsUpdatingScrollMode.WithValue(value)) + + /// Set the visibility of the vertical scroll bar + /// Current widget + /// true if the vertical scroll is enabled; otherwise, false + [] + static member inline verticalScrollBarVisibility(this: WidgetBuilder<'msg, #IFabItemsView>, value: ScrollBarVisibility) = + this.AddScalar(ItemsView.VerticalScrollBarVisibility.WithValue(value)) diff --git a/src/Fabulous.MauiControls/Views/Controls/Button/Button.Component.fs b/src/Fabulous.MauiControls/Views/Controls/Button/Button.Component.fs new file mode 100644 index 0000000..ba00f50 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Button/Button.Component.fs @@ -0,0 +1,40 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ButtonComponent = + let Clicked = + Attributes.Component.defineEventNoArg "ButtonComponent_Clicked" (fun target -> (target :?> Button).Clicked) + + let Pressed = + Attributes.Component.defineEventNoArg "ButtonComponent_Pressed" (fun target -> (target :?> Button).Pressed) + + let Released = + Attributes.Component.defineEventNoArg "ButtonComponent_Released" (fun target -> (target :?> Button).Released) + +[] +module ButtonComponentBuilders = + type Fabulous.Maui.View with + /// Create a Button widget with a text and listen for the Click event + /// The button on the tex + /// Function to execute + static member inline Button(text: string, onClicked: unit -> unit) = + WidgetBuilder(Button.WidgetKey, Button.Text.WithValue(text), ButtonComponent.Clicked.WithValue(onClicked)) + +[] +type ButtonComponentModifiers = + /// Listen for the Pressed event + /// Current widget + /// Function to execute + [] + static member inline onPressed(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ButtonComponent.Pressed.WithValue(fn)) + + /// Listen for the Released event + /// Current widget + /// Function to execute + [] + static member inline onReleased(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ButtonComponent.Released.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/Button/Button.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Button/Button.Mvu.fs new file mode 100644 index 0000000..382b2f7 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Button/Button.Mvu.fs @@ -0,0 +1,41 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ButtonMvu = + let Clicked = + Attributes.Mvu.defineEventNoArg "ButtonMvu_Clicked" (fun target -> (target :?> Button).Clicked) + + let Pressed = + Attributes.Mvu.defineEventNoArg "ButtonMvu_Pressed" (fun target -> (target :?> Button).Pressed) + + let Released = + Attributes.Mvu.defineEventNoArg "ButtonMvu_Released" (fun target -> (target :?> Button).Released) + +[] +module ButtonMvuBuilders = + type Fabulous.Maui.View with + + /// Create a Button widget with a text and listen for the Click event + /// The button on the tex + /// Message to dispatch + static member inline Button(text: string, onClicked: 'msg) = + WidgetBuilder<'msg, IFabButton>(Button.WidgetKey, Button.Text.WithValue(text), ButtonMvu.Clicked.WithValue(MsgValue(onClicked))) + +[] +type ButtonMvuModifiers = + /// Listen for the Pressed event + /// Current widget + /// Message to dispatch + [] + static member inline onPressed(this: WidgetBuilder<'msg, #IFabButton>, msg: 'msg) = + this.AddScalar(ButtonMvu.Pressed.WithValue(MsgValue(msg))) + + /// Listen for the Released event + /// Current widget + /// Message to dispatch + [] + static member inline onReleased(this: WidgetBuilder<'msg, #IFabButton>, msg: 'msg) = + this.AddScalar(ButtonMvu.Released.WithValue(MsgValue(msg))) diff --git a/src/Fabulous.MauiControls/Views/Controls/Button.fs b/src/Fabulous.MauiControls/Views/Controls/Button/Button.fs similarity index 75% rename from src/Fabulous.MauiControls/Views/Controls/Button.fs rename to src/Fabulous.MauiControls/Views/Controls/Button/Button.fs index 3dcdbea..fd07642 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Button.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Button/Button.fs @@ -21,12 +21,6 @@ module Button = let CharacterSpacing = Attributes.defineBindableFloat Button.CharacterSpacingProperty - let ClickedMsg = - Attributes.defineEventNoArg "Button_ClickedMsg" (fun target -> (target :?> Button).Clicked) - - let ClickedFn = - Attributes.defineEventNoArgNoDispatch "Button_ClickedFn" (fun target -> (target :?> Button).Clicked) - let ContentLayout = Attributes.defineBindableWithEquality Button.ContentLayoutProperty @@ -51,18 +45,6 @@ module Button = let Padding = Attributes.defineBindableWithEquality Button.PaddingProperty - let PressedMsg = - Attributes.defineEventNoArg "Button_PressedMsg" (fun target -> (target :?> Button).Pressed) - - let PressedFn = - Attributes.defineEventNoArgNoDispatch "Button_PressedFn" (fun target -> (target :?> Button).Pressed) - - let ReleasedMsg = - Attributes.defineEventNoArg "Button_ReleasedMsg" (fun target -> (target :?> Button).Released) - - let ReleasedFn = - Attributes.defineEventNoArgNoDispatch "Button_ReleasedFn" (fun target -> (target :?> Button).Released) - let Text = Attributes.defineBindableWithEquality Button.TextProperty let TextColor = Attributes.defineBindableColor Button.TextColorProperty @@ -70,22 +52,6 @@ module Button = let TextTransform = Attributes.defineBindableEnum Button.TextTransformProperty -[] -module ButtonBuilders = - type Fabulous.Maui.View with - - /// Create a Button widget with a text and listen for the Click event - /// The button on the tex - /// Message to dispatch - static member inline Button(text: string, onClicked: 'msg) = - WidgetBuilder<'msg, IFabButton>(Button.WidgetKey, Button.Text.WithValue(text), Button.ClickedMsg.WithValue(MsgValue(onClicked))) - - /// Create a Button widget with a text and listen for the Click event - /// The button on the tex - /// Function to execute - static member inline Button(text: string, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabButton>(Button.WidgetKey, Button.Text.WithValue(text), Button.ClickedFn.WithValue(onClicked)) - [] type ButtonModifiers = /// Set the border color @@ -179,34 +145,6 @@ type ButtonModifiers = static member inline lineBreakMode(this: WidgetBuilder<'msg, #IFabButton>, value: LineBreakMode) = this.AddScalar(Button.LineBreakMode.WithValue(value)) - /// Listen for the Pressed event - /// Current widget - /// Message to dispatch - [] - static member inline onPressed(this: WidgetBuilder<'msg, #IFabButton>, msg: 'msg) = - this.AddScalar(Button.PressedMsg.WithValue(MsgValue(msg))) - - /// Listen for the Pressed event - /// Current widget - /// Function to execute - [] - static member inline onPressed(this: WidgetBuilder<'msg, #IFabButton>, fn: unit -> unit) = - this.AddScalar(Button.PressedFn.WithValue(fn)) - - /// Listen for the Released event - /// Current widget - /// Message to dispatch - [] - static member inline onReleased(this: WidgetBuilder<'msg, #IFabButton>, msg: 'msg) = - this.AddScalar(Button.ReleasedMsg.WithValue(MsgValue(msg))) - - /// Listen for the Released event - /// Current widget - /// Function to execute - [] - static member inline onReleased(this: WidgetBuilder<'msg, #IFabButton>, fn: unit -> unit) = - this.AddScalar(Button.ReleasedFn.WithValue(fn)) - /// Set the padding inside the button /// Current widget /// The padding inside the button diff --git a/src/Fabulous.MauiControls/Views/Controls/CheckBox.fs b/src/Fabulous.MauiControls/Views/Controls/CheckBox.fs deleted file mode 100644 index 263d807..0000000 --- a/src/Fabulous.MauiControls/Views/Controls/CheckBox.fs +++ /dev/null @@ -1,60 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls -open Microsoft.Maui.Graphics - -type IFabCheckBox = - inherit IFabView - -module CheckBox = - let WidgetKey = Widgets.register() - - let Color = Attributes.defineBindableColor CheckBox.ColorProperty - - let IsCheckedWithEventMsg = - Attributes.defineBindableWithEvent "CheckBox_CheckedChangedMsg" CheckBox.IsCheckedProperty (fun target -> (target :?> CheckBox).CheckedChanged) - - let IsCheckedWithEventFn = - Attributes.defineBindableWithEventNoDispatch "CheckBox_CheckedChangedFn" CheckBox.IsCheckedProperty (fun target -> (target :?> CheckBox).CheckedChanged) - -[] -module CheckBoxBuilders = - type Fabulous.Maui.View with - - /// Create a CheckBox widget with a state and listen for state changes - /// The state of the checkbox - /// Message to dispatch - static member inline CheckBox(isChecked: bool, onCheckedChanged: bool -> 'msg) = - WidgetBuilder<'msg, IFabCheckBox>( - CheckBox.WidgetKey, - CheckBox.IsCheckedWithEventMsg.WithValue( - MsgValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onCheckedChanged args.Value) - ) - ) - - /// Create a CheckBox widget with a state and listen for state changes - /// The state of the checkbox - /// Message to dispatch - static member inline CheckBox(isChecked: bool, onCheckedChanged: bool -> unit) = - WidgetBuilder<'msg, IFabCheckBox>( - CheckBox.WidgetKey, - CheckBox.IsCheckedWithEventFn.WithValue(ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onCheckedChanged args.Value)) - ) - -[] -type CheckBoxModifiers = - /// Set the color of the check box - /// Current widget - /// The color of the check box - [] - static member inline color(this: WidgetBuilder<'msg, #IFabCheckBox>, value: Color) = - this.AddScalar(CheckBox.Color.WithValue(value)) - - /// Link a ViewRef to access the direct CheckBox control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabCheckBox>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs new file mode 100644 index 0000000..185b7cf --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs @@ -0,0 +1,21 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module CheckBoxComponent = + let IsCheckedWithEvent = + Attributes.Component.defineBindableWithEvent "CheckBoxComponent_CheckedChanged" CheckBox.IsCheckedProperty (fun target -> (target :?> CheckBox).CheckedChanged) + +[] +module CheckBoxComponentBuilders = + type Fabulous.Maui.View with + + /// Create a CheckBox widget with a state and listen for state changes + /// The state of the checkbox + /// Message to dispatch + static member inline CheckBox(isChecked: bool, onCheckedChanged: bool -> unit) = + WidgetBuilder( + CheckBox.WidgetKey, + CheckBoxComponent.IsCheckedWithEvent.WithValue(ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onCheckedChanged args.Value)) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Mvu.fs new file mode 100644 index 0000000..65de853 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Mvu.fs @@ -0,0 +1,23 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module CheckBoxMvu = + let IsCheckedWithEvent = + Attributes.Mvu.defineBindableWithEvent "CheckBoxMvu_CheckedChanged" CheckBox.IsCheckedProperty (fun target -> (target :?> CheckBox).CheckedChanged) + +[] +module CheckBoxMvuBuilders = + type Fabulous.Maui.View with + + /// Create a CheckBox widget with a state and listen for state changes + /// The state of the checkbox + /// Message to dispatch + static member inline CheckBox(isChecked: bool, onCheckedChanged: bool -> 'msg) = + WidgetBuilder<'msg, IFabCheckBox>( + CheckBox.WidgetKey, + CheckBoxMvu.IsCheckedWithEvent.WithValue( + MsgValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onCheckedChanged args.Value) + ) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.fs b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.fs new file mode 100644 index 0000000..8a78b63 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.fs @@ -0,0 +1,30 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls +open Microsoft.Maui.Graphics + +type IFabCheckBox = + inherit IFabView + +module CheckBox = + let WidgetKey = Widgets.register() + + let Color = Attributes.defineBindableColor CheckBox.ColorProperty + +[] +type CheckBoxModifiers = + /// Set the color of the check box + /// Current widget + /// The color of the check box + [] + static member inline color(this: WidgetBuilder<'msg, #IFabCheckBox>, value: Color) = + this.AddScalar(CheckBox.Color.WithValue(value)) + + /// Link a ViewRef to access the direct CheckBox control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabCheckBox>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/Controls/DatePicker.fs b/src/Fabulous.MauiControls/Views/Controls/DatePicker.fs deleted file mode 100644 index 1662c83..0000000 --- a/src/Fabulous.MauiControls/Views/Controls/DatePicker.fs +++ /dev/null @@ -1,250 +0,0 @@ -namespace Fabulous.Maui - -open System -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls -open Microsoft.Maui.Controls.PlatformConfiguration -open Microsoft.Maui.Graphics - -type IFabDatePicker = - inherit IFabView - -module DatePicker = - let WidgetKey = Widgets.register() - - let CharacterSpacing = - Attributes.defineBindableFloat DatePicker.CharacterSpacingProperty - - let DateWithEventMsg = - let name = "DatePicker_DateSelectedMsg" - let minProperty = DatePicker.MinimumDateProperty - let valueProperty = DatePicker.DateProperty - let maxProperty = DatePicker.MaximumDateProperty - - let key = - ScalarAttributeDefinitions.SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun oldValueOpt (newValueOpt: MsgValueEventData voption) node -> - let target = node.Target :?> DatePicker - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the event - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> - target.ClearValue(minProperty) - target.ClearValue(maxProperty) - target.ClearValue(valueProperty) - - | ValueSome curr -> - // Clean up the old event handler if any - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - let struct (min, max, value) = curr.Value - target.SetValue(minProperty, min) - target.SetValue(maxProperty, max) - target.SetValue(valueProperty, value) - - // Set the new event handler - let handler = - target.DateSelected.Subscribe(fun args -> - let (MsgValue r) = curr.Event args - Dispatcher.dispatch node r) - - node.SetHandler(name, handler)) - ) - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } - : ScalarAttributeDefinitions.SimpleScalarAttributeDefinition> - - let DateWithEventFn = - let name = "DatePicker_DateSelectedFn" - let minProperty = DatePicker.MinimumDateProperty - let valueProperty = DatePicker.DateProperty - let maxProperty = DatePicker.MaximumDateProperty - - let key = - ScalarAttributeDefinitions.SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun oldValueOpt (newValueOpt: ValueEventData voption) node -> - let target = node.Target :?> DatePicker - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the event - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> - target.ClearValue(minProperty) - target.ClearValue(maxProperty) - target.ClearValue(valueProperty) - - | ValueSome curr -> - // Clean up the old event handler if any - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - let struct (min, max, value) = curr.Value - target.SetValue(minProperty, min) - target.SetValue(maxProperty, max) - target.SetValue(valueProperty, value) - - // Set the new event handler - let handler = target.DateSelected.Subscribe(curr.Event) - - node.SetHandler(name, handler)) - ) - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } - : ScalarAttributeDefinitions.SimpleScalarAttributeDefinition> - - let FontAttributes = - Attributes.defineBindableWithEquality DatePicker.FontAttributesProperty - - let FontAutoScalingEnabled = - Attributes.defineBindableBool DatePicker.FontAutoScalingEnabledProperty - - let FontFamily = - Attributes.defineBindableWithEquality DatePicker.FontFamilyProperty - - let FontSize = Attributes.defineBindableFloat DatePicker.FontSizeProperty - - let Format = Attributes.defineBindableWithEquality DatePicker.FormatProperty - - let TextColor = Attributes.defineBindableColor DatePicker.TextColorProperty - -module DatePickerPlatform = - let UpdateMode = - Attributes.defineSimpleScalarWithEquality "DatePicker_UpdateMode" (fun _ newValueOpt node -> - let datePicker = node.Target :?> DatePicker - - let value = - match newValueOpt with - | ValueNone -> iOSSpecific.UpdateMode.Immediately - | ValueSome v -> v - - iOSSpecific.DatePicker.SetUpdateMode(datePicker, value)) - -[] -module DatePickerBuilders = - type Fabulous.Maui.View with - - /// Create a DatePicker widget with a date, min-max bounds and listen for the date changes - /// The minimum date allowed - /// The maximum date allowed - /// The selected date - /// Message to dispatch - static member inline DatePicker(min: DateTime, max: DateTime, date: DateTime, onDateSelected: DateTime -> 'msg) = - WidgetBuilder<'msg, IFabDatePicker>( - DatePicker.WidgetKey, - DatePicker.DateWithEventMsg.WithValue( - MsgValueEventData.create (struct (min, max, date)) (fun (args: DateChangedEventArgs) -> onDateSelected args.NewDate) - ) - ) - - /// Create a DatePicker widget with a date, min-max bounds and listen for the date changes - /// The minimum date allowed - /// The maximum date allowed - /// The selected date - /// Message to dispatch - static member inline DatePicker(min: DateTime, max: DateTime, date: DateTime, onDateSelected: DateTime -> unit) = - WidgetBuilder<'msg, IFabDatePicker>( - DatePicker.WidgetKey, - DatePicker.DateWithEventFn.WithValue( - ValueEventData.create (struct (min, max, date)) (fun (args: DateChangedEventArgs) -> onDateSelected args.NewDate) - ) - ) - -[] -type DatePickerModifiers = - /// Set the character spacing - /// Current widget - /// The character spacing - [] - static member inline characterSpacing(this: WidgetBuilder<'msg, #IFabDatePicker>, value: float) = - this.AddScalar(DatePicker.CharacterSpacing.WithValue(value)) - - /// Set the font - /// Current widget - /// The font size - /// The font attributes - /// The font family - /// The value indicating whether auto-scaling is enabled - [] - static member inline font - ( - this: WidgetBuilder<'msg, #IFabDatePicker>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = - - let mutable res = this - - match size with - | None -> () - | Some v -> res <- res.AddScalar(DatePicker.FontSize.WithValue(v)) - - match attributes with - | None -> () - | Some v -> res <- res.AddScalar(DatePicker.FontAttributes.WithValue(v)) - - match fontFamily with - | None -> () - | Some v -> res <- res.AddScalar(DatePicker.FontFamily.WithValue(v)) - - match autoScalingEnabled with - | None -> () - | Some v -> res <- res.AddScalar(DatePicker.FontAutoScalingEnabled.WithValue(v)) - - res - - /// Set the display format of the selected date - /// Current widget - /// The display format - [] - static member inline format(this: WidgetBuilder<'msg, #IFabDatePicker>, value: string) = - this.AddScalar(DatePicker.Format.WithValue(value)) - - /// Set the color of the text - /// Current widget - /// The color of the text - [] - static member inline textColor(this: WidgetBuilder<'msg, #IFabDatePicker>, value: Color) = - this.AddScalar(DatePicker.TextColor.WithValue(value)) - - /// Link a ViewRef to access the direct DatePicker control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabDatePicker>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) - -[] -type DatePickerPlatformModifiers = - /// iOS platform specific. Set a value that controls whether elements in the date picker are continuously updated while scrolling or updated once after scrolling has completed - /// Current widget - /// The value that controls whether elements in the date picker are continuously updated while scrolling or updated once after scrolling has completed. - [] - static member inline updateMode(this: WidgetBuilder<'msg, #IFabDatePicker>, value: iOSSpecific.UpdateMode) = - this.AddScalar(DatePickerPlatform.UpdateMode.WithValue(value)) diff --git a/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Component.fs b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Component.fs new file mode 100644 index 0000000..bbbb70d --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Component.fs @@ -0,0 +1,72 @@ +namespace Fabulous.Maui + +open System +open Fabulous +open Microsoft.Maui.Controls + +module DatePickerComponent = + let DateWithEvent = + let name = "DatePickerComponent_DateSelected" + let minProperty = DatePicker.MinimumDateProperty + let valueProperty = DatePicker.DateProperty + let maxProperty = DatePicker.MaximumDateProperty + + let key = + ScalarAttributeDefinitions.SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun oldValueOpt (newValueOpt: ValueEventData voption) node -> + let target = node.Target :?> DatePicker + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the event + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> + target.ClearValue(minProperty) + target.ClearValue(maxProperty) + target.ClearValue(valueProperty) + + | ValueSome curr -> + // Clean up the old event handler if any + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + let struct (min, max, value) = curr.Value + target.SetValue(minProperty, min) + target.SetValue(maxProperty, max) + target.SetValue(valueProperty, value) + + // Set the new event handler + let handler = target.DateSelected.Subscribe(curr.Event) + + node.SetHandler(name, handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } + : ScalarAttributeDefinitions.SimpleScalarAttributeDefinition> + +[] +module DatePickerComponentBuilders = + type Fabulous.Maui.View with + + /// Create a DatePicker widget with a date, min-max bounds and listen for the date changes + /// The minimum date allowed + /// The maximum date allowed + /// The selected date + /// Message to dispatch + static member inline DatePicker(min: DateTime, max: DateTime, date: DateTime, onDateSelected: DateTime -> unit) = + WidgetBuilder( + DatePicker.WidgetKey, + DatePickerComponent.DateWithEvent.WithValue( + ValueEventData.create (struct (min, max, date)) (fun (args: DateChangedEventArgs) -> onDateSelected args.NewDate) + ) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Mvu.fs new file mode 100644 index 0000000..f204cfe --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.Mvu.fs @@ -0,0 +1,75 @@ +namespace Fabulous.Maui + +open System +open Fabulous +open Microsoft.Maui.Controls + +module DatePickerMvu = + let DateWithEvent = + let name = "DatePickerMvu_DateSelected" + let minProperty = DatePicker.MinimumDateProperty + let valueProperty = DatePicker.DateProperty + let maxProperty = DatePicker.MaximumDateProperty + + let key = + ScalarAttributeDefinitions.SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun oldValueOpt (newValueOpt: MsgValueEventData voption) node -> + let target = node.Target :?> DatePicker + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the event + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> + target.ClearValue(minProperty) + target.ClearValue(maxProperty) + target.ClearValue(valueProperty) + + | ValueSome curr -> + // Clean up the old event handler if any + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + let struct (min, max, value) = curr.Value + target.SetValue(minProperty, min) + target.SetValue(maxProperty, max) + target.SetValue(valueProperty, value) + + // Set the new event handler + let handler = + target.DateSelected.Subscribe(fun args -> + let (MsgValue r) = curr.Event args + Dispatcher.dispatch node r) + + node.SetHandler(name, handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } + : ScalarAttributeDefinitions.SimpleScalarAttributeDefinition> + +[] +module DatePickerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a DatePicker widget with a date, min-max bounds and listen for the date changes + /// The minimum date allowed + /// The maximum date allowed + /// The selected date + /// Message to dispatch + static member inline DatePicker(min: DateTime, max: DateTime, date: DateTime, onDateSelected: DateTime -> 'msg) = + WidgetBuilder<'msg, IFabDatePicker>( + DatePicker.WidgetKey, + DatePickerMvu.DateWithEvent.WithValue( + MsgValueEventData.create (struct (min, max, date)) (fun (args: DateChangedEventArgs) -> onDateSelected args.NewDate) + ) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs new file mode 100644 index 0000000..22076a8 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs @@ -0,0 +1,118 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls +open Microsoft.Maui.Controls.PlatformConfiguration +open Microsoft.Maui.Graphics + +type IFabDatePicker = + inherit IFabView + +module DatePicker = + let WidgetKey = Widgets.register() + + let CharacterSpacing = + Attributes.defineBindableFloat DatePicker.CharacterSpacingProperty + + let FontAttributes = + Attributes.defineBindableWithEquality DatePicker.FontAttributesProperty + + let FontAutoScalingEnabled = + Attributes.defineBindableBool DatePicker.FontAutoScalingEnabledProperty + + let FontFamily = + Attributes.defineBindableWithEquality DatePicker.FontFamilyProperty + + let FontSize = Attributes.defineBindableFloat DatePicker.FontSizeProperty + + let Format = Attributes.defineBindableWithEquality DatePicker.FormatProperty + + let TextColor = Attributes.defineBindableColor DatePicker.TextColorProperty + +module DatePickerPlatform = + let UpdateMode = + Attributes.defineSimpleScalarWithEquality "DatePicker_UpdateMode" (fun _ newValueOpt node -> + let datePicker = node.Target :?> DatePicker + + let value = + match newValueOpt with + | ValueNone -> iOSSpecific.UpdateMode.Immediately + | ValueSome v -> v + + iOSSpecific.DatePicker.SetUpdateMode(datePicker, value)) + +[] +type DatePickerModifiers = + /// Set the character spacing + /// Current widget + /// The character spacing + [] + static member inline characterSpacing(this: WidgetBuilder<'msg, #IFabDatePicker>, value: float) = + this.AddScalar(DatePicker.CharacterSpacing.WithValue(value)) + + /// Set the font + /// Current widget + /// The font size + /// The font attributes + /// The font family + /// The value indicating whether auto-scaling is enabled + [] + static member inline font + ( + this: WidgetBuilder<'msg, #IFabDatePicker>, + ?size: float, + ?attributes: FontAttributes, + ?fontFamily: string, + ?autoScalingEnabled: bool + ) = + + let mutable res = this + + match size with + | None -> () + | Some v -> res <- res.AddScalar(DatePicker.FontSize.WithValue(v)) + + match attributes with + | None -> () + | Some v -> res <- res.AddScalar(DatePicker.FontAttributes.WithValue(v)) + + match fontFamily with + | None -> () + | Some v -> res <- res.AddScalar(DatePicker.FontFamily.WithValue(v)) + + match autoScalingEnabled with + | None -> () + | Some v -> res <- res.AddScalar(DatePicker.FontAutoScalingEnabled.WithValue(v)) + + res + + /// Set the display format of the selected date + /// Current widget + /// The display format + [] + static member inline format(this: WidgetBuilder<'msg, #IFabDatePicker>, value: string) = + this.AddScalar(DatePicker.Format.WithValue(value)) + + /// Set the color of the text + /// Current widget + /// The color of the text + [] + static member inline textColor(this: WidgetBuilder<'msg, #IFabDatePicker>, value: Color) = + this.AddScalar(DatePicker.TextColor.WithValue(value)) + + /// Link a ViewRef to access the direct DatePicker control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabDatePicker>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) + +[] +type DatePickerPlatformModifiers = + /// iOS platform specific. Set a value that controls whether elements in the date picker are continuously updated while scrolling or updated once after scrolling has completed + /// Current widget + /// The value that controls whether elements in the date picker are continuously updated while scrolling or updated once after scrolling has completed. + [] + static member inline updateMode(this: WidgetBuilder<'msg, #IFabDatePicker>, value: iOSSpecific.UpdateMode) = + this.AddScalar(DatePickerPlatform.UpdateMode.WithValue(value)) diff --git a/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Component.fs b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Component.fs new file mode 100644 index 0000000..4a161bd --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Component.fs @@ -0,0 +1,31 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module EditorComponent = + let Completed = + Attributes.Component.defineEventNoArg "EditorComponent_Completed" (fun target -> (target :?> Editor).Completed) + +[] +module EditorComponentBuilders = + type Fabulous.Maui.View with + + /// Create an Editor widget with a text and listen for text changes + /// The text value + /// Message to dispatch + static member inline Editor(text: string, onTextChanged: string -> unit) = + WidgetBuilder( + Editor.WidgetKey, + InputViewComponent.TextWithEvent.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) + ) + +[] +type EditorComponentModifiers = + /// Listen for the Completed event + /// Current widget + /// Function to execute + [] + static member inline onCompleted(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(EditorComponent.Completed.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Mvu.fs new file mode 100644 index 0000000..badfe55 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.Mvu.fs @@ -0,0 +1,31 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module EditorMvu = + let Completed = + Attributes.Mvu.defineEventNoArg "EditorMvu_Completed" (fun target -> (target :?> Editor).Completed) + +[] +module EditorMvuBuilders = + type Fabulous.Maui.View with + + /// Create an Editor widget with a text and listen for text changes + /// The text value + /// Message to dispatch + static member inline Editor(text: string, onTextChanged: string -> 'msg) = + WidgetBuilder<'msg, IFabEditor>( + Editor.WidgetKey, + InputViewMvu.TextWithEvent.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) + ) + +[] +type EditorMvuModifiers = + /// Listen for the Completed event + /// Current widget + /// Message to dispatch + [] + static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEditor>, msg: 'msg) = + this.AddScalar(EditorMvu.Completed.WithValue(MsgValue(msg))) diff --git a/src/Fabulous.MauiControls/Views/Controls/Editor.fs b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.fs similarity index 71% rename from src/Fabulous.MauiControls/Views/Controls/Editor.fs rename to src/Fabulous.MauiControls/Views/Controls/Editor/Editor.fs index 44c53e5..8ed935d 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Editor.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.fs @@ -14,12 +14,6 @@ module Editor = let AutoSize = Attributes.defineBindableEnum Editor.AutoSizeProperty - let CompletedMsg = - Attributes.defineEventNoArg "Editor_CompletedMsg" (fun target -> (target :?> Editor).Completed) - - let CompletedFn = - Attributes.defineEventNoArgNoDispatch "Editor_CompletedFn" (fun target -> (target :?> Editor).Completed) - let CursorPosition = Attributes.defineBindableInt Editor.CursorPositionProperty let FontAttributes = @@ -44,28 +38,6 @@ module Editor = let VerticalTextAlignment = Attributes.defineBindableEnum Editor.VerticalTextAlignmentProperty -[] -module EditorBuilders = - type Fabulous.Maui.View with - - /// Create an Editor widget with a text and listen for text changes - /// The text value - /// Message to dispatch - static member inline Editor(text: string, onTextChanged: string -> 'msg) = - WidgetBuilder<'msg, IFabEditor>( - Editor.WidgetKey, - InputView.TextWithEventMsg.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) - ) - - /// Create an Editor widget with a text and listen for text changes - /// The text value - /// Message to dispatch - static member inline Editor(text: string, onTextChanged: string -> unit) = - WidgetBuilder<'msg, IFabEditor>( - Editor.WidgetKey, - InputView.TextWithEventFn.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) - ) - [] type EditorModifiers = /// Set the font @@ -132,20 +104,6 @@ type EditorModifiers = static member inline isPredictionEnabled(this: WidgetBuilder<'msg, #IFabEditor>, value: bool) = this.AddScalar(Editor.IsTextPredictionEnabled.WithValue(value)) - /// Listen for the Completed event - /// Current widget - /// Message to dispatch - [] - static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEditor>, msg: 'msg) = - this.AddScalar(Editor.CompletedMsg.WithValue(MsgValue(msg))) - - /// Listen for the Completed event - /// Current widget - /// Function to execute - [] - static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEditor>, fn: unit -> unit) = - this.AddScalar(Editor.CompletedFn.WithValue(fn)) - /// Set the selection length /// Current widget /// The selection length diff --git a/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Component.fs b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Component.fs new file mode 100644 index 0000000..875a00d --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Component.fs @@ -0,0 +1,31 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module EntryComponent = + let Completed = + Attributes.Component.defineEventNoArg "EntryComponent_Completed" (fun target -> (target :?> Entry).Completed) + +[] +module EntryComponentBuilders = + type Fabulous.Maui.View with + + /// Create an Entry widget with a text and listen for text changes + /// The text value + /// Message to dispatch + static member inline Entry(text: string, onTextChanged: string -> unit) = + WidgetBuilder( + Entry.WidgetKey, + InputViewComponent.TextWithEvent.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) + ) + +[] +type EntryComponentModifiers = + /// Listen for the Completed event + /// Current widget + /// Function to execute + [] + static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntry>, fn: unit -> unit) = + this.AddScalar(EntryComponent.Completed.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs new file mode 100644 index 0000000..6c3762e --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs @@ -0,0 +1,32 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module EntryMvu = + let Completed = + Attributes.Mvu.defineEventNoArg "EntryMvu_Completed" (fun target -> (target :?> Entry).Completed) + +[] +module EntryMvuBuilders = + type Fabulous.Maui.View with + + /// Create an Entry widget with a text and listen for text changes + /// The text value + /// Message to dispatch + static member inline Entry(text: string, onTextChanged: string -> 'msg) = + WidgetBuilder<'msg, IFabEntry>( + Entry.WidgetKey, + InputViewMvu.TextWithEvent.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) + ) + +[] +type EntryMvuModifiers = + /// Listen for the Completed event + /// Current widget + /// Message to dispatch + [] + static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntry>, msg: 'msg) = + this.AddScalar(EntryMvu.Completed.WithValue(MsgValue(msg))) + \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Controls/Entry.fs b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.fs similarity index 77% rename from src/Fabulous.MauiControls/Views/Controls/Entry.fs rename to src/Fabulous.MauiControls/Views/Controls/Entry/Entry.fs index ff9f890..4ef23a8 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Entry.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.fs @@ -16,12 +16,6 @@ module Entry = let ClearButtonVisibility = Attributes.defineBindableEnum Entry.ClearButtonVisibilityProperty - let CompletedMsg = - Attributes.defineEventNoArg "Entry_CompletedMsg" (fun target -> (target :?> Entry).Completed) - - let CompletedFn = - Attributes.defineEventNoArgNoDispatch "Entry_CompletedFn" (fun target -> (target :?> Entry).Completed) - let CursorPosition = Attributes.defineBindableInt Entry.CursorPositionProperty let FontAttributes = @@ -62,28 +56,6 @@ module EntryPlatform = iOSSpecific.Entry.SetCursorColor(entry, value)) -[] -module EntryBuilders = - type Fabulous.Maui.View with - - /// Create an Entry widget with a text and listen for text changes - /// The text value - /// Message to dispatch - static member inline Entry(text: string, onTextChanged: string -> 'msg) = - WidgetBuilder<'msg, IFabEntry>( - Entry.WidgetKey, - InputView.TextWithEventMsg.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) - ) - - /// Create an Entry widget with a text and listen for text changes - /// The text value - /// Message to dispatch - static member inline Entry(text: string, onTextChanged: string -> unit) = - WidgetBuilder<'msg, IFabEntry>( - Entry.WidgetKey, - InputView.TextWithEventFn.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)) - ) - [] type EntryModifiers = /// Set the visibility of the clear button @@ -157,20 +129,6 @@ type EntryModifiers = static member inline isTextPredictionEnabled(this: WidgetBuilder<'msg, #IFabEntry>, value: bool) = this.AddScalar(Entry.IsTextPredictionEnabled.WithValue(value)) - /// Listen for the Completed event - /// Current widget - /// Message to dispatch - [] - static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntry>, msg: 'msg) = - this.AddScalar(Entry.CompletedMsg.WithValue(MsgValue(msg))) - - /// Listen for the Completed event - /// Current widget - /// Function to execute - [] - static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntry>, fn: unit -> unit) = - this.AddScalar(Entry.CompletedFn.WithValue(fn)) - /// Set the return type of the keyboard /// Current widget /// The return type of the keyboard diff --git a/src/Fabulous.MauiControls/Views/Controls/GraphicsView.fs b/src/Fabulous.MauiControls/Views/Controls/GraphicsView.fs deleted file mode 100644 index 367887c..0000000 --- a/src/Fabulous.MauiControls/Views/Controls/GraphicsView.fs +++ /dev/null @@ -1,167 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls -open Microsoft.Maui.Graphics - -type IGraphicsView = - inherit IFabView - -module GraphicsView = - let WidgetKey = Widgets.register() - - let CancelInteractionMsg = - Attributes.defineEventNoArg "GraphicsView_CancelInteractionMsg" (fun target -> (target :?> GraphicsView).CancelInteraction) - - let CancelInteractionFn = - Attributes.defineEventNoArgNoDispatch "GraphicsView_CancelInteractionFn" (fun target -> (target :?> GraphicsView).CancelInteraction) - - let DragInteractionMsg = - Attributes.defineEvent "GraphicsView_DragInteractionMsg" (fun target -> (target :?> GraphicsView).DragInteraction) - - let DragInteractionFn = - Attributes.defineEventNoDispatch "GraphicsView_DragInteractionFn" (fun target -> (target :?> GraphicsView).DragInteraction) - - let Drawable = - Attributes.defineBindableWithEquality GraphicsView.DrawableProperty - - let EndHoverInteractionMsg = - Attributes.defineEventNoArg "GraphicsView_EndHoverInteractionMsg" (fun target -> (target :?> GraphicsView).EndHoverInteraction) - - let EndHoverInteractionFn = - Attributes.defineEventNoArgNoDispatch "GraphicsView_EndHoverInteractionFn" (fun target -> (target :?> GraphicsView).EndHoverInteraction) - - let EndInteractionMsg = - Attributes.defineEvent "GraphicsView_EndInteractionMsg" (fun target -> (target :?> GraphicsView).EndInteraction) - - let EndInteractionFn = - Attributes.defineEventNoDispatch "GraphicsView_EndInteractionFn" (fun target -> (target :?> GraphicsView).EndInteraction) - - let MoveHoverInteractionMsg = - Attributes.defineEvent "GraphicsView_MoveHoverInteractionMsg" (fun target -> (target :?> GraphicsView).MoveHoverInteraction) - - let MoveHoverInteractionFn = - Attributes.defineEventNoDispatch "GraphicsView_MoveHoverInteractionFn" (fun target -> (target :?> GraphicsView).MoveHoverInteraction) - - let StartHoverInteractionMsg = - Attributes.defineEvent "GraphicsView_StartHoverInteractionMsg" (fun target -> (target :?> GraphicsView).StartHoverInteraction) - - let StartHoverInteractionFn = - Attributes.defineEventNoDispatch "GraphicsView_StartHoverInteractionFn" (fun target -> (target :?> GraphicsView).StartHoverInteraction) - - let StartInteractionMsg = - Attributes.defineEvent "GraphicsView_StartInteractionMsg" (fun target -> (target :?> GraphicsView).StartInteraction) - - let StartInteractionFn = - Attributes.defineEventNoDispatch "GraphicsView_StartInteractionFn" (fun target -> (target :?> GraphicsView).StartInteraction) - -[] -module GraphicsViewBuilders = - /// GraphicsView defines the Drawable property, of type IDrawable, which specifies the content that will be drawn. - type Fabulous.Maui.View with - - /// Create a GraphicsView widget with a drawable content - /// The drawable content - static member inline GraphicsView(drawable: IDrawable) = - WidgetBuilder<'msg, IGraphicsView>(GraphicsView.WidgetKey, GraphicsView.Drawable.WithValue(drawable)) - -[] -type GraphicsViewModifiers = - /// Listen for the CancelInteraction event, which is raised when the press that made contact with the GraphicsView loses contact - /// Current widget - /// Message to dispatch - [] - static member inline onCancelInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, msg: 'msg) = - this.AddScalar(GraphicsView.CancelInteractionMsg.WithValue(MsgValue(msg))) - - /// Listen for the CancelInteraction event, which is raised when the press that made contact with the GraphicsView loses contact - /// Current widget - /// Function to execute - [] - static member inline onCancelInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: unit -> unit) = - this.AddScalar(GraphicsView.CancelInteractionFn.WithValue(fn)) - - /// Listen for the DragInteraction event, with TouchEventArgs, which is raised when the GraphicsView is dragged - /// Current widget - /// Message to dispatch - [] - static member inline onDragInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = - this.AddScalar(GraphicsView.DragInteractionMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the DragInteraction event, with TouchEventArgs, which is raised when the GraphicsView is dragged - /// Current widget - /// Message to dispatch - [] - static member inline onDragInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> unit) = - this.AddScalar(GraphicsView.DragInteractionFn.WithValue(fn)) - - /// Listen for the EndHoverInteraction event, which is raised when a pointer leaves the hit test area of the GraphicsView - /// Current widget - /// Message to dispatch - [] - static member inline onEndHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, msg: 'msg) = - this.AddScalar(GraphicsView.EndHoverInteractionMsg.WithValue(MsgValue(msg))) - - /// Listen for the EndHoverInteraction event, which is raised when a pointer leaves the hit test area of the GraphicsView - /// Current widget - /// Function to execute - [] - static member inline onEndHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: unit -> unit) = - this.AddScalar(GraphicsView.EndHoverInteractionFn.WithValue(fn)) - - /// Listen for the EndInteraction event, with TouchEventArgs, which is raised when the press that raised the StartInteraction event is released - /// Current widget - /// Message to dispatch - [] - static member inline onEndInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = - this.AddScalar(GraphicsView.EndInteractionMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the EndInteraction event, with TouchEventArgs, which is raised when the press that raised the StartInteraction event is released - /// Current widget - /// Message to dispatch - [] - static member inline onEndInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> unit) = - this.AddScalar(GraphicsView.EndInteractionFn.WithValue(fn)) - - /// Listen for the MoveHoverInteraction event, with TouchEventArgs, which is raised when a pointer moves while the pointer remains within the hit test area of the GraphicsView - /// Current widget - /// Message to dispatch - [] - static member inline onMoveHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = - this.AddScalar(GraphicsView.MoveHoverInteractionMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the MoveHoverInteraction event, with TouchEventArgs, which is raised when a pointer moves while the pointer remains within the hit test area of the GraphicsView - /// Current widget - /// Message to dispatch - [] - static member inline onMoveHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> unit) = - this.AddScalar(GraphicsView.MoveHoverInteractionFn.WithValue(fn)) - - /// Listen for the StartHoverInteraction event, with TouchEventArgs, which is raised when a pointer enters the hit test area of the GraphicsView - /// Current widget - /// Message to dispatch - [] - static member inline onStartHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = - this.AddScalar(GraphicsView.StartHoverInteractionMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the StartHoverInteraction event, with TouchEventArgs, which is raised when a pointer enters the hit test area of the GraphicsView - /// Current widget - /// Message to dispatch - [] - static member inline onStartHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> unit) = - this.AddScalar(GraphicsView.StartHoverInteractionFn.WithValue(fn)) - - /// Listen for the StartInteraction event, with TouchEventArgs, which is raised when the GraphicsView is pressed - /// Current widget - /// Message to dispatch - [] - static member inline onStartInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = - this.AddScalar(GraphicsView.StartInteractionMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the StartInteraction event, with TouchEventArgs, which is raised when the GraphicsView is pressed - /// Current widget - /// Message to dispatch - [] - static member inline onStartInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> unit) = - this.AddScalar(GraphicsView.StartInteractionFn.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs new file mode 100644 index 0000000..ce0181b --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs @@ -0,0 +1,78 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module GraphicsViewComponent = + let CancelInteraction = + Attributes.Component.defineEventNoArg "GraphicsViewComponent_CancelInteraction" (fun target -> (target :?> GraphicsView).CancelInteraction) + + let DragInteraction = + Attributes.Component.defineEvent "GraphicsViewComponent_DragInteraction" (fun target -> (target :?> GraphicsView).DragInteraction) + + let EndHoverInteraction = + Attributes.Component.defineEventNoArg "GraphicsViewComponent_EndHoverInteraction" (fun target -> (target :?> GraphicsView).EndHoverInteraction) + + let EndInteraction = + Attributes.Component.defineEvent "GraphicsViewComponent_EndInteraction" (fun target -> (target :?> GraphicsView).EndInteraction) + + let MoveHoverInteraction = + Attributes.Component.defineEvent "GraphicsViewComponent_MoveHoverInteraction" (fun target -> (target :?> GraphicsView).MoveHoverInteraction) + + let StartHoverInteraction = + Attributes.Component.defineEvent "GraphicsViewComponent_StartHoverInteraction" (fun target -> (target :?> GraphicsView).StartHoverInteraction) + + let StartInteraction = + Attributes.Component.defineEvent "GraphicsViewComponent_StartInteraction" (fun target -> (target :?> GraphicsView).StartInteraction) + +[] +type GraphicsViewComponentModifiers = + /// Listen for the CancelInteraction event, which is raised when the press that made contact with the GraphicsView loses contact + /// Current widget + /// Function to execute + [] + static member inline onCancelInteraction(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(GraphicsViewComponent.CancelInteraction.WithValue(fn)) + + /// Listen for the DragInteraction event, with TouchEventArgs, which is raised when the GraphicsView is dragged + /// Current widget + /// Message to dispatch + [] + static member inline onDragInteraction(this: WidgetBuilder, fn: TouchEventArgs -> unit) = + this.AddScalar(GraphicsViewComponent.DragInteraction.WithValue(fn)) + + /// Listen for the EndHoverInteraction event, which is raised when a pointer leaves the hit test area of the GraphicsView + /// Current widget + /// Function to execute + [] + static member inline onEndHoverInteraction(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(GraphicsViewComponent.EndHoverInteraction.WithValue(fn)) + + /// Listen for the EndInteraction event, with TouchEventArgs, which is raised when the press that raised the StartInteraction event is released + /// Current widget + /// Message to dispatch + [] + static member inline onEndInteraction(this: WidgetBuilder, fn: TouchEventArgs -> unit) = + this.AddScalar(GraphicsViewComponent.EndInteraction.WithValue(fn)) + + /// Listen for the MoveHoverInteraction event, with TouchEventArgs, which is raised when a pointer moves while the pointer remains within the hit test area of the GraphicsView + /// Current widget + /// Message to dispatch + [] + static member inline onMoveHoverInteraction(this: WidgetBuilder, fn: TouchEventArgs -> unit) = + this.AddScalar(GraphicsViewComponent.MoveHoverInteraction.WithValue(fn)) + + /// Listen for the StartHoverInteraction event, with TouchEventArgs, which is raised when a pointer enters the hit test area of the GraphicsView + /// Current widget + /// Message to dispatch + [] + static member inline onStartHoverInteraction(this: WidgetBuilder, fn: TouchEventArgs -> unit) = + this.AddScalar(GraphicsViewComponent.StartHoverInteraction.WithValue(fn)) + + /// Listen for the StartInteraction event, with TouchEventArgs, which is raised when the GraphicsView is pressed + /// Current widget + /// Message to dispatch + [] + static member inline onStartInteraction(this: WidgetBuilder, fn: TouchEventArgs -> unit) = + this.AddScalar(GraphicsViewComponent.StartInteraction.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Mvu.fs new file mode 100644 index 0000000..7be84e1 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Mvu.fs @@ -0,0 +1,78 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module GraphicsViewMvu = + let CancelInteraction = + Attributes.Mvu.defineEventNoArg "GraphicsViewMvu_CancelInteraction" (fun target -> (target :?> GraphicsView).CancelInteraction) + + let DragInteraction = + Attributes.Mvu.defineEvent "GraphicsViewMvu_DragInteraction" (fun target -> (target :?> GraphicsView).DragInteraction) + + let EndHoverInteraction = + Attributes.Mvu.defineEventNoArg "GraphicsViewMvu_EndHoverInteraction" (fun target -> (target :?> GraphicsView).EndHoverInteraction) + + let EndInteraction = + Attributes.Mvu.defineEvent "GraphicsViewMvu_EndInteraction" (fun target -> (target :?> GraphicsView).EndInteraction) + + let MoveHoverInteraction = + Attributes.Mvu.defineEvent "GraphicsViewMvu_MoveHoverInteraction" (fun target -> (target :?> GraphicsView).MoveHoverInteraction) + + let StartHoverInteraction = + Attributes.Mvu.defineEvent "GraphicsViewMvu_StartHoverInteraction" (fun target -> (target :?> GraphicsView).StartHoverInteraction) + + let StartInteraction = + Attributes.Mvu.defineEvent "GraphicsViewMvu_StartInteraction" (fun target -> (target :?> GraphicsView).StartInteraction) + +[] +type GraphicsViewMvuModifiers = + /// Listen for the CancelInteraction event, which is raised when the press that made contact with the GraphicsView loses contact + /// Current widget + /// Message to dispatch + [] + static member inline onCancelInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, msg: 'msg) = + this.AddScalar(GraphicsViewMvu.CancelInteraction.WithValue(MsgValue(msg))) + + /// Listen for the DragInteraction event, with TouchEventArgs, which is raised when the GraphicsView is dragged + /// Current widget + /// Message to dispatch + [] + static member inline onDragInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = + this.AddScalar(GraphicsViewMvu.DragInteraction.WithValue(fun args -> fn args |> box)) + + /// Listen for the EndHoverInteraction event, which is raised when a pointer leaves the hit test area of the GraphicsView + /// Current widget + /// Message to dispatch + [] + static member inline onEndHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, msg: 'msg) = + this.AddScalar(GraphicsViewMvu.EndHoverInteraction.WithValue(MsgValue(msg))) + + /// Listen for the EndInteraction event, with TouchEventArgs, which is raised when the press that raised the StartInteraction event is released + /// Current widget + /// Message to dispatch + [] + static member inline onEndInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = + this.AddScalar(GraphicsViewMvu.EndInteraction.WithValue(fun args -> fn args |> box)) + + /// Listen for the MoveHoverInteraction event, with TouchEventArgs, which is raised when a pointer moves while the pointer remains within the hit test area of the GraphicsView + /// Current widget + /// Message to dispatch + [] + static member inline onMoveHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = + this.AddScalar(GraphicsViewMvu.MoveHoverInteraction.WithValue(fun args -> fn args |> box)) + + /// Listen for the StartHoverInteraction event, with TouchEventArgs, which is raised when a pointer enters the hit test area of the GraphicsView + /// Current widget + /// Message to dispatch + [] + static member inline onStartHoverInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = + this.AddScalar(GraphicsViewMvu.StartHoverInteraction.WithValue(fun args -> fn args |> box)) + + /// Listen for the StartInteraction event, with TouchEventArgs, which is raised when the GraphicsView is pressed + /// Current widget + /// Message to dispatch + [] + static member inline onStartInteraction(this: WidgetBuilder<'msg, #IGraphicsView>, fn: TouchEventArgs -> 'msg) = + this.AddScalar(GraphicsViewMvu.StartInteraction.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.fs b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.fs new file mode 100644 index 0000000..4183408 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.fs @@ -0,0 +1,24 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls +open Microsoft.Maui.Graphics + +type IGraphicsView = + inherit IFabView + +module GraphicsView = + let WidgetKey = Widgets.register() + + let Drawable = + Attributes.defineBindableWithEquality GraphicsView.DrawableProperty + +[] +module GraphicsViewBuilders = + /// GraphicsView defines the Drawable property, of type IDrawable, which specifies the content that will be drawn. + type Fabulous.Maui.View with + + /// Create a GraphicsView widget with a drawable content + /// The drawable content + static member inline GraphicsView(drawable: IDrawable) = + WidgetBuilder<'msg, IGraphicsView>(GraphicsView.WidgetKey, GraphicsView.Drawable.WithValue(drawable)) diff --git a/src/Fabulous.MauiControls/Views/Controls/ImageButton.fs b/src/Fabulous.MauiControls/Views/Controls/ImageButton.fs deleted file mode 100644 index 4618677..0000000 --- a/src/Fabulous.MauiControls/Views/Controls/ImageButton.fs +++ /dev/null @@ -1,345 +0,0 @@ -namespace Fabulous.Maui - -open System.IO -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui -open Microsoft.Maui.Controls -open System -open Microsoft.Maui.Graphics - -type IFabImageButton = - inherit IFabView - -module ImageButton = - let WidgetKey = Widgets.register() - - let Aspect = - Attributes.defineBindableEnum ImageButton.AspectProperty - - let BorderColor = Attributes.defineBindableColor ImageButton.BorderColorProperty - - let BorderWidth = Attributes.defineBindableFloat ImageButton.BorderWidthProperty - - let ClickedMsg = - Attributes.defineEventNoArg "ImageButton_ClickedMsg" (fun target -> (target :?> ImageButton).Clicked) - - let ClickedFn = - Attributes.defineEventNoArgNoDispatch "ImageButton_ClickedFn" (fun target -> (target :?> ImageButton).Clicked) - - let CornerRadius = Attributes.defineBindableFloat ImageButton.CornerRadiusProperty - - let IsLoading = Attributes.defineBindableBool ImageButton.IsLoadingProperty - - let IsOpaque = Attributes.defineBindableBool ImageButton.IsOpaqueProperty - - let IsPressed = Attributes.defineBindableBool ImageButton.IsPressedProperty - - let Padding = - Attributes.defineBindableWithEquality ImageButton.PaddingProperty - - let PressedMsg = - Attributes.defineEventNoArg "ImageButton_PressedMsg" (fun target -> (target :?> ImageButton).Pressed) - - let PressedFn = - Attributes.defineEventNoArgNoDispatch "ImageButton_PressedFn" (fun target -> (target :?> ImageButton).Pressed) - - let ReleasedMsg = - Attributes.defineEventNoArg "ImageButton_ReleasedMsg" (fun target -> (target :?> ImageButton).Released) - - let ReleasedFn = - Attributes.defineEventNoArgNoDispatch "ImageButton_ReleasedFn" (fun target -> (target :?> ImageButton).Released) - - let Source = Attributes.defineBindableImageSource ImageButton.SourceProperty - -[] -module ImageButtonBuilders = - type Fabulous.Maui.View with - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: ImageSource, onClicked: 'msg) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.Source source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: ImageSource, onClicked: 'msg, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.Source source), - ImageButton.Aspect.WithValue(aspect) - ) - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: string, onClicked: 'msg) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.File source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: string, onClicked: 'msg, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.File source), - ImageButton.Aspect.WithValue(aspect) - ) - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: Uri, onClicked: 'msg) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.Uri source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: Uri, onClicked: 'msg, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.Uri source), - ImageButton.Aspect.WithValue(aspect) - ) - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: Stream, onClicked: 'msg) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.Stream source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: Stream, onClicked: 'msg, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedMsg.WithValue(MsgValue(onClicked)), - ImageButton.Source.WithValue(ImageSourceValue.Stream source), - ImageButton.Aspect.WithValue(aspect) - ) - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: ImageSource, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.Source source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: ImageSource, onClicked: unit -> unit, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.Source source), - ImageButton.Aspect.WithValue(aspect) - ) - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: string, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.File source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: string, onClicked: unit -> unit, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.File source), - ImageButton.Aspect.WithValue(aspect) - ) - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: Uri, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.Uri source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: Uri, onClicked: unit -> unit, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.Uri source), - ImageButton.Aspect.WithValue(aspect) - ) - - /// Create an ImageButton with an image source and listen for the Click event - /// The image source - /// Message to dispatch - static member inline ImageButton(source: Stream, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.Stream source) - ) - - /// Create an ImageButton with an image source and an aspect and listen for the Click event - /// The image source - /// Message to dispatch - /// The aspect value - static member inline ImageButton(source: Stream, onClicked: unit -> unit, aspect: Aspect) = - WidgetBuilder<'msg, IFabImageButton>( - ImageButton.WidgetKey, - ImageButton.ClickedFn.WithValue(onClicked), - ImageButton.Source.WithValue(ImageSourceValue.Stream source), - ImageButton.Aspect.WithValue(aspect) - ) - -[] -type ImageButtonModifiers = - /// Set the color of the image button border - /// Current widget - /// The color of the image button border - [] - static member inline borderColor(this: WidgetBuilder<'msg, #IFabImageButton>, value: Color) = - this.AddScalar(ImageButton.BorderColor.WithValue(value)) - - /// Set the width of the image button border - /// Current widget - /// The width of the image button border - [] - static member inline borderWidth(this: WidgetBuilder<'msg, #IFabImageButton>, value: float) = - this.AddScalar(ImageButton.BorderWidth.WithValue(value)) - - /// Set the corner radius of the image button - /// Current widget - /// The corner radius of the image button - [] - static member inline cornerRadius(this: WidgetBuilder<'msg, #IFabImageButton>, value: float) = - this.AddScalar(ImageButton.CornerRadius.WithValue(value)) - - /// Set the loading status of the image - /// Current widget - /// The loading status of the image - [] - static member inline isLoading(this: WidgetBuilder<'msg, #IFabImageButton>, value: bool) = - this.AddScalar(ImageButton.IsLoading.WithValue(value)) - - /// Set whether the rendering engine may treat the image as opaque while rendering it - /// Current widget - /// The value indicating whether the rendering engine may treat the image as opaque while rendering it - [] - static member inline isOpaque(this: WidgetBuilder<'msg, #IFabImageButton>, value: bool) = - this.AddScalar(ImageButton.IsOpaque.WithValue(value)) - - /// Set whether the button is pressed - /// Current widget - /// The value indicating whether the button is pressed - [] - static member inline isPressed(this: WidgetBuilder<'msg, #IFabImageButton>, value: bool) = - this.AddScalar(ImageButton.IsPressed.WithValue(value)) - - /// Listen for the Pressed event - /// Current widget - /// Message to dispatch - [] - static member inline onPressed(this: WidgetBuilder<'msg, #IFabImageButton>, msg: 'msg) = - this.AddScalar(ImageButton.PressedMsg.WithValue(MsgValue(msg))) - - /// Listen for the Pressed event - /// Current widget - /// Function to execute - [] - static member inline onPressed(this: WidgetBuilder<'msg, #IFabImageButton>, fn: unit -> unit) = - this.AddScalar(ImageButton.PressedFn.WithValue(fn)) - - /// Listen for the Released event - /// Current widget - /// Message to dispatch - [] - static member inline onReleased(this: WidgetBuilder<'msg, #IFabImageButton>, msg: 'msg) = - this.AddScalar(ImageButton.ReleasedMsg.WithValue(MsgValue(msg))) - - /// Listen for the Released event - /// Current widget - /// Function to execute - [] - static member inline onReleased(this: WidgetBuilder<'msg, #IFabImageButton>, fn: unit -> unit) = - this.AddScalar(ImageButton.ReleasedFn.WithValue(fn)) - - /// Set the padding inside the button - /// Current widget - /// The padding inside the button - [] - static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, value: Thickness) = - this.AddScalar(ImageButton.Padding.WithValue(value)) - - /// Link a ViewRef to access the direct ImageButton control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabImageButton>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) - -[] -type ImageButtonExtraModifiers = - /// Set the padding inside the button - /// Current widget - /// The uniform padding inside the button - [] - static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, uniformSize: float) = this.padding(Thickness(uniformSize)) - - /// Set the padding inside the widget - /// Current widget - /// The padding value that will be applied to both left and right sides - /// The padding value that will be applied to both top and bottom sides - [] - static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, horizontalSize: float, verticalSize: float) = - this.padding(Thickness(horizontalSize, verticalSize)) - - /// Set the padding inside the button - /// Current widget - /// The left component of the padding inside the button - /// The top component of the padding inside the button - /// The right component of the padding inside the button - /// The bottom component of the padding inside the button - [] - static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, left: float, top: float, right: float, bottom: float) = - this.padding(Thickness(left, top, right, bottom)) diff --git a/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Component.fs b/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Component.fs new file mode 100644 index 0000000..2cab2ae --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Component.fs @@ -0,0 +1,126 @@ +namespace Fabulous.Maui + +open System.IO +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui +open Microsoft.Maui.Controls +open System + +module ImageButtonComponent = + let Clicked = + Attributes.Component.defineEventNoArg "ImageButtonComponent_Clicked" (fun target -> (target :?> ImageButton).Clicked) + + let Pressed = + Attributes.Component.defineEventNoArg "ImageButtonComponent_Pressed" (fun target -> (target :?> ImageButton).Pressed) + + let Released = + Attributes.Component.defineEventNoArg "ImageButtonComponent_Released" (fun target -> (target :?> ImageButton).Released) + +[] +module ImageButtonComponentBuilders = + type Fabulous.Maui.View with + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: ImageSource, onClicked: unit -> unit) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.Source source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: ImageSource, onClicked: unit -> unit, aspect: Aspect) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.Source source), + ImageButton.Aspect.WithValue(aspect) + ) + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: string, onClicked: unit -> unit) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.File source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: string, onClicked: unit -> unit, aspect: Aspect) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.File source), + ImageButton.Aspect.WithValue(aspect) + ) + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: Uri, onClicked: unit -> unit) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.Uri source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: Uri, onClicked: unit -> unit, aspect: Aspect) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.Uri source), + ImageButton.Aspect.WithValue(aspect) + ) + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: Stream, onClicked: unit -> unit) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.Stream source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: Stream, onClicked: unit -> unit, aspect: Aspect) = + WidgetBuilder( + ImageButton.WidgetKey, + ImageButtonComponent.Clicked.WithValue(onClicked), + ImageButton.Source.WithValue(ImageSourceValue.Stream source), + ImageButton.Aspect.WithValue(aspect) + ) + +[] +type ImageButtonComponentModifiers = + /// Listen for the Pressed event + /// Current widget + /// Function to execute + [] + static member inline onPressed(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ImageButtonComponent.Pressed.WithValue(fn)) + + /// Listen for the Released event + /// Current widget + /// Function to execute + [] + static member inline onReleased(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(ImageButtonComponent.Released.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Mvu.fs new file mode 100644 index 0000000..997b5a9 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.Mvu.fs @@ -0,0 +1,126 @@ +namespace Fabulous.Maui + +open System.IO +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui +open Microsoft.Maui.Controls +open System + +module ImageButtonMvu = + let Clicked = + Attributes.Mvu.defineEventNoArg "ImageButtonMvu_Clicked" (fun target -> (target :?> ImageButton).Clicked) + + let Pressed = + Attributes.Mvu.defineEventNoArg "ImageButtonMvu_Pressed" (fun target -> (target :?> ImageButton).Pressed) + + let Released = + Attributes.Mvu.defineEventNoArg "ImageButtonMvu_Released" (fun target -> (target :?> ImageButton).Released) + +[] +module ImageButtonBuilders = + type Fabulous.Maui.View with + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: ImageSource, onClicked: 'msg) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.Source source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: ImageSource, onClicked: 'msg, aspect: Aspect) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.Source source), + ImageButton.Aspect.WithValue(aspect) + ) + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: string, onClicked: 'msg) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.File source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: string, onClicked: 'msg, aspect: Aspect) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.File source), + ImageButton.Aspect.WithValue(aspect) + ) + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: Uri, onClicked: 'msg) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.Uri source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: Uri, onClicked: 'msg, aspect: Aspect) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.Uri source), + ImageButton.Aspect.WithValue(aspect) + ) + + /// Create an ImageButton with an image source and listen for the Click event + /// The image source + /// Message to dispatch + static member inline ImageButton(source: Stream, onClicked: 'msg) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.Stream source) + ) + + /// Create an ImageButton with an image source and an aspect and listen for the Click event + /// The image source + /// Message to dispatch + /// The aspect value + static member inline ImageButton(source: Stream, onClicked: 'msg, aspect: Aspect) = + WidgetBuilder<'msg, IFabImageButton>( + ImageButton.WidgetKey, + ImageButtonMvu.Clicked.WithValue(MsgValue(onClicked)), + ImageButton.Source.WithValue(ImageSourceValue.Stream source), + ImageButton.Aspect.WithValue(aspect) + ) + +[] +type ImageButtonMvuModifiers = + /// Listen for the Pressed event + /// Current widget + /// Message to dispatch + [] + static member inline onPressed(this: WidgetBuilder<'msg, #IFabImageButton>, msg: 'msg) = + this.AddScalar(ImageButtonMvu.Pressed.WithValue(MsgValue(msg))) + + /// Listen for the Released event + /// Current widget + /// Message to dispatch + [] + static member inline onReleased(this: WidgetBuilder<'msg, #IFabImageButton>, msg: 'msg) = + this.AddScalar(ImageButtonMvu.Released.WithValue(MsgValue(msg))) diff --git a/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.fs b/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.fs new file mode 100644 index 0000000..1ba1209 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/ImageButton/ImageButton.fs @@ -0,0 +1,117 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui +open Microsoft.Maui.Controls +open Microsoft.Maui.Graphics + +type IFabImageButton = + inherit IFabView + +module ImageButton = + let WidgetKey = Widgets.register() + + let Aspect = + Attributes.defineBindableEnum ImageButton.AspectProperty + + let BorderColor = Attributes.defineBindableColor ImageButton.BorderColorProperty + + let BorderWidth = Attributes.defineBindableFloat ImageButton.BorderWidthProperty + + let CornerRadius = Attributes.defineBindableFloat ImageButton.CornerRadiusProperty + + let IsLoading = Attributes.defineBindableBool ImageButton.IsLoadingProperty + + let IsOpaque = Attributes.defineBindableBool ImageButton.IsOpaqueProperty + + let IsPressed = Attributes.defineBindableBool ImageButton.IsPressedProperty + + let Padding = + Attributes.defineBindableWithEquality ImageButton.PaddingProperty + + let Source = Attributes.defineBindableImageSource ImageButton.SourceProperty + +[] +type ImageButtonModifiers = + /// Set the color of the image button border + /// Current widget + /// The color of the image button border + [] + static member inline borderColor(this: WidgetBuilder<'msg, #IFabImageButton>, value: Color) = + this.AddScalar(ImageButton.BorderColor.WithValue(value)) + + /// Set the width of the image button border + /// Current widget + /// The width of the image button border + [] + static member inline borderWidth(this: WidgetBuilder<'msg, #IFabImageButton>, value: float) = + this.AddScalar(ImageButton.BorderWidth.WithValue(value)) + + /// Set the corner radius of the image button + /// Current widget + /// The corner radius of the image button + [] + static member inline cornerRadius(this: WidgetBuilder<'msg, #IFabImageButton>, value: float) = + this.AddScalar(ImageButton.CornerRadius.WithValue(value)) + + /// Set the loading status of the image + /// Current widget + /// The loading status of the image + [] + static member inline isLoading(this: WidgetBuilder<'msg, #IFabImageButton>, value: bool) = + this.AddScalar(ImageButton.IsLoading.WithValue(value)) + + /// Set whether the rendering engine may treat the image as opaque while rendering it + /// Current widget + /// The value indicating whether the rendering engine may treat the image as opaque while rendering it + [] + static member inline isOpaque(this: WidgetBuilder<'msg, #IFabImageButton>, value: bool) = + this.AddScalar(ImageButton.IsOpaque.WithValue(value)) + + /// Set whether the button is pressed + /// Current widget + /// The value indicating whether the button is pressed + [] + static member inline isPressed(this: WidgetBuilder<'msg, #IFabImageButton>, value: bool) = + this.AddScalar(ImageButton.IsPressed.WithValue(value)) + + /// Set the padding inside the button + /// Current widget + /// The padding inside the button + [] + static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, value: Thickness) = + this.AddScalar(ImageButton.Padding.WithValue(value)) + + /// Link a ViewRef to access the direct ImageButton control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabImageButton>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) + +[] +type ImageButtonExtraModifiers = + /// Set the padding inside the button + /// Current widget + /// The uniform padding inside the button + [] + static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, uniformSize: float) = this.padding(Thickness(uniformSize)) + + /// Set the padding inside the widget + /// Current widget + /// The padding value that will be applied to both left and right sides + /// The padding value that will be applied to both top and bottom sides + [] + static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, horizontalSize: float, verticalSize: float) = + this.padding(Thickness(horizontalSize, verticalSize)) + + /// Set the padding inside the button + /// Current widget + /// The left component of the padding inside the button + /// The top component of the padding inside the button + /// The right component of the padding inside the button + /// The bottom component of the padding inside the button + [] + static member inline padding(this: WidgetBuilder<'msg, #IFabImageButton>, left: float, top: float, right: float, bottom: float) = + this.padding(Thickness(left, top, right, bottom)) diff --git a/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Component.fs b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Component.fs new file mode 100644 index 0000000..befc267 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Component.fs @@ -0,0 +1,26 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module PickerComponent = + let SelectedIndexWithEvent = + Attributes.Component.defineBindableWithEvent "PickerComponent_SelectedIndexChanged" Picker.SelectedIndexProperty (fun target -> + (target :?> FabPicker).CustomSelectedIndexChanged) + +[] +module PickerComponentBuilders = + type Fabulous.Maui.View with + + /// Create a Picker widget with a list of items, the selected index and listen to the selected index changes + /// The items list + /// The selected index + /// Message to dispatch + static member inline Picker(items: string list, selectedIndex: int, onSelectedIndexChanged: int -> unit) = + WidgetBuilder( + Picker.WidgetKey, + Picker.ItemsSource.WithValue(Array.ofList items), + PickerComponent.SelectedIndexWithEvent.WithValue( + ValueEventData.create selectedIndex (fun (args: FabPositionChangedEventArgs) -> onSelectedIndexChanged args.CurrentPosition) + ) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Mvu.fs new file mode 100644 index 0000000..430edee --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.Mvu.fs @@ -0,0 +1,26 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module PickerMvu = + let SelectedIndexWithEvent = + Attributes.Mvu.defineBindableWithEvent "PickerMvu_SelectedIndexChanged" Picker.SelectedIndexProperty (fun target -> + (target :?> FabPicker).CustomSelectedIndexChanged) + +[] +module PickerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a Picker widget with a list of items, the selected index and listen to the selected index changes + /// The items list + /// The selected index + /// Message to dispatch + static member inline Picker(items: string list, selectedIndex: int, onSelectedIndexChanged: int -> 'msg) = + WidgetBuilder<'msg, IFabPicker>( + Picker.WidgetKey, + Picker.ItemsSource.WithValue(Array.ofList items), + PickerMvu.SelectedIndexWithEvent.WithValue( + MsgValueEventData.create selectedIndex (fun (args: FabPositionChangedEventArgs) -> onSelectedIndexChanged args.CurrentPosition) + ) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/Picker.fs b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.fs similarity index 74% rename from src/Fabulous.MauiControls/Views/Controls/Picker.fs rename to src/Fabulous.MauiControls/Views/Controls/Picker/Picker.fs index df057c4..2daf879 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Picker.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.fs @@ -11,7 +11,7 @@ open Microsoft.Maui.Graphics type IFabPicker = inherit IFabView -type PositionChangedEventArgs(previousPosition: int, currentPosition: int) = +type FabPositionChangedEventArgs(previousPosition: int, currentPosition: int) = inherit EventArgs() member _.PreviousPosition = previousPosition member _.CurrentPosition = currentPosition @@ -22,7 +22,7 @@ type FabPicker() = let mutable oldSelectedIndex = -1 - let selectedIndexChanged = Event, _>() + let selectedIndexChanged = Event, _>() [] member _.CustomSelectedIndexChanged = selectedIndexChanged.Publish @@ -31,7 +31,7 @@ type FabPicker() = base.OnPropertyChanged(propertyName) if propertyName = Picker.SelectedIndexProperty.PropertyName then - selectedIndexChanged.Trigger(this, PositionChangedEventArgs(oldSelectedIndex, this.SelectedIndex)) + selectedIndexChanged.Trigger(this, FabPositionChangedEventArgs(oldSelectedIndex, this.SelectedIndex)) override this.OnPropertyChanging(propertyName) = base.OnPropertyChanging(propertyName) @@ -67,14 +67,6 @@ module Picker = | ValueNone -> target.ClearValue(Picker.ItemsSourceProperty) | ValueSome value -> target.SetValue(Picker.ItemsSourceProperty, value)) - let SelectedIndexWithEventMsg = - Attributes.defineBindableWithEvent "Picker_SelectedIndexChangedMsg" Picker.SelectedIndexProperty (fun target -> - (target :?> FabPicker).CustomSelectedIndexChanged) - - let SelectedIndexWithEventFn = - Attributes.defineBindableWithEventNoDispatch "Picker_SelectedIndexChangedFn" Picker.SelectedIndexProperty (fun target -> - (target :?> FabPicker).CustomSelectedIndexChanged) - let TextColor = Attributes.defineBindableColor Picker.TextColorProperty let Title = Attributes.defineBindableWithEquality Picker.TitleProperty @@ -96,36 +88,6 @@ module PickerPlatform = iOSSpecific.Picker.SetUpdateMode(picker, value)) -[] -module PickerBuilders = - type Fabulous.Maui.View with - - /// Create a Picker widget with a list of items, the selected index and listen to the selected index changes - /// The items list - /// The selected index - /// Message to dispatch - static member inline Picker(items: string list, selectedIndex: int, onSelectedIndexChanged: int -> 'msg) = - WidgetBuilder<'msg, IFabPicker>( - Picker.WidgetKey, - Picker.ItemsSource.WithValue(Array.ofList items), - Picker.SelectedIndexWithEventMsg.WithValue( - MsgValueEventData.create selectedIndex (fun (args: PositionChangedEventArgs) -> onSelectedIndexChanged args.CurrentPosition) - ) - ) - - /// Create a Picker widget with a list of items, the selected index and listen to the selected index changes - /// The items list - /// The selected index - /// Message to dispatch - static member inline Picker(items: string list, selectedIndex: int, onSelectedIndexChanged: int -> unit) = - WidgetBuilder<'msg, IFabPicker>( - Picker.WidgetKey, - Picker.ItemsSource.WithValue(Array.ofList items), - Picker.SelectedIndexWithEventFn.WithValue( - ValueEventData.create selectedIndex (fun (args: PositionChangedEventArgs) -> onSelectedIndexChanged args.CurrentPosition) - ) - ) - [] type PickerModifiers = /// Set the character spacing of the text diff --git a/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Component.fs b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Component.fs new file mode 100644 index 0000000..3a61c4c --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Component.fs @@ -0,0 +1,43 @@ +namespace Fabulous.Maui + +open Fabulous +open Fabulous.StackAllocatedCollections.StackList +open Microsoft.Maui.Controls + +module RadioButtonComponent = + let IsCheckedWithEvent = + Attributes.Component.defineBindableWithEvent "RadioButtonComponent_CheckedChanged" RadioButton.IsCheckedProperty (fun target -> + (target :?> RadioButton).CheckedChanged) + +[] +module RadioButtonComponentBuilders = + type Fabulous.Maui.View with + + /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes + /// The content + /// The checked state + /// Message to dispatch + static member inline RadioButton(content: string, isChecked: bool, onChecked: bool -> unit) = + WidgetBuilder( + RadioButton.WidgetKey, + RadioButtonComponent.IsCheckedWithEvent.WithValue(ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value)), + RadioButton.ContentString.WithValue(content) + ) + + /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes + /// The content widget + /// The checked state + /// Message to dispatch + static member inline RadioButton(content: WidgetBuilder<'msg, #IFabView>, isChecked: bool, onChecked: bool -> unit) = + WidgetBuilder( + RadioButton.WidgetKey, + AttributesBundle( + StackList.one( + RadioButtonComponent.IsCheckedWithEvent.WithValue( + ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value) + ) + ), + ValueSome [| RadioButton.ContentWidget.WithValue(content.Compile()) |], + ValueNone + ) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs new file mode 100644 index 0000000..64a582c --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs @@ -0,0 +1,42 @@ +namespace Fabulous.Maui + +open Fabulous +open Fabulous.StackAllocatedCollections.StackList +open Microsoft.Maui.Controls + +module RadioButtonMvu = + let IsCheckedWithEvent = + Attributes.Mvu.defineBindableWithEvent "RadioButtonMvu_CheckedChanged" RadioButton.IsCheckedProperty (fun target -> (target :?> RadioButton).CheckedChanged) + +[] +module RadioButtonMvuBuilders = + type Fabulous.Maui.View with + + /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes + /// The content + /// The checked state + /// Message to dispatch + static member inline RadioButton(content: string, isChecked: bool, onChecked: bool -> 'msg) = + WidgetBuilder<'msg, IFabRadioButton>( + RadioButton.WidgetKey, + RadioButtonMvu.IsCheckedWithEvent.WithValue(MsgValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value)), + RadioButton.ContentString.WithValue(content) + ) + + /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes + /// The content widget + /// The checked state + /// Message to dispatch + static member inline RadioButton(content: WidgetBuilder<'msg, #IFabView>, isChecked: bool, onChecked: bool -> 'msg) = + WidgetBuilder<'msg, IFabRadioButton>( + RadioButton.WidgetKey, + AttributesBundle( + StackList.one( + RadioButtonMvu.IsCheckedWithEvent.WithValue( + MsgValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value) + ) + ), + ValueSome [| RadioButton.ContentWidget.WithValue(content.Compile()) |], + ValueNone + ) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/RadioButton.fs b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.fs similarity index 61% rename from src/Fabulous.MauiControls/Views/Controls/RadioButton.fs rename to src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.fs index 10721fc..d634403 100644 --- a/src/Fabulous.MauiControls/Views/Controls/RadioButton.fs +++ b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.fs @@ -2,7 +2,6 @@ namespace Fabulous.Maui open System.Runtime.CompilerServices open Fabulous -open Fabulous.StackAllocatedCollections.StackList open Microsoft.Maui open Microsoft.Maui.Controls open Microsoft.Maui.Graphics @@ -41,13 +40,6 @@ module RadioButton = let GroupName = Attributes.defineBindableWithEquality RadioButton.GroupNameProperty - let IsCheckedWithEventMsg = - Attributes.defineBindableWithEvent "RadioButton_CheckedChangedMsg" RadioButton.IsCheckedProperty (fun target -> (target :?> RadioButton).CheckedChanged) - - let IsCheckedWithEventFn = - Attributes.defineBindableWithEventNoDispatch "RadioButton_CheckedChangedFn" RadioButton.IsCheckedProperty (fun target -> - (target :?> RadioButton).CheckedChanged) - let TextColor = Attributes.defineBindableColor RadioButton.TextColorProperty let TextTransform = @@ -57,68 +49,6 @@ module RadioButtonAttached = let RadioButtonGroupName = Attributes.defineBindableWithEquality RadioButtonGroup.GroupNameProperty -[] -module RadioButtonBuilders = - type Fabulous.Maui.View with - - /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes - /// The content - /// The checked state - /// Message to dispatch - static member inline RadioButton(content: string, isChecked: bool, onChecked: bool -> 'msg) = - WidgetBuilder<'msg, IFabRadioButton>( - RadioButton.WidgetKey, - RadioButton.IsCheckedWithEventMsg.WithValue(MsgValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value)), - RadioButton.ContentString.WithValue(content) - ) - - /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes - /// The content - /// The checked state - /// Message to dispatch - static member inline RadioButton(content: string, isChecked: bool, onChecked: bool -> unit) = - WidgetBuilder<'msg, IFabRadioButton>( - RadioButton.WidgetKey, - RadioButton.IsCheckedWithEventFn.WithValue(ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value)), - RadioButton.ContentString.WithValue(content) - ) - - /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes - /// The content widget - /// The checked state - /// Message to dispatch - static member inline RadioButton(content: WidgetBuilder<'msg, #IFabView>, isChecked: bool, onChecked: bool -> 'msg) = - WidgetBuilder<'msg, IFabRadioButton>( - RadioButton.WidgetKey, - AttributesBundle( - StackList.one( - RadioButton.IsCheckedWithEventMsg.WithValue( - MsgValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value) - ) - ), - ValueSome [| RadioButton.ContentWidget.WithValue(content.Compile()) |], - ValueNone - ) - ) - - /// Create a RadioButton widget with a content, a checked state and listen for the checked state changes - /// The content widget - /// The checked state - /// Message to dispatch - static member inline RadioButton(content: WidgetBuilder<'msg, #IFabView>, isChecked: bool, onChecked: bool -> unit) = - WidgetBuilder<'msg, IFabRadioButton>( - RadioButton.WidgetKey, - AttributesBundle( - StackList.one( - RadioButton.IsCheckedWithEventFn.WithValue( - ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onChecked args.Value) - ) - ), - ValueSome [| RadioButton.ContentWidget.WithValue(content.Compile()) |], - ValueNone - ) - ) - [] type RadioButtonModifiers = /// Set the border color of the radio button diff --git a/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Component.fs b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Component.fs new file mode 100644 index 0000000..8232fff --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Component.fs @@ -0,0 +1,23 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SearchBarComponent = + let SearchButtonPressed = + Attributes.Component.defineEventNoArg "SearchBarComponent_SearchButtonPressed" (fun target -> (target :?> SearchBar).SearchButtonPressed) + +[] +module SearchBarComponentBuilders = + type Fabulous.Maui.View with + + /// Create a SearchBar widget with a text and listen for both text changes and search button presses + /// The text value + /// Message to dispatch + /// Message to dispatch + static member inline SearchBar(text: string, onTextChanged: string -> unit, onSearchButtonPressed: unit -> unit) = + WidgetBuilder( + SearchBar.WidgetKey, + InputViewComponent.TextWithEvent.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)), + SearchBarComponent.SearchButtonPressed.WithValue(onSearchButtonPressed) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs new file mode 100644 index 0000000..5188ce2 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs @@ -0,0 +1,23 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SearchBarMvu = + let SearchButtonPressed = + Attributes.Mvu.defineEventNoArg "SearchBar_SearchButtonPressedMsg" (fun target -> (target :?> SearchBar).SearchButtonPressed) + +[] +module SearchBarMvuBuilders = + type Fabulous.Maui.View with + + /// Create a SearchBar widget with a text and listen for both text changes and search button presses + /// The text value + /// Message to dispatch + /// Message to dispatch + static member inline SearchBar(text: string, onTextChanged: string -> 'msg, onSearchButtonPressed: 'msg) = + WidgetBuilder<'msg, IFabSearchBar>( + SearchBar.WidgetKey, + InputViewMvu.TextWithEvent.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)), + SearchBarMvu.SearchButtonPressed.WithValue(MsgValue(onSearchButtonPressed)) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Controls/SearchBar.fs b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.fs similarity index 72% rename from src/Fabulous.MauiControls/Views/Controls/SearchBar.fs rename to src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.fs index 05bba0e..c07536e 100644 --- a/src/Fabulous.MauiControls/Views/Controls/SearchBar.fs +++ b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.fs @@ -34,43 +34,11 @@ module SearchBar = let IsTextPredictionEnabled = Attributes.defineBindableBool SearchBar.IsTextPredictionEnabledProperty - let SearchButtonPressedMsg = - Attributes.defineEventNoArg "SearchBar_SearchButtonPressedMsg" (fun target -> (target :?> SearchBar).SearchButtonPressed) - - let SearchButtonPressedFn = - Attributes.defineEventNoArgNoDispatch "SearchBar_SearchButtonPressedFn" (fun target -> (target :?> SearchBar).SearchButtonPressed) - let SelectionLength = Attributes.defineBindableInt SearchBar.SelectionLengthProperty let VerticalTextAlignment = Attributes.defineBindableEnum SearchBar.VerticalTextAlignmentProperty -[] -module SearchBarBuilders = - type Fabulous.Maui.View with - - /// Create a SearchBar widget with a text and listen for both text changes and search button presses - /// The text value - /// Message to dispatch - /// Message to dispatch - static member inline SearchBar(text: string, onTextChanged: string -> 'msg, onSearchButtonPressed: 'msg) = - WidgetBuilder<'msg, IFabSearchBar>( - SearchBar.WidgetKey, - InputView.TextWithEventMsg.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)), - SearchBar.SearchButtonPressedMsg.WithValue(MsgValue(onSearchButtonPressed)) - ) - - /// Create a SearchBar widget with a text and listen for both text changes and search button presses - /// The text value - /// Message to dispatch - /// Message to dispatch - static member inline SearchBar(text: string, onTextChanged: string -> unit, onSearchButtonPressed: unit -> unit) = - WidgetBuilder<'msg, IFabSearchBar>( - SearchBar.WidgetKey, - InputView.TextWithEventFn.WithValue(ValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)), - SearchBar.SearchButtonPressedFn.WithValue(onSearchButtonPressed) - ) - [] type SearchBarModifiers = /// Set the color of the cancel button text diff --git a/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Component.fs b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Component.fs new file mode 100644 index 0000000..02b771f --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Component.fs @@ -0,0 +1,47 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module SliderComponent = + let DragCompleted = + Attributes.Component.defineEventNoArg "SliderComponent_DragCompleted" (fun target -> (target :?> Slider).DragCompleted) + + let DragStarted = + Attributes.Component.defineEventNoArg "SliderComponent_DragStarted" (fun target -> (target :?> Slider).DragStarted) + + let ValueWithEvent = + Attributes.Component.defineBindableWithEvent "SliderComponent_ValueWithEvent" Slider.ValueProperty (fun target -> (target :?> Slider).ValueChanged) + +[] +module SliderComponentBuilders = + type Fabulous.Maui.View with + + /// Create a Slider widget with a min/max bounds and a value, listen for the value changes + /// The minimum bound + /// The maximum bound + /// The current value + /// Message to dispatch + static member inline Slider(min: float, max: float, value: float, onValueChanged: float -> unit) = + WidgetBuilder( + Slider.WidgetKey, + Slider.MinimumMaximum.WithValue(struct (min, max)), + SliderComponent.ValueWithEvent.WithValue(ValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) + ) + +[] +type SliderComponentModifiers = + /// Listen for the DragCompleted event + /// Current widget + /// Function to execute + [] + static member inline onDragCompleted(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(SliderComponent.DragCompleted.WithValue(fn)) + + /// Listen for the DragStarted event + /// Current widget + /// Function to execute + [] + static member inline onDragStarted(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(SliderComponent.DragStarted.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Mvu.fs new file mode 100644 index 0000000..3dab05e --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.Mvu.fs @@ -0,0 +1,47 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module SliderMvu = + let DragCompleted = + Attributes.Mvu.defineEventNoArg "SliderMvu_DragCompleted" (fun target -> (target :?> Slider).DragCompleted) + + let DragStarted = + Attributes.Mvu.defineEventNoArg "SliderMvu_DragStarted" (fun target -> (target :?> Slider).DragStarted) + + let ValueWithEvent = + Attributes.Mvu.defineBindableWithEvent "SliderMvu_ValueWithEvent" Slider.ValueProperty (fun target -> (target :?> Slider).ValueChanged) + +[] +module SliderMvuBuilders = + type Fabulous.Maui.View with + + /// Create a Slider widget with a min/max bounds and a value, listen for the value changes + /// The minimum bound + /// The maximum bound + /// The current value + /// Message to dispatch + static member inline Slider(min: float, max: float, value: float, onValueChanged: float -> 'msg) = + WidgetBuilder<'msg, IFabSlider>( + Slider.WidgetKey, + Slider.MinimumMaximum.WithValue(struct (min, max)), + SliderMvu.ValueWithEvent.WithValue(MsgValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) + ) + +[] +type SliderMvuModifiers = + /// Listen for the DragCompleted event + /// Current widget + /// Message to dispatch + [] + static member inline onDragCompleted(this: WidgetBuilder<'msg, #IFabSlider>, msg: 'msg) = + this.AddScalar(SliderMvu.DragCompleted.WithValue(MsgValue(msg))) + + /// Listen for the DragStarted event + /// Current widget + /// Message to dispatch + [] + static member inline onDragStarted(this: WidgetBuilder<'msg, #IFabSlider>, msg: 'msg) = + this.AddScalar(SliderMvu.DragStarted.WithValue(MsgValue(msg))) diff --git a/src/Fabulous.MauiControls/Views/Controls/Slider.fs b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.fs similarity index 54% rename from src/Fabulous.MauiControls/Views/Controls/Slider.fs rename to src/Fabulous.MauiControls/Views/Controls/Slider/Slider.fs index cdc5639..5bbdde0 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Slider.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.fs @@ -30,19 +30,7 @@ module SliderUpdaters = module Slider = let WidgetKey = Widgets.register() - - let DragCompletedMsg = - Attributes.defineEventNoArg "Slider_DragCompletedMsg" (fun target -> (target :?> Slider).DragCompleted) - - let DragCompletedFn = - Attributes.defineEventNoArgNoDispatch "Slider_DragCompletedFn" (fun target -> (target :?> Slider).DragCompleted) - - let DragStartedMsg = - Attributes.defineEventNoArg "Slider_DragStartedMsg" (fun target -> (target :?> Slider).DragStarted) - - let DragStartedFn = - Attributes.defineEventNoArgNoDispatch "Slider_DragStartedFn" (fun target -> (target :?> Slider).DragStarted) - + let MaximumTrackColor = Attributes.defineBindableColor Slider.MaximumTrackColorProperty @@ -57,70 +45,8 @@ module Slider = let ThumbImageSource = Attributes.defineBindableImageSource Slider.ThumbImageSourceProperty - let ValueWithEventMsg = - Attributes.defineBindableWithEvent "Slider_ValueWithEventMsg" Slider.ValueProperty (fun target -> (target :?> Slider).ValueChanged) - - let ValueWithEventFn = - Attributes.defineBindableWithEventNoDispatch "Slider_ValueWithEventFn" Slider.ValueProperty (fun target -> (target :?> Slider).ValueChanged) - -[] -module SliderBuilders = - type Fabulous.Maui.View with - - /// Create a Slider widget with a min/max bounds and a value, listen for the value changes - /// The minimum bound - /// The maximum bound - /// The current value - /// Message to dispatch - static member inline Slider(min: float, max: float, value: float, onValueChanged: float -> 'msg) = - WidgetBuilder<'msg, IFabSlider>( - Slider.WidgetKey, - Slider.MinimumMaximum.WithValue(struct (min, max)), - Slider.ValueWithEventMsg.WithValue(MsgValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) - ) - - /// Create a Slider widget with a min/max bounds and a value, listen for the value changes - /// The minimum bound - /// The maximum bound - /// The current value - /// Message to dispatch - static member inline Slider(min: float, max: float, value: float, onValueChanged: float -> unit) = - WidgetBuilder<'msg, IFabSlider>( - Slider.WidgetKey, - Slider.MinimumMaximum.WithValue(struct (min, max)), - Slider.ValueWithEventFn.WithValue(ValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) - ) - [] type SliderModifiers = - /// Listen for the DragCompleted event - /// Current widget - /// Message to dispatch - [] - static member inline onDragCompleted(this: WidgetBuilder<'msg, #IFabSlider>, msg: 'msg) = - this.AddScalar(Slider.DragCompletedMsg.WithValue(MsgValue(msg))) - - /// Listen for the DragCompleted event - /// Current widget - /// Function to execute - [] - static member inline onDragCompleted(this: WidgetBuilder<'msg, #IFabSlider>, fn: unit -> unit) = - this.AddScalar(Slider.DragCompletedFn.WithValue(fn)) - - /// Listen for the DragStarted event - /// Current widget - /// Message to dispatch - [] - static member inline onDragStarted(this: WidgetBuilder<'msg, #IFabSlider>, msg: 'msg) = - this.AddScalar(Slider.DragStartedMsg.WithValue(MsgValue(msg))) - - /// Listen for the DragStarted event - /// Current widget - /// Function to execute - [] - static member inline onDragStarted(this: WidgetBuilder<'msg, #IFabSlider>, fn: unit -> unit) = - this.AddScalar(Slider.DragStartedFn.WithValue(fn)) - /// Set the color of the maximum track /// Current widget /// The color of the maximum track diff --git a/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Component.fs b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Component.fs new file mode 100644 index 0000000..8ec7fff --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Component.fs @@ -0,0 +1,24 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module StepperComponent = + let ValueWithEvent = + Attributes.Component.defineBindableWithEvent "StepperComponent_ValueChanged" Stepper.ValueProperty (fun target -> (target :?> Stepper).ValueChanged) + +[] +module StepperComponentBuilders = + type Fabulous.Maui.View with + + /// Create a Stepper widget with min and max values, a current value, and listen for value changes + /// The minimum value + /// The maximum value + /// The current value + /// Message to dispatch + static member inline Stepper(min: float, max: float, value: float, onValueChanged: float -> unit) = + WidgetBuilder( + Stepper.WidgetKey, + Stepper.MinimumMaximum.WithValue(struct (min, max)), + StepperComponent.ValueWithEvent.WithValue(ValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs new file mode 100644 index 0000000..e648a43 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs @@ -0,0 +1,25 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module StepperMvu = + let ValueWithEvent = + Attributes.Mvu.defineBindableWithEvent "StepperMvu_ValueChanged" Stepper.ValueProperty (fun target -> (target :?> Stepper).ValueChanged) + +[] +module StepperMvuBuilders = + type Fabulous.Maui.View with + + /// Create a Stepper widget with min and max values, a current value, and listen for value changes + /// The minimum value + /// The maximum value + /// The current value + /// Message to dispatch + static member inline Stepper(min: float, max: float, value: float, onValueChanged: float -> 'msg) = + WidgetBuilder<'msg, IFabStepper>( + Stepper.WidgetKey, + Stepper.MinimumMaximum.WithValue(struct (min, max)), + StepperMvu.ValueWithEvent.WithValue(MsgValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) + ) + \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Controls/Stepper.fs b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.fs similarity index 50% rename from src/Fabulous.MauiControls/Views/Controls/Stepper.fs rename to src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.fs index d72d14a..bd394c0 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Stepper.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.fs @@ -33,40 +33,6 @@ module Stepper = let MinimumMaximum = Attributes.defineSimpleScalarWithEquality "Stepper_MinimumMaximum" StepperUpdaters.updateStepperMinMax - let ValueWithEventMsg = - Attributes.defineBindableWithEvent "Stepper_ValueChangedMsg" Stepper.ValueProperty (fun target -> (target :?> Stepper).ValueChanged) - - let ValueWithEventFn = - Attributes.defineBindableWithEventNoDispatch "Stepper_ValueChangedFn" Stepper.ValueProperty (fun target -> (target :?> Stepper).ValueChanged) - -[] -module StepperBuilders = - type Fabulous.Maui.View with - - /// Create a Stepper widget with min and max values, a current value, and listen for value changes - /// The minimum value - /// The maximum value - /// The current value - /// Message to dispatch - static member inline Stepper(min: float, max: float, value: float, onValueChanged: float -> 'msg) = - WidgetBuilder<'msg, IFabStepper>( - Stepper.WidgetKey, - Stepper.MinimumMaximum.WithValue(struct (min, max)), - Stepper.ValueWithEventMsg.WithValue(MsgValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) - ) - - /// Create a Stepper widget with min and max values, a current value, and listen for value changes - /// The minimum value - /// The maximum value - /// The current value - /// Message to dispatch - static member inline Stepper(min: float, max: float, value: float, onValueChanged: float -> unit) = - WidgetBuilder<'msg, IFabStepper>( - Stepper.WidgetKey, - Stepper.MinimumMaximum.WithValue(struct (min, max)), - Stepper.ValueWithEventFn.WithValue(ValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) - ) - [] type StepperModifiers = /// Set the increment step diff --git a/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Component.fs b/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Component.fs new file mode 100644 index 0000000..90e4637 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Component.fs @@ -0,0 +1,21 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SwitchComponent = + let IsToggledWithEvent = + Attributes.Component.defineBindableWithEvent "SwitchComponent_Toggled" Switch.IsToggledProperty (fun target -> (target :?> Switch).Toggled) + +[] +module SwitchComponentBuilders = + type Fabulous.Maui.View with + + /// Create a Switch widget with a toggle state and listen for toggle state changes + /// The toggle state + /// Message to dispatch + static member inline Switch(isToggled: bool, onToggled: bool -> unit) = + WidgetBuilder( + Switch.WidgetKey, + SwitchComponent.IsToggledWithEvent.WithValue(ValueEventData.create isToggled (fun (args: ToggledEventArgs) -> onToggled args.Value)) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Mvu.fs new file mode 100644 index 0000000..0f599ee --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.Mvu.fs @@ -0,0 +1,21 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SwitchMvu = + let IsToggledWithEvent = + Attributes.Mvu.defineBindableWithEvent "SwitchMvu_Toggled" Switch.IsToggledProperty (fun target -> (target :?> Switch).Toggled) + +[] +module SwitchMvuBuilders = + type Fabulous.Maui.View with + + /// Create a Switch widget with a toggle state and listen for toggle state changes + /// The toggle state + /// Message to dispatch + static member inline Switch(isToggled: bool, onToggled: bool -> 'msg) = + WidgetBuilder<'msg, IFabSwitch>( + Switch.WidgetKey, + SwitchMvu.IsToggledWithEvent.WithValue(MsgValueEventData.create isToggled (fun (args: ToggledEventArgs) -> onToggled args.Value)) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/Switch.fs b/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.fs similarity index 50% rename from src/Fabulous.MauiControls/Views/Controls/Switch.fs rename to src/Fabulous.MauiControls/Views/Controls/Switch/Switch.fs index bd5d559..6479b89 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Switch.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Switch/Switch.fs @@ -15,34 +15,6 @@ module Switch = let ThumbColor = Attributes.defineBindableColor Switch.ThumbColorProperty - let IsToggledWithEventMsg = - Attributes.defineBindableWithEvent "Switch_ToggledMsg" Switch.IsToggledProperty (fun target -> (target :?> Switch).Toggled) - - let IsToggledWithEventFn = - Attributes.defineBindableWithEventNoDispatch "Switch_ToggledFn" Switch.IsToggledProperty (fun target -> (target :?> Switch).Toggled) - -[] -module SwitchBuilders = - type Fabulous.Maui.View with - - /// Create a Switch widget with a toggle state and listen for toggle state changes - /// The toggle state - /// Message to dispatch - static member inline Switch(isToggled: bool, onToggled: bool -> 'msg) = - WidgetBuilder<'msg, IFabSwitch>( - Switch.WidgetKey, - Switch.IsToggledWithEventMsg.WithValue(MsgValueEventData.create isToggled (fun (args: ToggledEventArgs) -> onToggled args.Value)) - ) - - /// Create a Switch widget with a toggle state and listen for toggle state changes - /// The toggle state - /// Message to dispatch - static member inline Switch(isToggled: bool, onToggled: bool -> unit) = - WidgetBuilder<'msg, IFabSwitch>( - Switch.WidgetKey, - Switch.IsToggledWithEventFn.WithValue(ValueEventData.create isToggled (fun (args: ToggledEventArgs) -> onToggled args.Value)) - ) - [] type SwitchModifiers = /// Set the color of the on state diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs new file mode 100644 index 0000000..5233af7 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs @@ -0,0 +1,22 @@ +namespace Fabulous.Maui + +open System +open Fabulous +open Microsoft.Maui.Controls + +module TimePickerComponent = + let TimeWithEvent = + Attributes.Component.defineBindableWithEvent "TimePickerComponent_TimeSelected" TimePicker.TimeProperty (fun target -> (target :?> FabTimePicker).TimeSelected) + +[] +module TimePickerComponentBuilders = + type Fabulous.Maui.View with + + /// Create a TimePicker widget with a selected time and listen for the selected time changes + /// The selected time + /// Message to dispatch + static member inline TimePicker(time: TimeSpan, onTimeSelected: TimeSpan -> unit) = + WidgetBuilder( + TimePicker.WidgetKey, + TimePickerComponent.TimeWithEvent.WithValue(ValueEventData.create time (fun (args: TimeSelectedEventArgs) -> onTimeSelected args.NewTime)) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs new file mode 100644 index 0000000..d0046e7 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs @@ -0,0 +1,22 @@ +namespace Fabulous.Maui + +open System +open Fabulous +open Microsoft.Maui.Controls + +module TimePickerMvu = + let TimeWithEvent = + Attributes.Mvu.defineBindableWithEvent "TimePickerMvu_TimeSelected" TimePicker.TimeProperty (fun target -> (target :?> FabTimePicker).TimeSelected) + +[] +module TimePickerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a TimePicker widget with a selected time and listen for the selected time changes + /// The selected time + /// Message to dispatch + static member inline TimePicker(time: TimeSpan, onTimeSelected: TimeSpan -> 'msg) = + WidgetBuilder<'msg, IFabTimePicker>( + TimePicker.WidgetKey, + TimePickerMvu.TimeWithEvent.WithValue(MsgValueEventData.create time (fun (args: TimeSelectedEventArgs) -> onTimeSelected args.NewTime)) + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs similarity index 77% rename from src/Fabulous.MauiControls/Views/Controls/TimePicker.fs rename to src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs index a14e94e..5beef25 100644 --- a/src/Fabulous.MauiControls/Views/Controls/TimePicker.fs +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs @@ -35,12 +35,6 @@ module TimePicker = let CharacterSpacing = Attributes.defineBindableFloat TimePicker.CharacterSpacingProperty - let TimeWithEventMsg = - Attributes.defineBindableWithEvent "TimePicker_TimeSelectedMsg" TimePicker.TimeProperty (fun target -> (target :?> FabTimePicker).TimeSelected) - - let TimeWithEventFn = - Attributes.defineBindableWithEventNoDispatch "TimePicker_TimeSelectedFn" TimePicker.TimeProperty (fun target -> (target :?> FabTimePicker).TimeSelected) - let FontAttributes = Attributes.defineBindableEnum TimePicker.FontAttributesProperty @@ -68,28 +62,6 @@ module TimePickerPlatform = iOSSpecific.TimePicker.SetUpdateMode(timePicker, value)) -[] -module TimePickerBuilders = - type Fabulous.Maui.View with - - /// Create a TimePicker widget with a selected time and listen for the selected time changes - /// The selected time - /// Message to dispatch - static member inline TimePicker(time: TimeSpan, onTimeSelected: TimeSpan -> 'msg) = - WidgetBuilder<'msg, IFabTimePicker>( - TimePicker.WidgetKey, - TimePicker.TimeWithEventMsg.WithValue(MsgValueEventData.create time (fun (args: TimeSelectedEventArgs) -> onTimeSelected args.NewTime)) - ) - - /// Create a TimePicker widget with a selected time and listen for the selected time changes - /// The selected time - /// Message to dispatch - static member inline TimePicker(time: TimeSpan, onTimeSelected: TimeSpan -> unit) = - WidgetBuilder<'msg, IFabTimePicker>( - TimePicker.WidgetKey, - TimePicker.TimeWithEventFn.WithValue(ValueEventData.create time (fun (args: TimeSelectedEventArgs) -> onTimeSelected args.NewTime)) - ) - [] type TimePickerModifiers = /// Set the character spacing diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs new file mode 100644 index 0000000..a8986c6 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs @@ -0,0 +1,28 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module WebViewComponent = + let Navigated = + Attributes.Component.defineEvent "WebViewComponent_Navigated" (fun target -> (target :?> WebView).Navigated) + + let Navigating = + Attributes.Component.defineEvent "WebViewComponent_Navigating" (fun target -> (target :?> WebView).Navigating) + +[] +type WebViewComponentModifiers() = + /// Listen for the Navigated event + /// Current widget + /// Message to dispatch + [] + static member inline onNavigated(this: WidgetBuilder, fn: WebNavigatedEventArgs -> unit) = + this.AddScalar(WebViewComponent.Navigated.WithValue(fn)) + + /// Listen for the Navigating event + /// Current widget + /// Message to dispatch + [] + static member inline onNavigating(this: WidgetBuilder, fn: WebNavigatingEventArgs -> unit) = + this.AddScalar(WebViewComponent.Navigating.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs new file mode 100644 index 0000000..40dfe68 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs @@ -0,0 +1,28 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module WebViewMvu = + let Navigated = + Attributes.Mvu.defineEvent "WebViewMvu_Navigated" (fun target -> (target :?> WebView).Navigated) + + let Navigating = + Attributes.Mvu.defineEvent "WebViewMvu_Navigating" (fun target -> (target :?> WebView).Navigating) + +[] +type WebViewMvuModifiers() = + /// Listen for the Navigated event + /// Current widget + /// Message to dispatch + [] + static member inline onNavigated(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebNavigatedEventArgs -> 'msg) = + this.AddScalar(WebViewMvu.Navigated.WithValue(fun args -> fn args |> box)) + + /// Listen for the Navigating event + /// Current widget + /// Message to dispatch + [] + static member inline onNavigating(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebNavigatingEventArgs -> 'msg) = + this.AddScalar(WebViewMvu.Navigating.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs similarity index 71% rename from src/Fabulous.MauiControls/Views/Controls/WebView.fs rename to src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs index ceae5ce..15ee3b1 100644 --- a/src/Fabulous.MauiControls/Views/Controls/WebView.fs +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs @@ -20,18 +20,6 @@ module WebView = let Cookies = Attributes.defineBindableWithEquality WebView.CookiesProperty - let NavigatedMsg = - Attributes.defineEvent "WebView_NavigatedMsg" (fun target -> (target :?> WebView).Navigated) - - let NavigatedFn = - Attributes.defineEventNoDispatch "WebView_NavigatedFn" (fun target -> (target :?> WebView).Navigated) - - let NavigatingMsg = - Attributes.defineEvent "WebView_NavigatingMsg" (fun target -> (target :?> WebView).Navigating) - - let NavigatingFn = - Attributes.defineEventNoDispatch "WebView_NavigatingFn" (fun target -> (target :?> WebView).Navigating) - let Source = Attributes.defineBindableWithEquality WebView.SourceProperty @@ -111,34 +99,6 @@ type WebViewModifiers() = static member inline cookies(this: WidgetBuilder<'msg, #IFabWebView>, value: CookieContainer) = this.AddScalar(WebView.Cookies.WithValue(value)) - /// Listen for the Navigated event - /// Current widget - /// Message to dispatch - [] - static member inline onNavigated(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebNavigatedEventArgs -> 'msg) = - this.AddScalar(WebView.NavigatedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the Navigated event - /// Current widget - /// Message to dispatch - [] - static member inline onNavigated(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebNavigatedEventArgs -> unit) = - this.AddScalar(WebView.NavigatedFn.WithValue(fn)) - - /// Listen for the Navigating event - /// Current widget - /// Message to dispatch - [] - static member inline onNavigating(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebNavigatingEventArgs -> 'msg) = - this.AddScalar(WebView.NavigatingMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the Navigating event - /// Current widget - /// Message to dispatch - [] - static member inline onNavigating(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebNavigatingEventArgs -> unit) = - this.AddScalar(WebView.NavigatingFn.WithValue(fn)) - /// Link a ViewRef to access the direct WebView control instance /// Current widget /// The ViewRef instance that will receive access to the underlying control diff --git a/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Component.fs new file mode 100644 index 0000000..ac46f3f --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Component.fs @@ -0,0 +1,8 @@ +namespace Fabulous.Maui + +open Microsoft.Maui.Controls + +module InputViewComponent = + let TextWithEvent = + Attributes.Component.defineBindableWithEvent "InputViewComponent_TextChanged" InputView.TextProperty (fun target -> + (target :?> InputView).TextChanged) diff --git a/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Mvu.fs new file mode 100644 index 0000000..c6131e7 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.Mvu.fs @@ -0,0 +1,8 @@ +namespace Fabulous.Maui + +open Microsoft.Maui.Controls + +module InputViewMvu = + let TextWithEvent = + Attributes.Mvu.defineBindableWithEvent "InputViewMvu_TextChanged" InputView.TextProperty (fun target -> + (target :?> InputView).TextChanged) diff --git a/src/Fabulous.MauiControls/Views/Controls/_InputView.fs b/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.fs similarity index 91% rename from src/Fabulous.MauiControls/Views/Controls/_InputView.fs rename to src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.fs index 19e862e..70efd1a 100644 --- a/src/Fabulous.MauiControls/Views/Controls/_InputView.fs +++ b/src/Fabulous.MauiControls/Views/Controls/_InputView/InputView.fs @@ -34,14 +34,6 @@ module InputView = let TextTransform = Attributes.defineBindableEnum InputView.TextTransformProperty - let TextWithEventMsg = - Attributes.defineBindableWithEvent "InputView_TextChangedMsg" InputView.TextProperty (fun target -> - (target :?> InputView).TextChanged) - - let TextWithEventFn = - Attributes.defineBindableWithEventNoDispatch "InputView_TextChangedFn" InputView.TextProperty (fun target -> - (target :?> InputView).TextChanged) - [] type InputViewModifiers = /// Set the character spacing diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer.fs deleted file mode 100644 index fa70dec..0000000 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer.fs +++ /dev/null @@ -1,77 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls - -type IFabDragGestureRecognizer = - inherit IFabGestureRecognizer - -module DragGestureRecognizer = - let WidgetKey = Widgets.register() - - let CanDrag = Attributes.defineBindableBool DragGestureRecognizer.CanDragProperty - - let DragStartingMsg = - Attributes.defineEvent "DragGestureRecognizer_DragStartingMsg" (fun target -> (target :?> DragGestureRecognizer).DragStarting) - - let DragStartingFn = - Attributes.defineEventNoDispatch "DragGestureRecognizer_DragStartingFn" (fun target -> - (target :?> DragGestureRecognizer).DragStarting) - - let DropCompletedMsg = - Attributes.defineEvent "DragGestureRecognizer_DropCompletedMsg" (fun target -> (target :?> DragGestureRecognizer).DropCompleted) - - let DropCompletedFn = - Attributes.defineEvent "DragGestureRecognizer_DropCompletedFn" (fun target -> (target :?> DragGestureRecognizer).DropCompleted) - -[] -module DragGestureRecognizerBuilders = - type Fabulous.Maui.View with - - /// Create a DragGestureRecognizer that listens for DragStarting event - /// Message to dispatch - static member inline DragGestureRecognizer<'msg when 'msg: equality>(onDragStarting: DragStartingEventArgs -> 'msg) = - WidgetBuilder<'msg, IFabDragGestureRecognizer>( - DragGestureRecognizer.WidgetKey, - DragGestureRecognizer.DragStartingMsg.WithValue(fun args -> onDragStarting args |> box) - ) - - /// Create a DragGestureRecognizer that listens for DragStarting event - /// Message to dispatch - static member inline DragGestureRecognizer(onDragStarting: DragStartingEventArgs -> unit) = - WidgetBuilder<'msg, IFabDragGestureRecognizer>(DragGestureRecognizer.WidgetKey, DragGestureRecognizer.DragStartingMsg.WithValue(onDragStarting)) - -[] -type DragGestureRecognizerModifiers = - /// Set whether users are allowed to drag - /// Current widget - /// true to allow users to drag; otherwise, false - [] - static member inline canDrag(this: WidgetBuilder<'msg, #IFabDragGestureRecognizer>, value: bool) = - this.AddScalar(DragGestureRecognizer.CanDrag.WithValue(value)) - - /// Listen for DropCompleted event - /// Current widget - /// Message to dispatch - [] - static member inline onDropCompleted<'msg, 'marker when 'msg: equality and 'marker :> IFabDragGestureRecognizer> - ( - this: WidgetBuilder<'msg, 'marker>, - msg: 'msg - ) = - this.AddScalar(DragGestureRecognizer.DropCompletedMsg.WithValue(fun _ -> box msg)) - - /// Listen for DropCompleted event - /// Current widget - /// Function to execute - [] - static member inline onDropCompleted(this: WidgetBuilder<'msg, #IFabDragGestureRecognizer>, fn: unit -> unit) = - this.AddScalar(DragGestureRecognizer.DropCompletedFn.WithValue(fun _ -> fn())) - - /// Link a ViewRef to access the direct DragGestureRecognizer control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabDragGestureRecognizer>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs new file mode 100644 index 0000000..a412057 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs @@ -0,0 +1,30 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module DragGestureRecognizerComponent = + let DragStarting = + Attributes.Component.defineEvent "DragGestureRecognizerComponent_DragStarting" (fun target -> + (target :?> DragGestureRecognizer).DragStarting) + + let DropCompleted = + Attributes.Component.defineEvent "DragGestureRecognizerComponent_DropCompleted" (fun target -> (target :?> DragGestureRecognizer).DropCompleted) + +[] +module DragGestureRecognizerComponentBuilders = + type Fabulous.Maui.View with + /// Create a DragGestureRecognizer that listens for DragStarting event + /// Message to dispatch + static member inline DragGestureRecognizer(onDragStarting: DragStartingEventArgs -> unit) = + WidgetBuilder(DragGestureRecognizer.WidgetKey, DragGestureRecognizerComponent.DragStarting.WithValue(onDragStarting)) + +[] +type DragGestureRecognizerComponentModifiers = + /// Listen for DropCompleted event + /// Current widget + /// Function to execute + [] + static member inline onDropCompleted(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(DragGestureRecognizerComponent.DropCompleted.WithValue(fun _ -> fn())) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs new file mode 100644 index 0000000..b34f885 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs @@ -0,0 +1,37 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module DragGestureRecognizerMvu = + let DragStarting = + Attributes.Mvu.defineEvent "DragGestureRecognizerMvu_DragStarting" (fun target -> (target :?> DragGestureRecognizer).DragStarting) + + let DropCompleted = + Attributes.Mvu.defineEvent "DragGestureRecognizerMvu_DropCompleted" (fun target -> (target :?> DragGestureRecognizer).DropCompleted) + +[] +module DragGestureRecognizerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a DragGestureRecognizer that listens for DragStarting event + /// Message to dispatch + static member inline DragGestureRecognizer<'msg when 'msg: equality>(onDragStarting: DragStartingEventArgs -> 'msg) = + WidgetBuilder<'msg, IFabDragGestureRecognizer>( + DragGestureRecognizer.WidgetKey, + DragGestureRecognizerMvu.DragStarting.WithValue(fun args -> onDragStarting args |> box) + ) + +[] +type DragGestureRecognizerMvuModifiers = + /// Listen for DropCompleted event + /// Current widget + /// Message to dispatch + [] + static member inline onDropCompleted<'msg, 'marker when 'msg: equality and 'marker :> IFabDragGestureRecognizer> + ( + this: WidgetBuilder<'msg, 'marker>, + msg: 'msg + ) = + this.AddScalar(DragGestureRecognizerMvu.DropCompleted.WithValue(fun _ -> box msg)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.fs new file mode 100644 index 0000000..6cd33cf --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.fs @@ -0,0 +1,29 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +type IFabDragGestureRecognizer = + inherit IFabGestureRecognizer + +module DragGestureRecognizer = + let WidgetKey = Widgets.register() + + let CanDrag = Attributes.defineBindableBool DragGestureRecognizer.CanDragProperty + +[] +type DragGestureRecognizerModifiers = + /// Set whether users are allowed to drag + /// Current widget + /// true to allow users to drag; otherwise, false + [] + static member inline canDrag(this: WidgetBuilder<'msg, #IFabDragGestureRecognizer>, value: bool) = + this.AddScalar(DragGestureRecognizer.CanDrag.WithValue(value)) + + /// Link a ViewRef to access the direct DragGestureRecognizer control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabDragGestureRecognizer>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer.fs deleted file mode 100644 index aaa3554..0000000 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer.fs +++ /dev/null @@ -1,101 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls - -type IFabDropGestureRecognizer = - inherit IFabGestureRecognizer - -module DropGestureRecognizer = - let WidgetKey = Widgets.register() - - let AllowDrop = - Attributes.defineBindableBool DropGestureRecognizer.AllowDropProperty - - let DropMsg = - Attributes.defineEvent "DropGestureRecognizer_DropMsg" (fun target -> (target :?> DropGestureRecognizer).Drop) - - let DropFn = - Attributes.defineEventNoDispatch "DropGestureRecognizer_DropFn" (fun target -> (target :?> DropGestureRecognizer).Drop) - - let DragOverMsg = - Attributes.defineEvent "DropGestureRecognizer_DragOverMsg" (fun target -> (target :?> DropGestureRecognizer).DragOver) - - let DragOverFn = - Attributes.defineEvent "DropGestureRecognizer_DragOverFn" (fun target -> (target :?> DropGestureRecognizer).DragOver) - - let DragLeaveMsg = - Attributes.defineEvent "DropGestureRecognizer_DragLeaveMsg" (fun target -> (target :?> DropGestureRecognizer).DragLeave) - - let DragLeaveFn = - Attributes.defineEvent "DropGestureRecognizer_DragLeaveFn" (fun target -> (target :?> DropGestureRecognizer).DragLeave) - -[] -module DropGestureRecognizerBuilders = - type Fabulous.Maui.View with - - /// Create a DropGestureRecognizer that listens for Drop event - /// Message to dispatch - static member inline DropGestureRecognizer<'msg when 'msg: equality>(onDrop: DropEventArgs -> 'msg) = - WidgetBuilder<'msg, IFabDropGestureRecognizer>( - DropGestureRecognizer.WidgetKey, - DropGestureRecognizer.DropMsg.WithValue(fun args -> onDrop args |> box) - ) - - /// Create a DropGestureRecognizer that listens for Drop event - /// Message to dispatch - static member inline DropGestureRecognizer(onDrop: DropEventArgs -> unit) = - WidgetBuilder<'msg, IFabDropGestureRecognizer>(DropGestureRecognizer.WidgetKey, DropGestureRecognizer.DropFn.WithValue(onDrop)) - -[] -type DropGestureRecognizerModifiers = - /// Set whether users are allowed to drop - /// Current widget - /// true to allow users to drop; otherwise, false - [] - static member inline allowDrop(this: WidgetBuilder<'msg, #IFabDropGestureRecognizer>, value: bool) = - this.AddScalar(DropGestureRecognizer.AllowDrop.WithValue(value)) - - /// Listen for the DragOver event - /// Current widget - /// Message to dispatch - [] - static member inline onDragOver<'msg, 'marker when 'msg: equality and 'marker :> IFabDropGestureRecognizer> - ( - this: WidgetBuilder<'msg, 'marker>, - fn: DragEventArgs -> 'msg - ) = - this.AddScalar(DropGestureRecognizer.DragOverMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the DragOver event - /// Current widget - /// Message to dispatch - [] - static member inline onDragOver(this: WidgetBuilder<'msg, #IFabDropGestureRecognizer>, fn: DragEventArgs -> unit) = - this.AddScalar(DropGestureRecognizer.DragOverFn.WithValue(fn)) - - /// Listen for the DragLeave event - /// Current widget - /// Message to dispatch - [] - static member inline onDragLeave<'msg, 'marker when 'msg: equality and 'marker :> IFabDragGestureRecognizer> - ( - this: WidgetBuilder<'msg, 'marker>, - fn: DragEventArgs -> 'msg - ) = - this.AddScalar(DropGestureRecognizer.DragLeaveMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the DragLeave event - /// Current widget - /// Message to dispatch - [] - static member inline onDragLeave(this: WidgetBuilder<'msg, #IFabDropGestureRecognizer>, fn: DragEventArgs -> unit) = - this.AddScalar(DropGestureRecognizer.DragLeaveFn.WithValue(fn)) - - /// Link a ViewRef to access the direct DropGestureRecognizer control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabDropGestureRecognizer>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Component.fs new file mode 100644 index 0000000..50798cb --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Component.fs @@ -0,0 +1,40 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module DropGestureRecognizerComponent = + let Drop = + Attributes.Component.defineEvent "DropGestureRecognizerComponent_Drop" (fun target -> (target :?> DropGestureRecognizer).Drop) + + let DragOver = + Attributes.Component.defineEvent "DropGestureRecognizerComponent_DragOver" (fun target -> (target :?> DropGestureRecognizer).DragOver) + + let DragLeave = + Attributes.Component.defineEvent "DropGestureRecognizerComponent_DragLeave" (fun target -> (target :?> DropGestureRecognizer).DragLeave) + +[] +module DropGestureRecognizerComponentBuilders = + type Fabulous.Maui.View with + + /// Create a DropGestureRecognizer that listens for Drop event + /// Message to dispatch + static member inline DropGestureRecognizer(onDrop: DropEventArgs -> unit) = + WidgetBuilder(DropGestureRecognizer.WidgetKey, DropGestureRecognizerComponent.Drop.WithValue(onDrop)) + +[] +type DropGestureRecognizerComponentModifiers = + /// Listen for the DragOver event + /// Current widget + /// Message to dispatch + [] + static member inline onDragOver(this: WidgetBuilder, fn: DragEventArgs -> unit) = + this.AddScalar(DropGestureRecognizerComponent.DragOver.WithValue(fn)) + + /// Listen for the DragLeave event + /// Current widget + /// Message to dispatch + [] + static member inline onDragLeave(this: WidgetBuilder, fn: DragEventArgs -> unit) = + this.AddScalar(DropGestureRecognizerComponent.DragLeave.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs new file mode 100644 index 0000000..c5a4783 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs @@ -0,0 +1,51 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module DropGestureRecognizerMvu = + let Drop = + Attributes.Mvu.defineEvent "DropGestureRecognizerMvu_Drop" (fun target -> (target :?> DropGestureRecognizer).Drop) + + let DragOver = + Attributes.Mvu.defineEvent "DropGestureRecognizerMvu_DragOver" (fun target -> (target :?> DropGestureRecognizer).DragOver) + + let DragLeave = + Attributes.Mvu.defineEvent "DropGestureRecognizerMvu_DragLeave" (fun target -> (target :?> DropGestureRecognizer).DragLeave) + +[] +module DropGestureRecognizerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a DropGestureRecognizer that listens for Drop event + /// Message to dispatch + static member inline DropGestureRecognizer<'msg when 'msg: equality>(onDrop: DropEventArgs -> 'msg) = + WidgetBuilder<'msg, IFabDropGestureRecognizer>( + DropGestureRecognizer.WidgetKey, + DropGestureRecognizerMvu.Drop.WithValue(fun args -> onDrop args |> box) + ) + +[] +type DropGestureRecognizerMvuModifiers = + /// Listen for the DragOver event + /// Current widget + /// Message to dispatch + [] + static member inline onDragOver<'msg, 'marker when 'msg: equality and 'marker :> IFabDropGestureRecognizer> + ( + this: WidgetBuilder<'msg, 'marker>, + fn: DragEventArgs -> 'msg + ) = + this.AddScalar(DropGestureRecognizerMvu.DragOver.WithValue(fun args -> fn args |> box)) + + /// Listen for the DragLeave event + /// Current widget + /// Message to dispatch + [] + static member inline onDragLeave<'msg, 'marker when 'msg: equality and 'marker :> IFabDragGestureRecognizer> + ( + this: WidgetBuilder<'msg, 'marker>, + fn: DragEventArgs -> 'msg + ) = + this.AddScalar(DropGestureRecognizerMvu.DragLeave.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs new file mode 100644 index 0000000..15c9b98 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs @@ -0,0 +1,30 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +type IFabDropGestureRecognizer = + inherit IFabGestureRecognizer + +module DropGestureRecognizer = + let WidgetKey = Widgets.register() + + let AllowDrop = + Attributes.defineBindableBool DropGestureRecognizer.AllowDropProperty + +[] +type DropGestureRecognizerModifiers = + /// Set whether users are allowed to drop + /// Current widget + /// true to allow users to drop; otherwise, false + [] + static member inline allowDrop(this: WidgetBuilder<'msg, #IFabDropGestureRecognizer>, value: bool) = + this.AddScalar(DropGestureRecognizer.AllowDrop.WithValue(value)) + + /// Link a ViewRef to access the direct DropGestureRecognizer control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabDropGestureRecognizer>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs new file mode 100644 index 0000000..f89348d --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module PanGestureRecognizerComponent = + let PanUpdated = + Attributes.Component.defineEvent "PanGestureRecognizerComponent_PanUpdated" (fun target -> (target :?> PanGestureRecognizer).PanUpdated) + +[] +module PanGestureRecognizerComponentBuilders = + type Fabulous.Maui.View with + + /// Create a PanGestureRecognizer that listens for Pan event + /// Message to dispatch + static member inline PanGestureRecognizer(onPanUpdated: PanUpdatedEventArgs -> unit) = + WidgetBuilder(PanGestureRecognizer.WidgetKey, PanGestureRecognizerComponent.PanUpdated.WithValue(onPanUpdated)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Mvu.fs new file mode 100644 index 0000000..5a1084f --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Mvu.fs @@ -0,0 +1,20 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module PanGestureRecognizerMvu = + let PanUpdated = + Attributes.Mvu.defineEvent "PanGestureRecognizerMvu_PanUpdated" (fun target -> (target :?> PanGestureRecognizer).PanUpdated) + +[] +module PanGestureRecognizerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a PanGestureRecognizer that listens for Pan event + /// Message to dispatch + static member inline PanGestureRecognizer<'msg when 'msg: equality>(onPanUpdated: PanUpdatedEventArgs -> 'msg) = + WidgetBuilder<'msg, IFabPanGestureRecognizer>( + PanGestureRecognizer.WidgetKey, + PanGestureRecognizerMvu.PanUpdated.WithValue(fun args -> onPanUpdated args |> box) + ) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.fs similarity index 50% rename from src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer.fs rename to src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.fs index 92f9e63..dcf6fb6 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.fs @@ -9,33 +9,10 @@ type IFabPanGestureRecognizer = module PanGestureRecognizer = let WidgetKey = Widgets.register() - - let PanUpdatedMsg = - Attributes.defineEvent "PanGestureRecognizer_PanUpdatedMsg" (fun target -> (target :?> PanGestureRecognizer).PanUpdated) - - let PanUpdatedFn = - Attributes.defineEventNoDispatch "PanGestureRecognizer_PanUpdatedFn" (fun target -> (target :?> PanGestureRecognizer).PanUpdated) - + let TouchPoints = Attributes.defineBindableInt PanGestureRecognizer.TouchPointsProperty -[] -module PanGestureRecognizerBuilders = - type Fabulous.Maui.View with - - /// Create a PanGestureRecognizer that listens for Pan event - /// Message to dispatch - static member inline PanGestureRecognizer<'msg when 'msg: equality>(onPanUpdated: PanUpdatedEventArgs -> 'msg) = - WidgetBuilder<'msg, IFabPanGestureRecognizer>( - PanGestureRecognizer.WidgetKey, - PanGestureRecognizer.PanUpdatedMsg.WithValue(fun args -> onPanUpdated args |> box) - ) - - /// Create a PanGestureRecognizer that listens for Pan event - /// Message to dispatch - static member inline PanGestureRecognizer(onPanUpdated: PanUpdatedEventArgs -> unit) = - WidgetBuilder<'msg, IFabPanGestureRecognizer>(PanGestureRecognizer.WidgetKey, PanGestureRecognizer.PanUpdatedFn.WithValue(onPanUpdated)) - [] type PanGestureRecognizerModifiers = /// Set the number of touch points to trigger the gesture diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer.fs deleted file mode 100644 index 43a5254..0000000 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer.fs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls - -type IFabPinchGestureRecognizer = - inherit IFabGestureRecognizer - -module PinchGestureRecognizer = - let WidgetKey = Widgets.register() - - let PinchUpdatedMsg = - Attributes.defineEvent "PinchGestureRecognizer_PinchUpdatedMsg" (fun target -> - (target :?> PinchGestureRecognizer).PinchUpdated) - - let PinchUpdatedFn = - Attributes.defineEventNoDispatch "PinchGestureRecognizer_PinchUpdatedFn" (fun target -> - (target :?> PinchGestureRecognizer).PinchUpdated) - -[] -module PinchGestureRecognizerBuilders = - type Fabulous.Maui.View with - - /// Create a PinchGestureRecognizer that listens for Pinch event - /// Message to dispatch - static member inline PinchGestureRecognizer<'msg when 'msg: equality>(onPinchUpdated: PinchGestureUpdatedEventArgs -> 'msg) = - WidgetBuilder<'msg, IFabPinchGestureRecognizer>( - PinchGestureRecognizer.WidgetKey, - PinchGestureRecognizer.PinchUpdatedMsg.WithValue(fun args -> onPinchUpdated args |> box) - ) - - /// Create a PinchGestureRecognizer that listens for Pinch event - /// Message to dispatch - static member inline PinchGestureRecognizer(onPinchUpdated: PinchGestureUpdatedEventArgs -> unit) = - WidgetBuilder<'msg, IFabPinchGestureRecognizer>(PinchGestureRecognizer.WidgetKey, PinchGestureRecognizer.PinchUpdatedFn.WithValue(onPinchUpdated)) - -[] -type PinchGestureRecognizerModifiers = - /// Link a ViewRef to access the direct PinchGestureRecognizer control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabPinchGestureRecognizer>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs new file mode 100644 index 0000000..b5a4aa2 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module PinchGestureRecognizerComponent = + let PinchUpdated = + Attributes.Component.defineEvent "PinchGestureRecognizerComponent_PinchUpdated" (fun target -> + (target :?> PinchGestureRecognizer).PinchUpdated) + +[] +module PinchGestureRecognizerComponentBuilders = + type Fabulous.Maui.View with + /// Create a PinchGestureRecognizer that listens for Pinch event + /// Message to dispatch + static member inline PinchGestureRecognizer(onPinchUpdated: PinchGestureUpdatedEventArgs -> unit) = + WidgetBuilder(PinchGestureRecognizer.WidgetKey, PinchGestureRecognizerComponent.PinchUpdated.WithValue(onPinchUpdated)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs new file mode 100644 index 0000000..5241266 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs @@ -0,0 +1,21 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module PinchGestureRecognizerMvu = + let PinchUpdated = + Attributes.Mvu.defineEvent "PinchGestureRecognizerMvu_PinchUpdated" (fun target -> + (target :?> PinchGestureRecognizer).PinchUpdated) + +[] +module PinchGestureRecognizerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a PinchGestureRecognizer that listens for Pinch event + /// Message to dispatch + static member inline PinchGestureRecognizer<'msg when 'msg: equality>(onPinchUpdated: PinchGestureUpdatedEventArgs -> 'msg) = + WidgetBuilder<'msg, IFabPinchGestureRecognizer>( + PinchGestureRecognizer.WidgetKey, + PinchGestureRecognizerMvu.PinchUpdated.WithValue(fun args -> onPinchUpdated args |> box) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.fs new file mode 100644 index 0000000..20c4e38 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.fs @@ -0,0 +1,20 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +type IFabPinchGestureRecognizer = + inherit IFabGestureRecognizer + +module PinchGestureRecognizer = + let WidgetKey = Widgets.register() + +[] +type PinchGestureRecognizerModifiers = + /// Link a ViewRef to access the direct PinchGestureRecognizer control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabPinchGestureRecognizer>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs new file mode 100644 index 0000000..6586e98 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs @@ -0,0 +1,21 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui +open Microsoft.Maui.Controls + +module SwipeGestureRecognizerComponent = + let Swiped = + Attributes.Component.defineEvent "SwipeGestureRecognizerComponent_Swiped" (fun target -> (target :?> SwipeGestureRecognizer).Swiped) + +[] +module SwipeGestureRecognizerComponentBuilders = + type Fabulous.Maui.View with + + /// Create a SwipeGestureRecognizer that listens for Swipe event + /// Message to dispatch + static member inline SwipeGestureRecognizer(onSwiped: SwipeDirection -> unit) = + WidgetBuilder( + SwipeGestureRecognizer.WidgetKey, + SwipeGestureRecognizerComponent.Swiped.WithValue(fun args -> onSwiped args.Direction) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs new file mode 100644 index 0000000..b0ca1b6 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs @@ -0,0 +1,21 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui +open Microsoft.Maui.Controls + +module SwipeGestureRecognizerMvu = + let Swiped = + Attributes.Mvu.defineEvent "SwipeGestureRecognizerMvu_Swiped" (fun target -> (target :?> SwipeGestureRecognizer).Swiped) + +[] +module SwipeGestureRecognizerMvuBuilders = + type Fabulous.Maui.View with + + /// Create a SwipeGestureRecognizer that listens for Swipe event + /// Message to dispatch + static member inline SwipeGestureRecognizer<'msg when 'msg: equality>(onSwiped: SwipeDirection -> 'msg) = + WidgetBuilder<'msg, IFabSwipeGestureRecognizer>( + SwipeGestureRecognizer.WidgetKey, + SwipeGestureRecognizerMvu.Swiped.WithValue(fun args -> onSwiped args.Direction |> box) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.fs similarity index 57% rename from src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer.fs rename to src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.fs index 991d755..c363bb8 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.fs @@ -14,35 +14,9 @@ module SwipeGestureRecognizer = let Direction = Attributes.defineBindableEnum SwipeGestureRecognizer.DirectionProperty - let SwipedMsg = - Attributes.defineEvent "SwipeGestureRecognizer_SwipedMsg" (fun target -> (target :?> SwipeGestureRecognizer).Swiped) - - let SwipedFn = - Attributes.defineEventNoDispatch "SwipeGestureRecognizer_SwipedFn" (fun target -> (target :?> SwipeGestureRecognizer).Swiped) - let Threshold = Attributes.defineBindableInt SwipeGestureRecognizer.ThresholdProperty -[] -module SwipeGestureRecognizerBuilders = - type Fabulous.Maui.View with - - /// Create a SwipeGestureRecognizer that listens for Swipe event - /// Message to dispatch - static member inline SwipeGestureRecognizer<'msg when 'msg: equality>(onSwiped: SwipeDirection -> 'msg) = - WidgetBuilder<'msg, IFabSwipeGestureRecognizer>( - SwipeGestureRecognizer.WidgetKey, - SwipeGestureRecognizer.SwipedMsg.WithValue(fun args -> onSwiped args.Direction |> box) - ) - - /// Create a SwipeGestureRecognizer that listens for Swipe event - /// Message to dispatch - static member inline SwipeGestureRecognizer(onSwiped: SwipeDirection -> unit) = - WidgetBuilder<'msg, IFabSwipeGestureRecognizer>( - SwipeGestureRecognizer.WidgetKey, - SwipeGestureRecognizer.SwipedFn.WithValue(fun args -> onSwiped args.Direction) - ) - [] type SwipeGestureRecognizerModifiers = /// Set the direction of swipes to recognize. diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Component.fs new file mode 100644 index 0000000..4e0d52e --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Component.fs @@ -0,0 +1,16 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module TapGestureRecognizerComponent = + let Tapped = + Attributes.Component.defineEvent "TapGestureRecognizerComponent_Tapped" (fun target -> (target :?> TapGestureRecognizer).Tapped) + +[] +module TapGestureRecognizerComponentBuilders = + type Fabulous.Maui.View with + /// Create a TapGestureRecognizer that listens for Tapped event + /// Message to dispatch + static member inline TapGestureRecognizer(onTapped: unit -> unit) = + WidgetBuilder(TapGestureRecognizer.WidgetKey, TapGestureRecognizerComponent.Tapped.WithValue(fun _ -> onTapped())) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Mvu.fs new file mode 100644 index 0000000..9fd34e7 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.Mvu.fs @@ -0,0 +1,16 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module TapGestureRecognizerMvu = + let Tapped = + Attributes.Mvu.defineEvent "TapGestureRecognizerMvu_Tapped" (fun target -> (target :?> TapGestureRecognizer).Tapped) + +[] +module TapGestureRecognizerBuilders = + type Fabulous.Maui.View with + /// Create a TapGestureRecognizer that listens for Tapped event + /// Message to dispatch + static member inline TapGestureRecognizer<'msg when 'msg: equality>(onTapped: 'msg) = + WidgetBuilder<'msg, IFabTapGestureRecognizer>(TapGestureRecognizer.WidgetKey, TapGestureRecognizerMvu.Tapped.WithValue(fun _ -> box onTapped)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.fs similarity index 53% rename from src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer.fs rename to src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.fs index d21ec53..5f419c5 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/TapGestureRecognizer/TapGestureRecognizer.fs @@ -13,26 +13,6 @@ module TapGestureRecognizer = let NumberOfTapsRequired = Attributes.defineBindableInt TapGestureRecognizer.NumberOfTapsRequiredProperty - let TappedMsg = - Attributes.defineEvent "TapGestureRecognizer_TappedMsg" (fun target -> (target :?> TapGestureRecognizer).Tapped) - - let TappedFn = - Attributes.defineEventNoDispatch "TapGestureRecognizer_TappedFn" (fun target -> (target :?> TapGestureRecognizer).Tapped) - -[] -module TapGestureRecognizerBuilders = - type Fabulous.Maui.View with - - /// Create a TapGestureRecognizer that listens for Tapped event - /// Message to dispatch - static member inline TapGestureRecognizer<'msg when 'msg: equality>(onTapped: 'msg) = - WidgetBuilder<'msg, IFabTapGestureRecognizer>(TapGestureRecognizer.WidgetKey, TapGestureRecognizer.TappedMsg.WithValue(fun _ -> box onTapped)) - - /// Create a TapGestureRecognizer that listens for Tapped event - /// Message to dispatch - static member inline TapGestureRecognizer(onTapped: unit -> unit) = - WidgetBuilder<'msg, IFabTapGestureRecognizer>(TapGestureRecognizer.WidgetKey, TapGestureRecognizer.TappedFn.WithValue(fun _ -> onTapped())) - [] type TapGestureRecognizerModifiers = /// Set the number of taps required to trigger the gesture diff --git a/src/Fabulous.MauiControls/Views/Layouts/FlexLayout.fs b/src/Fabulous.MauiControls/Views/Layouts/FlexLayout.fs index 4788b41..0bb72d7 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/FlexLayout.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/FlexLayout.fs @@ -1,10 +1,8 @@ namespace Fabulous.Maui -open System open System.Runtime.CompilerServices open Fabulous open Fabulous.Maui -open Microsoft.Maui open Microsoft.Maui.Controls open Microsoft.Maui.Layouts diff --git a/src/Fabulous.MauiControls/Views/Layouts/RefreshView.fs b/src/Fabulous.MauiControls/Views/Layouts/RefreshView.fs deleted file mode 100644 index 57d1cd8..0000000 --- a/src/Fabulous.MauiControls/Views/Layouts/RefreshView.fs +++ /dev/null @@ -1,71 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Fabulous.StackAllocatedCollections.StackList -open Microsoft.Maui.Controls -open Microsoft.Maui.Graphics - -type IFabRefreshView = - inherit IFabContentView - -module RefreshView = - let WidgetKey = Widgets.register() - - let IsRefreshing = Attributes.defineBindableBool RefreshView.IsRefreshingProperty - - let RefreshColor = Attributes.defineBindableColor RefreshView.RefreshColorProperty - - let RefreshingMsg = - Attributes.defineEventNoArg "RefreshView_RefreshingMsg" (fun target -> (target :?> RefreshView).Refreshing) - - let RefreshingFn = - Attributes.defineEventNoArgNoDispatch "RefreshView_RefreshingFn" (fun target -> (target :?> RefreshView).Refreshing) - -[] -module RefreshViewBuilders = - type Fabulous.Maui.View with - - /// Create a RefreshView widget with content - /// The refresh state - /// Message to dispatch when refresh state changes - /// The content widget - static member inline RefreshView(isRefreshing: bool, onRefreshing: 'msg, content: WidgetBuilder<'msg, #IFabView>) = - WidgetBuilder<'msg, IFabRefreshView>( - RefreshView.WidgetKey, - AttributesBundle( - StackList.two(RefreshView.IsRefreshing.WithValue(isRefreshing), RefreshView.RefreshingMsg.WithValue(MsgValue(onRefreshing))), - ValueSome [| ContentView.Content.WithValue(content.Compile()) |], - ValueNone - ) - ) - - /// Create a RefreshView widget with content - /// The refresh state - /// Message to dispatch when refresh state changes - /// The content widget - static member inline RefreshView(isRefreshing: bool, onRefreshing: unit -> unit, content: WidgetBuilder<'msg, #IFabView>) = - WidgetBuilder<'msg, IFabRefreshView>( - RefreshView.WidgetKey, - AttributesBundle( - StackList.two(RefreshView.IsRefreshing.WithValue(isRefreshing), RefreshView.RefreshingFn.WithValue(onRefreshing)), - ValueSome [| ContentView.Content.WithValue(content.Compile()) |], - ValueNone - ) - ) - -[] -type RefreshViewModifiers = - /// Set the color of the refresh indicator - /// Current widget - /// The color of the refresh indicator - [] - static member inline refreshColor(this: WidgetBuilder<'msg, #IFabRefreshView>, value: Color) = - this.AddScalar(RefreshView.RefreshColor.WithValue(value)) - - /// Link a ViewRef to access the direct RefreshView control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabRefreshView>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs new file mode 100644 index 0000000..66e7179 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs @@ -0,0 +1,27 @@ +namespace Fabulous.Maui + +open Fabulous +open Fabulous.StackAllocatedCollections.StackList +open Microsoft.Maui.Controls + +module RefreshViewComponent = + let Refreshing = + Attributes.Component.defineEventNoArg "RefreshViewComponent_Refreshing" (fun target -> (target :?> RefreshView).Refreshing) + +[] +module RefreshViewComponentBuilders = + type Fabulous.Maui.View with + + /// Create a RefreshView widget with content + /// The refresh state + /// Message to dispatch when refresh state changes + /// The content widget + static member inline RefreshView(isRefreshing: bool, onRefreshing: unit -> unit, content: WidgetBuilder) = + WidgetBuilder( + RefreshView.WidgetKey, + AttributesBundle( + StackList.two(RefreshView.IsRefreshing.WithValue(isRefreshing), RefreshViewComponent.Refreshing.WithValue(onRefreshing)), + ValueSome [| ContentView.Content.WithValue(content.Compile()) |], + ValueNone + ) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs new file mode 100644 index 0000000..f8d427c --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs @@ -0,0 +1,27 @@ +namespace Fabulous.Maui + +open Fabulous +open Fabulous.StackAllocatedCollections.StackList +open Microsoft.Maui.Controls + +module RefreshViewMvu = + let Refreshing = + Attributes.Mvu.defineEventNoArg "RefreshViewMvu_Refreshing" (fun target -> (target :?> RefreshView).Refreshing) + +[] +module RefreshViewMvuBuilders = + type Fabulous.Maui.View with + + /// Create a RefreshView widget with content + /// The refresh state + /// Message to dispatch when refresh state changes + /// The content widget + static member inline RefreshView(isRefreshing: bool, onRefreshing: 'msg, content: WidgetBuilder<'msg, #IFabView>) = + WidgetBuilder<'msg, IFabRefreshView>( + RefreshView.WidgetKey, + AttributesBundle( + StackList.two(RefreshView.IsRefreshing.WithValue(isRefreshing), RefreshViewMvu.Refreshing.WithValue(MsgValue(onRefreshing))), + ValueSome [| ContentView.Content.WithValue(content.Compile()) |], + ValueNone + ) + ) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.fs b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.fs new file mode 100644 index 0000000..1535e49 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.fs @@ -0,0 +1,32 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls +open Microsoft.Maui.Graphics + +type IFabRefreshView = + inherit IFabContentView + +module RefreshView = + let WidgetKey = Widgets.register() + + let IsRefreshing = Attributes.defineBindableBool RefreshView.IsRefreshingProperty + + let RefreshColor = Attributes.defineBindableColor RefreshView.RefreshColorProperty + +[] +type RefreshViewModifiers = + /// Set the color of the refresh indicator + /// Current widget + /// The color of the refresh indicator + [] + static member inline refreshColor(this: WidgetBuilder<'msg, #IFabRefreshView>, value: Color) = + this.AddScalar(RefreshView.RefreshColor.WithValue(value)) + + /// Link a ViewRef to access the direct RefreshView control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabRefreshView>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Component.fs b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Component.fs new file mode 100644 index 0000000..6d90265 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Component.fs @@ -0,0 +1,18 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ScrollViewComponent = + let Scrolled = + Attributes.Component.defineEvent "ScrollViewComponent_Scrolled" (fun target -> (target :?> ScrollView).Scrolled) + +[] +type ScrollViewComponentModifiers = + /// Listen for the Scrolled event + /// Current widget + /// Message to dispatch + [] + static member inline onScrolled(this: WidgetBuilder<'msg, #IFabScrollView>, fn: ScrolledEventArgs -> unit) = + this.AddScalar(ScrollViewComponent.Scrolled.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs new file mode 100644 index 0000000..c2dd244 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs @@ -0,0 +1,18 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module ScrollViewMvu = + let Scrolled = + Attributes.Mvu.defineEvent "ScrollViewMvu_Scrolled" (fun target -> (target :?> ScrollView).Scrolled) + +[] +type ScrollViewMvuModifiers = + /// Listen for the Scrolled event + /// Current widget + /// Message to dispatch + [] + static member inline onScrolled(this: WidgetBuilder<'msg, #IFabScrollView>, fn: ScrolledEventArgs -> 'msg) = + this.AddScalar(ScrollViewMvu.Scrolled.WithValue(fun args -> fn args |> box)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Layouts/ScrollView.fs b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.fs similarity index 83% rename from src/Fabulous.MauiControls/Views/Layouts/ScrollView.fs rename to src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.fs index 1b1f44d..cb2a8c7 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/ScrollView.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.fs @@ -26,12 +26,6 @@ module ScrollView = let Orientation = Attributes.defineBindableEnum ScrollView.OrientationProperty - let ScrolledMsg = - Attributes.defineEvent "ScrollView_ScrolledMsg" (fun target -> (target :?> ScrollView).Scrolled) - - let ScrolledFn = - Attributes.defineEventNoDispatch "ScrollView_ScrolledFn" (fun target -> (target :?> ScrollView).Scrolled) - let ScrollPosition = Attributes.defineSimpleScalarWithEquality "ScrollView_ScrollPosition" (fun _ newValueOpt node -> let view = node.Target :?> ScrollView @@ -96,20 +90,6 @@ type ScrollViewModifiers = static member inline verticalScrollBarVisibility(this: WidgetBuilder<'msg, #IFabScrollView>, value: ScrollBarVisibility) = this.AddScalar(ScrollView.VerticalScrollBarVisibility.WithValue(value)) - /// Listen for the Scrolled event - /// Current widget - /// Message to dispatch - [] - static member inline onScrolled(this: WidgetBuilder<'msg, #IFabScrollView>, fn: ScrolledEventArgs -> 'msg) = - this.AddScalar(ScrollView.ScrolledMsg.WithValue(fun args -> fn args |> box)) - - /// Listen for the Scrolled event - /// Current widget - /// Message to dispatch - [] - static member inline onScrolled(this: WidgetBuilder<'msg, #IFabScrollView>, fn: ScrolledEventArgs -> unit) = - this.AddScalar(ScrollView.ScrolledFn.WithValue(fn)) - /// Link a ViewRef to access the direct ScrollView control instance /// Current widget /// The ViewRef instance that will receive access to the underlying control diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs new file mode 100644 index 0000000..49ed322 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs @@ -0,0 +1,16 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SwipeItemComponent = + let Invoked = + Attributes.Component.defineEvent "SwipeItemComponent_Invoked" (fun target -> (target :?> SwipeItem).Invoked) + +[] +module SwipeItemComponentBuilders = + type Fabulous.Maui.View with + /// Create a SwipeItem widget and listen for the Invoke event + /// Message to dispatch + static member inline SwipeItem(onInvoked: unit -> unit) = + WidgetBuilder(SwipeItem.WidgetKey, SwipeItemComponent.Invoked.WithValue(fun _ -> onInvoked())) diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Mvu.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Mvu.fs new file mode 100644 index 0000000..0dc8541 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Mvu.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module SwipeItemMvu = + let Invoked = + Attributes.Mvu.defineEvent "SwipeItemMvu_Invoked" (fun target -> (target :?> SwipeItem).Invoked) + +[] +module SwipeItemMvuBuilders = + type Fabulous.Maui.View with + + /// Create a SwipeItem widget and listen for the Invoke event + /// Message to dispatch + static member inline SwipeItem(onInvoked: 'msg) = + WidgetBuilder<'msg, IFabSwipeItem>(SwipeItem.WidgetKey, SwipeItemMvu.Invoked.WithValue(fun _ -> box onInvoked)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeItem.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.fs similarity index 62% rename from src/Fabulous.MauiControls/Views/Layouts/SwipeItem.fs rename to src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.fs index ea5f67e..779c4e4 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/SwipeItem.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.fs @@ -14,28 +14,8 @@ module SwipeItem = let BackgroundColor = Attributes.defineBindableColor SwipeItem.BackgroundColorProperty - let InvokedMsg = - Attributes.defineEvent "SwipeItem_InvokedMsg" (fun target -> (target :?> SwipeItem).Invoked) - - let InvokedFn = - Attributes.defineEvent "SwipeItem_InvokedFn" (fun target -> (target :?> SwipeItem).Invoked) - let IsVisible = Attributes.defineBindableBool SwipeItem.IsVisibleProperty -[] -module SwipeItemBuilders = - type Fabulous.Maui.View with - - /// Create a SwipeItem widget and listen for the Invoke event - /// Message to dispatch - static member inline SwipeItem(onInvoked: 'msg) = - WidgetBuilder<'msg, IFabSwipeItem>(SwipeItem.WidgetKey, SwipeItem.InvokedMsg.WithValue(fun _ -> box onInvoked)) - - /// Create a SwipeItem widget and listen for the Invoke event - /// Message to dispatch - static member inline SwipeItem(onInvoked: unit -> unit) = - WidgetBuilder<'msg, IFabSwipeItem>(SwipeItem.WidgetKey, SwipeItem.InvokedFn.WithValue(fun _ -> onInvoked())) - [] type SwipeItemModifiers() = /// Set the background color of the SwipeItem diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeView.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeView.fs deleted file mode 100644 index abe859a..0000000 --- a/src/Fabulous.MauiControls/Views/Layouts/SwipeView.fs +++ /dev/null @@ -1,174 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Fabulous -open Microsoft.Maui.Controls - -type IFabSwipeView = - inherit IFabContentView - -module SwipeView = - let WidgetKey = Widgets.register() - - let BottomSwipeItems = Attributes.defineBindableWidget SwipeView.BottomItemsProperty - - let CloseRequestedMsg = - Attributes.defineEvent "SwipeView_CloseRequestedMsg" (fun target -> (target :?> SwipeView).CloseRequested) - - let CloseRequestedFn = - Attributes.defineEventNoDispatch "SwipeView_CloseRequestedFn" (fun target -> (target :?> SwipeView).CloseRequested) - - let LeftSwipeItems = Attributes.defineBindableWidget SwipeView.LeftItemsProperty - - let OpenRequestedMsg = - Attributes.defineEvent "SwipeView_OpenRequestedMsg" (fun target -> (target :?> SwipeView).OpenRequested) - - let OpenRequestedFn = - Attributes.defineEventNoDispatch "SwipeView_OpenRequestedFn" (fun target -> (target :?> SwipeView).OpenRequested) - - let RightSwipeItems = Attributes.defineBindableWidget SwipeView.RightItemsProperty - - let SwipeChangingMsg = - Attributes.defineEvent "SwipeView_SwipeChangingMsg" (fun target -> (target :?> SwipeView).SwipeChanging) - - let SwipeChangingFn = - Attributes.defineEventNoDispatch "SwipeView_SwipeChangingFn" (fun target -> (target :?> SwipeView).SwipeChanging) - - let SwipeEndedMsg = - Attributes.defineEvent "SwipeView_SwipeEndedMsg" (fun target -> (target :?> SwipeView).SwipeEnded) - - let SwipeEndedFn = - Attributes.defineEventNoDispatch "SwipeView_SwipeEndedFn" (fun target -> (target :?> SwipeView).SwipeEnded) - - let SwipeStartedMsg = - Attributes.defineEvent "SwipeView_SwipeStartedMsg" (fun target -> (target :?> SwipeView).SwipeStarted) - - let SwipeStartedFn = - Attributes.defineEventNoDispatch "SwipeView_SwipeStartedFn" (fun target -> (target :?> SwipeView).SwipeStarted) - - let SwipeThreshold = Attributes.defineBindableInt SwipeView.ThresholdProperty - - let TopSwipeItems = Attributes.defineBindableWidget SwipeView.TopItemsProperty - -[] -module SwipeViewBuilders = - type Fabulous.Maui.View with - - /// Create a SwipeView widget with a content - /// The content widget - static member inline SwipeView(content: WidgetBuilder<'msg, #IFabView>) = - WidgetHelpers.buildWidgets<'msg, IFabSwipeView> SwipeView.WidgetKey [| ContentView.Content.WithValue(content.Compile()) |] - -[] -type SwipeViewModifiers() = - /// Set the bottom swipe items - /// Current widget - /// The SwipeItems widget - [] - static member inline bottomItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = - this.AddWidget(SwipeView.BottomSwipeItems.WithValue(content.Compile())) - - /// Set the left swipe items - /// Current widget - /// The SwipeItems widget - [] - static member inline leftItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = - this.AddWidget(SwipeView.LeftSwipeItems.WithValue(content.Compile())) - - /// Set the right swipe items - /// Current widget - /// The SwipeItems widget - [] - static member inline rightItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = - this.AddWidget(SwipeView.RightSwipeItems.WithValue(content.Compile())) - - /// Set the swipe threshold - /// Current widget - /// The threshold value - [] - static member inline threshold(this: WidgetBuilder<'msg, #IFabSwipeView>, value: int) = - this.AddScalar(SwipeView.SwipeThreshold.WithValue(value)) - - /// Listen to the SwipeStarted event - /// Current widget - /// Message to dispatch - [] - static member inline onSwipeStarted(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeStartedEventArgs -> 'msg) = - this.AddScalar(SwipeView.SwipeStartedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen to the SwipeStarted event - /// Current widget - /// Message to dispatch - [] - static member inline onSwipeStarted(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeStartedEventArgs -> unit) = - this.AddScalar(SwipeView.SwipeStartedFn.WithValue(fn)) - - /// Listen to the SwipeChanging event - /// Current widget - /// Message to dispatch - [] - static member inline onSwipeChanging(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeChangingEventArgs -> 'msg) = - this.AddScalar(SwipeView.SwipeChangingMsg.WithValue(fun args -> fn args |> box)) - - /// Listen to the SwipeChanging event - /// Current widget - /// Message to dispatch - [] - static member inline onSwipeChanging(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeChangingEventArgs -> unit) = - this.AddScalar(SwipeView.SwipeChangingFn.WithValue(fn)) - - /// Listen to the SwipeEnded event - /// Current widget - /// Message to dispatch - [] - static member inline onSwipeEnded(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeEndedEventArgs -> 'msg) = - this.AddScalar(SwipeView.SwipeEndedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen to the SwipeEnded event - /// Current widget - /// Message to dispatch - [] - static member inline onSwipeEnded(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeEndedEventArgs -> unit) = - this.AddScalar(SwipeView.SwipeEndedFn.WithValue(fn)) - - /// Listen to the OpenRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onOpenRequested(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: OpenRequestedEventArgs -> 'msg) = - this.AddScalar(SwipeView.OpenRequestedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen to the OpenRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onOpenRequested(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: OpenRequestedEventArgs -> unit) = - this.AddScalar(SwipeView.OpenRequestedFn.WithValue(fn)) - - /// Listen to the CloseRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onCloseRequested(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: CloseRequestedEventArgs -> 'msg) = - this.AddScalar(SwipeView.CloseRequestedMsg.WithValue(fun args -> fn args |> box)) - - /// Listen to the CloseRequested event - /// Current widget - /// Message to dispatch - [] - static member inline onCloseRequested(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: CloseRequestedEventArgs -> unit) = - this.AddScalar(SwipeView.CloseRequestedFn.WithValue(fn)) - - /// Set the top swipe items - /// Current widget - /// The SwipeItems widget - [] - static member inline topItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = - this.AddWidget(SwipeView.TopSwipeItems.WithValue(content.Compile())) - - /// Link a ViewRef to access the direct SwipeView control instance - /// Current widget - /// The ViewRef instance that will receive access to the underlying control - [] - static member inline reference(this: WidgetBuilder<'msg, IFabSwipeView>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Component.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Component.fs new file mode 100644 index 0000000..02ad9df --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Component.fs @@ -0,0 +1,58 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module SwipeViewComponent = + let CloseRequested = + Attributes.Component.defineEvent "SwipeViewComponent_CloseRequested" (fun target -> (target :?> SwipeView).CloseRequested) + + let OpenRequested = + Attributes.Component.defineEvent "SwipeViewComponent_OpenRequested" (fun target -> (target :?> SwipeView).OpenRequested) + + let SwipeChanging = + Attributes.Component.defineEvent "SwipeViewComponent_SwipeChanging" (fun target -> (target :?> SwipeView).SwipeChanging) + + let SwipeEnded = + Attributes.Component.defineEvent "SwipeViewComponent_SwipeEnded" (fun target -> (target :?> SwipeView).SwipeEnded) + + let SwipeStarted = + Attributes.Component.defineEvent "SwipeViewComponent_SwipeStarted" (fun target -> (target :?> SwipeView).SwipeStarted) + +[] +type SwipeViewComponentModifiers() = + /// Listen to the SwipeStarted event + /// Current widget + /// Message to dispatch + [] + static member inline onSwipeStarted(this: WidgetBuilder, fn: SwipeStartedEventArgs -> unit) = + this.AddScalar(SwipeViewComponent.SwipeStarted.WithValue(fn)) + + /// Listen to the SwipeChanging event + /// Current widget + /// Message to dispatch + [] + static member inline onSwipeChanging(this: WidgetBuilder, fn: SwipeChangingEventArgs -> unit) = + this.AddScalar(SwipeViewComponent.SwipeChanging.WithValue(fn)) + + /// Listen to the SwipeEnded event + /// Current widget + /// Message to dispatch + [] + static member inline onSwipeEnded(this: WidgetBuilder, fn: SwipeEndedEventArgs -> unit) = + this.AddScalar(SwipeViewComponent.SwipeEnded.WithValue(fn)) + + /// Listen to the OpenRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onOpenRequested(this: WidgetBuilder, fn: OpenRequestedEventArgs -> unit) = + this.AddScalar(SwipeViewComponent.OpenRequested.WithValue(fn)) + + /// Listen to the CloseRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onCloseRequested(this: WidgetBuilder, fn: CloseRequestedEventArgs -> unit) = + this.AddScalar(SwipeViewComponent.CloseRequested.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Mvu.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Mvu.fs new file mode 100644 index 0000000..0be158a --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.Mvu.fs @@ -0,0 +1,58 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module SwipeViewMvu = + let CloseRequested = + Attributes.Mvu.defineEvent "SwipeViewMvu_CloseRequested" (fun target -> (target :?> SwipeView).CloseRequested) + + let OpenRequested = + Attributes.Mvu.defineEvent "SwipeViewMvu_OpenRequested" (fun target -> (target :?> SwipeView).OpenRequested) + + let SwipeChanging = + Attributes.Mvu.defineEvent "SwipeViewMvu_SwipeChanging" (fun target -> (target :?> SwipeView).SwipeChanging) + + let SwipeEnded = + Attributes.Mvu.defineEvent "SwipeViewMvu_SwipeEnded" (fun target -> (target :?> SwipeView).SwipeEnded) + + let SwipeStarted = + Attributes.Mvu.defineEvent "SwipeViewMvu_SwipeStarted" (fun target -> (target :?> SwipeView).SwipeStarted) + +[] +type SwipeViewMvuModifiers() = + /// Listen to the SwipeStarted event + /// Current widget + /// Message to dispatch + [] + static member inline onSwipeStarted(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeStartedEventArgs -> 'msg) = + this.AddScalar(SwipeViewMvu.SwipeStarted.WithValue(fun args -> fn args |> box)) + + /// Listen to the SwipeChanging event + /// Current widget + /// Message to dispatch + [] + static member inline onSwipeChanging(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeChangingEventArgs -> 'msg) = + this.AddScalar(SwipeViewMvu.SwipeChanging.WithValue(fun args -> fn args |> box)) + + /// Listen to the SwipeEnded event + /// Current widget + /// Message to dispatch + [] + static member inline onSwipeEnded(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: SwipeEndedEventArgs -> 'msg) = + this.AddScalar(SwipeViewMvu.SwipeEnded.WithValue(fun args -> fn args |> box)) + + /// Listen to the OpenRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onOpenRequested(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: OpenRequestedEventArgs -> 'msg) = + this.AddScalar(SwipeViewMvu.OpenRequested.WithValue(fun args -> fn args |> box)) + + /// Listen to the CloseRequested event + /// Current widget + /// Message to dispatch + [] + static member inline onCloseRequested(this: WidgetBuilder<'msg, #IFabSwipeView>, fn: CloseRequestedEventArgs -> 'msg) = + this.AddScalar(SwipeViewMvu.CloseRequested.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs new file mode 100644 index 0000000..401a4f8 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs @@ -0,0 +1,74 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +type IFabSwipeView = + inherit IFabContentView + +module SwipeView = + let WidgetKey = Widgets.register() + + let BottomSwipeItems = Attributes.defineBindableWidget SwipeView.BottomItemsProperty + + let LeftSwipeItems = Attributes.defineBindableWidget SwipeView.LeftItemsProperty + + let RightSwipeItems = Attributes.defineBindableWidget SwipeView.RightItemsProperty + + let SwipeThreshold = Attributes.defineBindableInt SwipeView.ThresholdProperty + + let TopSwipeItems = Attributes.defineBindableWidget SwipeView.TopItemsProperty + +[] +module SwipeViewBuilders = + type Fabulous.Maui.View with + + /// Create a SwipeView widget with a content + /// The content widget + static member inline SwipeView(content: WidgetBuilder<'msg, #IFabView>) = + WidgetHelpers.buildWidgets<'msg, IFabSwipeView> SwipeView.WidgetKey [| ContentView.Content.WithValue(content.Compile()) |] + +[] +type SwipeViewModifiers() = + /// Set the bottom swipe items + /// Current widget + /// The SwipeItems widget + [] + static member inline bottomItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = + this.AddWidget(SwipeView.BottomSwipeItems.WithValue(content.Compile())) + + /// Set the left swipe items + /// Current widget + /// The SwipeItems widget + [] + static member inline leftItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = + this.AddWidget(SwipeView.LeftSwipeItems.WithValue(content.Compile())) + + /// Set the right swipe items + /// Current widget + /// The SwipeItems widget + [] + static member inline rightItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = + this.AddWidget(SwipeView.RightSwipeItems.WithValue(content.Compile())) + + /// Set the swipe threshold + /// Current widget + /// The threshold value + [] + static member inline threshold(this: WidgetBuilder<'msg, #IFabSwipeView>, value: int) = + this.AddScalar(SwipeView.SwipeThreshold.WithValue(value)) + + /// Set the top swipe items + /// Current widget + /// The SwipeItems widget + [] + static member inline topItems(this: WidgetBuilder<'msg, #IFabSwipeView>, content: WidgetBuilder<'msg, #IFabSwipeItems>) = + this.AddWidget(SwipeView.TopSwipeItems.WithValue(content.Compile())) + + /// Link a ViewRef to access the direct SwipeView control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabSwipeView>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Component.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Component.fs new file mode 100644 index 0000000..070e86a --- /dev/null +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Component.fs @@ -0,0 +1,12 @@ +namespace Fabulous.Maui + +open Fabulous + +[] +module MenuFlyoutItemComponentBuilders = + type Fabulous.Maui.View with + /// Create a MenuItem widget with a text and a Click callback + /// The text + /// The click callback + static member inline MenuFlyoutItem(text: string, onClicked: unit -> unit) = + WidgetBuilder<'msg, IFabMenuFlyoutItem>(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItemComponent.Clicked.WithValue(onClicked)) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Mvu.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Mvu.fs new file mode 100644 index 0000000..2904d38 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.Mvu.fs @@ -0,0 +1,13 @@ +namespace Fabulous.Maui + +open Fabulous + +[] +module MenuFlyoutItemMvuBuilders = + type Fabulous.Maui.View with + + /// Create a MenuItem widget with a text and a Click callback + /// The text + /// The click callback + static member inline MenuFlyoutItem(text: string, onClicked: 'msg) = + WidgetBuilder<'msg, IFabMenuFlyoutItem>(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItemMvu.Clicked.WithValue(MsgValue(onClicked))) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.fs similarity index 62% rename from src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem.fs rename to src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.fs index e710556..f122927 100644 --- a/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem.fs +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.fs @@ -14,22 +14,6 @@ module MenuFlyoutItem = let KeyboardAccelerators = Attributes.defineListWidgetCollection "KeyboardAccelerators" (fun target -> (target :?> MenuFlyoutItem).KeyboardAccelerators) -[] -module MenuFlyoutItemBuilders = - type Fabulous.Maui.View with - - /// Create a MenuItem widget with a text and a Click callback - /// The text - /// The click callback - static member inline MenuFlyoutItem(text: string, onClicked: 'msg) = - WidgetBuilder<'msg, IFabMenuFlyoutItem>(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItem.ClickedMsg.WithValue(MsgValue(onClicked))) - - /// Create a MenuItem widget with a text and a Click callback - /// The text - /// The click callback - static member inline MenuFlyoutItem(text: string, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabMenuFlyoutItem>(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItem.ClickedFn.WithValue(onClicked)) - [] type MenuFlyoutItemModifiers = /// Set the keyboard accelerators of this widget diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Component.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Component.fs new file mode 100644 index 0000000..e078c05 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Component.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module MenuItemComponent = + let Clicked = + Attributes.Component.defineEventNoArg "MenuItemComponent_Clicked" (fun target -> (target :?> MenuItem).Clicked) + +[] +module MenuItemComponentBuilders = + type Fabulous.Maui.View with + /// Create a MenuItem widget with a text and a Click callback + /// The text + /// The click callback + static member inline MenuItem(text: string, onClicked: unit -> unit) = + WidgetBuilder(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItemComponent.Clicked.WithValue(onClicked)) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Mvu.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Mvu.fs new file mode 100644 index 0000000..1f91b8d --- /dev/null +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.Mvu.fs @@ -0,0 +1,18 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +module MenuItemMvu = + let Clicked = + Attributes.Mvu.defineEventNoArg "MenuItemMvu_Clicked" (fun target -> (target :?> MenuItem).Clicked) + +[] +module MenuItemMvuBuilders = + type Fabulous.Maui.View with + + /// Create a MenuItem widget with a text and a Click callback + /// The text + /// The click callback + static member inline MenuItem(text: string, onClicked: 'msg) = + WidgetBuilder<'msg, IFabMenuItem>(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItemMvu.Clicked.WithValue(MsgValue(onClicked))) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuItem.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.fs similarity index 67% rename from src/Fabulous.MauiControls/Views/MenuItems/MenuItem.fs rename to src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.fs index 9eda680..d30d729 100644 --- a/src/Fabulous.MauiControls/Views/MenuItems/MenuItem.fs +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.fs @@ -1,11 +1,10 @@ namespace Fabulous.Maui -#nowarn "0044" // Disable obsolete warnings in Fabulous.MauiControls. Please remove after deleting obsolete code. - open System open System.IO open System.Runtime.CompilerServices open Fabulous +open Fabulous.ScalarAttributeDefinitions open Microsoft.Maui.Controls type IFabMenuItem = @@ -13,35 +12,13 @@ type IFabMenuItem = module MenuItem = let WidgetKey = Widgets.register() - - let ClickedMsg = - Attributes.defineEventNoArg "MenuItem_ClickedMsg" (fun target -> (target :?> MenuItem).Clicked) - - let ClickedFn = - Attributes.defineEventNoArgNoDispatch "MenuItem_ClickedFn" (fun target -> (target :?> MenuItem).Clicked) - + let IconImageSource = Attributes.defineBindableImageSource MenuItem.IconImageSourceProperty let IsDestructive = Attributes.defineBindableBool MenuItem.IsDestructiveProperty - let Text = Attributes.defineBindableWithEquality MenuItem.TextProperty - -[] -module MenuItemBuilders = - type Fabulous.Maui.View with - - /// Create a MenuItem widget with a text and a Click callback - /// The text - /// The click callback - static member inline MenuItem(text: string, onClicked: 'msg) = - WidgetBuilder<'msg, IFabMenuItem>(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItem.ClickedMsg.WithValue(MsgValue(onClicked))) - - /// Create a MenuItem widget with a text and a Click callback - /// The text - /// The click callback - static member inline MenuItem(text: string, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabMenuItem>(MenuItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItem.ClickedFn.WithValue(onClicked)) + let Text: SimpleScalarAttributeDefinition = Attributes.defineBindableWithEquality MenuItem.TextProperty [] type MenuItemModifiers = diff --git a/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs new file mode 100644 index 0000000..f22283a --- /dev/null +++ b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs @@ -0,0 +1,13 @@ +namespace Fabulous.Maui + +open Fabulous + +[] +module ToolbarItemComponentBuilders = + type Fabulous.Maui.View with + + /// Create a ToolbarItem widget with a text and a Click callback + /// The text + /// The click callback + static member inline ToolbarItem(text: string, onClicked: unit -> unit) = + WidgetBuilder(ToolbarItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItemComponent.Clicked.WithValue(onClicked)) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Mvu.fs b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Mvu.fs new file mode 100644 index 0000000..9361186 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Mvu.fs @@ -0,0 +1,13 @@ +namespace Fabulous.Maui + +open Fabulous + +[] +module ToolbarItemMvuBuilders = + type Fabulous.Maui.View with + + /// Create a ToolbarItem widget with a text and a Click callback + /// The text + /// The click callback + static member inline ToolbarItem(text: string, onClicked: 'msg) = + WidgetBuilder<'msg, IFabToolbarItem>(ToolbarItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItemMvu.Clicked.WithValue(MsgValue(onClicked))) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem.fs b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.fs similarity index 69% rename from src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem.fs rename to src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.fs index 346ac8b..31d51e9 100644 --- a/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem.fs +++ b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.fs @@ -26,22 +26,6 @@ module ToolbarItem = | ValueNone -> toolbarItem.Priority <- 0 | ValueSome priority -> toolbarItem.Priority <- priority) -[] -module ToolbarItemBuilders = - type Fabulous.Maui.View with - - /// Create a ToolbarItem widget with a text and a Click callback - /// The text - /// The click callback - static member inline ToolbarItem(text: string, onClicked: 'msg) = - WidgetBuilder<'msg, IFabToolbarItem>(ToolbarItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItem.ClickedMsg.WithValue(MsgValue(onClicked))) - - /// Create a ToolbarItem widget with a text and a Click callback - /// The text - /// The click callback - static member inline ToolbarItem(text: string, onClicked: unit -> unit) = - WidgetBuilder<'msg, IFabToolbarItem>(ToolbarItem.WidgetKey, MenuItem.Text.WithValue(text), MenuItem.ClickedFn.WithValue(onClicked)) - [] type ToolbarItemModifiers = /// Set a value that indicates on which of the primary, secondary, or default toolbar surfaces to display diff --git a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Component.fs b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Component.fs new file mode 100644 index 0000000..5c91a81 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Component.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous + +module ContentPageComponent = + let SizeAllocated = + Attributes.Component.defineEvent "ContentPageComponent_SizeAllocated" (fun target -> (target :?> FabContentPage).SizeAllocated) + +[] +type ContentPageComponentModifiers = + /// Listen for SizeAllocated event + /// Current widget + /// Message to dispatch + [] + static member inline onSizeAllocated(this: WidgetBuilder, fn: SizeAllocatedEventArgs -> unit) = + this.AddScalar(ContentPageComponent.SizeAllocated.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs new file mode 100644 index 0000000..e116063 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous + +module ContentPageMvu = + let SizeAllocated = + Attributes.Mvu.defineEvent "ContentPageMvu_SizeAllocated" (fun target -> (target :?> FabContentPage).SizeAllocated) + +[] +type ContentPageMvuModifiers = + /// Listen for SizeAllocated event + /// Current widget + /// Message to dispatch + [] + static member inline onSizeAllocated(this: WidgetBuilder<'msg, #IFabContentPage>, fn: SizeAllocatedEventArgs -> 'msg) = + this.AddScalar(ContentPageMvu.SizeAllocated.WithValue(fn)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Pages/ContentPage.fs b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs similarity index 66% rename from src/Fabulous.MauiControls/Views/Pages/ContentPage.fs rename to src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs index 2c8f3f2..19457ba 100644 --- a/src/Fabulous.MauiControls/Views/Pages/ContentPage.fs +++ b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs @@ -29,13 +29,7 @@ module ContentPage = let WidgetKey = Widgets.register() let Content = Attributes.defineBindableWidget ContentPage.ContentProperty - - let SizeAllocatedMsg = - Attributes.defineEvent "ContentPage_SizeAllocatedMsg" (fun target -> (target :?> FabContentPage).SizeAllocated) - - let SizeAllocatedFn = - Attributes.defineEventNoDispatch "ContentPage_SizeAllocatedFn" (fun target -> (target :?> FabContentPage).SizeAllocated) - + [] module ContentPageBuilders = type Fabulous.Maui.View with @@ -53,20 +47,6 @@ module ContentPageBuilders = [] type ContentPageModifiers = - /// Listen for SizeAllocated event - /// Current widget - /// Message to dispatch - [] - static member inline onSizeAllocated(this: WidgetBuilder<'msg, #IFabContentPage>, fn: SizeAllocatedEventArgs -> 'msg) = - this.AddScalar(ContentPage.SizeAllocatedMsg.WithValue(fn)) - - /// Listen for SizeAllocated event - /// Current widget - /// Message to dispatch - [] - static member inline onSizeAllocated(this: WidgetBuilder<'msg, #IFabContentPage>, fn: SizeAllocatedEventArgs -> unit) = - this.AddScalar(ContentPage.SizeAllocatedFn.WithValue(fn)) - /// Link a ViewRef to access the direct ContentPage control instance /// Current widget /// The ViewRef instance that will receive access to the underlying control diff --git a/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Component.fs b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Component.fs new file mode 100644 index 0000000..512b910 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Component.fs @@ -0,0 +1,30 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module FlyoutPageComponent = + let BackButtonPressed = + Attributes.Component.defineEvent "FlyoutPageComponent_BackButtonPressed" (fun target -> (target :?> FlyoutPage).BackButtonPressed) + + let IsPresented = + Attributes.Component.defineBindableWithEvent "FlyoutPageComponent_IsPresentedChanged" FlyoutPage.IsPresentedProperty (fun target -> + (target :?> FabFlyoutPage).CustomIsPresentedChanged) + +[] +type FlyoutPageComponentModifiers = + /// Set whether the flyout is presented, and listen for presentation state changes + /// Current widget + /// The value indicating whether the flyout is presented + /// Message to dispatch + [] + static member inline isPresented(this: WidgetBuilder, value: bool, onChanged: bool -> unit) = + this.AddScalar(FlyoutPageComponent.IsPresented.WithValue(ValueEventData.create value onChanged)) + + /// Listen for back button pressed + /// Current widget + /// Message to dispatch + [] + static member inline onBackButtonPressed(this: WidgetBuilder, fn: bool -> unit) = + this.AddScalar(FlyoutPageComponent.BackButtonPressed.WithValue(fun args -> fn args.Handled)) diff --git a/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Mvu.fs b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Mvu.fs new file mode 100644 index 0000000..9096328 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.Mvu.fs @@ -0,0 +1,30 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module FlyoutPageMvu = + let BackButtonPressed = + Attributes.Mvu.defineEvent "FlyoutPageMvu_BackButtonPressed" (fun target -> (target :?> FlyoutPage).BackButtonPressed) + + let IsPresented = + Attributes.Mvu.defineBindableWithEvent "FlyoutPageMvu_IsPresentedChanged" FlyoutPage.IsPresentedProperty (fun target -> + (target :?> FabFlyoutPage).CustomIsPresentedChanged) + +[] +type FlyoutPageMvuModifiers = + /// Set whether the flyout is presented, and listen for presentation state changes + /// Current widget + /// The value indicating whether the flyout is presented + /// Message to dispatch + [] + static member inline isPresented(this: WidgetBuilder<'msg, #IFabFlyoutPage>, value: bool, onChanged: bool -> 'msg) = + this.AddScalar(FlyoutPageMvu.IsPresented.WithValue(MsgValueEventData.create value onChanged)) + + /// Listen for back button pressed + /// Current widget + /// Message to dispatch + [] + static member inline onBackButtonPressed(this: WidgetBuilder<'msg, #IFabFlyoutPage>, fn: bool -> 'msg) = + this.AddScalar(FlyoutPageMvu.BackButtonPressed.WithValue(fun args -> fn args.Handled)) diff --git a/src/Fabulous.MauiControls/Views/Pages/FlyoutPage.fs b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.fs similarity index 55% rename from src/Fabulous.MauiControls/Views/Pages/FlyoutPage.fs rename to src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.fs index e66a6c0..12fc642 100644 --- a/src/Fabulous.MauiControls/Views/Pages/FlyoutPage.fs +++ b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.fs @@ -24,13 +24,7 @@ type FabFlyoutPage() as this = module FlyoutPage = let WidgetKey = Widgets.register() - - let BackButtonPressedMsg = - Attributes.defineEvent "FlyoutPage_BackButtonPressedMsg" (fun target -> (target :?> FlyoutPage).BackButtonPressed) - - let BackButtonPressedFn = - Attributes.defineEventNoDispatch "FlyoutPage_BackButtonPressedFn" (fun target -> (target :?> FlyoutPage).BackButtonPressed) - + let Detail = Attributes.definePropertyWidget "FlyoutPage_Detail" (fun target -> (target :?> FlyoutPage).Detail :> obj) (fun target value -> (target :?> FlyoutPage).Detail <- value) @@ -45,14 +39,6 @@ module FlyoutPage = let IsGestureEnabled = Attributes.defineBindableBool FlyoutPage.IsGestureEnabledProperty - let IsPresentedMsg = - Attributes.defineBindableWithEvent "FlyoutPage_IsPresentedChangedMsg" FlyoutPage.IsPresentedProperty (fun target -> - (target :?> FabFlyoutPage).CustomIsPresentedChanged) - - let IsPresentedFn = - Attributes.defineBindableWithEventNoDispatch "FlyoutPage_IsPresentedChangedFn" FlyoutPage.IsPresentedProperty (fun target -> - (target :?> FabFlyoutPage).CustomIsPresentedChanged) - [] module FlyoutPageBuilders = type Fabulous.Maui.View with @@ -75,22 +61,6 @@ type FlyoutPageModifiers = static member inline flyoutLayoutBehavior(this: WidgetBuilder<'msg, #IFabFlyoutPage>, value: FlyoutLayoutBehavior) = this.AddScalar(FlyoutPage.FlyoutLayoutBehavior.WithValue(value)) - /// Set whether the flyout is presented, and listen for presentation state changes - /// Current widget - /// The value indicating whether the flyout is presented - /// Message to dispatch - [] - static member inline isPresented(this: WidgetBuilder<'msg, #IFabFlyoutPage>, value: bool, onChanged: bool -> 'msg) = - this.AddScalar(FlyoutPage.IsPresentedMsg.WithValue(MsgValueEventData.create value onChanged)) - - /// Set whether the flyout is presented, and listen for presentation state changes - /// Current widget - /// The value indicating whether the flyout is presented - /// Message to dispatch - [] - static member inline isPresented(this: WidgetBuilder<'msg, #IFabFlyoutPage>, value: bool, onChanged: bool -> unit) = - this.AddScalar(FlyoutPage.IsPresentedFn.WithValue(ValueEventData.create value onChanged)) - /// Set whether gesture is enabled to open the flyout /// Current widget /// The value indicating whether gesture is enabled @@ -98,20 +68,6 @@ type FlyoutPageModifiers = static member inline isGestureEnabled(this: WidgetBuilder<'msg, #IFabFlyoutPage>, value: bool) = this.AddScalar(FlyoutPage.IsGestureEnabled.WithValue(value)) - /// Listen for back button pressed - /// Current widget - /// Message to dispatch - [] - static member inline onBackButtonPressed(this: WidgetBuilder<'msg, #IFabFlyoutPage>, fn: bool -> 'msg) = - this.AddScalar(FlyoutPage.BackButtonPressedMsg.WithValue(fun args -> fn args.Handled)) - - /// Listen for back button pressed - /// Current widget - /// Message to dispatch - [] - static member inline onBackButtonPressed(this: WidgetBuilder<'msg, #IFabFlyoutPage>, fn: bool -> unit) = - this.AddScalar(FlyoutPage.BackButtonPressedFn.WithValue(fun args -> fn args.Handled)) - /// Link a ViewRef to access the direct FlyoutPage control instance /// Current widget /// The ViewRef instance that will receive access to the underlying control diff --git a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs new file mode 100644 index 0000000..e61aa83 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs @@ -0,0 +1,30 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous + +module NavigationPageComponent = + let WidgetKey = Widgets.register() + + let BackButtonPressed = + Attributes.Component.defineEventNoArg "NavigationPageComponent_BackButtonPressed" (fun target -> (target :?> FabNavigationPage).BackButtonPressed) + + let BackNavigated = + Attributes.Component.defineEventNoArg "NavigationPageComponent_BackNavigated" (fun target -> (target :?> FabNavigationPage).BackNavigated) + +[] +type NavigationPageComponentModifiers = + /// Listen to the user pressing the system back button. Doesn't support the iOS back button + /// Current widget + /// Function to execute + /// Setting this modifier will prevent the default behavior of the system back button. It's up to you to update the navigation stack. + [] + static member inline onBackButtonPressed(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(NavigationPageComponent.BackButtonPressed.WithValue(fn)) + + /// Listen to the user back navigating + /// Current widget + /// Function to execute + [] + static member inline onBackNavigated(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(NavigationPageComponent.BackNavigated.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs new file mode 100644 index 0000000..111e8e5 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs @@ -0,0 +1,28 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous + +module NavigationPageMvu = + let BackButtonPressed = + Attributes.Mvu.defineEventNoArg "NavigationPageMvu_BackButtonPressed" (fun target -> (target :?> FabNavigationPage).BackButtonPressed) + + let BackNavigated = + Attributes.Mvu.defineEventNoArg "NavigationPageMvu_BackNavigated" (fun target -> (target :?> FabNavigationPage).BackNavigated) + +[] +type NavigationPageMvuModifiers = + /// Listen to the user pressing the system back button. Doesn't support the iOS back button + /// Current widget + /// Msg to dispatch + /// Setting this modifier will prevent the default behavior of the system back button. It's up to you to update the navigation stack. + [] + static member inline onBackButtonPressed(this: WidgetBuilder<'msg, #IFabNavigationPage>, msg: 'msg) = + this.AddScalar(NavigationPageMvu.BackButtonPressed.WithValue(MsgValue(msg))) + + /// Listen to the user back navigating + /// Current widget + /// Message to dispatch + [] + static member inline onBackNavigated(this: WidgetBuilder<'msg, #IFabNavigationPage>, msg: 'msg) = + this.AddScalar(NavigationPageMvu.BackNavigated.WithValue(MsgValue(msg))) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Pages/NavigationPage.fs b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.fs similarity index 88% rename from src/Fabulous.MauiControls/Views/Pages/NavigationPage.fs rename to src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.fs index 73d9218..8df57c4 100644 --- a/src/Fabulous.MauiControls/Views/Pages/NavigationPage.fs +++ b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.fs @@ -267,19 +267,7 @@ module NavigationPageUpdaters = module NavigationPage = let WidgetKey = Widgets.register() - - let BackButtonPressedMsg = - Attributes.defineEventNoArg "NavigationPage_BackButtonPressedMsg" (fun target -> (target :?> FabNavigationPage).BackButtonPressed) - - let BackButtonPressedFn = - Attributes.defineEventNoArgNoDispatch "NavigationPage_BackButtonPressedFn" (fun target -> (target :?> FabNavigationPage).BackButtonPressed) - - let BackNavigatedMsg = - Attributes.defineEventNoArg "NavigationPage_BackNavigatedMsg" (fun target -> (target :?> FabNavigationPage).BackNavigated) - - let BackNavigatedFn = - Attributes.defineEventNoArgNoDispatch "NavigationPage_BackNavigatedFn" (fun target -> (target :?> FabNavigationPage).BackNavigated) - + let BarBackground = Attributes.defineBindableWithEquality NavigationPage.BarBackgroundProperty @@ -377,36 +365,6 @@ type NavigationPageModifiers = static member inline barTextColor(this: WidgetBuilder<'msg, #IFabNavigationPage>, value: Color) = this.AddScalar(NavigationPage.BarTextColor.WithValue(value)) - /// Listen to the user pressing the system back button. Doesn't support the iOS back button - /// Current widget - /// Msg to dispatch - /// Setting this modifier will prevent the default behavior of the system back button. It's up to you to update the navigation stack. - [] - static member inline onBackButtonPressed(this: WidgetBuilder<'msg, #IFabNavigationPage>, msg: 'msg) = - this.AddScalar(NavigationPage.BackButtonPressedMsg.WithValue(MsgValue(msg))) - - /// Listen to the user pressing the system back button. Doesn't support the iOS back button - /// Current widget - /// Function to execute - /// Setting this modifier will prevent the default behavior of the system back button. It's up to you to update the navigation stack. - [] - static member inline onBackButtonPressed(this: WidgetBuilder<'msg, #IFabNavigationPage>, fn: unit -> unit) = - this.AddScalar(NavigationPage.BackButtonPressedFn.WithValue(fn)) - - /// Listen to the user back navigating - /// Current widget - /// Message to dispatch - [] - static member inline onBackNavigated(this: WidgetBuilder<'msg, #IFabNavigationPage>, msg: 'msg) = - this.AddScalar(NavigationPage.BackNavigatedMsg.WithValue(MsgValue(msg))) - - /// Listen to the user back navigating - /// Current widget - /// Function to execute - [] - static member inline onBackNavigated(this: WidgetBuilder<'msg, #IFabNavigationPage>, fn: unit -> unit) = - this.AddScalar(NavigationPage.BackNavigatedFn.WithValue(fn)) - /// Link a ViewRef to access the direct NavigationPage control instance /// Current widget /// The ViewRef instance that will receive access to the underlying control diff --git a/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage.fs b/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage.fs deleted file mode 100644 index dbf6aba..0000000 --- a/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage.fs +++ /dev/null @@ -1,116 +0,0 @@ -namespace Fabulous.Maui - -open Fabulous -open Fabulous.ScalarAttributeDefinitions -open Microsoft.Maui.Controls -open System.Runtime.CompilerServices - -type IFabMultiPageOfPage = - inherit IFabPage - -module MultiPageOfPage = - let Children = - Attributes.defineListWidgetCollection "MultiPageOfPage" (fun target -> (target :?> MultiPage).Children) - - let CurrentPageWithEventMsg = - let name = "MultiPageOfPage_CurrentPageWithEventMsg" - - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun oldValueOpt (newValueOpt: MsgValueEventData voption) node -> - let target = node.Target :?> MultiPage - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the event - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> target.CurrentPage <- target.Children.[0] - - | ValueSome curr -> - // Clean up the old event handler if any - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - target.CurrentPage <- target.Children.[curr.Value] - - // Set the new event handler - let handler = - target.CurrentPageChanged.Subscribe(fun _args -> - let currentPageIndex = target.Children.IndexOf(target.CurrentPage) - let (MsgValue r) = curr.Event currentPageIndex - Dispatcher.dispatch node r) - - node.SetHandler(name, handler)) - ) - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name }: SimpleScalarAttributeDefinition> - - let CurrentPageWithEventFn = - let name = "MultiPageOfPage_CurrentPageWithEventFn" - - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun oldValueOpt (newValueOpt: ValueEventData voption) node -> - let target = node.Target :?> MultiPage - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the event - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> target.CurrentPage <- target.Children.[0] - - | ValueSome curr -> - // Clean up the old event handler if any - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - target.CurrentPage <- target.Children.[curr.Value] - - // Set the new event handler - let handler = - target.CurrentPageChanged.Subscribe(fun _args -> - let currentPageIndex = target.Children.IndexOf(target.CurrentPage) - curr.Event currentPageIndex) - - node.SetHandler(name, handler)) - ) - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name }: SimpleScalarAttributeDefinition> - -[] -type MultiPageOfPageModifiers = - /// Set the current page and listen for changes - /// Current widget - /// The current page index - /// Function to invoke - [] - static member inline currentPage(this: WidgetBuilder<'msg, #IFabMultiPageOfPage>, currentPage: int, onCurrentPageChanged: int -> 'msg) = - this.AddScalar(MultiPageOfPage.CurrentPageWithEventMsg.WithValue(MsgValueEventData.create currentPage onCurrentPageChanged)) - - /// Set the current page and listen for changes - /// Current widget - /// The current page index - /// Function to invoke - [] - static member inline currentPage(this: WidgetBuilder<'msg, #IFabMultiPageOfPage>, currentPage: int, onCurrentPageChanged: int -> unit) = - this.AddScalar(MultiPageOfPage.CurrentPageWithEventFn.WithValue(ValueEventData.create currentPage onCurrentPageChanged)) diff --git a/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Component.fs b/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Component.fs new file mode 100644 index 0000000..0d60fb6 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Component.fs @@ -0,0 +1,59 @@ +namespace Fabulous.Maui + +open Fabulous +open Fabulous.ScalarAttributeDefinitions +open Microsoft.Maui.Controls +open System.Runtime.CompilerServices + +module MultiPageOfPageComponent = + let CurrentPageWithEvent = + let name = "MultiPageOfPageComponent_CurrentPageWithEvent" + + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun oldValueOpt (newValueOpt: ValueEventData voption) node -> + let target = node.Target :?> MultiPage + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the event + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> target.CurrentPage <- target.Children.[0] + + | ValueSome curr -> + // Clean up the old event handler if any + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + target.CurrentPage <- target.Children.[curr.Value] + + // Set the new event handler + let handler = + target.CurrentPageChanged.Subscribe(fun _args -> + let currentPageIndex = target.Children.IndexOf(target.CurrentPage) + curr.Event currentPageIndex) + + node.SetHandler(name, handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name }: SimpleScalarAttributeDefinition> + +[] +type MultiPageOfPageComponentModifiers = + /// Set the current page and listen for changes + /// Current widget + /// The current page index + /// Function to invoke + [] + static member inline currentPage(this: WidgetBuilder, currentPage: int, onCurrentPageChanged: int -> unit) = + this.AddScalar(MultiPageOfPageComponent.CurrentPageWithEvent.WithValue(ValueEventData.create currentPage onCurrentPageChanged)) diff --git a/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Mvu.fs b/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Mvu.fs new file mode 100644 index 0000000..f4608f1 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.Mvu.fs @@ -0,0 +1,60 @@ +namespace Fabulous.Maui + +open Fabulous +open Fabulous.ScalarAttributeDefinitions +open Microsoft.Maui.Controls +open System.Runtime.CompilerServices + +module MultiPageOfPageMvu = + let CurrentPageWithEvent = + let name = "MultiPageOfPageMvu_CurrentPageWithEvent" + + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun oldValueOpt (newValueOpt: MsgValueEventData voption) node -> + let target = node.Target :?> MultiPage + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the event + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> target.CurrentPage <- target.Children.[0] + + | ValueSome curr -> + // Clean up the old event handler if any + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + target.CurrentPage <- target.Children.[curr.Value] + + // Set the new event handler + let handler = + target.CurrentPageChanged.Subscribe(fun _args -> + let currentPageIndex = target.Children.IndexOf(target.CurrentPage) + let (MsgValue r) = curr.Event currentPageIndex + Dispatcher.dispatch node r) + + node.SetHandler(name, handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name }: SimpleScalarAttributeDefinition> + +[] +type MultiPageOfPageMvuModifiers = + /// Set the current page and listen for changes + /// Current widget + /// The current page index + /// Function to invoke + [] + static member inline currentPage(this: WidgetBuilder<'msg, #IFabMultiPageOfPage>, currentPage: int, onCurrentPageChanged: int -> 'msg) = + this.AddScalar(MultiPageOfPageMvu.CurrentPageWithEvent.WithValue(MsgValueEventData.create currentPage onCurrentPageChanged)) diff --git a/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.fs b/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.fs new file mode 100644 index 0000000..d3f783a --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/_MultiPageOfPage/MultiPageOfPage.fs @@ -0,0 +1,11 @@ +namespace Fabulous.Maui + +open Fabulous +open Microsoft.Maui.Controls + +type IFabMultiPageOfPage = + inherit IFabPage + +module MultiPageOfPage = + let Children = + Attributes.defineListWidgetCollection "MultiPageOfPage" (fun target -> (target :?> MultiPage).Children) diff --git a/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs new file mode 100644 index 0000000..ed10eae --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs @@ -0,0 +1,42 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module PageComponent = + let Appearing = + Attributes.Component.defineEventNoArg "PageComponent_Appearing" (fun target -> (target :?> Page).Appearing) + + let Disappearing = + Attributes.Component.defineEventNoArg "PageComponent_Disappearing" (fun target -> (target :?> Page).Disappearing) + + let NavigatedTo = + Attributes.Component.defineEvent "PageComponent_NavigatedTo" (fun target -> (target :?> Page).NavigatedTo) + + let NavigatedFrom = + Attributes.Component.defineEvent "PageComponent_NavigatedFrom" (fun target -> (target :?> Page).NavigatedFrom) + +[] +type PageComponentModifiers = + /// Listen to the Appearing event + /// Current widget + /// Function to execute + [] + static member inline onAppearing(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(PageComponent.Appearing.WithValue(fn)) + + /// Listen to the Disappearing event + /// Current widget + /// Function to execute + [] + static member inline onDisappearing(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(PageComponent.Disappearing.WithValue(fn)) + + [] + static member inline onNavigatedTo(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(PageComponent.NavigatedTo.WithValue(fun _ -> fn())) + + [] + static member inline onNavigatedFrom(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(PageComponent.NavigatedFrom.WithValue(fun _ -> fn())) diff --git a/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Mvu.fs b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Mvu.fs new file mode 100644 index 0000000..0ed97b7 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Mvu.fs @@ -0,0 +1,42 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module PageMvu = + let Appearing = + Attributes.Mvu.defineEventNoArg "PageMvu_Appearing" (fun target -> (target :?> Page).Appearing) + + let Disappearing = + Attributes.Mvu.defineEventNoArg "PageMvu_Disappearing" (fun target -> (target :?> Page).Disappearing) + + let NavigatedTo = + Attributes.Mvu.defineEvent "PageMvu_NavigatedTo" (fun target -> (target :?> Page).NavigatedTo) + + let NavigatedFrom = + Attributes.Mvu.defineEvent "PageMvu_NavigatedFrom" (fun target -> (target :?> Page).NavigatedFrom) + +[] +type PageMvuModifiers = + /// Listen to the Appearing event + /// Current widget + /// Message to dispatch + [] + static member inline onAppearing(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = + this.AddScalar(PageMvu.Appearing.WithValue(MsgValue(msg))) + + /// Listen to the Disappearing event + /// Current widget + /// Message to dispatch + [] + static member inline onDisappearing(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = + this.AddScalar(PageMvu.Disappearing.WithValue(MsgValue(msg))) + + [] + static member inline onNavigatedTo(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = + this.AddScalar(PageMvu.NavigatedTo.WithValue(fun _ -> msg)) + + [] + static member inline onNavigatedFrom(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = + this.AddScalar(PageMvu.NavigatedFrom.WithValue(fun _ -> msg)) diff --git a/src/Fabulous.MauiControls/Views/Pages/_Page.fs b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.fs similarity index 71% rename from src/Fabulous.MauiControls/Views/Pages/_Page.fs rename to src/Fabulous.MauiControls/Views/Pages/_Page/Page.fs index 22cb90a..7eaa82e 100644 --- a/src/Fabulous.MauiControls/Views/Pages/_Page.fs +++ b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.fs @@ -13,38 +13,14 @@ type IFabPage = inherit IFabVisualElement module Page = - let AppearingMsg = - Attributes.defineEventNoArg "Page_AppearingMsg" (fun target -> (target :?> Page).Appearing) - - let AppearingFn = - Attributes.defineEventNoArgNoDispatch "Page_AppearingFn" (fun target -> (target :?> Page).Appearing) - let BackgroundImageSource = Attributes.defineBindableImageSource Page.BackgroundImageSourceProperty - let DisappearingMsg = - Attributes.defineEventNoArg "Page_DisappearingMsg" (fun target -> (target :?> Page).Disappearing) - - let DisappearingFn = - Attributes.defineEventNoArgNoDispatch "Page_DisappearingFn" (fun target -> (target :?> Page).Disappearing) - let IconImageSource = Attributes.defineBindableImageSource Page.IconImageSourceProperty let IsBusy = Attributes.defineBindableBool Page.IsBusyProperty - let NavigatedToMsg = - Attributes.defineEvent "NavigatedToMsg" (fun target -> (target :?> Page).NavigatedTo) - - let NavigatedToFn = - Attributes.defineEventNoDispatch "NavigatedToFn" (fun target -> (target :?> Page).NavigatedTo) - - let NavigatedFromMsg = - Attributes.defineEvent "NavigatedFromMsg" (fun target -> (target :?> Page).NavigatedFrom) - - let NavigatedFromFn = - Attributes.defineEventNoDispatch "NavigatedFromFn" (fun target -> (target :?> Page).NavigatedFrom) - let Padding = Attributes.defineBindableWithEquality Page.PaddingProperty let Title = Attributes.defineBindableWithEquality Page.TitleProperty @@ -86,50 +62,6 @@ type PageModifiers = static member inline isBusy(this: WidgetBuilder<'msg, #IFabPage>, value: bool) = this.AddScalar(Page.IsBusy.WithValue(value)) - /// Listen to the Appearing event - /// Current widget - /// Message to dispatch - [] - static member inline onAppearing(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = - this.AddScalar(Page.AppearingMsg.WithValue(MsgValue(msg))) - - /// Listen to the Appearing event - /// Current widget - /// Function to execute - [] - static member inline onAppearing(this: WidgetBuilder<'msg, #IFabPage>, fn: unit -> unit) = - this.AddScalar(Page.AppearingFn.WithValue(fn)) - - /// Listen to the Disappearing event - /// Current widget - /// Message to dispatch - [] - static member inline onDisappearing(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = - this.AddScalar(Page.DisappearingMsg.WithValue(MsgValue(msg))) - - /// Listen to the Disappearing event - /// Current widget - /// Function to execute - [] - static member inline onDisappearing(this: WidgetBuilder<'msg, #IFabPage>, fn: unit -> unit) = - this.AddScalar(Page.DisappearingFn.WithValue(fn)) - - [] - static member inline onNavigatedTo(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = - this.AddScalar(Page.NavigatedToMsg.WithValue(fun _ -> msg)) - - [] - static member inline onNavigatedTo(this: WidgetBuilder<'msg, #IFabPage>, fn: unit -> unit) = - this.AddScalar(Page.NavigatedToFn.WithValue(fun _ -> fn())) - - [] - static member inline onNavigatedFrom(this: WidgetBuilder<'msg, #IFabPage>, msg: 'msg) = - this.AddScalar(Page.NavigatedFromMsg.WithValue(fun _ -> msg)) - - [] - static member inline onNavigatedFrom(this: WidgetBuilder<'msg, #IFabPage>, fn: unit -> unit) = - this.AddScalar(Page.NavigatedFromFn.WithValue(fun _ -> fn())) - /// Set the padding inside the widget /// Current widget /// The padding value diff --git a/src/Fabulous.MauiControls/Views/Shapes/Geometries/RoundRectangleGeometry.fs b/src/Fabulous.MauiControls/Views/Shapes/Geometries/RoundRectangleGeometry.fs index 85fdb16..b6ecf67 100644 --- a/src/Fabulous.MauiControls/Views/Shapes/Geometries/RoundRectangleGeometry.fs +++ b/src/Fabulous.MauiControls/Views/Shapes/Geometries/RoundRectangleGeometry.fs @@ -1,6 +1,5 @@ namespace Fabulous.Maui -open System open System.Runtime.CompilerServices open Fabulous open Microsoft.Maui diff --git a/src/Fabulous.MauiControls/Views/Window.fs b/src/Fabulous.MauiControls/Views/Window.fs deleted file mode 100644 index 4a3f9f0..0000000 --- a/src/Fabulous.MauiControls/Views/Window.fs +++ /dev/null @@ -1,220 +0,0 @@ -namespace Fabulous.Maui - -open System.Runtime.CompilerServices -open Microsoft.Maui -open Microsoft.Maui.Controls -open Fabulous -open Fabulous.StackAllocatedCollections.StackList -open Fabulous.Maui - -type IFabWindow = - inherit IFabNavigableElement - -module Window = - let WidgetKey = Widgets.register() - - let Page = Attributes.defineBindableWidget Window.PageProperty - - let FlowDirection = - Attributes.defineBindableWithEquality Window.FlowDirectionProperty - - let Height = Attributes.defineBindableWithEquality Window.HeightProperty - - let MaximumHeight = - Attributes.defineBindableWithEquality Window.MaximumHeightProperty - - let MaximumWidth = Attributes.defineBindableWithEquality Window.MaximumWidthProperty - - let MinimumHeight = - Attributes.defineBindableWithEquality Window.MinimumHeightProperty - - let MinimumWidth = Attributes.defineBindableWithEquality Window.MinimumWidthProperty - - let ActivatedMsg = - Attributes.defineEventNoArg "Window_ActivatedMsg" (fun target -> (target :?> Window).Activated) - - let ActivatedFn = - Attributes.defineEventNoArgNoDispatch "Window_ActivatedFn" (fun target -> (target :?> Window).Activated) - - let BackgroundingMsg = - Attributes.defineEvent "Window_BackgroundingMsg" (fun target -> (target :?> Window).Backgrounding) - - let BackgroundingFn = - Attributes.defineEventNoDispatch "Window_BackgroundingFn" (fun target -> (target :?> Window).Backgrounding) - - let CreatedMsg = - Attributes.defineEventNoArg "Window_CreatedMsg" (fun target -> (target :?> Window).Created) - - let CreatedFn = - Attributes.defineEventNoArgNoDispatch "Window_CreatedFn" (fun target -> (target :?> Window).Created) - - let DeactivatedMsg = - Attributes.defineEventNoArg "Window_DeactivatedMsg" (fun target -> (target :?> Window).Deactivated) - - let DeactivatedFn = - Attributes.defineEventNoArgNoDispatch "Window_DeactivatedFn" (fun target -> (target :?> Window).Deactivated) - - let DestroyingMsg = - Attributes.defineEventNoArg "Window_DestroyingMsg" (fun target -> (target :?> Window).Destroying) - - let DestroyingFn = - Attributes.defineEventNoArgNoDispatch "Window_DestroyingFn" (fun target -> (target :?> Window).Destroying) - - let DisplayDensityChangedMsg = - Attributes.defineEvent "Window_DisplayDensityChangedMsg" (fun target -> (target :?> Window).DisplayDensityChanged) - - let DisplayDensityChangedFn = - Attributes.defineEventNoDispatch "Window_DisplayDensityChangedFn" (fun target -> (target :?> Window).DisplayDensityChanged) - - let SizeChangedMsg = - Attributes.defineEventNoArg "Window_SizeChangedMsg" (fun target -> (target :?> Window).SizeChanged) - - let SizeChangedFn = - Attributes.defineEventNoArgNoDispatch "Window_SizeChangedFn" (fun target -> (target :?> Window).SizeChanged) - - let ResumedMsg = - Attributes.defineEventNoArg "Window_ResumedMsg" (fun target -> (target :?> Window).Resumed) - - let ResumedFn = - Attributes.defineEventNoArgNoDispatch "Window_ResumedFn" (fun target -> (target :?> Window).Resumed) - - let StoppedMsg = - Attributes.defineEventNoArg "Window_StoppedMsg" (fun target -> (target :?> Window).Stopped) - - let StoppedFn = - Attributes.defineEventNoArgNoDispatch "Window_StoppedFn" (fun target -> (target :?> Window).Stopped) - - let Title = Attributes.defineBindableWithEquality Window.TitleProperty - - let Width = Attributes.defineBindableWithEquality Window.WidthProperty - - let X = Attributes.defineBindableWithEquality Window.XProperty - - let Y = Attributes.defineBindableWithEquality Window.YProperty - -[] -module WindowBuilders = - type Fabulous.Maui.View with - - static member inline Window(content: WidgetBuilder<'msg, #IFabPage>) = - WidgetBuilder<'msg, IFabWindow>( - Window.WidgetKey, - AttributesBundle(StackList.empty(), ValueSome [| Window.Page.WithValue(content.Compile()) |], ValueNone) - ) - - static member inline Window() = - SingleChildBuilder<'msg, IFabWindow, #IFabPage>(Window.WidgetKey, Window.Page) - -[] -type WindowModifiers = - [] - static member inline flowDirection(this: WidgetBuilder<'msg, #IFabWindow>, value: FlowDirection) = - this.AddScalar(Window.FlowDirection.WithValue(value)) - - [] - static member inline height(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.Height.WithValue(value)) - - [] - static member inline maximumHeight(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.MaximumHeight.WithValue(value)) - - [] - static member inline maximumWidth(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.MaximumWidth.WithValue(value)) - - [] - static member inline minimumHeight(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.MinimumHeight.WithValue(value)) - - [] - static member inline minimumWidth(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.MinimumWidth.WithValue(value)) - - [] - static member inline onActivated(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = - this.AddScalar(Window.ActivatedMsg.WithValue(MsgValue msg)) - - [] - static member inline onActivated(this: WidgetBuilder<'msg, #IFabWindow>, fn: unit -> unit) = - this.AddScalar(Window.ActivatedFn.WithValue(fn)) - - [] - static member inline onBackgrounding(this: WidgetBuilder<'msg, #IFabWindow>, fn: BackgroundingEventArgs -> 'msg) = - this.AddScalar(Window.BackgroundingMsg.WithValue(fn)) - - [] - static member inline onBackgrounding(this: WidgetBuilder<'msg, #IFabWindow>, fn: BackgroundingEventArgs -> unit) = - this.AddScalar(Window.BackgroundingFn.WithValue(fn)) - - [] - static member inline onCreated(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = - this.AddScalar(Window.CreatedMsg.WithValue(MsgValue msg)) - - [] - static member inline onCreated(this: WidgetBuilder<'msg, #IFabWindow>, fn: unit -> unit) = - this.AddScalar(Window.CreatedFn.WithValue(fn)) - - [] - static member inline onDeactivated(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = - this.AddScalar(Window.DeactivatedMsg.WithValue(MsgValue msg)) - - [] - static member inline onDeactivated(this: WidgetBuilder<'msg, #IFabWindow>, fn: unit -> unit) = - this.AddScalar(Window.DeactivatedFn.WithValue(fn)) - - [] - static member inline onDestroying(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = - this.AddScalar(Window.DestroyingMsg.WithValue(MsgValue msg)) - - [] - static member inline onDestroying(this: WidgetBuilder<'msg, #IFabWindow>, fn: unit -> unit) = - this.AddScalar(Window.DestroyingFn.WithValue(fn)) - - [] - static member inline onDisplayDensityChanged(this: WidgetBuilder<'msg, #IFabWindow>, fn: DisplayDensityChangedEventArgs -> 'msg) = - this.AddScalar(Window.DisplayDensityChangedMsg.WithValue(fn)) - - [] - static member inline onDisplayDensityChanged(this: WidgetBuilder<'msg, #IFabWindow>, fn: DisplayDensityChangedEventArgs -> unit) = - this.AddScalar(Window.DisplayDensityChangedFn.WithValue(fn)) - - [] - static member inline onSizeChanged(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = - this.AddScalar(Window.SizeChangedMsg.WithValue(MsgValue msg)) - - [] - static member inline onSizeChanged(this: WidgetBuilder<'msg, #IFabWindow>, fn: unit -> unit) = - this.AddScalar(Window.SizeChangedFn.WithValue(fn)) - - [] - static member inline onResumed(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = - this.AddScalar(Window.ResumedMsg.WithValue(MsgValue msg)) - - [] - static member inline onResumed(this: WidgetBuilder<'msg, #IFabWindow>, fn: unit -> unit) = - this.AddScalar(Window.ResumedFn.WithValue(fn)) - - [] - static member inline onStopped(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = - this.AddScalar(Window.StoppedMsg.WithValue(MsgValue msg)) - - [] - static member inline onStopped(this: WidgetBuilder<'msg, #IFabWindow>, fn: unit -> unit) = - this.AddScalar(Window.StoppedFn.WithValue(fn)) - - [] - static member inline title(this: WidgetBuilder<'msg, #IFabWindow>, value: string) = - this.AddScalar(Window.Title.WithValue(value)) - - [] - static member inline width(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.Width.WithValue(value)) - - [] - static member inline x(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.X.WithValue(value)) - - [] - static member inline y(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = - this.AddScalar(Window.Y.WithValue(value)) diff --git a/src/Fabulous.MauiControls/Views/Window/Window.Component.fs b/src/Fabulous.MauiControls/Views/Window/Window.Component.fs new file mode 100644 index 0000000..fd2ba25 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Window/Window.Component.fs @@ -0,0 +1,72 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Microsoft.Maui.Controls +open Fabulous +open Fabulous.Maui + +module WindowComponent = + let Activated = + Attributes.Component.defineEventNoArg "WindowComponent_Activated" (fun target -> (target :?> Window).Activated) + + let Backgrounding = + Attributes.Component.defineEvent "WindowComponent_Backgrounding" (fun target -> (target :?> Window).Backgrounding) + + let Created = + Attributes.Component.defineEventNoArg "WindowComponent_Created" (fun target -> (target :?> Window).Created) + + let Deactivated = + Attributes.Component.defineEventNoArg "WindowComponent_Deactivated" (fun target -> (target :?> Window).Deactivated) + + let Destroying = + Attributes.Component.defineEventNoArg "WindowComponent_Destroying" (fun target -> (target :?> Window).Destroying) + + let DisplayDensityChanged = + Attributes.Component.defineEvent "WindowComponent_DisplayDensityChanged" (fun target -> (target :?> Window).DisplayDensityChanged) + + let SizeChanged = + Attributes.Component.defineEventNoArg "WindowComponent_SizeChanged" (fun target -> (target :?> Window).SizeChanged) + + let Resumed = + Attributes.Component.defineEventNoArg "WindowComponent_Resumed" (fun target -> (target :?> Window).Resumed) + + let Stopped = + Attributes.Component.defineEventNoArg "WindowComponent_Stopped" (fun target -> (target :?> Window).Stopped) + +[] +type WindowComponentModifiers = + [] + static member inline onActivated(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(WindowComponent.Activated.WithValue(fn)) + + [] + static member inline onBackgrounding(this: WidgetBuilder, fn: BackgroundingEventArgs -> unit) = + this.AddScalar(WindowComponent.Backgrounding.WithValue(fn)) + + [] + static member inline onCreated(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(WindowComponent.Created.WithValue(fn)) + + [] + static member inline onDeactivated(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(WindowComponent.Deactivated.WithValue(fn)) + + [] + static member inline onDestroying(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(WindowComponent.Destroying.WithValue(fn)) + + [] + static member inline onDisplayDensityChanged(this: WidgetBuilder, fn: DisplayDensityChangedEventArgs -> unit) = + this.AddScalar(WindowComponent.DisplayDensityChanged.WithValue(fn)) + + [] + static member inline onSizeChanged(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(WindowComponent.SizeChanged.WithValue(fn)) + + [] + static member inline onResumed(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(WindowComponent.Resumed.WithValue(fn)) + + [] + static member inline onStopped(this: WidgetBuilder, fn: unit -> unit) = + this.AddScalar(WindowComponent.Stopped.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Window/Window.Mvu.fs b/src/Fabulous.MauiControls/Views/Window/Window.Mvu.fs new file mode 100644 index 0000000..0850156 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Window/Window.Mvu.fs @@ -0,0 +1,72 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Microsoft.Maui.Controls +open Fabulous +open Fabulous.Maui + +module WindowMvu = + let Activated = + Attributes.Mvu.defineEventNoArg "WindowMvu_Activated" (fun target -> (target :?> Window).Activated) + + let Backgrounding = + Attributes.Mvu.defineEvent "WindowMvu_Backgrounding" (fun target -> (target :?> Window).Backgrounding) + + let Created = + Attributes.Mvu.defineEventNoArg "WindowMvu_Created" (fun target -> (target :?> Window).Created) + + let Deactivated = + Attributes.Mvu.defineEventNoArg "WindowMvu_Deactivated" (fun target -> (target :?> Window).Deactivated) + + let Destroying = + Attributes.Mvu.defineEventNoArg "WindowMvu_Destroying" (fun target -> (target :?> Window).Destroying) + + let DisplayDensityChanged = + Attributes.Mvu.defineEvent "WindowMvu_DisplayDensityChanged" (fun target -> (target :?> Window).DisplayDensityChanged) + + let SizeChanged = + Attributes.Mvu.defineEventNoArg "WindowMvu_SizeChanged" (fun target -> (target :?> Window).SizeChanged) + + let Resumed = + Attributes.Mvu.defineEventNoArg "WindowMvu_Resumed" (fun target -> (target :?> Window).Resumed) + + let Stopped = + Attributes.Mvu.defineEventNoArg "WindowMvu_Stopped" (fun target -> (target :?> Window).Stopped) + +[] +type WindowMvuModifiers = + [] + static member inline onActivated(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = + this.AddScalar(WindowMvu.Activated.WithValue(MsgValue msg)) + + [] + static member inline onBackgrounding(this: WidgetBuilder<'msg, #IFabWindow>, fn: BackgroundingEventArgs -> 'msg) = + this.AddScalar(WindowMvu.Backgrounding.WithValue(fn)) + + [] + static member inline onCreated(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = + this.AddScalar(WindowMvu.Created.WithValue(MsgValue msg)) + + [] + static member inline onDeactivated(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = + this.AddScalar(WindowMvu.Deactivated.WithValue(MsgValue msg)) + + [] + static member inline onDestroying(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = + this.AddScalar(WindowMvu.Destroying.WithValue(MsgValue msg)) + + [] + static member inline onDisplayDensityChanged(this: WidgetBuilder<'msg, #IFabWindow>, fn: DisplayDensityChangedEventArgs -> 'msg) = + this.AddScalar(WindowMvu.DisplayDensityChanged.WithValue(fn)) + + [] + static member inline onSizeChanged(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = + this.AddScalar(WindowMvu.SizeChanged.WithValue(MsgValue msg)) + + [] + static member inline onResumed(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = + this.AddScalar(WindowMvu.Resumed.WithValue(MsgValue msg)) + + [] + static member inline onStopped(this: WidgetBuilder<'msg, #IFabWindow>, msg: 'msg) = + this.AddScalar(WindowMvu.Stopped.WithValue(MsgValue msg)) diff --git a/src/Fabulous.MauiControls/Views/Window/Window.fs b/src/Fabulous.MauiControls/Views/Window/Window.fs new file mode 100644 index 0000000..9fcaad5 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Window/Window.fs @@ -0,0 +1,94 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Microsoft.Maui +open Microsoft.Maui.Controls +open Fabulous +open Fabulous.StackAllocatedCollections.StackList +open Fabulous.Maui + +type IFabWindow = + inherit IFabNavigableElement + +module Window = + let WidgetKey = Widgets.register() + + let Page = Attributes.defineBindableWidget Window.PageProperty + + let FlowDirection = + Attributes.defineBindableWithEquality Window.FlowDirectionProperty + + let Height = Attributes.defineBindableWithEquality Window.HeightProperty + + let MaximumHeight = + Attributes.defineBindableWithEquality Window.MaximumHeightProperty + + let MaximumWidth = Attributes.defineBindableWithEquality Window.MaximumWidthProperty + + let MinimumHeight = + Attributes.defineBindableWithEquality Window.MinimumHeightProperty + + let MinimumWidth = Attributes.defineBindableWithEquality Window.MinimumWidthProperty + + let Title = Attributes.defineBindableWithEquality Window.TitleProperty + + let Width = Attributes.defineBindableWithEquality Window.WidthProperty + + let X = Attributes.defineBindableWithEquality Window.XProperty + + let Y = Attributes.defineBindableWithEquality Window.YProperty + +[] +module WindowBuilders = + type Fabulous.Maui.View with + + static member inline Window(content: WidgetBuilder<'msg, #IFabPage>) = + WidgetBuilder<'msg, IFabWindow>( + Window.WidgetKey, + AttributesBundle(StackList.empty(), ValueSome [| Window.Page.WithValue(content.Compile()) |], ValueNone) + ) + + static member inline Window() = + SingleChildBuilder<'msg, IFabWindow, #IFabPage>(Window.WidgetKey, Window.Page) + +[] +type WindowModifiers = + [] + static member inline flowDirection(this: WidgetBuilder<'msg, #IFabWindow>, value: FlowDirection) = + this.AddScalar(Window.FlowDirection.WithValue(value)) + + [] + static member inline height(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.Height.WithValue(value)) + + [] + static member inline maximumHeight(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.MaximumHeight.WithValue(value)) + + [] + static member inline maximumWidth(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.MaximumWidth.WithValue(value)) + + [] + static member inline minimumHeight(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.MinimumHeight.WithValue(value)) + + [] + static member inline minimumWidth(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.MinimumWidth.WithValue(value)) + + [] + static member inline title(this: WidgetBuilder<'msg, #IFabWindow>, value: string) = + this.AddScalar(Window.Title.WithValue(value)) + + [] + static member inline width(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.Width.WithValue(value)) + + [] + static member inline x(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.X.WithValue(value)) + + [] + static member inline y(this: WidgetBuilder<'msg, #IFabWindow>, value: double) = + this.AddScalar(Window.Y.WithValue(value)) diff --git a/src/Fabulous.MauiControls/Views/_Element.fs b/src/Fabulous.MauiControls/Views/_Element/Element.Mvu.fs similarity index 53% rename from src/Fabulous.MauiControls/Views/_Element.fs rename to src/Fabulous.MauiControls/Views/_Element/Element.Mvu.fs index 2a2bef0..6b38f37 100644 --- a/src/Fabulous.MauiControls/Views/_Element.fs +++ b/src/Fabulous.MauiControls/Views/_Element/Element.Mvu.fs @@ -2,25 +2,9 @@ namespace Fabulous.Maui open System.Runtime.CompilerServices open Fabulous -open Microsoft.Maui.Controls - -type IFabElement = - interface - end - -module Element = - let AutomationId = - Attributes.defineBindableWithEquality Element.AutomationIdProperty [] -type ElementModifiers = - /// Sets a value that allows the automation framework to find and interact with this element - /// Current widget - /// A value that the automation framework can use to find and interact with this element. - [] - static member inline automationId(this: WidgetBuilder<'msg, #IFabElement>, value: string) = - this.AddScalar(Element.AutomationId.WithValue(value)) - +type ElementMvuModifiers = /// Listen to the widget being mounted /// Current widget /// Message to dispatch on trigger diff --git a/src/Fabulous.MauiControls/Views/_Element/Element.fs b/src/Fabulous.MauiControls/Views/_Element/Element.fs new file mode 100644 index 0000000..7e36d0b --- /dev/null +++ b/src/Fabulous.MauiControls/Views/_Element/Element.fs @@ -0,0 +1,22 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +type IFabElement = + interface + end + +module Element = + let AutomationId = + Attributes.defineBindableWithEquality Element.AutomationIdProperty + +[] +type ElementModifiers = + /// Sets a value that allows the automation framework to find and interact with this element + /// Current widget + /// A value that the automation framework can use to find and interact with this element. + [] + static member inline automationId(this: WidgetBuilder<'msg, #IFabElement>, value: string) = + this.AddScalar(Element.AutomationId.WithValue(value)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs new file mode 100644 index 0000000..25f96f5 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs @@ -0,0 +1,70 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module VisualElementComponentUpdaters = + let updateVisualElementFocus oldValueOpt (newValueOpt: ValueEventData voption) (node: IViewNode) = + let target = node.Target :?> VisualElement + + let onEventName = "Focus_On" + let offEventName = "Focus_Off" + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the events + match node.TryGetHandler(onEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match node.TryGetHandler(offEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> + if target.IsFocused then + target.Unfocus() + + | ValueSome curr -> + // Clean up the old event handlers if any + match node.TryGetHandler(onEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match node.TryGetHandler(offEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + if target.IsFocused <> curr.Value then + if curr.Value then + target.Focus() |> ignore + else + target.Unfocus() + + // Set the new event handlers + let onHandler = target.Focused.Subscribe(fun _args -> curr.Event true) + + node.SetHandler(onEventName, onHandler) + + let offHandler = target.Unfocused.Subscribe(fun _args -> curr.Event false) + + node.SetHandler(offEventName, offHandler) + +module VisualElementComponent = + let FocusWithEvent = + Attributes.defineSimpleScalar "VisualElementComponent_FocusWithEvent" ScalarAttributeComparers.noCompare VisualElementComponentUpdaters.updateVisualElementFocus + +[] +type VisualElementComponentModifiers = + /// Set the current focus state of the widget, and listen to focus state changes + /// Current widget + /// The focus state to apply + /// Message to dispatch when the widget's focus state changes + [] + static member inline focus(this: WidgetBuilder, value: bool, onFocusChanged: bool -> unit) = + this.AddScalar(VisualElementComponent.FocusWithEvent.WithValue(ValueEventData.create value onFocusChanged)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs new file mode 100644 index 0000000..65eb95a --- /dev/null +++ b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs @@ -0,0 +1,81 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module VisualElementMvuUpdaters = + let updateVisualElementFocus oldValueOpt (newValueOpt: MsgValueEventData voption) (node: IViewNode) = + let target = node.Target :?> VisualElement + + let onEventName = "Focus_On" + let offEventName = "Focus_Off" + + match newValueOpt with + | ValueNone -> + // The attribute is no longer applied, so we clean up the events + match node.TryGetHandler(onEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match node.TryGetHandler(offEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Only clear the property if a value was set before + match oldValueOpt with + | ValueNone -> () + | ValueSome _ -> + if target.IsFocused then + target.Unfocus() + + | ValueSome curr -> + // Clean up the old event handlers if any + match node.TryGetHandler(onEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match node.TryGetHandler(offEventName) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + // Set the new value + if target.IsFocused <> curr.Value then + if curr.Value then + target.Focus() |> ignore + else + target.Unfocus() + + // Set the new event handlers + let onHandler = + target.Focused.Subscribe(fun _args -> + let (MsgValue r) = curr.Event true + Dispatcher.dispatch node r) + + node.SetHandler(onEventName, onHandler) + + let offHandler = + target.Unfocused.Subscribe(fun _args -> + let (MsgValue r) = curr.Event false + Dispatcher.dispatch node r) + + node.SetHandler(offEventName, offHandler) + +module VisualElementMvu = + let FocusWithEvent = + Attributes.defineSimpleScalar "VisualElementMvu_FocusWithEvent" ScalarAttributeComparers.noCompare VisualElementMvuUpdaters.updateVisualElementFocus + +[] +type VisualElementMvuModifiers = + /// Set the current focus state of the widget, and listen to focus state changes + /// Current widget + /// The focus state to apply + /// Message to dispatch when the widget's focus state changes + [] + static member inline focus<'msg, 'marker when 'msg: equality and 'marker :> IFabVisualElement> + ( + this: WidgetBuilder<'msg, 'marker>, + value: bool, + onFocusChanged: bool -> 'msg + ) = + this.AddScalar(VisualElementMvu.FocusWithEvent.WithValue(MsgValueEventData.create value onFocusChanged)) diff --git a/src/Fabulous.MauiControls/Views/_VisualElement.fs b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.fs similarity index 80% rename from src/Fabulous.MauiControls/Views/_VisualElement.fs rename to src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.fs index acbe997..4bb9b0a 100644 --- a/src/Fabulous.MauiControls/Views/_VisualElement.fs +++ b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.fs @@ -33,113 +33,6 @@ type RotateToData = AnimationDuration: uint32 Easing: Easing } -module VisualElementUpdaters = - let updateVisualElementFocusFn oldValueOpt (newValueOpt: ValueEventData voption) (node: IViewNode) = - let target = node.Target :?> VisualElement - - let onEventName = "Focus_On" - let offEventName = "Focus_Off" - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the events - match node.TryGetHandler(onEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match node.TryGetHandler(offEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> - if target.IsFocused then - target.Unfocus() - - | ValueSome curr -> - // Clean up the old event handlers if any - match node.TryGetHandler(onEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match node.TryGetHandler(offEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - if target.IsFocused <> curr.Value then - if curr.Value then - target.Focus() |> ignore - else - target.Unfocus() - - // Set the new event handlers - let onHandler = target.Focused.Subscribe(fun _args -> curr.Event true) - - node.SetHandler(onEventName, onHandler) - - let offHandler = target.Unfocused.Subscribe(fun _args -> curr.Event false) - - node.SetHandler(offEventName, offHandler) - - let updateVisualElementFocusMsg oldValueOpt (newValueOpt: MsgValueEventData voption) (node: IViewNode) = - let target = node.Target :?> VisualElement - - let onEventName = "Focus_On" - let offEventName = "Focus_Off" - - match newValueOpt with - | ValueNone -> - // The attribute is no longer applied, so we clean up the events - match node.TryGetHandler(onEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match node.TryGetHandler(offEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Only clear the property if a value was set before - match oldValueOpt with - | ValueNone -> () - | ValueSome _ -> - if target.IsFocused then - target.Unfocus() - - | ValueSome curr -> - // Clean up the old event handlers if any - match node.TryGetHandler(onEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match node.TryGetHandler(offEventName) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - // Set the new value - if target.IsFocused <> curr.Value then - if curr.Value then - target.Focus() |> ignore - else - target.Unfocus() - - // Set the new event handlers - let onHandler = - target.Focused.Subscribe(fun _args -> - let (MsgValue r) = curr.Event true - Dispatcher.dispatch node r) - - node.SetHandler(onEventName, onHandler) - - let offHandler = - target.Unfocused.Subscribe(fun _args -> - let (MsgValue r) = curr.Event false - Dispatcher.dispatch node r) - - node.SetHandler(offEventName, offHandler) - module VisualElement = let AnchorX = Attributes.defineBindableFloat VisualElement.AnchorXProperty @@ -156,12 +49,6 @@ module VisualElement = let FlowDirection = Attributes.defineBindableEnum VisualElement.FlowDirectionProperty - let FocusWithEventMsg = - Attributes.defineSimpleScalar "VisualElement_FocusWithEventMsg" ScalarAttributeComparers.noCompare VisualElementUpdaters.updateVisualElementFocusMsg - - let FocusWithEventFn = - Attributes.defineSimpleScalar "VisualElement_FocusWithEventFn" ScalarAttributeComparers.noCompare VisualElementUpdaters.updateVisualElementFocusFn - let HeightRequest = Attributes.defineBindableFloat VisualElement.HeightRequestProperty @@ -305,27 +192,6 @@ type VisualElementModifiers = static member inline clip(this: WidgetBuilder<'msg, #IFabVisualElement>, content: WidgetBuilder<'msg, #IFabGeometry>) = this.AddWidget(VisualElement.Clip.WithValue(content.Compile())) - /// Set the current focus state of the widget, and listen to focus state changes - /// Current widget - /// The focus state to apply - /// Message to dispatch when the widget's focus state changes - [] - static member inline focus<'msg, 'marker when 'msg: equality and 'marker :> IFabVisualElement> - ( - this: WidgetBuilder<'msg, 'marker>, - value: bool, - onFocusChanged: bool -> 'msg - ) = - this.AddScalar(VisualElement.FocusWithEventMsg.WithValue(MsgValueEventData.create value onFocusChanged)) - - /// Set the current focus state of the widget, and listen to focus state changes - /// Current widget - /// The focus state to apply - /// Message to dispatch when the widget's focus state changes - [] - static member inline focus(this: WidgetBuilder<'msg, #IFabVisualElement>, value: bool, onFocusChanged: bool -> unit) = - this.AddScalar(VisualElement.FocusWithEventFn.WithValue(ValueEventData.create value onFocusChanged)) - /// Set the layout flow direction /// Current widget /// The layout flow direction From cbb5f356f6c72a6dc730d637000d0b12b77faac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Larivi=C3=A8re?= Date: Thu, 14 Nov 2024 11:02:35 +0100 Subject: [PATCH 2/6] Upgrade to .NET 9.0 --- samples/Calculator/Calculator.fsproj | 8 ++++---- samples/Components/HelloComponent/HelloComponent.fsproj | 6 +++--- samples/Components/MultipleMvus/MultipleMvus.fsproj | 8 ++++---- samples/Components/MvuCounter/MvuCounter.fsproj | 8 ++++---- samples/Components/SimpleCounter/SimpleCounter.fsproj | 8 ++++---- samples/Components/TicTacComponent/TicTacComponent.fsproj | 8 ++++---- samples/CounterApp/CounterApp.fsproj | 8 ++++---- samples/Gallery/Gallery.fsproj | 4 ++-- samples/HelloWorld/HelloWorld.fsproj | 6 +++--- samples/Navigation/BasicNavigation/BasicNavigation.fsproj | 6 +++--- .../ComponentNavigation/ComponentNavigation.fsproj | 6 +++--- samples/Navigation/NavigationPath/NavigationPath.fsproj | 6 +++--- samples/Playground/Playground.fsproj | 8 ++++---- samples/TicTacToe/TicTacToe.fsproj | 8 ++++---- 14 files changed, 49 insertions(+), 49 deletions(-) diff --git a/samples/Calculator/Calculator.fsproj b/samples/Calculator/Calculator.fsproj index b65d65d..017abd1 100644 --- a/samples/Calculator/Calculator.fsproj +++ b/samples/Calculator/Calculator.fsproj @@ -1,10 +1,10 @@ - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe TicTacToe true @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Components/HelloComponent/HelloComponent.fsproj b/samples/Components/HelloComponent/HelloComponent.fsproj index 54216b6..94653a7 100644 --- a/samples/Components/HelloComponent/HelloComponent.fsproj +++ b/samples/Components/HelloComponent/HelloComponent.fsproj @@ -1,9 +1,9 @@ - net8.0-ios;net8.0-android;net8.0-maccatalyst + net9.0-ios;net9.0-android;net9.0-maccatalyst - + Exe true true @@ -23,7 +23,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Components/MultipleMvus/MultipleMvus.fsproj b/samples/Components/MultipleMvus/MultipleMvus.fsproj index 7b442f6..bea0649 100644 --- a/samples/Components/MultipleMvus/MultipleMvus.fsproj +++ b/samples/Components/MultipleMvus/MultipleMvus.fsproj @@ -1,10 +1,10 @@  - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe true true @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Components/MvuCounter/MvuCounter.fsproj b/samples/Components/MvuCounter/MvuCounter.fsproj index 34d982a..540851d 100644 --- a/samples/Components/MvuCounter/MvuCounter.fsproj +++ b/samples/Components/MvuCounter/MvuCounter.fsproj @@ -1,10 +1,10 @@  - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe true true @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Components/SimpleCounter/SimpleCounter.fsproj b/samples/Components/SimpleCounter/SimpleCounter.fsproj index bf08f8c..d4354c3 100644 --- a/samples/Components/SimpleCounter/SimpleCounter.fsproj +++ b/samples/Components/SimpleCounter/SimpleCounter.fsproj @@ -1,10 +1,10 @@  - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe true true @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Components/TicTacComponent/TicTacComponent.fsproj b/samples/Components/TicTacComponent/TicTacComponent.fsproj index 7096682..aa6ddef 100644 --- a/samples/Components/TicTacComponent/TicTacComponent.fsproj +++ b/samples/Components/TicTacComponent/TicTacComponent.fsproj @@ -1,10 +1,10 @@  - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe TicTacToe true @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/CounterApp/CounterApp.fsproj b/samples/CounterApp/CounterApp.fsproj index 771fad4..bc00d0c 100644 --- a/samples/CounterApp/CounterApp.fsproj +++ b/samples/CounterApp/CounterApp.fsproj @@ -1,10 +1,10 @@  - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe CounterApp true @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Gallery/Gallery.fsproj b/samples/Gallery/Gallery.fsproj index fc2d218..e8101a0 100644 --- a/samples/Gallery/Gallery.fsproj +++ b/samples/Gallery/Gallery.fsproj @@ -1,6 +1,6 @@ - net8.0-ios + net9.0-ios Exe true true @@ -20,7 +20,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/HelloWorld/HelloWorld.fsproj b/samples/HelloWorld/HelloWorld.fsproj index 297ba7d..6459c48 100644 --- a/samples/HelloWorld/HelloWorld.fsproj +++ b/samples/HelloWorld/HelloWorld.fsproj @@ -1,9 +1,9 @@ - net8.0-ios;net8.0-android;net8.0-maccatalyst + net9.0-ios;net9.0-android;net9.0-maccatalyst - + Exe HelloWorld true @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Navigation/BasicNavigation/BasicNavigation.fsproj b/samples/Navigation/BasicNavigation/BasicNavigation.fsproj index 3fd59ae..87e4bdf 100644 --- a/samples/Navigation/BasicNavigation/BasicNavigation.fsproj +++ b/samples/Navigation/BasicNavigation/BasicNavigation.fsproj @@ -1,8 +1,8 @@ - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 Exe @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj b/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj index 7d26527..28b5755 100644 --- a/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj +++ b/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj @@ -1,8 +1,8 @@ - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 Exe @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Navigation/NavigationPath/NavigationPath.fsproj b/samples/Navigation/NavigationPath/NavigationPath.fsproj index 603c0a9..61fabbe 100644 --- a/samples/Navigation/NavigationPath/NavigationPath.fsproj +++ b/samples/Navigation/NavigationPath/NavigationPath.fsproj @@ -1,8 +1,8 @@ - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 Exe @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/Playground/Playground.fsproj b/samples/Playground/Playground.fsproj index 5008bfe..86c3494 100644 --- a/samples/Playground/Playground.fsproj +++ b/samples/Playground/Playground.fsproj @@ -1,10 +1,10 @@  - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe Playground true @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 diff --git a/samples/TicTacToe/TicTacToe.fsproj b/samples/TicTacToe/TicTacToe.fsproj index 8321c10..717eef2 100644 --- a/samples/TicTacToe/TicTacToe.fsproj +++ b/samples/TicTacToe/TicTacToe.fsproj @@ -1,10 +1,10 @@  - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe TicTacToe true @@ -25,7 +25,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) 14.2 - 14.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 From 408336f269d2e2726e302e97e61b7349775665ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Larivi=C3=A8re?= Date: Thu, 14 Nov 2024 12:22:08 +0100 Subject: [PATCH 3/6] Add support for HybridWebView and TitleBar --- samples/Calculator/App.fs | 84 ++++++------- samples/Calculator/Calculator.fsproj | 2 +- .../HelloComponent/HelloComponent.fsproj | 2 +- samples/Components/MultipleMvus/App.fs | 50 ++++---- .../MultipleMvus/MultipleMvus.fsproj | 2 +- samples/Components/MvuCounter/App.fs | 38 +++--- .../Components/MvuCounter/MvuCounter.fsproj | 2 +- samples/Components/SimpleCounter/App.fs | 30 ++--- .../SimpleCounter/SimpleCounter.fsproj | 2 +- samples/Components/TicTacComponent/App.fs | 114 +++++++++--------- .../TicTacComponent/TicTacComponent.fsproj | 2 +- samples/CounterApp/App.fs | 40 +++--- samples/CounterApp/CounterApp.fsproj | 2 +- samples/Gallery/App.fs | 38 +++--- samples/Gallery/Gallery.fsproj | 2 +- samples/HelloWorld/App.fs | 6 +- samples/HelloWorld/HelloWorld.fsproj | 2 +- .../BasicNavigation/BasicNavigation.fsproj | 2 +- samples/Navigation/BasicNavigation/Sample.fs | 34 +++--- .../ComponentNavigation.fsproj | 2 +- .../Navigation/ComponentNavigation/Sample.fs | 24 ++-- .../NavigationPath/NavigationPath.fsproj | 2 +- samples/Navigation/NavigationPath/Sample.fs | 26 ++-- samples/Playground/App.fs | 8 +- samples/Playground/Playground.fsproj | 2 +- samples/TicTacToe/App.fs | 114 +++++++++--------- samples/TicTacToe/TicTacToe.fsproj | 2 +- .../Fabulous.MauiControls.Tests.fsproj | 2 +- .../Fabulous.MauiControls.fsproj | 15 ++- .../Views/Application/Application.fs | 9 -- .../HybridWebView/HybridWebView.Component.fs | 17 +++ .../HybridWebView/HybridWebView.Mvu.fs | 17 +++ .../Controls/HybridWebView/HybridWebView.fs | 33 +++++ .../TimePicker/TimePicker.Component.fs | 4 +- .../Controls/TimePicker/TimePicker.Mvu.fs | 4 +- .../Views/Controls/TimePicker/TimePicker.fs | 21 +--- .../Controls/WebView/WebView.Component.fs | 9 ++ .../Views/Controls/WebView/WebView.Mvu.fs | 9 ++ .../Views/Controls/WebView/WebView.fs | 10 ++ .../PointerGestureRecognizer.Component.fs | 37 ++++++ .../PointerGestureRecognizer.Mvu.fs | 37 ++++++ .../PointerGestureRecognizer.fs | 27 +++++ .../Views/Layouts/TitleBar.fs | 83 +++++++++++++ .../Views/Pages/ContentPage/ContentPage.fs | 9 ++ 44 files changed, 635 insertions(+), 342 deletions(-) create mode 100644 src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs create mode 100644 src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs create mode 100644 src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs diff --git a/samples/Calculator/App.fs b/samples/Calculator/App.fs index 8fa7b40..9ad7b74 100644 --- a/samples/Calculator/App.fs +++ b/samples/Calculator/App.fs @@ -106,47 +106,49 @@ module App = .background(orange) .textColor(Colors.Black) - Application( - ContentPage( - (Grid(rowdefs = [ Star; Star; Star; Star; Star; Star ], coldefs = [ Star; Star; Star; Star ]) { - View - .Label(display model) - .font(size = 48.0, attributes = FontAttributes.Bold) - .background(Colors.Black) - .textColor(Colors.White) - .alignEndTextHorizontal() - .centerTextVertical() - .gridColumnSpan(4) - - mkNumberButton 7 1 0 - mkNumberButton 8 1 1 - mkNumberButton 9 1 2 - mkNumberButton 4 2 0 - mkNumberButton 5 2 1 - mkNumberButton 6 2 2 - mkNumberButton 1 3 0 - mkNumberButton 2 3 1 - mkNumberButton 3 3 2 - - (mkNumberButton 0 4 0).gridColumnSpan(3) - - mkOperatorButton "÷" Divide 1 3 - mkOperatorButton "×" Multiply 2 3 - mkOperatorButton "-" Subtract 3 3 - mkOperatorButton "+" Add 4 3 - (mkButton "A" Clear 5 0).background(gray).textColor(Colors.White) - (mkButton "." Equals 5 1).background(orange).textColor(Colors.Black) - - (mkButton "=" Equals 5 2) - .background(orange) - .gridColumnSpan(2) - .textColor(Colors.White) - }) - .rowSpacing(1.0) - .columnSpacing(1.0) - .background(gray) - ) - ) + Application() { + Window() { + ContentPage( + (Grid(rowdefs = [ Star; Star; Star; Star; Star; Star ], coldefs = [ Star; Star; Star; Star ]) { + View + .Label(display model) + .font(size = 48.0, attributes = FontAttributes.Bold) + .background(Colors.Black) + .textColor(Colors.White) + .alignEndTextHorizontal() + .centerTextVertical() + .gridColumnSpan(4) + + mkNumberButton 7 1 0 + mkNumberButton 8 1 1 + mkNumberButton 9 1 2 + mkNumberButton 4 2 0 + mkNumberButton 5 2 1 + mkNumberButton 6 2 2 + mkNumberButton 1 3 0 + mkNumberButton 2 3 1 + mkNumberButton 3 3 2 + + (mkNumberButton 0 4 0).gridColumnSpan(3) + + mkOperatorButton "÷" Divide 1 3 + mkOperatorButton "×" Multiply 2 3 + mkOperatorButton "-" Subtract 3 3 + mkOperatorButton "+" Add 4 3 + (mkButton "A" Clear 5 0).background(gray).textColor(Colors.White) + (mkButton "." Equals 5 1).background(orange).textColor(Colors.Black) + + (mkButton "=" Equals 5 2) + .background(orange) + .gridColumnSpan(2) + .textColor(Colors.White) + }) + .rowSpacing(1.0) + .columnSpacing(1.0) + .background(gray) + ) + } + } let program = Program.stateful (fun () -> Initial) update diff --git a/samples/Calculator/Calculator.fsproj b/samples/Calculator/Calculator.fsproj index 017abd1..1028124 100644 --- a/samples/Calculator/Calculator.fsproj +++ b/samples/Calculator/Calculator.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Components/HelloComponent/HelloComponent.fsproj b/samples/Components/HelloComponent/HelloComponent.fsproj index 94653a7..13e8d2e 100644 --- a/samples/Components/HelloComponent/HelloComponent.fsproj +++ b/samples/Components/HelloComponent/HelloComponent.fsproj @@ -22,7 +22,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Components/MultipleMvus/App.fs b/samples/Components/MultipleMvus/App.fs index ac64e45..1dab467 100644 --- a/samples/Components/MultipleMvus/App.fs +++ b/samples/Components/MultipleMvus/App.fs @@ -39,32 +39,34 @@ module Form = module App = let view () = - Application( - ContentPage() { - (VStack(spacing = 25.) { - Label("App") - - Component("Counter") { - let! model = Context.Mvu(Counter.program) - - VStack() { - Label($"Count = {model.Count}") - Button("Increment", Counter.Increment) - Button("Decrement", Counter.Decrement) + Application() { + Window() { + ContentPage() { + (VStack(spacing = 25.) { + Label("App") + + Component("Counter") { + let! model = Context.Mvu(Counter.program) + + VStack() { + Label($"Count = {model.Count}") + Button("Increment", Counter.Increment) + Button("Decrement", Counter.Decrement) + } } - } - Component("Form") { - let! model = Context.Mvu(Form.program) + Component("Form") { + let! model = Context.Mvu(Form.program) - VStack() { - Label($"Hello {model.FirstName} {model.LastName}") - Entry(model.FirstName, Form.FirstNameChanged) - Entry(model.LastName, Form.LastNameChanged) + VStack() { + Label($"Hello {model.FirstName} {model.LastName}") + Entry(model.FirstName, Form.FirstNameChanged) + Entry(model.LastName, Form.LastNameChanged) + } } - } - }) - .width(250.) - .center() + }) + .width(250.) + .center() + } } - ) + } diff --git a/samples/Components/MultipleMvus/MultipleMvus.fsproj b/samples/Components/MultipleMvus/MultipleMvus.fsproj index bea0649..76bb2a0 100644 --- a/samples/Components/MultipleMvus/MultipleMvus.fsproj +++ b/samples/Components/MultipleMvus/MultipleMvus.fsproj @@ -23,7 +23,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Components/MvuCounter/App.fs b/samples/Components/MvuCounter/App.fs index 1599271..66ba2e2 100644 --- a/samples/Components/MvuCounter/App.fs +++ b/samples/Components/MvuCounter/App.fs @@ -55,30 +55,32 @@ module App = Component("Counter") { let! model = Context.Mvu(program) - Application( - ContentPage() { - (VStack() { - Label($"%d{model.Count}").centerTextHorizontal() + Application() { + Window() { + ContentPage() { + (VStack() { + Label($"%d{model.Count}").centerTextHorizontal() - Button("Increment", Increment) + Button("Increment", Increment) - Button("Decrement", Decrement) + Button("Decrement", Decrement) - (HStack() { - Label("Timer") + (HStack() { + Label("Timer") - Switch(model.TimerOn, TimerToggled) - }) - .padding(20.) - .centerHorizontal() + Switch(model.TimerOn, TimerToggled) + }) + .padding(20.) + .centerHorizontal() - Slider(0.0, 10.0, double model.Step, SetStep) + Slider(0.0, 10.0, double model.Step, SetStep) - Label($"Step size: %d{model.Step}").centerTextHorizontal() + Label($"Step size: %d{model.Step}").centerTextHorizontal() - Button("Reset", Reset) - }) - .center() + Button("Reset", Reset) + }) + .center() + } } - ) + } } diff --git a/samples/Components/MvuCounter/MvuCounter.fsproj b/samples/Components/MvuCounter/MvuCounter.fsproj index 540851d..898db20 100644 --- a/samples/Components/MvuCounter/MvuCounter.fsproj +++ b/samples/Components/MvuCounter/MvuCounter.fsproj @@ -23,7 +23,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Components/SimpleCounter/App.fs b/samples/Components/SimpleCounter/App.fs index 3a3d4e8..7fd37e4 100644 --- a/samples/Components/SimpleCounter/App.fs +++ b/samples/Components/SimpleCounter/App.fs @@ -36,20 +36,22 @@ module App = let! theme = Context.Environment(EnvironmentKeys.Theme) let! model = Context.Mvu(program) - Application( - ContentPage( - (VStack() { - Label("Theme is: " + theme.ToString()).centerTextHorizontal() - Label($"%d{model}").centerTextHorizontal() - Button("Increment", Increment) - Button("Decrement", Decrement) - Child.view "Child 1" - Child.view "Child 2" - Child.view "Child 3" - }) - .center() - ) - ) + (Application() { + Window() { + ContentPage( + (VStack() { + Label("Theme is: " + theme.ToString()).centerTextHorizontal() + Label($"%d{model}").centerTextHorizontal() + Button("Increment", Increment) + Button("Decrement", Decrement) + Child.view "Child 1" + Child.view "Child 2" + Child.view "Child 3" + }) + .center() + ) + } + }) .environment(EnvironmentKeys.Count, model) } diff --git a/samples/Components/SimpleCounter/SimpleCounter.fsproj b/samples/Components/SimpleCounter/SimpleCounter.fsproj index d4354c3..814a57f 100644 --- a/samples/Components/SimpleCounter/SimpleCounter.fsproj +++ b/samples/Components/SimpleCounter/SimpleCounter.fsproj @@ -23,7 +23,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Components/TicTacComponent/App.fs b/samples/Components/TicTacComponent/App.fs index f196646..8568267 100644 --- a/samples/Components/TicTacComponent/App.fs +++ b/samples/Components/TicTacComponent/App.fs @@ -205,63 +205,65 @@ module App = Component("TicTacToe") { let! model = Context.Mvu(program) - Application( - ContentPage( - Grid(coldefs = [ Star ], rowdefs = [ Star; Auto; Auto ]) { - (Grid(coldefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ], rowdefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ]) { - - let gridColor = - match model.Theme with - | AppTheme.Dark -> Controls.SolidColorBrush(Colors.White) - | _ -> Controls.SolidColorBrush(Colors.Black) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(1).gridColumnSpan(5) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(3).gridColumnSpan(5) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(1).gridRowSpan(5) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(3).gridRowSpan(5) - - for row, col as pos in positions do - if canPlay model model.Board[pos] then - Button("", Play pos) - .background(Colors.LightBlue) - .gridRow(row * 2) - .gridColumn(col * 2) - else - match model.Board[pos] with - | Empty -> () - | Full X -> - Label("X") - .font(size = model.VisualBoardSize / 3.) - .centerText() - .margin(10.) - .gridRow(row * 2) - .gridColumn(col * 2) + Application() { + Window() { + ContentPage( + Grid(coldefs = [ Star ], rowdefs = [ Star; Auto; Auto ]) { + (Grid(coldefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ], rowdefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ]) { + + let gridColor = + match model.Theme with + | AppTheme.Dark -> Controls.SolidColorBrush(Colors.White) + | _ -> Controls.SolidColorBrush(Colors.Black) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(1).gridColumnSpan(5) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(3).gridColumnSpan(5) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(1).gridRowSpan(5) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(3).gridRowSpan(5) - | Full O -> - Label("O") - .font(size = model.VisualBoardSize / 3.) - .centerText() - .margin(10.) + for row, col as pos in positions do + if canPlay model model.Board[pos] then + Button("", Play pos) + .background(Colors.LightBlue) .gridRow(row * 2) .gridColumn(col * 2) - }) - .rowSpacing(0.) - .columnSpacing(0.) - .centerVertical() - .size(model.VisualBoardSize, model.VisualBoardSize) - .gridRow(0) - - Label(getMessage model).font(size = 32.).center().margin(10.).gridRow(1) - - Button("Restart game", Restart) - .textColor(Colors.Black) - .background(Colors.LightBlue) - .font(size = 32.) - .gridRow(2) - } - ) - ) + else + match model.Board[pos] with + | Empty -> () + | Full X -> + Label("X") + .font(size = model.VisualBoardSize / 3.) + .centerText() + .margin(10.) + .gridRow(row * 2) + .gridColumn(col * 2) + + | Full O -> + Label("O") + .font(size = model.VisualBoardSize / 3.) + .centerText() + .margin(10.) + .gridRow(row * 2) + .gridColumn(col * 2) + }) + .rowSpacing(0.) + .columnSpacing(0.) + .centerVertical() + .size(model.VisualBoardSize, model.VisualBoardSize) + .gridRow(0) + + Label(getMessage model).font(size = 32.).center().margin(10.).gridRow(1) + + Button("Restart game", Restart) + .textColor(Colors.Black) + .background(Colors.LightBlue) + .font(size = 32.) + .gridRow(2) + } + ) + } + } } diff --git a/samples/Components/TicTacComponent/TicTacComponent.fsproj b/samples/Components/TicTacComponent/TicTacComponent.fsproj index aa6ddef..e212a8e 100644 --- a/samples/Components/TicTacComponent/TicTacComponent.fsproj +++ b/samples/Components/TicTacComponent/TicTacComponent.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/CounterApp/App.fs b/samples/CounterApp/App.fs index 2a3cf7c..79b10b5 100644 --- a/samples/CounterApp/App.fs +++ b/samples/CounterApp/App.fs @@ -50,31 +50,33 @@ module App = model, Cmd.none let view model = - Application( - ContentPage( - (VStack() { - Label($"%d{model.Count}").centerTextHorizontal() + Application() { + Window() { + ContentPage( + (VStack() { + Label($"%d{model.Count}").centerTextHorizontal() - Button("Increment", Increment) + Button("Increment", Increment) - Button("Decrement", Decrement) + Button("Decrement", Decrement) - (HStack() { - Label("Timer") + (HStack() { + Label("Timer") - Switch(model.TimerOn, TimerToggled) - }) - .padding(20.) - .centerHorizontal() + Switch(model.TimerOn, TimerToggled) + }) + .padding(20.) + .centerHorizontal() - Slider(0.0, 10.0, double model.Step, SetStep) + Slider(0.0, 10.0, double model.Step, SetStep) - Label($"Step size: %d{model.Step}").centerTextHorizontal() + Label($"Step size: %d{model.Step}").centerTextHorizontal() - Button("Reset", Reset) - }) - .center() - ) - ) + Button("Reset", Reset) + }) + .center() + ) + } + } let program = Program.statefulWithCmd init update |> Program.withView view diff --git a/samples/CounterApp/CounterApp.fsproj b/samples/CounterApp/CounterApp.fsproj index bc00d0c..24ff773 100644 --- a/samples/CounterApp/CounterApp.fsproj +++ b/samples/CounterApp/CounterApp.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Gallery/App.fs b/samples/Gallery/App.fs index 42b42fc..1b2aa40 100644 --- a/samples/Gallery/App.fs +++ b/samples/Gallery/App.fs @@ -40,24 +40,26 @@ module App = | GoBack -> { Paths = List.tail model.Paths } let view model = - Application( - TabbedPage() { - ContentPage( - match List.head model.Paths with - | Overview -> AnyView(Overview.view GoToSample) - | Sample(index, sampleModel) -> AnyView(SamplePage.view GoBack SampleMsg index sampleModel) - ) - .title("Samples") - - ContentPage( - VStack() { - Label("Fabulous.Maui Gallery") - .horizontalOptions(LayoutOptions.Center) - .verticalOptions(LayoutOptions.Center) - } - ) - .title("Info") + Application() { + Window() { + TabbedPage() { + ContentPage( + match List.head model.Paths with + | Overview -> AnyView(Overview.view GoToSample) + | Sample(index, sampleModel) -> AnyView(SamplePage.view GoBack SampleMsg index sampleModel) + ) + .title("Samples") + + ContentPage( + VStack() { + Label("Fabulous.Maui Gallery") + .horizontalOptions(LayoutOptions.Center) + .verticalOptions(LayoutOptions.Center) + } + ) + .title("Info") + } } - ) + } let program = Program.stateful init update |> Program.withView view diff --git a/samples/Gallery/Gallery.fsproj b/samples/Gallery/Gallery.fsproj index e8101a0..36e0799 100644 --- a/samples/Gallery/Gallery.fsproj +++ b/samples/Gallery/Gallery.fsproj @@ -19,7 +19,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/HelloWorld/App.fs b/samples/HelloWorld/App.fs index 33d2056..abad0f3 100644 --- a/samples/HelloWorld/App.fs +++ b/samples/HelloWorld/App.fs @@ -7,7 +7,11 @@ open type Fabulous.Maui.View module App = let view () = - Application(ContentPage(Label("Hello World").center())) + Application() { + Window() { + ContentPage(Label("Hello World").center()) + } + } type MauiProgram = static member CreateMauiApp() = diff --git a/samples/HelloWorld/HelloWorld.fsproj b/samples/HelloWorld/HelloWorld.fsproj index 6459c48..c214826 100644 --- a/samples/HelloWorld/HelloWorld.fsproj +++ b/samples/HelloWorld/HelloWorld.fsproj @@ -23,7 +23,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Navigation/BasicNavigation/BasicNavigation.fsproj b/samples/Navigation/BasicNavigation/BasicNavigation.fsproj index 87e4bdf..ff47ca6 100644 --- a/samples/Navigation/BasicNavigation/BasicNavigation.fsproj +++ b/samples/Navigation/BasicNavigation/BasicNavigation.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Navigation/BasicNavigation/Sample.fs b/samples/Navigation/BasicNavigation/Sample.fs index 7cb29de..4d3d452 100644 --- a/samples/Navigation/BasicNavigation/Sample.fs +++ b/samples/Navigation/BasicNavigation/Sample.fs @@ -56,25 +56,27 @@ module Sample = | GoToPageC -> { model with CurrentStep = Step.PageC } let view model = - Application( - ContentPage( - (Grid(coldefs = [ Star; Star; Star ], rowdefs = [ Auto; Star ]) { - Button("Page A", GoToPageA).gridColumn(0) + Application() { + Window() { + ContentPage( + (Grid(coldefs = [ Star; Star; Star ], rowdefs = [ Auto; Star ]) { + Button("Page A", GoToPageA).gridColumn(0) - Button("Page B", GoToPageB).gridColumn(1) + Button("Page B", GoToPageB).gridColumn(1) - Button("Page C", GoToPageC).gridColumn(2) + Button("Page C", GoToPageC).gridColumn(2) - (match model.CurrentStep with - | Step.PageA -> View.map PageAMsg (PageA.view model.PageAModel) - | Step.PageB -> View.map PageBMsg (PageB.view model.PageBModel) - | Step.PageC -> View.map PageCMsg (PageC.view model.PageCModel)) - .gridRow(1) - .gridColumnSpan(3) - }) - .rowSpacing(30.) - ) - ) + (match model.CurrentStep with + | Step.PageA -> View.map PageAMsg (PageA.view model.PageAModel) + | Step.PageB -> View.map PageBMsg (PageB.view model.PageBModel) + | Step.PageC -> View.map PageCMsg (PageC.view model.PageCModel)) + .gridRow(1) + .gridColumnSpan(3) + }) + .rowSpacing(30.) + ) + } + } let program = Program.stateful init update |> Program.withView view diff --git a/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj b/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj index 28b5755..0f1bd74 100644 --- a/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj +++ b/samples/Navigation/ComponentNavigation/ComponentNavigation.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Navigation/ComponentNavigation/Sample.fs b/samples/Navigation/ComponentNavigation/Sample.fs index 912533b..c673a57 100644 --- a/samples/Navigation/ComponentNavigation/Sample.fs +++ b/samples/Navigation/ComponentNavigation/Sample.fs @@ -52,16 +52,18 @@ module Sample = Component("Sample") { let! model = Context.Mvu(program nav appMsgDispatcher) - Application( - (NavigationPage() { - // We inject in the NavigationPage history the back stack of our navigation - for navPath in List.rev model.Navigation.BackStack do - navView nav appMsgDispatcher navPath + Application() { + Window() { + (NavigationPage() { + // We inject in the NavigationPage history the back stack of our navigation + for navPath in List.rev model.Navigation.BackStack do + navView nav appMsgDispatcher navPath - // The page currently displayed is the one on top of the stack - navView nav appMsgDispatcher model.Navigation.CurrentPage - }) - .onBackButtonPressed(BackButtonPressed) - .onBackNavigated(BackNavigationMsg) - ) + // The page currently displayed is the one on top of the stack + navView nav appMsgDispatcher model.Navigation.CurrentPage + }) + .onBackButtonPressed(BackButtonPressed) + .onBackNavigated(BackNavigationMsg) + } + } } diff --git a/samples/Navigation/NavigationPath/NavigationPath.fsproj b/samples/Navigation/NavigationPath/NavigationPath.fsproj index 61fabbe..03accec 100644 --- a/samples/Navigation/NavigationPath/NavigationPath.fsproj +++ b/samples/Navigation/NavigationPath/NavigationPath.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/Navigation/NavigationPath/Sample.fs b/samples/Navigation/NavigationPath/Sample.fs index 23c4bb6..6783b68 100644 --- a/samples/Navigation/NavigationPath/Sample.fs +++ b/samples/Navigation/NavigationPath/Sample.fs @@ -61,17 +61,19 @@ module Sample = /// Because of MVU, all the pages need to return the same Msg type but they all have their own. /// To be able to wrap those Msgs into the app's root Msg type, we use the View.map helper function. let view model = - Application( - (NavigationPage() { - // We inject in the NavigationPage history the back stack of our navigation - for navModel in List.rev model.Navigation.BackStack do - (View.map NavigationMsg (NavigationState.view navModel)).hasBackButton(false) - - // The page currently displayed is the one on top of the stack - (View.map NavigationMsg (NavigationState.view model.Navigation.CurrentPage)) - .hasBackButton(false) - }) - .onBackButtonPressed(BackButtonPressed) - ) + Application() { + Window() { + (NavigationPage() { + // We inject in the NavigationPage history the back stack of our navigation + for navModel in List.rev model.Navigation.BackStack do + (View.map NavigationMsg (NavigationState.view navModel)).hasBackButton(false) + + // The page currently displayed is the one on top of the stack + (View.map NavigationMsg (NavigationState.view model.Navigation.CurrentPage)) + .hasBackButton(false) + }) + .onBackButtonPressed(BackButtonPressed) + } + } let program = Program.statefulWithCmd init update |> Program.withView view diff --git a/samples/Playground/App.fs b/samples/Playground/App.fs index b32209e..76ba707 100644 --- a/samples/Playground/App.fs +++ b/samples/Playground/App.fs @@ -41,7 +41,7 @@ module App = let view model = Application() { - Window( + Window() { ContentPage( (VStack(spacing = 20.) { let text = @@ -68,10 +68,10 @@ module App = }) .margin(20.) ) - ) + } if model.WindowOpened then - Window( + Window() { ContentPage( (VStack(spacing = 20.) { Label("Window opened") @@ -79,7 +79,7 @@ module App = }) .margin(20.) ) - ) + } } let program = Program.stateful init update |> Program.withView view diff --git a/samples/Playground/Playground.fsproj b/samples/Playground/Playground.fsproj index 86c3494..d8776d8 100644 --- a/samples/Playground/Playground.fsproj +++ b/samples/Playground/Playground.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/samples/TicTacToe/App.fs b/samples/TicTacToe/App.fs index 8c4b009..140b13c 100644 --- a/samples/TicTacToe/App.fs +++ b/samples/TicTacToe/App.fs @@ -189,65 +189,67 @@ module App = /// The dynamic 'view' function giving the updated content for the view let view model = - Application( - ContentPage( - Grid(coldefs = [ Star ], rowdefs = [ Star; Auto; Auto ]) { - (Grid(coldefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ], rowdefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ]) { - - let gridColor = - match model.Theme with - | AppTheme.Dark -> Controls.SolidColorBrush(Colors.White) - | _ -> Controls.SolidColorBrush(Colors.Black) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(1).gridColumnSpan(5) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(3).gridColumnSpan(5) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(1).gridRowSpan(5) - - Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(3).gridRowSpan(5) - - for row, col as pos in positions do - if canPlay model model.Board[pos] then - Button("", Play pos) - .background(Colors.LightBlue) - .gridRow(row * 2) - .gridColumn(col * 2) - else - match model.Board[pos] with - | Empty -> () - | Full X -> - Label("X") - .font(size = model.VisualBoardSize / 3.) - .centerText() - .margin(10.) - .gridRow(row * 2) - .gridColumn(col * 2) + Application() { + Window() { + ContentPage( + Grid(coldefs = [ Star ], rowdefs = [ Star; Auto; Auto ]) { + (Grid(coldefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ], rowdefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ]) { + + let gridColor = + match model.Theme with + | AppTheme.Dark -> Controls.SolidColorBrush(Colors.White) + | _ -> Controls.SolidColorBrush(Colors.Black) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(1).gridColumnSpan(5) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridRow(3).gridColumnSpan(5) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(1).gridRowSpan(5) + + Rectangle().stroke(gridColor).strokeThickness(5.).gridColumn(3).gridRowSpan(5) - | Full O -> - Label("O") - .font(size = model.VisualBoardSize / 3.) - .centerText() - .margin(10.) + for row, col as pos in positions do + if canPlay model model.Board[pos] then + Button("", Play pos) + .background(Colors.LightBlue) .gridRow(row * 2) .gridColumn(col * 2) - }) - .rowSpacing(0.) - .columnSpacing(0.) - .centerVertical() - .size(model.VisualBoardSize, model.VisualBoardSize) - .gridRow(0) - - Label(getMessage model).font(size = 32.).center().margin(10.).gridRow(1) - - Button("Restart game", Restart) - .textColor(Colors.Black) - .background(Colors.LightBlue) - .font(size = 32.) - .gridRow(2) - } - ) - ) + else + match model.Board[pos] with + | Empty -> () + | Full X -> + Label("X") + .font(size = model.VisualBoardSize / 3.) + .centerText() + .margin(10.) + .gridRow(row * 2) + .gridColumn(col * 2) + + | Full O -> + Label("O") + .font(size = model.VisualBoardSize / 3.) + .centerText() + .margin(10.) + .gridRow(row * 2) + .gridColumn(col * 2) + }) + .rowSpacing(0.) + .columnSpacing(0.) + .centerVertical() + .size(model.VisualBoardSize, model.VisualBoardSize) + .gridRow(0) + + Label(getMessage model).font(size = 32.).center().margin(10.).gridRow(1) + + Button("Restart game", Restart) + .textColor(Colors.Black) + .background(Colors.LightBlue) + .font(size = 32.) + .gridRow(2) + } + ) + } + } let subscribe _ = let displayInfoChanged dispatch = diff --git a/samples/TicTacToe/TicTacToe.fsproj b/samples/TicTacToe/TicTacToe.fsproj index 717eef2..e41d557 100644 --- a/samples/TicTacToe/TicTacToe.fsproj +++ b/samples/TicTacToe/TicTacToe.fsproj @@ -24,7 +24,7 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 + 15.0 15.0 21.0 10.0.17763.0 diff --git a/src/Fabulous.MauiControls.Tests/Fabulous.MauiControls.Tests.fsproj b/src/Fabulous.MauiControls.Tests/Fabulous.MauiControls.Tests.fsproj index c6e7905..d0da230 100644 --- a/src/Fabulous.MauiControls.Tests/Fabulous.MauiControls.Tests.fsproj +++ b/src/Fabulous.MauiControls.Tests/Fabulous.MauiControls.Tests.fsproj @@ -1,6 +1,6 @@  - net8.0 + net9.0 true Library false diff --git a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj index 1318fd5..9ac8e12 100644 --- a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj +++ b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj @@ -2,7 +2,7 @@ true - net8.0 + net9.0 true true @@ -61,6 +61,9 @@ + + + @@ -156,6 +159,7 @@ + @@ -212,6 +216,9 @@ + + + @@ -243,11 +250,11 @@ FSharp.Core is fixed to a specific version that is not necessarily the latest one. This version will be used as the lower bound in the NuGet package --> - + - - + + diff --git a/src/Fabulous.MauiControls/Views/Application/Application.fs b/src/Fabulous.MauiControls/Views/Application/Application.fs index f4dbea0..6f62a9c 100644 --- a/src/Fabulous.MauiControls/Views/Application/Application.fs +++ b/src/Fabulous.MauiControls/Views/Application/Application.fs @@ -63,10 +63,6 @@ type FabApplication() = module Application = let WidgetKey = Widgets.register() - let MainPage = - Attributes.definePropertyWidget "Application_MainPage" (fun target -> (target :?> Application).MainPage :> obj) (fun target value -> - (target :?> Application).MainPage <- value) - let UserAppTheme = Attributes.defineEnum "Application_UserAppTheme" (fun _ newValueOpt node -> let application = node.Target :?> Application @@ -85,11 +81,6 @@ module Application = module ApplicationBuilders = type Fabulous.Maui.View with - /// Create an Application widget with a main page - /// The main page widget - static member inline Application(mainPage: WidgetBuilder<'msg, #IFabPage>) = - WidgetHelpers.buildWidgets<'msg, IFabApplication> Application.WidgetKey [| Application.MainPage.WithValue(mainPage.Compile()) |] - /// Create an Application widget with a list of windows static member inline Application<'msg, 'itemMarker when 'msg: equality and 'itemMarker :> IFabWindow>() = CollectionBuilder<'msg, IFabApplication, 'itemMarker>(Application.WidgetKey, Application.Windows) diff --git a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs new file mode 100644 index 0000000..cb24a60 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module HybridWebViewComponent = + let RawMessageReceived = Attributes.Component.defineEvent "HybridWebViewComponent_RawMessageReceived" (fun target -> (target :?> HybridWebView).RawMessageReceived) + +[] +type HybridWebViewComponentModifiers = + /// Listen for the RawMessageReceived event + /// Current widget + /// Message to dispatch + [] + static member inline onRawMessageReceived(this: WidgetBuilder, fn: HybridWebViewRawMessageReceivedEventArgs -> unit) = + this.AddScalar(HybridWebViewComponent.RawMessageReceived.WithValue(fn)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs new file mode 100644 index 0000000..105add0 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs @@ -0,0 +1,17 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls + +module HybridWebViewMvu = + let RawMessageReceived = Attributes.Mvu.defineEvent "HybridWebViewMvu_RawMessageReceived" (fun target -> (target :?> HybridWebView).RawMessageReceived) + +[] +type HybridWebViewMvuModifiers = + /// Listen for the RawMessageReceived event + /// Current widget + /// Message to dispatch + [] + static member inline onRawMessageReceived(this: WidgetBuilder<'msg, #IFabHybridWebView>, fn: HybridWebViewRawMessageReceivedEventArgs -> 'msg) = + this.AddScalar(HybridWebViewMvu.RawMessageReceived.WithValue(fn)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs new file mode 100644 index 0000000..05d30ff --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs @@ -0,0 +1,33 @@ +namespace Fabulous.Maui + +open System.Runtime.CompilerServices +open Fabulous +open Fabulous.StackAllocatedCollections.StackList +open Microsoft.Maui.Controls + +type IFabHybridWebView = + inherit IFabView + +module HybridWebView = + let WidgetKey = Widgets.register() + + let DefaultFile = Attributes.defineBindableWithEquality HybridWebView.DefaultFileProperty + + let HybridRoot = Attributes.defineBindableWithEquality HybridWebView.HybridRootProperty + +[] +module HybridWebViewBuilders = + type Fabulous.Maui.View with + static member inline HybridWebView() = + WidgetBuilder<'msg, IFabHybridWebView>(HybridWebView.WidgetKey, AttributesBundle(StackList.empty(), ValueNone, ValueNone)) + +[] +type HybridWebViewModifiers = + [] + static member inline defaultFile(this: WidgetBuilder<'msg, #IFabHybridWebView>, value: string) = + this.AddScalar(HybridWebView.DefaultFile.WithValue(value)) + + [] + static member inline hybridRoot(this: WidgetBuilder<'msg, #IFabHybridWebView>, value: string) = + this.AddScalar(HybridWebView.HybridRoot.WithValue(value)) + diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs index 5233af7..2c9fc24 100644 --- a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs @@ -6,7 +6,7 @@ open Microsoft.Maui.Controls module TimePickerComponent = let TimeWithEvent = - Attributes.Component.defineBindableWithEvent "TimePickerComponent_TimeSelected" TimePicker.TimeProperty (fun target -> (target :?> FabTimePicker).TimeSelected) + Attributes.Component.defineBindableWithEvent "TimePickerComponent_TimeSelected" TimePicker.TimeProperty (fun target -> (target :?> TimePicker).TimeSelected) [] module TimePickerComponentBuilders = @@ -18,5 +18,5 @@ module TimePickerComponentBuilders = static member inline TimePicker(time: TimeSpan, onTimeSelected: TimeSpan -> unit) = WidgetBuilder( TimePicker.WidgetKey, - TimePickerComponent.TimeWithEvent.WithValue(ValueEventData.create time (fun (args: TimeSelectedEventArgs) -> onTimeSelected args.NewTime)) + TimePickerComponent.TimeWithEvent.WithValue(ValueEventData.create time (fun (args: TimeChangedEventArgs) -> onTimeSelected args.NewTime)) ) diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs index d0046e7..4258906 100644 --- a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Mvu.fs @@ -6,7 +6,7 @@ open Microsoft.Maui.Controls module TimePickerMvu = let TimeWithEvent = - Attributes.Mvu.defineBindableWithEvent "TimePickerMvu_TimeSelected" TimePicker.TimeProperty (fun target -> (target :?> FabTimePicker).TimeSelected) + Attributes.Mvu.defineBindableWithEvent "TimePickerMvu_TimeSelected" TimePicker.TimeProperty (fun target -> (target :?> TimePicker).TimeSelected) [] module TimePickerMvuBuilders = @@ -18,5 +18,5 @@ module TimePickerMvuBuilders = static member inline TimePicker(time: TimeSpan, onTimeSelected: TimeSpan -> 'msg) = WidgetBuilder<'msg, IFabTimePicker>( TimePicker.WidgetKey, - TimePickerMvu.TimeWithEvent.WithValue(MsgValueEventData.create time (fun (args: TimeSelectedEventArgs) -> onTimeSelected args.NewTime)) + TimePickerMvu.TimeWithEvent.WithValue(MsgValueEventData.create time (fun (args: TimeChangedEventArgs) -> onTimeSelected args.NewTime)) ) diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs index 5beef25..b5cd8d8 100644 --- a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs @@ -10,27 +10,8 @@ open Microsoft.Maui.Graphics type IFabTimePicker = inherit IFabView -type TimeSelectedEventArgs(newTime: TimeSpan) = - inherit EventArgs() - member _.NewTime = newTime - -/// Microsoft.Maui doesn't provide an event for selecting the time on a TimePicker, so we implement it -type FabTimePicker() = - inherit TimePicker() - - let timeSelected = Event, _>() - - [] - member _.TimeSelected = timeSelected.Publish - - override this.OnPropertyChanged(propertyName) = - base.OnPropertyChanged(propertyName) - - if propertyName = TimePicker.TimeProperty.PropertyName then - timeSelected.Trigger(this, TimeSelectedEventArgs(this.Time)) - module TimePicker = - let WidgetKey = Widgets.register() + let WidgetKey = Widgets.register() let CharacterSpacing = Attributes.defineBindableFloat TimePicker.CharacterSpacingProperty diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs index a8986c6..472f6ff 100644 --- a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs @@ -5,6 +5,8 @@ open Fabulous open Microsoft.Maui.Controls module WebViewComponent = + let ProcessTerminated = Attributes.Component.defineEvent "WebViewComponent_ProcessTerminated" (fun target -> (target :?> WebView).ProcessTerminated) + let Navigated = Attributes.Component.defineEvent "WebViewComponent_Navigated" (fun target -> (target :?> WebView).Navigated) @@ -13,6 +15,13 @@ module WebViewComponent = [] type WebViewComponentModifiers() = + /// Listen for the ProcessTerminated event + /// Current widget + /// Message to dispatch + [] + static member inline onProcessTerminated(this: WidgetBuilder, fn: WebViewProcessTerminatedEventArgs -> unit) = + this.AddScalar(WebViewComponent.ProcessTerminated.WithValue(fn)) + /// Listen for the Navigated event /// Current widget /// Message to dispatch diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs index 40dfe68..4bcb1a8 100644 --- a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs @@ -5,6 +5,8 @@ open Fabulous open Microsoft.Maui.Controls module WebViewMvu = + let ProcessTerminated = Attributes.Mvu.defineEvent "WebViewMvu_ProcessTerminated" (fun target -> (target :?> WebView).ProcessTerminated) + let Navigated = Attributes.Mvu.defineEvent "WebViewMvu_Navigated" (fun target -> (target :?> WebView).Navigated) @@ -13,6 +15,13 @@ module WebViewMvu = [] type WebViewMvuModifiers() = + /// Listen for the ProcessTerminated event + /// Current widget + /// Message to dispatch + [] + static member inline onProcessTerminated(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebViewProcessTerminatedEventArgs -> 'msg) = + this.AddScalar(WebViewMvu.ProcessTerminated.WithValue(fun args -> fn args |> box)) + /// Listen for the Navigated event /// Current widget /// Message to dispatch diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs index 15ee3b1..8c563ee 100644 --- a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs @@ -22,6 +22,9 @@ module WebView = let Source = Attributes.defineBindableWithEquality WebView.SourceProperty + + let UserAgent = + Attributes.defineBindableWithEquality WebView.UserAgentProperty module WebViewPlatform = let DisplayZoomControls = @@ -98,6 +101,13 @@ type WebViewModifiers() = [] static member inline cookies(this: WidgetBuilder<'msg, #IFabWebView>, value: CookieContainer) = this.AddScalar(WebView.Cookies.WithValue(value)) + + /// Set the user agent + /// Current widget + /// The user agent + [] + static member inline userAgent(this: WidgetBuilder<'msg, #IFabWebView>, value: string) = + this.AddScalar(WebView.UserAgent.WithValue(value)) /// Link a ViewRef to access the direct WebView control instance /// Current widget diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs new file mode 100644 index 0000000..0ff3bbf --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs @@ -0,0 +1,37 @@ +namespace Fabulous.Maui + +open Fabulous +open System.Runtime.CompilerServices +open Microsoft.Maui.Controls + +module PointerGestureRecognizerComponent = + let PointerEntered = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerEntered" (fun target -> (target :?> PointerGestureRecognizer).PointerEntered) + + let PointerExited = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerExited" (fun target -> (target :?> PointerGestureRecognizer).PointerExited) + + let PointerMoved = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerMoved" (fun target -> (target :?> PointerGestureRecognizer).PointerMoved) + + let PointerPressed = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerPressed" (fun target -> (target :?> PointerGestureRecognizer).PointerPressed) + + let PointerReleased = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerReleased" (fun target -> (target :?> PointerGestureRecognizer).PointerReleased) + +[] +type PointerGestureRecognizerComponentModifiers = + [] + static member inline onPointerEntered(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerComponent.PointerEntered.WithValue(fn)) + + [] + static member inline onPointerExited(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerComponent.PointerExited.WithValue(fn)) + [] + static member inline onPointerMoved(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerComponent.PointerMoved.WithValue(fn)) + + [] + static member inline onPointerPressed(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerComponent.PointerPressed.WithValue(fn)) + + [] + static member inline onPointerReleased(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerComponent.PointerReleased.WithValue(fn)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs new file mode 100644 index 0000000..49913b0 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs @@ -0,0 +1,37 @@ +namespace Fabulous.Maui + +open Fabulous +open System.Runtime.CompilerServices +open Microsoft.Maui.Controls + +module PointerGestureRecognizerMvu = + let PointerEntered = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerEntered" (fun target -> (target :?> PointerGestureRecognizer).PointerEntered) + + let PointerExited = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerExited" (fun target -> (target :?> PointerGestureRecognizer).PointerExited) + + let PointerMoved = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerMoved" (fun target -> (target :?> PointerGestureRecognizer).PointerMoved) + + let PointerPressed = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerPressed" (fun target -> (target :?> PointerGestureRecognizer).PointerPressed) + + let PointerReleased = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerReleased" (fun target -> (target :?> PointerGestureRecognizer).PointerReleased) + +[] +type PointerGestureRecognizerMvuModifiers = + [] + static member inline onPointerEntered(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerMvu.PointerEntered.WithValue(fn)) + + [] + static member inline onPointerExited(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerMvu.PointerExited.WithValue(fn)) + [] + static member inline onPointerMoved(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerMvu.PointerMoved.WithValue(fn)) + + [] + static member inline onPointerPressed(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerMvu.PointerPressed.WithValue(fn)) + + [] + static member inline onPointerReleased(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = + this.AddScalar(PointerGestureRecognizerMvu.PointerReleased.WithValue(fn)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs new file mode 100644 index 0000000..e6b468f --- /dev/null +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs @@ -0,0 +1,27 @@ +namespace Fabulous.Maui + +open Fabulous +open System.Runtime.CompilerServices +open Fabulous.StackAllocatedCollections.StackList +open Microsoft.Maui.Controls + +type IFabPointerGestureRecognizer = + inherit IFabGestureRecognizer + +module PointerGestureRecognizer = + let WidgetKey = Widgets.register() + +[] +module PointerGestureRecognizerBuilders = + type Fabulous.Maui.View with + static member inline PointerGestureRecognizer() = + WidgetBuilder<'msg, IFabPointerGestureRecognizer>(PointerGestureRecognizer.WidgetKey, AttributesBundle(StackList.empty(), ValueNone, ValueNone)) + +[] +type PointerGestureRecognizerModifiers = + /// Link a ViewRef to access the direct PointerGestureRecognizer control instance + /// Current widget + /// The ViewRef instance that will receive access to the underlying control + [] + static member inline reference(this: WidgetBuilder<'msg, IFabPointerGestureRecognizer>, value: ViewRef) = + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs b/src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs new file mode 100644 index 0000000..fa40a96 --- /dev/null +++ b/src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs @@ -0,0 +1,83 @@ +namespace Fabulous.Maui + +open System +open System.IO +open System.Runtime.CompilerServices +open Fabulous +open Microsoft.Maui.Controls +open Microsoft.Maui.Graphics + +type IFabTitleBar = + inherit IFabTemplatedView + +module TitleBar = + let WidgetKey = Widgets.register() + + let Content = Attributes.defineBindableWidget TitleBar.ContentProperty + + let ForegroundColor = Attributes.defineBindableColor TitleBar.ForegroundColorProperty + + let Icon = Attributes.defineBindableImageSource TitleBar.IconProperty + + let LeadingContent = Attributes.defineBindableWidget TitleBar.LeadingContentProperty + + let Subtitle = Attributes.defineBindableWithEquality TitleBar.SubtitleProperty + + let Title = Attributes.defineBindableWithEquality TitleBar.TitleProperty + + let TrailingContent = Attributes.defineBindableWidget TitleBar.TrailingContentProperty + +[] +module TitleBarBuilders = + type Fabulous.Maui.View with + static member inline TitleBar(icon: ImageSource, title: string) = + WidgetBuilder<'msg, IFabTitleBar>( + TitleBar.WidgetKey, + TitleBar.Icon.WithValue(ImageSourceValue.Source icon), + TitleBar.Title.WithValue(title) + ) + + static member inline TitleBar(icon: string, title: string) = + WidgetBuilder<'msg, IFabTitleBar>( + TitleBar.WidgetKey, + TitleBar.Icon.WithValue(ImageSourceValue.File icon), + TitleBar.Title.WithValue(title) + ) + static member inline TitleBar(icon: Uri, title: string) = + WidgetBuilder<'msg, IFabTitleBar>( + TitleBar.WidgetKey, + TitleBar.Icon.WithValue(ImageSourceValue.Uri icon), + TitleBar.Title.WithValue(title) + ) + static member inline TitleBar(icon: Stream, title: string) = + WidgetBuilder<'msg, IFabTitleBar>( + TitleBar.WidgetKey, + TitleBar.Icon.WithValue(ImageSourceValue.Stream icon), + TitleBar.Title.WithValue(title) + ) + +[] +type TitleBarModifiers = + [] + static member inline content(this: WidgetBuilder<'msg, #IFabTitleBar>, widget: WidgetBuilder<'msg, #IFabView>) = + this.AddWidget(TitleBar.Content.WithValue(widget.Compile())) + + [] + static member inline foregroundColor(this: WidgetBuilder<'msg, #IFabTitleBar>, value: Color) = + this.AddScalar(TitleBar.ForegroundColor.WithValue(value)) + + [] + static member inline leadingContent(this: WidgetBuilder<'msg, #IFabTitleBar>, widget: WidgetBuilder<'msg, #IFabView>) = + this.AddWidget(TitleBar.LeadingContent.WithValue(widget.Compile())) + + [] + static member inline subtitle(this: WidgetBuilder<'msg, #IFabTitleBar>, value: string) = + this.AddScalar(TitleBar.Subtitle.WithValue(value)) + + [] + static member inline title(this: WidgetBuilder<'msg, #IFabTitleBar>, value: string) = + this.AddScalar(TitleBar.Title.WithValue(value)) + + [] + static member inline trailingContent(this: WidgetBuilder<'msg, #IFabTitleBar>, widget: WidgetBuilder<'msg, #IFabView>) = + this.AddWidget(TitleBar.TrailingContent.WithValue(widget.Compile())) diff --git a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs index 19457ba..3810430 100644 --- a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs +++ b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs @@ -30,6 +30,8 @@ module ContentPage = let Content = Attributes.defineBindableWidget ContentPage.ContentProperty + let HideSoftInputOnTapped = Attributes.defineBindableBool ContentPage.HideSoftInputOnTappedProperty + [] module ContentPageBuilders = type Fabulous.Maui.View with @@ -47,6 +49,13 @@ module ContentPageBuilders = [] type ContentPageModifiers = + /// Sets a value that indicates whether tapping anywhere on the page will cause the soft input to hide + /// Current widget + /// true will cause the soft input to hide on tap; false otherwise + [] + static member inline hideSoftInputOnTapped(this: WidgetBuilder<'msg, IFabContentPage>, value: bool) = + this.AddScalar(ContentPage.HideSoftInputOnTapped.WithValue(value)) + /// Link a ViewRef to access the direct ContentPage control instance /// Current widget /// The ViewRef instance that will receive access to the underlying control From 8a471fd96b2f91f61c478a9e25e221d07a8b6b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Larivi=C3=A8re?= Date: Thu, 14 Nov 2024 14:20:40 +0100 Subject: [PATCH 4/6] Bump to 9.0.0 --- CHANGELOG.md | 19 +++++- Directory.Packages.props | 2 +- Fabulous.MauiControls.sln | 6 -- .../Fabulous.MauiControls.fsproj | 2 +- .../blank/.template.config/template.json | 6 +- templates/content/blank/App.fs | 62 ++++++++++--------- templates/content/blank/NewApp.fsproj | 4 +- 7 files changed, 57 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6406d86..383c825 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 _No unreleased changes_ +## [9.0.0-pre1] - 2024-11-14 + +### Added +- Added HybridWebView widget +- Added TitleBar widget +- Added PointerGestureRecognizer widget +- Added hideSoftInputOnTapped modifier on ContentPage widget + +### Changed +- Upgraded to .NET MAUI 9.0.0 +- Upgraded to Fabulous 3.0.0-pre10 +- Removed custom TimeSelected event from TimePicker widget to use the standard TimeSelected event from MAUI + +### Removed +- Removed MainPage support on Application widget + ## [8.1.0-pre21] - 2024-11-08 ### Fixed @@ -260,7 +276,8 @@ Essentially v2.8.1 and v8.0.0 are similar except for the required .NET version. ### Changed - Fabulous.MauiControls has moved from the Fabulous repository to its own repository: [https://github.com/fabulous-dev/Fabulous.MauiControls](https://github.com/fabulous-dev/Fabulous.MauiControls) -[unreleased]: https://github.com/fabulous-dev/Fabulous.MauiControls/compare/8.1.0-pre21...HEAD +[unreleased]: https://github.com/fabulous-dev/Fabulous.MauiControls/compare/9.0.0-pre1...HEAD +[9.0.0-pre1]: https://github.com/fabulous-dev/Fabulous.MauiControls/releases/tag/9.0.0-pre1 [8.1.0-pre21]: https://github.com/fabulous-dev/Fabulous.MauiControls/releases/tag/8.1.0-pre21 [8.1.0-pre20]: https://github.com/fabulous-dev/Fabulous.MauiControls/releases/tag/8.1.0-pre20 [8.1.0-pre19]: https://github.com/fabulous-dev/Fabulous.MauiControls/releases/tag/8.1.0-pre19 diff --git a/Directory.Packages.props b/Directory.Packages.props index 74f2295..13a3c20 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,7 @@ - + diff --git a/Fabulous.MauiControls.sln b/Fabulous.MauiControls.sln index 3b4d4b6..7eeb56e 100644 --- a/Fabulous.MauiControls.sln +++ b/Fabulous.MauiControls.sln @@ -57,8 +57,6 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ComponentNavigation", "samp EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Calculator", "samples\Calculator\Calculator.fsproj", "{E24F96A8-B1FF-45AA-A7D9-379F3F88F422}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabulous", "..\Fabulous\src\Fabulous\Fabulous.fsproj", "{A5D5A010-8A72-4B4F-8266-8D25FD9662B7}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -142,10 +140,6 @@ Global {66532A61-1BB8-4BD1-A281-A160ABB0EFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU {66532A61-1BB8-4BD1-A281-A160ABB0EFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU {66532A61-1BB8-4BD1-A281-A160ABB0EFE7}.Release|Any CPU.Build.0 = Release|Any CPU - {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A5D5A010-8A72-4B4F-8266-8D25FD9662B7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {67FB01A1-1A3E-4A3B-83DC-7D63B56FB1A1} = {35A6823C-8312-4F92-818A-5117BB31A569} diff --git a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj index 9ac8e12..7a1b01c 100644 --- a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj +++ b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj @@ -1,6 +1,6 @@ - true + false net9.0 true diff --git a/templates/content/blank/.template.config/template.json b/templates/content/blank/.template.config/template.json index d9fd139..26ba5df 100644 --- a/templates/content/blank/.template.config/template.json +++ b/templates/content/blank/.template.config/template.json @@ -46,7 +46,7 @@ "type": "parameter", "dataType": "string", "replaces": "FabulousPkgVersion", - "defaultValue": "3.0.0-pre2" + "defaultValue": "3.0.0-pre10" }, "FabulousMauiControlsPkgVersion": { "type": "parameter", @@ -58,7 +58,7 @@ "type": "parameter", "dataType": "string", "replaces": "FSharpCorePkgVersion", - "defaultValue": "8.0.100" + "defaultValue": "9.0.100" }, "FSharpMauiWinUICompatPkgVersion": { "type": "parameter", @@ -70,7 +70,7 @@ "type": "parameter", "dataType": "string", "replaces": "MicrosoftMauiControlsPkgVersion", - "defaultValue": "8.0.14" + "defaultValue": "9.0.0" } } } \ No newline at end of file diff --git a/templates/content/blank/App.fs b/templates/content/blank/App.fs index 6a69d5f..6c950f5 100644 --- a/templates/content/blank/App.fs +++ b/templates/content/blank/App.fs @@ -30,39 +30,41 @@ module App = | Clicked -> { model with Count = model.Count + 1 }, [ SemanticAnnounce $"Clicked {model.Count} times" ] let view model = - Application( - ContentPage( - ScrollView( - (VStack(spacing = 25.) { - Image("dotnet_bot.png") - .semantics(description = "Cute dotnet bot waving hi to you!") - .height(200.) - .centerHorizontal() + Application() { + Window() { + ContentPage() { + ScrollView( + (VStack(spacing = 25.) { + Image("dotnet_bot.png") + .semantics(description = "Cute dotnet bot waving hi to you!") + .height(200.) + .centerHorizontal() - Label("Hello, World!") - .semantics(SemanticHeadingLevel.Level1) - .font(size = 32.) - .centerTextHorizontal() + Label("Hello, World!") + .semantics(SemanticHeadingLevel.Level1) + .font(size = 32.) + .centerTextHorizontal() - Label("Welcome to .NET Multi-platform App UI powered by Fabulous") - .semantics(SemanticHeadingLevel.Level2, "Welcome to dot net Multi platform App U I powered by Fabulous") - .font(size = 18.) - .centerTextHorizontal() + Label("Welcome to .NET Multi-platform App UI powered by Fabulous") + .semantics(SemanticHeadingLevel.Level2, "Welcome to dot net Multi platform App U I powered by Fabulous") + .font(size = 18.) + .centerTextHorizontal() - let text = - if model.Count = 0 then - "Click me" - else - $"Clicked {model.Count} times" + let text = + if model.Count = 0 then + "Click me" + else + $"Clicked {model.Count} times" - Button(text, Clicked) - .semantics(hint = "Counts the number of times you click") - .centerHorizontal() - }) - .padding(30., 0., 30., 0.) - .centerVertical() - ) - ) - ) + Button(text, Clicked) + .semantics(hint = "Counts the number of times you click") + .centerHorizontal() + }) + .padding(30., 0., 30., 0.) + .centerVertical() + ) + } + } + } let program = Program.statefulWithCmdMsg init update mapCmd |> Program.withView view diff --git a/templates/content/blank/NewApp.fsproj b/templates/content/blank/NewApp.fsproj index c52bc88..8466fd7 100644 --- a/templates/content/blank/NewApp.fsproj +++ b/templates/content/blank/NewApp.fsproj @@ -25,8 +25,8 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) - 14.2 - 14.0 + 15.0 + 15.0 21.0 10.0.17763.0 10.0.17763.0 From d4887aecad3665324e1b0efa218af28fcdcb6a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Larivi=C3=A8re?= Date: Thu, 14 Nov 2024 14:22:18 +0100 Subject: [PATCH 5/6] Format code --- .config/dotnet-tools.json | 5 +- samples/Components/HelloComponent/App.fs | 16 +---- samples/Components/SimpleCounter/App.fs | 16 ++--- samples/Components/TicTacComponent/App.fs | 2 +- samples/HelloWorld/App.fs | 6 +- .../WidgetTests.fs | 2 +- .../AppHostBuilderExtensions.fs | 33 +++------- src/Fabulous.MauiControls/Attributes.fs | 2 +- src/Fabulous.MauiControls/Environment.fs | 1 - src/Fabulous.MauiControls/Style.fs | 6 +- .../Application/Application.Component.fs | 2 +- .../Views/Application/Application.Mvu.fs | 3 +- .../Views/Application/Application.fs | 6 +- .../Views/Brushes/_GradientBrush.fs | 6 +- .../Cells/EntryCell/EntryCell.Component.fs | 7 +- .../Views/Cells/EntryCell/EntryCell.Mvu.fs | 2 +- .../Cells/SwitchCell/SwitchCell.Component.fs | 2 +- .../Views/Cells/SwitchCell/SwitchCell.Mvu.fs | 2 +- .../Views/Cells/SwitchCell/SwitchCell.fs | 5 +- .../Views/Cells/_Cell/Cell.fs | 6 +- .../ListView/ListView.Component.fs | 3 +- .../Collections/ListView/ListView.Mvu.fs | 2 +- .../_ItemsView/ItemsView.Component.fs | 6 +- .../Views/Controls/Button/Button.fs | 16 ++--- .../Controls/CheckBox/CheckBox.Component.fs | 7 +- .../Views/Controls/DatePicker/DatePicker.fs | 9 +-- .../Views/Controls/Editor/Editor.fs | 9 +-- .../Views/Controls/Entry/Entry.Mvu.fs | 1 - .../Views/Controls/Entry/Entry.fs | 9 +-- .../GraphicsView/GraphicsView.Component.fs | 6 +- .../HybridWebView/HybridWebView.Component.fs | 7 +- .../HybridWebView/HybridWebView.Mvu.fs | 7 +- .../Controls/HybridWebView/HybridWebView.fs | 19 +++--- .../Views/Controls/Label.fs | 9 +-- .../Views/Controls/Picker/Picker.fs | 9 +-- .../Controls/RadioButton/RadioButton.Mvu.fs | 3 +- .../Views/Controls/RadioButton/RadioButton.fs | 9 +-- .../Views/Controls/SearchBar/SearchBar.Mvu.fs | 2 +- .../Views/Controls/SearchBar/SearchBar.fs | 9 +-- .../Views/Controls/Slider/Slider.fs | 2 +- .../Views/Controls/Span.fs | 12 ++-- .../Views/Controls/Stepper/Stepper.Mvu.fs | 1 - .../TimePicker/TimePicker.Component.fs | 3 +- .../Views/Controls/TimePicker/TimePicker.fs | 9 +-- .../Controls/WebView/WebView.Component.fs | 7 +- .../Views/Controls/WebView/WebView.Mvu.fs | 7 +- .../Views/Controls/WebView/WebView.fs | 4 +- .../DragGestureRecognizer.Component.fs | 10 ++- .../DragGestureRecognizer.Mvu.fs | 14 ++-- .../DropGestureRecognizer.Mvu.fs | 14 ++-- .../DropGestureRecognizer.fs | 2 +- .../PanGestureRecognizer.Component.fs | 3 +- .../PanGestureRecognizer.fs | 2 +- .../PinchGestureRecognizer.Component.fs | 5 +- .../PinchGestureRecognizer.Mvu.fs | 2 +- .../PointerGestureRecognizer.Component.fs | 33 ++++++---- .../PointerGestureRecognizer.Mvu.fs | 32 +++++---- .../PointerGestureRecognizer.fs | 4 +- .../SwipeGestureRecognizer.Component.fs | 2 +- .../SwipeGestureRecognizer.Mvu.fs | 2 +- .../Views/KeyboardAccelerator.fs | 4 +- .../RefreshView/RefreshView.Component.fs | 2 +- .../Layouts/RefreshView/RefreshView.Mvu.fs | 4 +- .../Layouts/ScrollView/ScrollView.Mvu.fs | 2 +- .../Layouts/SwipeItem/SwipeItem.Component.fs | 2 +- .../Views/Layouts/SwipeItems.fs | 6 +- .../Views/Layouts/SwipeView/SwipeView.fs | 2 +- .../Views/Layouts/TitleBar.fs | 65 ++++++++----------- .../MenuFlyoutItem/MenuFlyoutItem.fs | 14 ++-- .../Views/MenuItems/MenuItem/MenuItem.fs | 5 +- .../ToolbarItem/ToolbarItem.Component.fs | 2 +- .../Pages/ContentPage/ContentPage.Mvu.fs | 2 +- .../Views/Pages/ContentPage/ContentPage.fs | 9 +-- .../Views/Pages/FlyoutPage/FlyoutPage.fs | 2 +- .../NavigationPage.Component.fs | 2 +- .../NavigationPage/NavigationPage.Mvu.fs | 2 +- .../Pages/NavigationPage/NavigationPage.fs | 2 +- .../Views/Pages/_Page/Page.Component.fs | 2 +- .../Views/Pages/_Page/Page.fs | 6 +- .../Views/Shapes/Geometries/GeometryGroup.fs | 6 +- .../Views/Shapes/Geometries/PathGeometry.fs | 6 +- .../Shapes/PathTransforms/TransformGroup.fs | 6 +- .../Views/Shapes/Segments/PathFigure.fs | 6 +- .../Views/_Element/Element.fs | 6 +- src/Fabulous.MauiControls/Views/_View.fs | 12 ++-- .../_VisualElement/VisualElement.Component.fs | 7 +- .../Views/_VisualElement/VisualElement.Mvu.fs | 7 +- .../VirtualizedCollection.fs | 1 + src/Fabulous.MauiControls/Widgets.fs | 4 +- 89 files changed, 273 insertions(+), 365 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 81ed678..a14a6d5 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,10 +3,11 @@ "isRoot": true, "tools": { "fantomas": { - "version": "6.2.3", + "version": "6.3.16", "commands": [ "fantomas" - ] + ], + "rollForward": false } } } \ No newline at end of file diff --git a/samples/Components/HelloComponent/App.fs b/samples/Components/HelloComponent/App.fs index 08cd13d..b4fa951 100644 --- a/samples/Components/HelloComponent/App.fs +++ b/samples/Components/HelloComponent/App.fs @@ -5,21 +5,9 @@ open Microsoft.Maui.Hosting open type Fabulous.Maui.View -module App = +module App = let view () = - Component("root") { - Application() { - Window() { - ContentPage() { - (VStack() { - Label("Hello Component") - .centerTextHorizontal() - }) - .centerVertical() - } - } - } - } + Component("root") { Application() { Window() { ContentPage() { (VStack() { Label("Hello Component").centerTextHorizontal() }).centerVertical() } } } } let createMauiApp () = MauiApp.CreateBuilder().UseFabulousApp(view).Build() diff --git a/samples/Components/SimpleCounter/App.fs b/samples/Components/SimpleCounter/App.fs index 7fd37e4..6bf583c 100644 --- a/samples/Components/SimpleCounter/App.fs +++ b/samples/Components/SimpleCounter/App.fs @@ -21,16 +21,14 @@ module App = | Increment | Decrement | CountChanged of int - + let program = - Program.stateful - (fun () -> 0) - (fun msg model -> - match msg with - | Increment -> model + 1 - | Decrement -> model - 1 - | CountChanged count -> count) - + Program.stateful (fun () -> 0) (fun msg model -> + match msg with + | Increment -> model + 1 + | Decrement -> model - 1 + | CountChanged count -> count) + let view () = Component("root") { let! theme = Context.Environment(EnvironmentKeys.Theme) diff --git a/samples/Components/TicTacComponent/App.fs b/samples/Components/TicTacComponent/App.fs index 8568267..9b5a4e3 100644 --- a/samples/Components/TicTacComponent/App.fs +++ b/samples/Components/TicTacComponent/App.fs @@ -206,7 +206,7 @@ module App = let! model = Context.Mvu(program) Application() { - Window() { + Window() { ContentPage( Grid(coldefs = [ Star ], rowdefs = [ Star; Auto; Auto ]) { (Grid(coldefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ], rowdefs = [ Star; Absolute 5.0; Star; Absolute 5.0; Star ]) { diff --git a/samples/HelloWorld/App.fs b/samples/HelloWorld/App.fs index abad0f3..99de2f8 100644 --- a/samples/HelloWorld/App.fs +++ b/samples/HelloWorld/App.fs @@ -7,11 +7,7 @@ open type Fabulous.Maui.View module App = let view () = - Application() { - Window() { - ContentPage(Label("Hello World").center()) - } - } + Application() { Window() { ContentPage(Label("Hello World").center()) } } type MauiProgram = static member CreateMauiApp() = diff --git a/src/Fabulous.MauiControls.Tests/WidgetTests.fs b/src/Fabulous.MauiControls.Tests/WidgetTests.fs index 6d33ccf..d3b3f0e 100644 --- a/src/Fabulous.MauiControls.Tests/WidgetTests.fs +++ b/src/Fabulous.MauiControls.Tests/WidgetTests.fs @@ -53,7 +53,7 @@ type WidgetTests() = } let envContext = new EnvironmentContext() - + let treeContext: ViewTreeContext = { CanReuseView = MauiViewHelpers.canReuseView GetViewNode = ViewNode.get diff --git a/src/Fabulous.MauiControls/AppHostBuilderExtensions.fs b/src/Fabulous.MauiControls/AppHostBuilderExtensions.fs index 3af8cee..c234897 100644 --- a/src/Fabulous.MauiControls/AppHostBuilderExtensions.fs +++ b/src/Fabulous.MauiControls/AppHostBuilderExtensions.fs @@ -10,13 +10,8 @@ open System type AppHostBuilderExtensions = [] static member inline private UseFabulousApp - ( - this: MauiAppBuilder, - canReuseView, - logger, - syncAction: (unit -> unit) -> unit, - [] viewFn: unit -> Widget - ) : MauiAppBuilder = + (this: MauiAppBuilder, canReuseView, logger, syncAction: (unit -> unit) -> unit, [] viewFn: unit -> Widget) + : MauiAppBuilder = this.UseMauiApp(fun (_serviceProvider: IServiceProvider) -> let widget = viewFn() @@ -28,22 +23,17 @@ type AppHostBuilderExtensions = GetViewNode = ViewNode.get GetComponent = Component.get SetComponent = Component.set } - + let envContext = new EnvironmentContext() let app = FabApplication() - + envContext.Set(EnvironmentKeys.Theme, app.RequestedTheme, false) let def = WidgetDefinitionStore.get widget.Key let node = def.AttachView(widget, envContext, treeContext, ValueNone, app) - - node.SetHandler( - "Theme", - app.RequestedThemeChanged.Subscribe(fun args -> - envContext.Set(EnvironmentKeys.Theme, args.RequestedTheme, false) - ) - ) - + + node.SetHandler("Theme", app.RequestedThemeChanged.Subscribe(fun args -> envContext.Set(EnvironmentKeys.Theme, args.RequestedTheme, false))) + app) [] @@ -84,13 +74,8 @@ type AppHostBuilderExtensions = [] static member UseFabulousApp - ( - this: MauiAppBuilder, - view: unit -> WidgetBuilder, - ?canReuseView, - ?logger, - ?syncAction: (unit -> unit) -> unit - ) : MauiAppBuilder = + (this: MauiAppBuilder, view: unit -> WidgetBuilder, ?canReuseView, ?logger, ?syncAction: (unit -> unit) -> unit) + : MauiAppBuilder = this.UseFabulousApp( (defaultArg canReuseView MauiViewHelpers.canReuseView), (defaultArg logger (ProgramDefaults.defaultLogger())), diff --git a/src/Fabulous.MauiControls/Attributes.fs b/src/Fabulous.MauiControls/Attributes.fs index 78aab45..b8b2684 100644 --- a/src/Fabulous.MauiControls/Attributes.fs +++ b/src/Fabulous.MauiControls/Attributes.fs @@ -157,7 +157,7 @@ module Attributes = bindableObject.ClearValue(bindableProperty) else bindableObject.SetValue(bindableProperty, value)) - + module Mvu = /// Update both a property and its related event. /// This definition makes sure that the event is only raised when the property is changed by the user, diff --git a/src/Fabulous.MauiControls/Environment.fs b/src/Fabulous.MauiControls/Environment.fs index b23c725..d000570 100644 --- a/src/Fabulous.MauiControls/Environment.fs +++ b/src/Fabulous.MauiControls/Environment.fs @@ -5,4 +5,3 @@ open Microsoft.Maui.ApplicationModel module EnvironmentKeys = let Theme = EnvironmentKey("Theme") - diff --git a/src/Fabulous.MauiControls/Style.fs b/src/Fabulous.MauiControls/Style.fs index 6fedb4a..deb250c 100644 --- a/src/Fabulous.MauiControls/Style.fs +++ b/src/Fabulous.MauiControls/Style.fs @@ -10,8 +10,6 @@ type FabElementExtensions = /// The style modifier function [] static member inline style<'msg, 'marker when 'msg: equality and 'marker :> IFabElement> - ( - this: WidgetBuilder<'msg, 'marker>, - fn: WidgetBuilder<'msg, 'marker> -> WidgetBuilder<'msg, 'marker> - ) = + (this: WidgetBuilder<'msg, 'marker>, fn: WidgetBuilder<'msg, 'marker> -> WidgetBuilder<'msg, 'marker>) + = fn this diff --git a/src/Fabulous.MauiControls/Views/Application/Application.Component.fs b/src/Fabulous.MauiControls/Views/Application/Application.Component.fs index aeb14bf..9f3d8b3 100644 --- a/src/Fabulous.MauiControls/Views/Application/Application.Component.fs +++ b/src/Fabulous.MauiControls/Views/Application/Application.Component.fs @@ -99,4 +99,4 @@ type ApplicationComponentModifiers = /// Message to dispatch [] static member inline onAppLinkRequestReceived(this: WidgetBuilder, fn: Uri -> unit) = - this.AddScalar(ApplicationComponent.AppLinkRequestReceived.WithValue(fn) ) + this.AddScalar(ApplicationComponent.AppLinkRequestReceived.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs b/src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs index 797a0c9..24f2490 100644 --- a/src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Application/Application.Mvu.fs @@ -21,7 +21,8 @@ module ApplicationMvu = Attributes.Mvu.defineEvent "ApplicationMvu_ModalPushing" (fun target -> (target :?> Application).ModalPushing) let RequestedThemeChanged = - Attributes.Mvu.defineEvent "ApplicationMvu_RequestedThemeChanged" (fun target -> (target :?> Application).RequestedThemeChanged) + Attributes.Mvu.defineEvent "ApplicationMvu_RequestedThemeChanged" (fun target -> + (target :?> Application).RequestedThemeChanged) let Resume = Attributes.Mvu.defineEventNoArg "ApplicationMvu_Resume" (fun target -> (target :?> FabApplication).Resume) diff --git a/src/Fabulous.MauiControls/Views/Application/Application.fs b/src/Fabulous.MauiControls/Views/Application/Application.fs index 6f62a9c..8773c5c 100644 --- a/src/Fabulous.MauiControls/Views/Application/Application.fs +++ b/src/Fabulous.MauiControls/Views/Application/Application.fs @@ -105,8 +105,6 @@ type ApplicationModifiers = type ApplicationYieldExtensions = [] static member inline Yield<'msg, 'marker, 'itemType when 'msg: equality and 'marker :> IFabApplication and 'itemType :> IFabWindow> - ( - _: CollectionBuilder<'msg, 'marker, IFabWindow>, - x: WidgetBuilder<'msg, 'itemType> - ) : Content<'msg> = + (_: CollectionBuilder<'msg, 'marker, IFabWindow>, x: WidgetBuilder<'msg, 'itemType>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Brushes/_GradientBrush.fs b/src/Fabulous.MauiControls/Views/Brushes/_GradientBrush.fs index 3ba599d..51c226a 100644 --- a/src/Fabulous.MauiControls/Views/Brushes/_GradientBrush.fs +++ b/src/Fabulous.MauiControls/Views/Brushes/_GradientBrush.fs @@ -22,8 +22,6 @@ type GradientBrushYieldExtensions = [] static member inline Yield - ( - _: CollectionBuilder<'msg, #IFabGradientBrush, IFabGradientStop>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabGradientStop>> - ) : Content<'msg> = + (_: CollectionBuilder<'msg, #IFabGradientBrush, IFabGradientStop>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabGradientStop>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs index 94f9fe8..26337dd 100644 --- a/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs +++ b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Component.fs @@ -9,12 +9,13 @@ module EntryCellComponent = Attributes.Component.defineEventNoArg "EntryCellComponent_Completed" (fun target -> (target :?> EntryCell).Completed) let TextWithEvent = - Attributes.Component.defineBindableWithEvent "EntryCellComponent_TextChanged" EntryCell.TextProperty (fun target -> (target :?> FabEntryCell).TextChanged) + Attributes.Component.defineBindableWithEvent "EntryCellComponent_TextChanged" EntryCell.TextProperty (fun target -> + (target :?> FabEntryCell).TextChanged) [] module EntryCellComponentBuilders = type Fabulous.Maui.View with - + /// Create an EntryCell with a label, a text, and listen to text changes /// The label value /// The text value @@ -33,4 +34,4 @@ type EntryCellComponentModifiers = /// Function to execute [] static member inline onCompleted(this: WidgetBuilder, fn: unit -> unit) = - this.AddScalar(EntryCellComponent.OnCompleted.WithValue(fn)) \ No newline at end of file + this.AddScalar(EntryCellComponent.OnCompleted.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs index 2290f63..b61bc6f 100644 --- a/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Cells/EntryCell/EntryCell.Mvu.fs @@ -34,4 +34,4 @@ type EntryCellMvuModifiers = /// Message to dispatch [] static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntryCell>, msg: 'msg) = - this.AddScalar(EntryCellMvu.OnCompleted.WithValue(MsgValue(msg))) \ No newline at end of file + this.AddScalar(EntryCellMvu.OnCompleted.WithValue(MsgValue(msg))) diff --git a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs index 75b5f73..ee2b0db 100644 --- a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs +++ b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Component.fs @@ -19,4 +19,4 @@ module SwitchCellComponentBuilders = SwitchCell.WidgetKey, SwitchCellComponent.OnWithEvent.WithValue(ValueEventData.create value (fun (args: ToggledEventArgs) -> onChanged args.Value)), SwitchCell.Text.WithValue(text) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs index 7625779..56845c6 100644 --- a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.Mvu.fs @@ -20,4 +20,4 @@ module SwitchCellBuilders = SwitchCell.WidgetKey, SwitchCellMvu.OnWithEvent.WithValue(MsgValueEventData.create value (fun (args: ToggledEventArgs) -> onChanged args.Value)), SwitchCell.Text.WithValue(text) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs index 67f0969..233b19f 100644 --- a/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs +++ b/src/Fabulous.MauiControls/Views/Cells/SwitchCell/SwitchCell.fs @@ -13,8 +13,9 @@ module SwitchCell = let WidgetKey = Widgets.register() let OnColor = Attributes.defineBindableColor SwitchCell.OnColorProperty - - let Text : SimpleScalarAttributeDefinition = Attributes.defineBindableWithEquality SwitchCell.TextProperty + + let Text: SimpleScalarAttributeDefinition = + Attributes.defineBindableWithEquality SwitchCell.TextProperty [] type SwitchCellModifiers = diff --git a/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs index 87fd99a..06a60d3 100644 --- a/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs +++ b/src/Fabulous.MauiControls/Views/Cells/_Cell/Cell.fs @@ -51,8 +51,6 @@ type CellModifiers = type CellYieldExtensions = [] static member inline Yield<'msg, 'marker, 'itemType when 'msg: equality and 'marker :> IFabCell and 'itemType :> IFabMenuItem> - ( - _: AttributeCollectionBuilder<'msg, 'marker, IFabMenuItem>, - x: WidgetBuilder<'msg, 'itemType> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, 'marker, IFabMenuItem>, x: WidgetBuilder<'msg, 'itemType>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs index bdef156..7516e42 100644 --- a/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs +++ b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Component.fs @@ -24,7 +24,8 @@ module ListViewComponent = Attributes.Component.defineEvent "ListViewComponent_Scrolled" (fun target -> (target :?> ListView).Scrolled) let ScrollToRequested = - Attributes.Component.defineEvent "ListViewComponent_ScrollToRequested" (fun target -> (target :?> ListView).ScrollToRequested) + Attributes.Component.defineEvent "ListViewComponent_ScrollToRequested" (fun target -> + (target :?> ListView).ScrollToRequested) [] type ListViewComponentModifiers = diff --git a/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs index b621227..74b587d 100644 --- a/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Collections/ListView/ListView.Mvu.fs @@ -62,7 +62,7 @@ type ListViewMvuModifiers = [] static member inline onRefreshing(this: WidgetBuilder<'msg, #IFabListView>, msg: 'msg) = this.AddScalar(ListViewMvu.Refreshing.WithValue(MsgValue(msg))) - + /// Listen for the Scrolled event /// Current widget /// Message to dispatch diff --git a/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs index 66a4494..2062863 100644 --- a/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs +++ b/src/Fabulous.MauiControls/Views/Collections/_ItemsView/ItemsView.Component.fs @@ -6,13 +6,15 @@ open Microsoft.Maui.Controls module ItemsViewComponent = let RemainingItemsThresholdReached = - Attributes.Component.defineEventNoArg "ItemsViewComponent_RemainingItemsThresholdReached" (fun target -> (target :?> ItemsView).RemainingItemsThresholdReached) + Attributes.Component.defineEventNoArg "ItemsViewComponent_RemainingItemsThresholdReached" (fun target -> + (target :?> ItemsView).RemainingItemsThresholdReached) let Scrolled = Attributes.Component.defineEvent "ItemsViewComponent_Scrolled" (fun target -> (target :?> ItemsView).Scrolled) let ScrollToRequested = - Attributes.Component.defineEvent "ItemsViewComponent_ScrolledRequested" (fun target -> (target :?> ItemsView).ScrollToRequested) + Attributes.Component.defineEvent "ItemsViewComponent_ScrolledRequested" (fun target -> + (target :?> ItemsView).ScrollToRequested) [] type ItemsViewComponentModifiers = diff --git a/src/Fabulous.MauiControls/Views/Controls/Button/Button.fs b/src/Fabulous.MauiControls/Views/Controls/Button/Button.fs index fd07642..5a0c7e0 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Button/Button.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Button/Button.fs @@ -88,11 +88,8 @@ type ButtonModifiers = /// The spacing [] static member inline contentLayout - ( - this: WidgetBuilder<'msg, #IFabButton>, - position: Microsoft.Maui.Controls.Button.ButtonContentLayout.ImagePosition, - spacing: float - ) = + (this: WidgetBuilder<'msg, #IFabButton>, position: Microsoft.Maui.Controls.Button.ButtonContentLayout.ImagePosition, spacing: float) + = this.AddScalar(Button.ContentLayout.WithValue(Button.ButtonContentLayout(position, spacing))) /// Set the font @@ -103,13 +100,8 @@ type ButtonModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabButton>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabButton>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs index 185b7cf..1979376 100644 --- a/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs +++ b/src/Fabulous.MauiControls/Views/Controls/CheckBox/CheckBox.Component.fs @@ -5,7 +5,8 @@ open Microsoft.Maui.Controls module CheckBoxComponent = let IsCheckedWithEvent = - Attributes.Component.defineBindableWithEvent "CheckBoxComponent_CheckedChanged" CheckBox.IsCheckedProperty (fun target -> (target :?> CheckBox).CheckedChanged) + Attributes.Component.defineBindableWithEvent "CheckBoxComponent_CheckedChanged" CheckBox.IsCheckedProperty (fun target -> + (target :?> CheckBox).CheckedChanged) [] module CheckBoxComponentBuilders = @@ -17,5 +18,7 @@ module CheckBoxComponentBuilders = static member inline CheckBox(isChecked: bool, onCheckedChanged: bool -> unit) = WidgetBuilder( CheckBox.WidgetKey, - CheckBoxComponent.IsCheckedWithEvent.WithValue(ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onCheckedChanged args.Value)) + CheckBoxComponent.IsCheckedWithEvent.WithValue( + ValueEventData.create isChecked (fun (args: CheckedChangedEventArgs) -> onCheckedChanged args.Value) + ) ) diff --git a/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs index 22076a8..0f64c7d 100644 --- a/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs +++ b/src/Fabulous.MauiControls/Views/Controls/DatePicker/DatePicker.fs @@ -59,13 +59,8 @@ type DatePickerModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabDatePicker>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabDatePicker>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.fs b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.fs index 8ed935d..9e63de7 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Editor/Editor.fs @@ -48,13 +48,8 @@ type EditorModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabEditor>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabEditor>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs index 6c3762e..210e1f7 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.Mvu.fs @@ -29,4 +29,3 @@ type EntryMvuModifiers = [] static member inline onCompleted(this: WidgetBuilder<'msg, #IFabEntry>, msg: 'msg) = this.AddScalar(EntryMvu.Completed.WithValue(MsgValue(msg))) - \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.fs b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.fs index 4ef23a8..26029fd 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Entry/Entry.fs @@ -80,13 +80,8 @@ type EntryModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabEntry>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabEntry>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs index ce0181b..c0d8a06 100644 --- a/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs +++ b/src/Fabulous.MauiControls/Views/Controls/GraphicsView/GraphicsView.Component.fs @@ -18,10 +18,12 @@ module GraphicsViewComponent = Attributes.Component.defineEvent "GraphicsViewComponent_EndInteraction" (fun target -> (target :?> GraphicsView).EndInteraction) let MoveHoverInteraction = - Attributes.Component.defineEvent "GraphicsViewComponent_MoveHoverInteraction" (fun target -> (target :?> GraphicsView).MoveHoverInteraction) + Attributes.Component.defineEvent "GraphicsViewComponent_MoveHoverInteraction" (fun target -> + (target :?> GraphicsView).MoveHoverInteraction) let StartHoverInteraction = - Attributes.Component.defineEvent "GraphicsViewComponent_StartHoverInteraction" (fun target -> (target :?> GraphicsView).StartHoverInteraction) + Attributes.Component.defineEvent "GraphicsViewComponent_StartHoverInteraction" (fun target -> + (target :?> GraphicsView).StartHoverInteraction) let StartInteraction = Attributes.Component.defineEvent "GraphicsViewComponent_StartInteraction" (fun target -> (target :?> GraphicsView).StartInteraction) diff --git a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs index cb24a60..5427872 100644 --- a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs +++ b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Component.fs @@ -5,8 +5,9 @@ open Fabulous open Microsoft.Maui.Controls module HybridWebViewComponent = - let RawMessageReceived = Attributes.Component.defineEvent "HybridWebViewComponent_RawMessageReceived" (fun target -> (target :?> HybridWebView).RawMessageReceived) - + let RawMessageReceived = + Attributes.Component.defineEvent "HybridWebViewComponent_RawMessageReceived" (fun target -> (target :?> HybridWebView).RawMessageReceived) + [] type HybridWebViewComponentModifiers = /// Listen for the RawMessageReceived event @@ -14,4 +15,4 @@ type HybridWebViewComponentModifiers = /// Message to dispatch [] static member inline onRawMessageReceived(this: WidgetBuilder, fn: HybridWebViewRawMessageReceivedEventArgs -> unit) = - this.AddScalar(HybridWebViewComponent.RawMessageReceived.WithValue(fn)) \ No newline at end of file + this.AddScalar(HybridWebViewComponent.RawMessageReceived.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs index 105add0..b4bd7a8 100644 --- a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.Mvu.fs @@ -5,8 +5,9 @@ open Fabulous open Microsoft.Maui.Controls module HybridWebViewMvu = - let RawMessageReceived = Attributes.Mvu.defineEvent "HybridWebViewMvu_RawMessageReceived" (fun target -> (target :?> HybridWebView).RawMessageReceived) - + let RawMessageReceived = + Attributes.Mvu.defineEvent "HybridWebViewMvu_RawMessageReceived" (fun target -> (target :?> HybridWebView).RawMessageReceived) + [] type HybridWebViewMvuModifiers = /// Listen for the RawMessageReceived event @@ -14,4 +15,4 @@ type HybridWebViewMvuModifiers = /// Message to dispatch [] static member inline onRawMessageReceived(this: WidgetBuilder<'msg, #IFabHybridWebView>, fn: HybridWebViewRawMessageReceivedEventArgs -> 'msg) = - this.AddScalar(HybridWebViewMvu.RawMessageReceived.WithValue(fn)) \ No newline at end of file + this.AddScalar(HybridWebViewMvu.RawMessageReceived.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs index 05d30ff..bcf8d46 100644 --- a/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs +++ b/src/Fabulous.MauiControls/Views/Controls/HybridWebView/HybridWebView.fs @@ -7,27 +7,28 @@ open Microsoft.Maui.Controls type IFabHybridWebView = inherit IFabView - + module HybridWebView = let WidgetKey = Widgets.register() - - let DefaultFile = Attributes.defineBindableWithEquality HybridWebView.DefaultFileProperty - - let HybridRoot = Attributes.defineBindableWithEquality HybridWebView.HybridRootProperty - + + let DefaultFile = + Attributes.defineBindableWithEquality HybridWebView.DefaultFileProperty + + let HybridRoot = + Attributes.defineBindableWithEquality HybridWebView.HybridRootProperty + [] module HybridWebViewBuilders = type Fabulous.Maui.View with static member inline HybridWebView() = WidgetBuilder<'msg, IFabHybridWebView>(HybridWebView.WidgetKey, AttributesBundle(StackList.empty(), ValueNone, ValueNone)) - + [] type HybridWebViewModifiers = [] static member inline defaultFile(this: WidgetBuilder<'msg, #IFabHybridWebView>, value: string) = this.AddScalar(HybridWebView.DefaultFile.WithValue(value)) - + [] static member inline hybridRoot(this: WidgetBuilder<'msg, #IFabHybridWebView>, value: string) = this.AddScalar(HybridWebView.HybridRoot.WithValue(value)) - diff --git a/src/Fabulous.MauiControls/Views/Controls/Label.fs b/src/Fabulous.MauiControls/Views/Controls/Label.fs index 255bdbe..bfdb4cb 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Label.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Label.fs @@ -78,13 +78,8 @@ type LabelModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabLabel>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabLabel>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.fs b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.fs index 2daf879..f81e7a4 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Picker/Picker.fs @@ -105,13 +105,8 @@ type PickerModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabPicker>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabPicker>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs index 64a582c..253fc9b 100644 --- a/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.Mvu.fs @@ -6,7 +6,8 @@ open Microsoft.Maui.Controls module RadioButtonMvu = let IsCheckedWithEvent = - Attributes.Mvu.defineBindableWithEvent "RadioButtonMvu_CheckedChanged" RadioButton.IsCheckedProperty (fun target -> (target :?> RadioButton).CheckedChanged) + Attributes.Mvu.defineBindableWithEvent "RadioButtonMvu_CheckedChanged" RadioButton.IsCheckedProperty (fun target -> + (target :?> RadioButton).CheckedChanged) [] module RadioButtonMvuBuilders = diff --git a/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.fs b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.fs index d634403..ac1747f 100644 --- a/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.fs +++ b/src/Fabulous.MauiControls/Views/Controls/RadioButton/RadioButton.fs @@ -94,13 +94,8 @@ type RadioButtonModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabRadioButton>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabRadioButton>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs index 5188ce2..b8a95fe 100644 --- a/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.Mvu.fs @@ -20,4 +20,4 @@ module SearchBarMvuBuilders = SearchBar.WidgetKey, InputViewMvu.TextWithEvent.WithValue(MsgValueEventData.create text (fun (args: TextChangedEventArgs) -> onTextChanged args.NewTextValue)), SearchBarMvu.SearchButtonPressed.WithValue(MsgValue(onSearchButtonPressed)) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.fs b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.fs index c07536e..5bab411 100644 --- a/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.fs +++ b/src/Fabulous.MauiControls/Views/Controls/SearchBar/SearchBar.fs @@ -56,13 +56,8 @@ type SearchBarModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabSearchBar>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabSearchBar>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.fs b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.fs index 5bbdde0..8110832 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Slider/Slider.fs @@ -30,7 +30,7 @@ module SliderUpdaters = module Slider = let WidgetKey = Widgets.register() - + let MaximumTrackColor = Attributes.defineBindableColor Slider.MaximumTrackColorProperty diff --git a/src/Fabulous.MauiControls/Views/Controls/Span.fs b/src/Fabulous.MauiControls/Views/Controls/Span.fs index 2f7dd3b..c20254e 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Span.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Span.fs @@ -142,18 +142,14 @@ type SpanModifiers = type SpanYieldExtensions = [] static member inline Yield - ( - _: AttributeCollectionBuilder<'msg, #IFabSpan, IFabGestureRecognizer>, - x: WidgetBuilder<'msg, #IFabGestureRecognizer> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, #IFabSpan, IFabGestureRecognizer>, x: WidgetBuilder<'msg, #IFabGestureRecognizer>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } [] static member inline Yield - ( - _: AttributeCollectionBuilder<'msg, #IFabSpan, IFabGestureRecognizer>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabGestureRecognizer>> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, #IFabSpan, IFabGestureRecognizer>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabGestureRecognizer>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } [] diff --git a/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs index e648a43..893585e 100644 --- a/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/Stepper/Stepper.Mvu.fs @@ -22,4 +22,3 @@ module StepperMvuBuilders = Stepper.MinimumMaximum.WithValue(struct (min, max)), StepperMvu.ValueWithEvent.WithValue(MsgValueEventData.create value (fun (args: ValueChangedEventArgs) -> onValueChanged args.NewValue)) ) - \ No newline at end of file diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs index 2c9fc24..aa2ad03 100644 --- a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.Component.fs @@ -6,7 +6,8 @@ open Microsoft.Maui.Controls module TimePickerComponent = let TimeWithEvent = - Attributes.Component.defineBindableWithEvent "TimePickerComponent_TimeSelected" TimePicker.TimeProperty (fun target -> (target :?> TimePicker).TimeSelected) + Attributes.Component.defineBindableWithEvent "TimePickerComponent_TimeSelected" TimePicker.TimeProperty (fun target -> + (target :?> TimePicker).TimeSelected) [] module TimePickerComponentBuilders = diff --git a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs index b5cd8d8..122521e 100644 --- a/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs +++ b/src/Fabulous.MauiControls/Views/Controls/TimePicker/TimePicker.fs @@ -60,13 +60,8 @@ type TimePickerModifiers = /// The value indicating whether auto-scaling is enabled [] static member inline font - ( - this: WidgetBuilder<'msg, #IFabTimePicker>, - ?size: float, - ?attributes: FontAttributes, - ?fontFamily: string, - ?autoScalingEnabled: bool - ) = + (this: WidgetBuilder<'msg, #IFabTimePicker>, ?size: float, ?attributes: FontAttributes, ?fontFamily: string, ?autoScalingEnabled: bool) + = let mutable res = this diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs index 472f6ff..a519ec2 100644 --- a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Component.fs @@ -5,8 +5,9 @@ open Fabulous open Microsoft.Maui.Controls module WebViewComponent = - let ProcessTerminated = Attributes.Component.defineEvent "WebViewComponent_ProcessTerminated" (fun target -> (target :?> WebView).ProcessTerminated) - + let ProcessTerminated = + Attributes.Component.defineEvent "WebViewComponent_ProcessTerminated" (fun target -> (target :?> WebView).ProcessTerminated) + let Navigated = Attributes.Component.defineEvent "WebViewComponent_Navigated" (fun target -> (target :?> WebView).Navigated) @@ -21,7 +22,7 @@ type WebViewComponentModifiers() = [] static member inline onProcessTerminated(this: WidgetBuilder, fn: WebViewProcessTerminatedEventArgs -> unit) = this.AddScalar(WebViewComponent.ProcessTerminated.WithValue(fn)) - + /// Listen for the Navigated event /// Current widget /// Message to dispatch diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs index 4bcb1a8..02c8e48 100644 --- a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.Mvu.fs @@ -5,8 +5,9 @@ open Fabulous open Microsoft.Maui.Controls module WebViewMvu = - let ProcessTerminated = Attributes.Mvu.defineEvent "WebViewMvu_ProcessTerminated" (fun target -> (target :?> WebView).ProcessTerminated) - + let ProcessTerminated = + Attributes.Mvu.defineEvent "WebViewMvu_ProcessTerminated" (fun target -> (target :?> WebView).ProcessTerminated) + let Navigated = Attributes.Mvu.defineEvent "WebViewMvu_Navigated" (fun target -> (target :?> WebView).Navigated) @@ -21,7 +22,7 @@ type WebViewMvuModifiers() = [] static member inline onProcessTerminated(this: WidgetBuilder<'msg, #IFabWebView>, fn: WebViewProcessTerminatedEventArgs -> 'msg) = this.AddScalar(WebViewMvu.ProcessTerminated.WithValue(fun args -> fn args |> box)) - + /// Listen for the Navigated event /// Current widget /// Message to dispatch diff --git a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs index 8c563ee..46f4345 100644 --- a/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs +++ b/src/Fabulous.MauiControls/Views/Controls/WebView/WebView.fs @@ -22,7 +22,7 @@ module WebView = let Source = Attributes.defineBindableWithEquality WebView.SourceProperty - + let UserAgent = Attributes.defineBindableWithEquality WebView.UserAgentProperty @@ -101,7 +101,7 @@ type WebViewModifiers() = [] static member inline cookies(this: WidgetBuilder<'msg, #IFabWebView>, value: CookieContainer) = this.AddScalar(WebView.Cookies.WithValue(value)) - + /// Set the user agent /// Current widget /// The user agent diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs index a412057..d0f64b2 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Component.fs @@ -8,9 +8,10 @@ module DragGestureRecognizerComponent = let DragStarting = Attributes.Component.defineEvent "DragGestureRecognizerComponent_DragStarting" (fun target -> (target :?> DragGestureRecognizer).DragStarting) - + let DropCompleted = - Attributes.Component.defineEvent "DragGestureRecognizerComponent_DropCompleted" (fun target -> (target :?> DragGestureRecognizer).DropCompleted) + Attributes.Component.defineEvent "DragGestureRecognizerComponent_DropCompleted" (fun target -> + (target :?> DragGestureRecognizer).DropCompleted) [] module DragGestureRecognizerComponentBuilders = @@ -18,7 +19,10 @@ module DragGestureRecognizerComponentBuilders = /// Create a DragGestureRecognizer that listens for DragStarting event /// Message to dispatch static member inline DragGestureRecognizer(onDragStarting: DragStartingEventArgs -> unit) = - WidgetBuilder(DragGestureRecognizer.WidgetKey, DragGestureRecognizerComponent.DragStarting.WithValue(onDragStarting)) + WidgetBuilder( + DragGestureRecognizer.WidgetKey, + DragGestureRecognizerComponent.DragStarting.WithValue(onDragStarting) + ) [] type DragGestureRecognizerComponentModifiers = diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs index b34f885..b8d001f 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DragGestureRecognizer/DragGestureRecognizer.Mvu.fs @@ -6,10 +6,12 @@ open Microsoft.Maui.Controls module DragGestureRecognizerMvu = let DragStarting = - Attributes.Mvu.defineEvent "DragGestureRecognizerMvu_DragStarting" (fun target -> (target :?> DragGestureRecognizer).DragStarting) + Attributes.Mvu.defineEvent "DragGestureRecognizerMvu_DragStarting" (fun target -> + (target :?> DragGestureRecognizer).DragStarting) let DropCompleted = - Attributes.Mvu.defineEvent "DragGestureRecognizerMvu_DropCompleted" (fun target -> (target :?> DragGestureRecognizer).DropCompleted) + Attributes.Mvu.defineEvent "DragGestureRecognizerMvu_DropCompleted" (fun target -> + (target :?> DragGestureRecognizer).DropCompleted) [] module DragGestureRecognizerMvuBuilders = @@ -22,7 +24,7 @@ module DragGestureRecognizerMvuBuilders = DragGestureRecognizer.WidgetKey, DragGestureRecognizerMvu.DragStarting.WithValue(fun args -> onDragStarting args |> box) ) - + [] type DragGestureRecognizerMvuModifiers = /// Listen for DropCompleted event @@ -30,8 +32,6 @@ type DragGestureRecognizerMvuModifiers = /// Message to dispatch [] static member inline onDropCompleted<'msg, 'marker when 'msg: equality and 'marker :> IFabDragGestureRecognizer> - ( - this: WidgetBuilder<'msg, 'marker>, - msg: 'msg - ) = + (this: WidgetBuilder<'msg, 'marker>, msg: 'msg) + = this.AddScalar(DragGestureRecognizerMvu.DropCompleted.WithValue(fun _ -> box msg)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs index c5a4783..d7f471c 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.Mvu.fs @@ -25,7 +25,7 @@ module DropGestureRecognizerMvuBuilders = DropGestureRecognizer.WidgetKey, DropGestureRecognizerMvu.Drop.WithValue(fun args -> onDrop args |> box) ) - + [] type DropGestureRecognizerMvuModifiers = /// Listen for the DragOver event @@ -33,10 +33,8 @@ type DropGestureRecognizerMvuModifiers = /// Message to dispatch [] static member inline onDragOver<'msg, 'marker when 'msg: equality and 'marker :> IFabDropGestureRecognizer> - ( - this: WidgetBuilder<'msg, 'marker>, - fn: DragEventArgs -> 'msg - ) = + (this: WidgetBuilder<'msg, 'marker>, fn: DragEventArgs -> 'msg) + = this.AddScalar(DropGestureRecognizerMvu.DragOver.WithValue(fun args -> fn args |> box)) /// Listen for the DragLeave event @@ -44,8 +42,6 @@ type DropGestureRecognizerMvuModifiers = /// Message to dispatch [] static member inline onDragLeave<'msg, 'marker when 'msg: equality and 'marker :> IFabDragGestureRecognizer> - ( - this: WidgetBuilder<'msg, 'marker>, - fn: DragEventArgs -> 'msg - ) = + (this: WidgetBuilder<'msg, 'marker>, fn: DragEventArgs -> 'msg) + = this.AddScalar(DropGestureRecognizerMvu.DragLeave.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs index 15c9b98..c5e0da3 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/DropGestureRecognizer/DropGestureRecognizer.fs @@ -12,7 +12,7 @@ module DropGestureRecognizer = let AllowDrop = Attributes.defineBindableBool DropGestureRecognizer.AllowDropProperty - + [] type DropGestureRecognizerModifiers = /// Set whether users are allowed to drop diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs index f89348d..ef2c7d3 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.Component.fs @@ -5,7 +5,8 @@ open Microsoft.Maui.Controls module PanGestureRecognizerComponent = let PanUpdated = - Attributes.Component.defineEvent "PanGestureRecognizerComponent_PanUpdated" (fun target -> (target :?> PanGestureRecognizer).PanUpdated) + Attributes.Component.defineEvent "PanGestureRecognizerComponent_PanUpdated" (fun target -> + (target :?> PanGestureRecognizer).PanUpdated) [] module PanGestureRecognizerComponentBuilders = diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.fs index dcf6fb6..831d3ac 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PanGestureRecognizer/PanGestureRecognizer.fs @@ -9,7 +9,7 @@ type IFabPanGestureRecognizer = module PanGestureRecognizer = let WidgetKey = Widgets.register() - + let TouchPoints = Attributes.defineBindableInt PanGestureRecognizer.TouchPointsProperty diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs index b5a4aa2..699fe6f 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Component.fs @@ -14,4 +14,7 @@ module PinchGestureRecognizerComponentBuilders = /// Create a PinchGestureRecognizer that listens for Pinch event /// Message to dispatch static member inline PinchGestureRecognizer(onPinchUpdated: PinchGestureUpdatedEventArgs -> unit) = - WidgetBuilder(PinchGestureRecognizer.WidgetKey, PinchGestureRecognizerComponent.PinchUpdated.WithValue(onPinchUpdated)) + WidgetBuilder( + PinchGestureRecognizer.WidgetKey, + PinchGestureRecognizerComponent.PinchUpdated.WithValue(onPinchUpdated) + ) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs index 5241266..ee42d05 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PinchGestureRecognizer/PinchGestureRecognizer.Mvu.fs @@ -18,4 +18,4 @@ module PinchGestureRecognizerMvuBuilders = WidgetBuilder<'msg, IFabPinchGestureRecognizer>( PinchGestureRecognizer.WidgetKey, PinchGestureRecognizerMvu.PinchUpdated.WithValue(fun args -> onPinchUpdated args |> box) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs index 0ff3bbf..2b014fa 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Component.fs @@ -5,33 +5,40 @@ open System.Runtime.CompilerServices open Microsoft.Maui.Controls module PointerGestureRecognizerComponent = - let PointerEntered = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerEntered" (fun target -> (target :?> PointerGestureRecognizer).PointerEntered) - - let PointerExited = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerExited" (fun target -> (target :?> PointerGestureRecognizer).PointerExited) - - let PointerMoved = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerMoved" (fun target -> (target :?> PointerGestureRecognizer).PointerMoved) - - let PointerPressed = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerPressed" (fun target -> (target :?> PointerGestureRecognizer).PointerPressed) - - let PointerReleased = Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerReleased" (fun target -> (target :?> PointerGestureRecognizer).PointerReleased) + let PointerEntered = + Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerEntered" (fun target -> (target :?> PointerGestureRecognizer).PointerEntered) + + let PointerExited = + Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerExited" (fun target -> (target :?> PointerGestureRecognizer).PointerExited) + + let PointerMoved = + Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerMoved" (fun target -> (target :?> PointerGestureRecognizer).PointerMoved) + + let PointerPressed = + Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerPressed" (fun target -> (target :?> PointerGestureRecognizer).PointerPressed) + + let PointerReleased = + Attributes.Component.defineEvent "PointerGestureRecognizerComponent_PointerReleased" (fun target -> + (target :?> PointerGestureRecognizer).PointerReleased) [] type PointerGestureRecognizerComponentModifiers = [] static member inline onPointerEntered(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerComponent.PointerEntered.WithValue(fn)) - + [] static member inline onPointerExited(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerComponent.PointerExited.WithValue(fn)) + [] static member inline onPointerMoved(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerComponent.PointerMoved.WithValue(fn)) - + [] static member inline onPointerPressed(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerComponent.PointerPressed.WithValue(fn)) - + [] static member inline onPointerReleased(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = - this.AddScalar(PointerGestureRecognizerComponent.PointerReleased.WithValue(fn)) \ No newline at end of file + this.AddScalar(PointerGestureRecognizerComponent.PointerReleased.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs index 49913b0..cc9dec0 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.Mvu.fs @@ -5,33 +5,39 @@ open System.Runtime.CompilerServices open Microsoft.Maui.Controls module PointerGestureRecognizerMvu = - let PointerEntered = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerEntered" (fun target -> (target :?> PointerGestureRecognizer).PointerEntered) - - let PointerExited = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerExited" (fun target -> (target :?> PointerGestureRecognizer).PointerExited) - - let PointerMoved = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerMoved" (fun target -> (target :?> PointerGestureRecognizer).PointerMoved) - - let PointerPressed = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerPressed" (fun target -> (target :?> PointerGestureRecognizer).PointerPressed) - - let PointerReleased = Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerReleased" (fun target -> (target :?> PointerGestureRecognizer).PointerReleased) + let PointerEntered = + Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerEntered" (fun target -> (target :?> PointerGestureRecognizer).PointerEntered) + + let PointerExited = + Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerExited" (fun target -> (target :?> PointerGestureRecognizer).PointerExited) + + let PointerMoved = + Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerMoved" (fun target -> (target :?> PointerGestureRecognizer).PointerMoved) + + let PointerPressed = + Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerPressed" (fun target -> (target :?> PointerGestureRecognizer).PointerPressed) + + let PointerReleased = + Attributes.Mvu.defineEvent "PointerGestureRecognizerMvu_PointerReleased" (fun target -> (target :?> PointerGestureRecognizer).PointerReleased) [] type PointerGestureRecognizerMvuModifiers = [] static member inline onPointerEntered(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerMvu.PointerEntered.WithValue(fn)) - + [] static member inline onPointerExited(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerMvu.PointerExited.WithValue(fn)) + [] static member inline onPointerMoved(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerMvu.PointerMoved.WithValue(fn)) - + [] static member inline onPointerPressed(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = this.AddScalar(PointerGestureRecognizerMvu.PointerPressed.WithValue(fn)) - + [] static member inline onPointerReleased(this: WidgetBuilder<'msg, #IFabPointerGestureRecognizer>, fn: PointerEventArgs -> unit) = - this.AddScalar(PointerGestureRecognizerMvu.PointerReleased.WithValue(fn)) \ No newline at end of file + this.AddScalar(PointerGestureRecognizerMvu.PointerReleased.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs index e6b468f..13ec920 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/PointerGestureRecognizer/PointerGestureRecognizer.fs @@ -10,7 +10,7 @@ type IFabPointerGestureRecognizer = module PointerGestureRecognizer = let WidgetKey = Widgets.register() - + [] module PointerGestureRecognizerBuilders = type Fabulous.Maui.View with @@ -24,4 +24,4 @@ type PointerGestureRecognizerModifiers = /// The ViewRef instance that will receive access to the underlying control [] static member inline reference(this: WidgetBuilder<'msg, IFabPointerGestureRecognizer>, value: ViewRef) = - this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) \ No newline at end of file + this.AddScalar(ViewRefAttributes.ViewRef.WithValue(value.Unbox)) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs index 6586e98..13d4ac7 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Component.fs @@ -18,4 +18,4 @@ module SwipeGestureRecognizerComponentBuilders = WidgetBuilder( SwipeGestureRecognizer.WidgetKey, SwipeGestureRecognizerComponent.Swiped.WithValue(fun args -> onSwiped args.Direction) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs index b0ca1b6..d82ff31 100644 --- a/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/GestureRecognizers/SwipeGestureRecognizer/SwipeGestureRecognizer.Mvu.fs @@ -18,4 +18,4 @@ module SwipeGestureRecognizerMvuBuilders = WidgetBuilder<'msg, IFabSwipeGestureRecognizer>( SwipeGestureRecognizer.WidgetKey, SwipeGestureRecognizerMvu.Swiped.WithValue(fun args -> onSwiped args.Direction |> box) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/KeyboardAccelerator.fs b/src/Fabulous.MauiControls/Views/KeyboardAccelerator.fs index 502e625..a44ecfc 100644 --- a/src/Fabulous.MauiControls/Views/KeyboardAccelerator.fs +++ b/src/Fabulous.MauiControls/Views/KeyboardAccelerator.fs @@ -4,9 +4,7 @@ open Fabulous open Microsoft.Maui open Microsoft.Maui.Controls -type IFabKeyboardAccelerator = - interface - end +type IFabKeyboardAccelerator = interface end module KeyboardAccelerator = let WidgetKey = Widgets.register() diff --git a/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs index 66e7179..9751609 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Component.fs @@ -24,4 +24,4 @@ module RefreshViewComponentBuilders = ValueSome [| ContentView.Content.WithValue(content.Compile()) |], ValueNone ) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs index f8d427c..0402fb6 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/RefreshView/RefreshView.Mvu.fs @@ -7,7 +7,7 @@ open Microsoft.Maui.Controls module RefreshViewMvu = let Refreshing = Attributes.Mvu.defineEventNoArg "RefreshViewMvu_Refreshing" (fun target -> (target :?> RefreshView).Refreshing) - + [] module RefreshViewMvuBuilders = type Fabulous.Maui.View with @@ -24,4 +24,4 @@ module RefreshViewMvuBuilders = ValueSome [| ContentView.Content.WithValue(content.Compile()) |], ValueNone ) - ) \ No newline at end of file + ) diff --git a/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs index c2dd244..6b00f5c 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/ScrollView/ScrollView.Mvu.fs @@ -15,4 +15,4 @@ type ScrollViewMvuModifiers = /// Message to dispatch [] static member inline onScrolled(this: WidgetBuilder<'msg, #IFabScrollView>, fn: ScrolledEventArgs -> 'msg) = - this.AddScalar(ScrollViewMvu.Scrolled.WithValue(fun args -> fn args |> box)) \ No newline at end of file + this.AddScalar(ScrollViewMvu.Scrolled.WithValue(fun args -> fn args |> box)) diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs index 49ed322..29c83a3 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeItem/SwipeItem.Component.fs @@ -6,7 +6,7 @@ open Microsoft.Maui.Controls module SwipeItemComponent = let Invoked = Attributes.Component.defineEvent "SwipeItemComponent_Invoked" (fun target -> (target :?> SwipeItem).Invoked) - + [] module SwipeItemComponentBuilders = type Fabulous.Maui.View with diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeItems.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeItems.fs index a6f5f4d..483b25a 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/SwipeItems.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeItems.fs @@ -61,8 +61,6 @@ type SwipeItemsYieldExtensions = [] static member inline Yield - ( - _: CollectionBuilder<'msg, #IFabSwipeItems, IFabSwipeItem>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabSwipeItem>> - ) : Content<'msg> = + (_: CollectionBuilder<'msg, #IFabSwipeItems, IFabSwipeItem>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabSwipeItem>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs index 401a4f8..0b347d1 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/SwipeView/SwipeView.fs @@ -11,7 +11,7 @@ module SwipeView = let WidgetKey = Widgets.register() let BottomSwipeItems = Attributes.defineBindableWidget SwipeView.BottomItemsProperty - + let LeftSwipeItems = Attributes.defineBindableWidget SwipeView.LeftItemsProperty let RightSwipeItems = Attributes.defineBindableWidget SwipeView.RightItemsProperty diff --git a/src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs b/src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs index fa40a96..0b5f314 100644 --- a/src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs +++ b/src/Fabulous.MauiControls/Views/Layouts/TitleBar.fs @@ -9,75 +9,64 @@ open Microsoft.Maui.Graphics type IFabTitleBar = inherit IFabTemplatedView - + module TitleBar = let WidgetKey = Widgets.register() - + let Content = Attributes.defineBindableWidget TitleBar.ContentProperty - - let ForegroundColor = Attributes.defineBindableColor TitleBar.ForegroundColorProperty - + + let ForegroundColor = + Attributes.defineBindableColor TitleBar.ForegroundColorProperty + let Icon = Attributes.defineBindableImageSource TitleBar.IconProperty - + let LeadingContent = Attributes.defineBindableWidget TitleBar.LeadingContentProperty - - let Subtitle = Attributes.defineBindableWithEquality TitleBar.SubtitleProperty - + + let Subtitle = + Attributes.defineBindableWithEquality TitleBar.SubtitleProperty + let Title = Attributes.defineBindableWithEquality TitleBar.TitleProperty - - let TrailingContent = Attributes.defineBindableWidget TitleBar.TrailingContentProperty - + + let TrailingContent = + Attributes.defineBindableWidget TitleBar.TrailingContentProperty + [] module TitleBarBuilders = type Fabulous.Maui.View with static member inline TitleBar(icon: ImageSource, title: string) = - WidgetBuilder<'msg, IFabTitleBar>( - TitleBar.WidgetKey, - TitleBar.Icon.WithValue(ImageSourceValue.Source icon), - TitleBar.Title.WithValue(title) - ) - + WidgetBuilder<'msg, IFabTitleBar>(TitleBar.WidgetKey, TitleBar.Icon.WithValue(ImageSourceValue.Source icon), TitleBar.Title.WithValue(title)) + static member inline TitleBar(icon: string, title: string) = - WidgetBuilder<'msg, IFabTitleBar>( - TitleBar.WidgetKey, - TitleBar.Icon.WithValue(ImageSourceValue.File icon), - TitleBar.Title.WithValue(title) - ) + WidgetBuilder<'msg, IFabTitleBar>(TitleBar.WidgetKey, TitleBar.Icon.WithValue(ImageSourceValue.File icon), TitleBar.Title.WithValue(title)) + static member inline TitleBar(icon: Uri, title: string) = - WidgetBuilder<'msg, IFabTitleBar>( - TitleBar.WidgetKey, - TitleBar.Icon.WithValue(ImageSourceValue.Uri icon), - TitleBar.Title.WithValue(title) - ) + WidgetBuilder<'msg, IFabTitleBar>(TitleBar.WidgetKey, TitleBar.Icon.WithValue(ImageSourceValue.Uri icon), TitleBar.Title.WithValue(title)) + static member inline TitleBar(icon: Stream, title: string) = - WidgetBuilder<'msg, IFabTitleBar>( - TitleBar.WidgetKey, - TitleBar.Icon.WithValue(ImageSourceValue.Stream icon), - TitleBar.Title.WithValue(title) - ) + WidgetBuilder<'msg, IFabTitleBar>(TitleBar.WidgetKey, TitleBar.Icon.WithValue(ImageSourceValue.Stream icon), TitleBar.Title.WithValue(title)) [] type TitleBarModifiers = [] static member inline content(this: WidgetBuilder<'msg, #IFabTitleBar>, widget: WidgetBuilder<'msg, #IFabView>) = this.AddWidget(TitleBar.Content.WithValue(widget.Compile())) - + [] static member inline foregroundColor(this: WidgetBuilder<'msg, #IFabTitleBar>, value: Color) = this.AddScalar(TitleBar.ForegroundColor.WithValue(value)) - + [] static member inline leadingContent(this: WidgetBuilder<'msg, #IFabTitleBar>, widget: WidgetBuilder<'msg, #IFabView>) = this.AddWidget(TitleBar.LeadingContent.WithValue(widget.Compile())) - + [] static member inline subtitle(this: WidgetBuilder<'msg, #IFabTitleBar>, value: string) = this.AddScalar(TitleBar.Subtitle.WithValue(value)) - + [] static member inline title(this: WidgetBuilder<'msg, #IFabTitleBar>, value: string) = this.AddScalar(TitleBar.Title.WithValue(value)) - + [] static member inline trailingContent(this: WidgetBuilder<'msg, #IFabTitleBar>, widget: WidgetBuilder<'msg, #IFabView>) = this.AddWidget(TitleBar.TrailingContent.WithValue(widget.Compile())) diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.fs index f122927..88eedd2 100644 --- a/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.fs +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuFlyoutItem/MenuFlyoutItem.fs @@ -26,16 +26,14 @@ type MenuFlyoutItemModifiers = type MenuFlyoutItemYieldExtensions = [] static member inline Yield - ( - _: AttributeCollectionBuilder<'msg, #IFabMenuFlyoutItem, IFabKeyboardAccelerator>, - x: WidgetBuilder<'msg, #IFabKeyboardAccelerator> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, #IFabMenuFlyoutItem, IFabKeyboardAccelerator>, x: WidgetBuilder<'msg, #IFabKeyboardAccelerator>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } [] static member inline Yield - ( - _: AttributeCollectionBuilder<'msg, #IFabMenuFlyoutItem, IFabKeyboardAccelerator>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabKeyboardAccelerator>> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, #IFabMenuFlyoutItem, IFabKeyboardAccelerator>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabKeyboardAccelerator>>) : Content< + 'msg + > + = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.fs b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.fs index d30d729..514346b 100644 --- a/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.fs +++ b/src/Fabulous.MauiControls/Views/MenuItems/MenuItem/MenuItem.fs @@ -12,13 +12,14 @@ type IFabMenuItem = module MenuItem = let WidgetKey = Widgets.register() - + let IconImageSource = Attributes.defineBindableImageSource MenuItem.IconImageSourceProperty let IsDestructive = Attributes.defineBindableBool MenuItem.IsDestructiveProperty - let Text: SimpleScalarAttributeDefinition = Attributes.defineBindableWithEquality MenuItem.TextProperty + let Text: SimpleScalarAttributeDefinition = + Attributes.defineBindableWithEquality MenuItem.TextProperty [] type MenuItemModifiers = diff --git a/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs index f22283a..3fb6c8b 100644 --- a/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs +++ b/src/Fabulous.MauiControls/Views/MenuItems/ToolbarItem/ToolbarItem.Component.fs @@ -5,7 +5,7 @@ open Fabulous [] module ToolbarItemComponentBuilders = type Fabulous.Maui.View with - + /// Create a ToolbarItem widget with a text and a Click callback /// The text /// The click callback diff --git a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs index e116063..f8b4461 100644 --- a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.Mvu.fs @@ -14,4 +14,4 @@ type ContentPageMvuModifiers = /// Message to dispatch [] static member inline onSizeAllocated(this: WidgetBuilder<'msg, #IFabContentPage>, fn: SizeAllocatedEventArgs -> 'msg) = - this.AddScalar(ContentPageMvu.SizeAllocated.WithValue(fn)) \ No newline at end of file + this.AddScalar(ContentPageMvu.SizeAllocated.WithValue(fn)) diff --git a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs index 3810430..8a0ab4a 100644 --- a/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs +++ b/src/Fabulous.MauiControls/Views/Pages/ContentPage/ContentPage.fs @@ -29,9 +29,10 @@ module ContentPage = let WidgetKey = Widgets.register() let Content = Attributes.defineBindableWidget ContentPage.ContentProperty - - let HideSoftInputOnTapped = Attributes.defineBindableBool ContentPage.HideSoftInputOnTappedProperty - + + let HideSoftInputOnTapped = + Attributes.defineBindableBool ContentPage.HideSoftInputOnTappedProperty + [] module ContentPageBuilders = type Fabulous.Maui.View with @@ -55,7 +56,7 @@ type ContentPageModifiers = [] static member inline hideSoftInputOnTapped(this: WidgetBuilder<'msg, IFabContentPage>, value: bool) = this.AddScalar(ContentPage.HideSoftInputOnTapped.WithValue(value)) - + /// Link a ViewRef to access the direct ContentPage control instance /// Current widget /// The ViewRef instance that will receive access to the underlying control diff --git a/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.fs b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.fs index 12fc642..ced2c0b 100644 --- a/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.fs +++ b/src/Fabulous.MauiControls/Views/Pages/FlyoutPage/FlyoutPage.fs @@ -24,7 +24,7 @@ type FabFlyoutPage() as this = module FlyoutPage = let WidgetKey = Widgets.register() - + let Detail = Attributes.definePropertyWidget "FlyoutPage_Detail" (fun target -> (target :?> FlyoutPage).Detail :> obj) (fun target value -> (target :?> FlyoutPage).Detail <- value) diff --git a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs index e61aa83..cef2953 100644 --- a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs +++ b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Component.fs @@ -5,7 +5,7 @@ open Fabulous module NavigationPageComponent = let WidgetKey = Widgets.register() - + let BackButtonPressed = Attributes.Component.defineEventNoArg "NavigationPageComponent_BackButtonPressed" (fun target -> (target :?> FabNavigationPage).BackButtonPressed) diff --git a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs index 111e8e5..fc30fc6 100644 --- a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.Mvu.fs @@ -25,4 +25,4 @@ type NavigationPageMvuModifiers = /// Message to dispatch [] static member inline onBackNavigated(this: WidgetBuilder<'msg, #IFabNavigationPage>, msg: 'msg) = - this.AddScalar(NavigationPageMvu.BackNavigated.WithValue(MsgValue(msg))) \ No newline at end of file + this.AddScalar(NavigationPageMvu.BackNavigated.WithValue(MsgValue(msg))) diff --git a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.fs b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.fs index 8df57c4..dababc7 100644 --- a/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.fs +++ b/src/Fabulous.MauiControls/Views/Pages/NavigationPage/NavigationPage.fs @@ -267,7 +267,7 @@ module NavigationPageUpdaters = module NavigationPage = let WidgetKey = Widgets.register() - + let BarBackground = Attributes.defineBindableWithEquality NavigationPage.BarBackgroundProperty diff --git a/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs index ed10eae..2c6079a 100644 --- a/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs +++ b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.Component.fs @@ -25,7 +25,7 @@ type PageComponentModifiers = [] static member inline onAppearing(this: WidgetBuilder, fn: unit -> unit) = this.AddScalar(PageComponent.Appearing.WithValue(fn)) - + /// Listen to the Disappearing event /// Current widget /// Function to execute diff --git a/src/Fabulous.MauiControls/Views/Pages/_Page/Page.fs b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.fs index 7eaa82e..c6b4cb4 100644 --- a/src/Fabulous.MauiControls/Views/Pages/_Page/Page.fs +++ b/src/Fabulous.MauiControls/Views/Pages/_Page/Page.fs @@ -165,8 +165,6 @@ type PageYieldExtensions = [] static member inline Yield - ( - _: AttributeCollectionBuilder<'msg, #IFabPage, IFabToolbarItem>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabToolbarItem>> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, #IFabPage, IFabToolbarItem>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabToolbarItem>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Shapes/Geometries/GeometryGroup.fs b/src/Fabulous.MauiControls/Views/Shapes/Geometries/GeometryGroup.fs index 3da6712..d577e3d 100644 --- a/src/Fabulous.MauiControls/Views/Shapes/Geometries/GeometryGroup.fs +++ b/src/Fabulous.MauiControls/Views/Shapes/Geometries/GeometryGroup.fs @@ -52,8 +52,6 @@ type GeometryGroupYieldExtensions = [] static member inline Yield - ( - _: CollectionBuilder<'msg, #IFabGeometryGroup, IFabGeometry>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabGeometry>> - ) : Content<'msg> = + (_: CollectionBuilder<'msg, #IFabGeometryGroup, IFabGeometry>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabGeometry>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Shapes/Geometries/PathGeometry.fs b/src/Fabulous.MauiControls/Views/Shapes/Geometries/PathGeometry.fs index 9922c32..18b47ab 100644 --- a/src/Fabulous.MauiControls/Views/Shapes/Geometries/PathGeometry.fs +++ b/src/Fabulous.MauiControls/Views/Shapes/Geometries/PathGeometry.fs @@ -75,8 +75,6 @@ type PathGeometryYieldExtensions = [] static member inline Yield - ( - _: CollectionBuilder<'msg, #IFabPathGeometry, IFabPathFigure>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabPathFigure>> - ) : Content<'msg> = + (_: CollectionBuilder<'msg, #IFabPathGeometry, IFabPathFigure>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabPathFigure>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Shapes/PathTransforms/TransformGroup.fs b/src/Fabulous.MauiControls/Views/Shapes/PathTransforms/TransformGroup.fs index 9624feb..62fdc9d 100644 --- a/src/Fabulous.MauiControls/Views/Shapes/PathTransforms/TransformGroup.fs +++ b/src/Fabulous.MauiControls/Views/Shapes/PathTransforms/TransformGroup.fs @@ -40,8 +40,6 @@ type TransformGroupYieldExtensions = [] static member inline Yield - ( - _: CollectionBuilder<'msg, #IFabTransformGroup, IFabTransform>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabTransform>> - ) : Content<'msg> = + (_: CollectionBuilder<'msg, #IFabTransformGroup, IFabTransform>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabTransform>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/Shapes/Segments/PathFigure.fs b/src/Fabulous.MauiControls/Views/Shapes/Segments/PathFigure.fs index e95f7fa..44af579 100644 --- a/src/Fabulous.MauiControls/Views/Shapes/Segments/PathFigure.fs +++ b/src/Fabulous.MauiControls/Views/Shapes/Segments/PathFigure.fs @@ -67,8 +67,6 @@ type PathFigureYieldExtensions = [] static member inline Yield - ( - _: CollectionBuilder<'msg, #IFabPathFigure, IFabPathSegment>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabPathSegment>> - ) : Content<'msg> = + (_: CollectionBuilder<'msg, #IFabPathFigure, IFabPathSegment>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabPathSegment>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } diff --git a/src/Fabulous.MauiControls/Views/_Element/Element.fs b/src/Fabulous.MauiControls/Views/_Element/Element.fs index 7e36d0b..6d7ffaa 100644 --- a/src/Fabulous.MauiControls/Views/_Element/Element.fs +++ b/src/Fabulous.MauiControls/Views/_Element/Element.fs @@ -4,9 +4,7 @@ open System.Runtime.CompilerServices open Fabulous open Microsoft.Maui.Controls -type IFabElement = - interface - end +type IFabElement = interface end module Element = let AutomationId = @@ -19,4 +17,4 @@ type ElementModifiers = /// A value that the automation framework can use to find and interact with this element. [] static member inline automationId(this: WidgetBuilder<'msg, #IFabElement>, value: string) = - this.AddScalar(Element.AutomationId.WithValue(value)) \ No newline at end of file + this.AddScalar(Element.AutomationId.WithValue(value)) diff --git a/src/Fabulous.MauiControls/Views/_View.fs b/src/Fabulous.MauiControls/Views/_View.fs index 99f1973..d7379e3 100644 --- a/src/Fabulous.MauiControls/Views/_View.fs +++ b/src/Fabulous.MauiControls/Views/_View.fs @@ -133,18 +133,14 @@ type ViewExtraModifiers = type ViewYieldExtensions = [] static member inline Yield - ( - _: AttributeCollectionBuilder<'msg, #IFabView, IFabGestureRecognizer>, - x: WidgetBuilder<'msg, #IFabGestureRecognizer> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, #IFabView, IFabGestureRecognizer>, x: WidgetBuilder<'msg, #IFabGestureRecognizer>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } [] static member inline Yield - ( - _: AttributeCollectionBuilder<'msg, #IFabView, IFabGestureRecognizer>, - x: WidgetBuilder<'msg, Memo.Memoized<#IFabGestureRecognizer>> - ) : Content<'msg> = + (_: AttributeCollectionBuilder<'msg, #IFabView, IFabGestureRecognizer>, x: WidgetBuilder<'msg, Memo.Memoized<#IFabGestureRecognizer>>) + : Content<'msg> = { Widgets = MutStackArray1.One(x.Compile()) } [] diff --git a/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs index 25f96f5..fbef0d1 100644 --- a/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs +++ b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Component.fs @@ -57,7 +57,10 @@ module VisualElementComponentUpdaters = module VisualElementComponent = let FocusWithEvent = - Attributes.defineSimpleScalar "VisualElementComponent_FocusWithEvent" ScalarAttributeComparers.noCompare VisualElementComponentUpdaters.updateVisualElementFocus + Attributes.defineSimpleScalar + "VisualElementComponent_FocusWithEvent" + ScalarAttributeComparers.noCompare + VisualElementComponentUpdaters.updateVisualElementFocus [] type VisualElementComponentModifiers = @@ -67,4 +70,4 @@ type VisualElementComponentModifiers = /// Message to dispatch when the widget's focus state changes [] static member inline focus(this: WidgetBuilder, value: bool, onFocusChanged: bool -> unit) = - this.AddScalar(VisualElementComponent.FocusWithEvent.WithValue(ValueEventData.create value onFocusChanged)) \ No newline at end of file + this.AddScalar(VisualElementComponent.FocusWithEvent.WithValue(ValueEventData.create value onFocusChanged)) diff --git a/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs index 65eb95a..96995c5 100644 --- a/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs +++ b/src/Fabulous.MauiControls/Views/_VisualElement/VisualElement.Mvu.fs @@ -73,9 +73,6 @@ type VisualElementMvuModifiers = /// Message to dispatch when the widget's focus state changes [] static member inline focus<'msg, 'marker when 'msg: equality and 'marker :> IFabVisualElement> - ( - this: WidgetBuilder<'msg, 'marker>, - value: bool, - onFocusChanged: bool -> 'msg - ) = + (this: WidgetBuilder<'msg, 'marker>, value: bool, onFocusChanged: bool -> 'msg) + = this.AddScalar(VisualElementMvu.FocusWithEvent.WithValue(MsgValueEventData.create value onFocusChanged)) diff --git a/src/Fabulous.MauiControls/VirtualizedCollection.fs b/src/Fabulous.MauiControls/VirtualizedCollection.fs index 7f6dad4..ef69a9a 100644 --- a/src/Fabulous.MauiControls/VirtualizedCollection.fs +++ b/src/Fabulous.MauiControls/VirtualizedCollection.fs @@ -33,6 +33,7 @@ type WidgetDataTemplate(parent: IViewNode, ``type``: Type, templateFn: obj -> Wi let bindableObject = Activator.CreateInstance ``type`` :?> BindableObject let envContext = new EnvironmentContext(parent.EnvironmentContext) + let viewNode = new ViewNode(Some parent, envContext, parent.TreeContext, WeakReference(bindableObject)) diff --git a/src/Fabulous.MauiControls/Widgets.fs b/src/Fabulous.MauiControls/Widgets.fs index 330f15b..ba47061 100644 --- a/src/Fabulous.MauiControls/Widgets.fs +++ b/src/Fabulous.MauiControls/Widgets.fs @@ -9,9 +9,7 @@ open Fabulous.Maui open Microsoft.FSharp.Core [] -type View = - class - end +type View = class end module Widgets = let registerWithAdditionalSetup<'T when 'T :> Microsoft.Maui.Controls.BindableObject and 'T: (new: unit -> 'T)> (additionalSetup: 'T -> IViewNode -> unit) = From 97a0c3e4c20a3b61f24f64027fe2cbbecb7f5b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Larivi=C3=A8re?= Date: Thu, 14 Nov 2024 14:27:43 +0100 Subject: [PATCH 6/6] Update CI/CD --- .github/workflows/build.yml | 6 ++--- .github/workflows/pull_request.yml | 10 +++++--- .github/workflows/release.yml | 6 ++--- README.md | 24 ++++++++++--------- .../Fabulous.MauiControls.fsproj | 2 +- templates/content/blank/NewApp.fsproj | 6 ++--- 6 files changed, 30 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 272d3a6..35e3cb3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,11 +12,11 @@ env: TEMPLATE_PROJ: templates/Fabulous.MauiControls.Templates.proj TEMPLATE_PKG: nupkgs/Fabulous.MauiControls.Templates NUPKG_FOLDER: nupkgs - XCODE_PATH: /Applications/Xcode_15.2.app/Contents/Developer + XCODE_PATH: /Applications/Xcode_16.0.app/Contents/Developer jobs: build: - runs-on: macos-13 + runs-on: macos-15 steps: - name: Checkout sources uses: actions/checkout@v3 @@ -34,7 +34,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.x + dotnet-version: 9.x - name: Use correct Xcode version run: sudo xcode-select -s ${XCODE_PATH} - name: Install dotnet workload diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d8e07e7..4441c09 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -4,15 +4,15 @@ on: pull_request env: SLN_FILE: Fabulous.MauiControls.NoSamples.sln CONFIG: Release - XCODE_PATH: /Applications/Xcode_15.0.1.app/Contents/Developer + XCODE_PATH: /Applications/Xcode_16.0.app/Contents/Developer jobs: pull_request: - runs-on: macos-13 + runs-on: macos-15 steps: - name: Checkout sources uses: actions/checkout@v3 - - name: Setup .NET + - name: Setup .NET for Fantomas uses: actions/setup-dotnet@v3 with: dotnet-version: 8.x @@ -20,6 +20,10 @@ jobs: run: | dotnet tool restore dotnet fantomas --check src samples templates + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 9.x - name: Use correct Xcode version run: sudo xcode-select -s ${XCODE_PATH} - name: Install dotnet workload diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0ce09d9..12c825a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,11 +10,11 @@ env: CONFIG: Release SLN_FILE: Fabulous.MauiControls.NoSamples.sln TEMPLATE_PROJ: templates/Fabulous.MauiControls.Templates.proj - XCODE_PATH: /Applications/Xcode_15.0.1.app/Contents/Developer + XCODE_PATH: /Applications/Xcode_16.0.app/Contents/Developer jobs: release: - runs-on: macos-13 + runs-on: macos-15 environment: nuget steps: - name: Checkout sources @@ -40,7 +40,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 8.x + dotnet-version: 9.x - name: Use correct Xcode version run: sudo xcode-select -s ${XCODE_PATH} - name: Install dotnet workload diff --git a/README.md b/README.md index 83b7500..36289e2 100644 --- a/README.md +++ b/README.md @@ -25,18 +25,20 @@ let update msg model = | Decrement -> { model with Count = model.Count - 1 } let view model = - Application( - ContentPage( - VStack(spacing = 16.) { - Image("fabulous.png") - - Label($"Count is {model.Count}") - - Button("Increment", Increment) - Button("Decrement", Decrement) + Application() { + Window() { + ContentPage() { + VStack(spacing = 16.) { + Image("fabulous.png") + + Label($"Count is {model.Count}") + + Button("Increment", Increment) + Button("Decrement", Decrement) + } } - ) - ) + } + } ``` ## Getting Started diff --git a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj index 7a1b01c..6a22340 100644 --- a/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj +++ b/src/Fabulous.MauiControls/Fabulous.MauiControls.fsproj @@ -251,7 +251,7 @@ This version will be used as the lower bound in the NuGet package --> - + diff --git a/templates/content/blank/NewApp.fsproj b/templates/content/blank/NewApp.fsproj index 8466fd7..a3fd74c 100644 --- a/templates/content/blank/NewApp.fsproj +++ b/templates/content/blank/NewApp.fsproj @@ -1,10 +1,10 @@ - net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 + net9.0-android;net9.0-ios;net9.0-maccatalyst + $(TargetFrameworks);net9.0-windows10.0.19041.0 - + Exe NewApp true