Skip to content

Commit

Permalink
Add missing Cell.ContextActions and MultiPage.CurrentPage
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLariviere committed Dec 7, 2023
1 parent 3e62e86 commit a92d9de
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/Fabulous.XamarinForms/CollectionBuilderExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ type CollectionBuilderExtensions =
) : Content<'msg> =
{ Widgets = MutStackArray1.One(x.Compile()) }

[<Extension>]
static member inline Yield<'msg, 'marker, 'itemType when 'marker :> ICell and 'itemType :> IMenuItem>
(
_: AttributeCollectionBuilder<'msg, 'marker, IMenuItem>,
x: WidgetBuilder<'msg, 'itemType>
) : Content<'msg> =
{ Widgets = MutStackArray1.One(x.Compile()) }

[<Extension>]
static member inline Yield<'msg, 'marker, 'itemType when 'itemType :> IPage>
Expand Down
7 changes: 7 additions & 0 deletions src/Fabulous.XamarinForms/Views/Cells/_Cell.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ module Cell =
let Tapped =
Attributes.defineEventNoArg "Cell_Tapped" (fun target -> (target :?> Cell).Tapped)

let ContextActions =
Attributes.defineListWidgetCollection "Cell_ContextActions" (fun target -> (target :?> Cell).ContextActions)

[<Extension>]
type CellModifiers =

Expand All @@ -56,3 +59,7 @@ type CellModifiers =
[<Extension>]
static member inline onTapped(this: WidgetBuilder<'msg, #ICell>, onTapped: 'msg) =
this.AddScalar(Cell.Tapped.WithValue(MsgValue onTapped))

[<Extension>]
static member inline contextActions<'msg, 'marker when 'marker :> ICell>(this: WidgetBuilder<'msg, 'marker>) =
WidgetHelpers.buildAttributeCollection<'msg, 'marker, IMenuItem> Cell.ContextActions this
54 changes: 54 additions & 0 deletions src/Fabulous.XamarinForms/Views/Pages/_MultiPageOfPage.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace Fabulous.XamarinForms

open System
open Fabulous
open Fabulous.ScalarAttributeDefinitions
open Xamarin.Forms
open System.Runtime.CompilerServices

Expand All @@ -11,13 +13,65 @@ module MultiPageOfPage =
let Children =
Attributes.defineListWidgetCollection "MultiPageOfPage" (fun target -> (target :?> MultiPage<Page>).Children)

[<Obsolete("Use CurrentPageWithEvent instead")>]
let CurrentPageChanged =
Attributes.defineEventNoArg "MultiPageOfPage_CurrentPageChanged" (fun target -> (target :?> MultiPage<Page>).CurrentPageChanged)

let CurrentPageWithEvent =
let name = "MultiPageOfPage_CurrentPageWithEvent"

let key =
SimpleScalarAttributeDefinition.CreateAttributeData(
ScalarAttributeComparers.noCompare,
(fun oldValueOpt (newValueOpt: ValueEventData<int, int> voption) node ->
let target = node.Target :?> MultiPage<Page>
let event = target.CurrentPageChanged

match newValueOpt with
| ValueNone ->
// The attribute is no longer applied, so we clean up the event
match node.TryGetHandler(name) with
| ValueNone -> ()
| ValueSome handler -> event.RemoveHandler(handler)

// 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 -> event.RemoveHandler(handler)

// Set the new value
target.CurrentPage <- target.Children.[curr.Value]

// Set the new event handler
let handler =
EventHandler(fun sender args ->
let multiPage = sender :?> MultiPage<Page>
let currentPageIndex = multiPage.Children.IndexOf(multiPage.CurrentPage)
let (MsgValue r) = curr.Event currentPageIndex
Dispatcher.dispatch node r)

node.SetHandler(name, ValueSome handler)
event.AddHandler(handler))
)
|> AttributeDefinitionStore.registerScalar

{ Key = key; Name = name }: SimpleScalarAttributeDefinition<ValueEventData<int, int>>


[<Extension>]
type MultiPageOfPageModifiers =
/// <summary>Raised when the CurrentPage property changes.</summary>
/// <param name="onCurrentPageChanged">The msg to invoke when the CurrentPage property changes.</param>
[<Extension>]
static member inline onCurrentPageChanged(this: WidgetBuilder<'msg, #IMultiPageOfPage>, onCurrentPageChanged: 'msg) =
this.AddScalar(MultiPageOfPage.CurrentPageChanged.WithValue(MsgValue onCurrentPageChanged))

[<Extension>]
static member inline currentPage(this: WidgetBuilder<'msg, #IMultiPageOfPage>, currentPage: int, onCurrentPageChanged: int -> 'msg) =
this.AddScalar(MultiPageOfPage.CurrentPageWithEvent.WithValue(ValueEventData.create currentPage onCurrentPageChanged))

0 comments on commit a92d9de

Please sign in to comment.