Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting the backing classes for UI elements #342

Merged
merged 4 commits into from
Feb 23, 2019

Conversation

sdaves
Copy link

@sdaves sdaves commented Feb 20, 2019

This small change allows setting ViewBuilders properties and enables me to replace the implementation of the underlying Xamarin.Forms classes used by Fabulous.

For example, if I need to override a virtual method on MasterDetailPage, this change enables running:

type MasterDetailPageWithoutToolbar() =
    inherit Xamarin.Forms.MasterDetailPage()
    override __.ShouldShowToolbarButton() = false

Fabulous.DynamicViews.ViewBuilders.CreateFuncMasterDetailPage <- fun () ->
    upcast(new MasterDetailPageWithoutToolbar())

This will cause the MasterDetailPageWithoutToolbar class to be loaded when using the standard:

View.MasterDetailPage()

This small change allows me to replace the implementation of the underlying Xamarin.Forms classes used by Fabulous.
@sdaves sdaves changed the title Allow setting the backing function for UI elements Allow setting the backing classes for UI elements Feb 20, 2019
@@ -75,7 +75,7 @@ module CodeGenerator =
w

let generateCreateFunction (data: CreateData) (w: StringWriter) =
w.printfn " static member val CreateFunc%s : (unit -> %s) = (fun () -> ViewBuilders.Create%s())" data.Name data.FullName data.Name
w.printfn " static member val CreateFunc%s : (unit -> %s) = (fun () -> ViewBuilders.Create%s()) with get, set" data.Name data.FullName data.Name
w.printfn ""
w.printfn " static member Create%s () : %s =" data.Name data.FullName
Copy link
Member

@TimLariviere TimLariviere Feb 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, you might want to extend this Create%s method instead.
It's the one with the upcast.

Nevermind, just realized it's a concrete method and can't be overwritten. :)

Copy link
Author

@sdaves sdaves Feb 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I went with the public setter. I first tried adding a static extension method of the same name in the same namespace, but in my project and not in Fabulous, hoping that would override the default static methods in ViewBuilders(), but that didn't work so I went with the property setters.

@TimLariviere
Copy link
Member

Ok, I think it could be a good addition.
It's a bit of an advance case, but this will complete our extension points (like ViewProto for default ViewElements).
And it's the same way that Fabulous uses its internal controls instead of the default implementation.

Do you think you can add some documentation on it?
I think we should stress the fact that it's not the recommended way for custom controls, only good for overridden controls like your example.

@sdaves
Copy link
Author

sdaves commented Feb 21, 2019

Sure thing will add some docs. Thanks for the feedback!

@TimLariviere
Copy link
Member

Retriggering CI

@sdaves
Copy link
Author

sdaves commented Feb 21, 2019

Looks like that only retriggered AppVeyor. The Travis build link still says its from 8 hours ago.

@SergejDK
Copy link
Collaborator

just needs some time.

@sdaves
Copy link
Author

sdaves commented Feb 22, 2019

Awesome it worked :)

@TimLariviere
Copy link
Member

Could you run .\build.cmd (or .\build.sh on macOS) to generate the new Xamarin.Forms.Core.fs based on your modification?

@sdaves
Copy link
Author

sdaves commented Feb 22, 2019

Built and uploaded!
Do you feel this could fit nicely in your release plans for 0.33.0?

@TimLariviere
Copy link
Member

Thanks!
Yes, it will be released in 0.33.0.

@TimLariviere TimLariviere merged commit e823190 into fabulous-dev:master Feb 23, 2019
@sdaves sdaves deleted the patch-1 branch February 23, 2019 14:26
@sdaves
Copy link
Author

sdaves commented Feb 23, 2019

Awesome, looking forward to it 👍

@dsyme
Copy link
Collaborator

dsyme commented Feb 26, 2019

MIght be good to add some docs for ViewProto too? I couldn't spot any on a quick glance

@sdaves
Copy link
Author

sdaves commented Feb 28, 2019

@dsyme Were you thinking we should document each member in type ViewProtos() or just a doc for the type?

I noticed some items are assigned in type ViewProtos(), but quite a few are left empty, such as ProtoContentPage and ProtoMasterDetailPage.

ViewProtos members seem to only be called from internal Update methods in the generated Xamarin.Forms.Core.fs file, so I'm not sure if they are intended to be used from outside of that file.

@TimLariviere
Copy link
Member

Ah maybe it's not what I thought it was. If that's the case, it needs to be marked as internal.

Nevertheless, I think it would be doable to propose things like this

let view model dispatch =
    View.ContentPage(
        content = View.StackLayout(
            children = [
                View.Label(text="Hello world")
            ]
        )
    )

type App() as app =
   inherit Application()

   ViewBuilders.DefaultLabel <- View.Label(fontFamily="Lobster-Regular")

    let runner =
        Program.mkProgram init update view 
        |> Program.runWithDynamicView app

@TimLariviere TimLariviere mentioned this pull request Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants