diff --git a/.gitignore b/.gitignore
index 3e759b7..458a7ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -328,3 +328,5 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
+
+.idea/
diff --git a/TemplateBundle/content/BasicTemplate/BasicTemplate.fsproj b/TemplateBundle/content/BasicTemplate/BasicTemplate.fsproj
index d053371..3ee11b4 100644
--- a/TemplateBundle/content/BasicTemplate/BasicTemplate.fsproj
+++ b/TemplateBundle/content/BasicTemplate/BasicTemplate.fsproj
@@ -13,10 +13,10 @@
-
-
-
-
+
+
+
+
diff --git a/TemplateBundle/content/BasicTemplate/Counter.fs b/TemplateBundle/content/BasicTemplate/Counter.fs
index 95fe7bf..ef79d82 100644
--- a/TemplateBundle/content/BasicTemplate/Counter.fs
+++ b/TemplateBundle/content/BasicTemplate/Counter.fs
@@ -4,18 +4,21 @@ module Counter =
open Avalonia.Controls
open Avalonia.FuncUI.DSL
open Avalonia.Layout
-
- type State = { count : int }
+
+ type State = { count: int }
let init = { count = 0 }
- type Msg = Increment | Decrement | Reset
+ type Msg =
+ | Increment
+ | Decrement
+ | Reset
- let update (msg: Msg) (state: State) : State =
+ let update (msg: Msg) (state: State): State =
match msg with
| Increment -> { state with count = state.count + 1 }
| Decrement -> { state with count = state.count - 1 }
| Reset -> init
-
+
let view (state: State) (dispatch) =
DockPanel.create [
DockPanel.children [
@@ -23,7 +26,7 @@ module Counter =
Button.dock Dock.Bottom
Button.onClick (fun _ -> dispatch Reset)
Button.content "reset"
- ]
+ ]
Button.create [
Button.dock Dock.Bottom
Button.onClick (fun _ -> dispatch Decrement)
@@ -42,4 +45,4 @@ module Counter =
TextBlock.text (string state.count)
]
]
- ]
\ No newline at end of file
+ ]
diff --git a/TemplateBundle/content/BasicTemplate/Program.fs b/TemplateBundle/content/BasicTemplate/Program.fs
index a7084d2..f25fdc7 100644
--- a/TemplateBundle/content/BasicTemplate/Program.fs
+++ b/TemplateBundle/content/BasicTemplate/Program.fs
@@ -10,45 +10,47 @@ open Avalonia.FuncUI.Components.Hosts
type MainWindow() as this =
inherit HostWindow()
+
do
base.Title <- "BasicTemplate"
base.Width <- 400.0
base.Height <- 400.0
-
+
//this.VisualRoot.VisualRoot.Renderer.DrawFps <- true
//this.VisualRoot.VisualRoot.Renderer.DrawDirtyRects <- true
-
+//-:cnd:noEmit
#if DEBUG
this.AttachDevTools(KeyGesture(Key.F12))
#endif
+//+:cnd:noEmit
Elmish.Program.mkSimple (fun () -> Counter.init) Counter.update Counter.view
|> Program.withHost this
+//-:cnd:noEmit
#if DEBUG
|> Program.withConsoleTrace
#endif
+//+:cnd:noEmit
|> Program.run
-
+
type App() =
inherit Application()
override this.Initialize() =
- this.Styles.Load "avares://Avalonia.Themes.Default/DefaultTheme.xaml"
- this.Styles.Load "avares://Avalonia.Themes.Default/Accents/BaseDark.xaml"
+ this.Styles.Load "avares://Avalonia.Themes.Fluent/FluentDark.xaml"
override this.OnFrameworkInitializationCompleted() =
match this.ApplicationLifetime with
- | :? IClassicDesktopStyleApplicationLifetime as desktopLifetime ->
- desktopLifetime.MainWindow <- MainWindow()
+ | :? IClassicDesktopStyleApplicationLifetime as desktopLifetime -> desktopLifetime.MainWindow <- MainWindow()
| _ -> ()
module Program =
[]
- let main(args: string[]) =
+ let main (args: string []) =
AppBuilder
.Configure()
.UsePlatformDetect()
.UseSkia()
- .StartWithClassicDesktopLifetime(args)
\ No newline at end of file
+ .StartWithClassicDesktopLifetime(args)
diff --git a/TemplateBundle/content/FullTemplate/About.fs b/TemplateBundle/content/FullTemplate/About.fs
index d12fe0d..6368070 100644
--- a/TemplateBundle/content/FullTemplate/About.fs
+++ b/TemplateBundle/content/FullTemplate/About.fs
@@ -13,8 +13,7 @@ module About =
open Avalonia.FuncUI.DSL
- type State =
- { noop: bool }
+ type State = { noop: bool }
type Links =
| AvaloniaRepository
@@ -33,9 +32,9 @@ module About =
let update (msg: Msg) (state: State) =
match msg with
- | OpenUrl link ->
- let url =
- match link with
+ | OpenUrl link ->
+ let url =
+ match link with
| AvaloniaRepository -> "https://github.com/AvaloniaUI/Avalonia"
| AvaloniaAwesome -> "https://github.com/AvaloniaCommunity/awesome-avalonia"
| AvaloniaGitter -> "https://gitter.im/AvaloniaUI"
@@ -44,17 +43,21 @@ module About =
| FuncUIGitter -> "https://gitter.im/Avalonia-FuncUI"
| FuncUINetTemplates -> "https://github.com/AvaloniaCommunity/Avalonia.FuncUI.ProjectTemplates"
| FuncUISamples -> "https://github.com/AvaloniaCommunity/Avalonia.FuncUI/tree/master/src/Examples"
-
+
if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
let start = sprintf "/c start %s" url
- Process.Start(ProcessStartInfo("cmd", start)) |> ignore
+
+ Process.Start(ProcessStartInfo("cmd", start))
+ |> ignore
else if RuntimeInformation.IsOSPlatform(OSPlatform.Linux) then
Process.Start("xdg-open", url) |> ignore
else if RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then
Process.Start("open", url) |> ignore
+
+
state, Cmd.none
- let headerView (dock: Dock): IView =
+ let headerView (dock: Dock): IView =
StackPanel.create [
StackPanel.dock dock
StackPanel.verticalAlignment VerticalAlignment.Top
@@ -65,17 +68,17 @@ module About =
]
TextBlock.create [
TextBlock.classes [ "subtitle" ]
- TextBlock.text (
- "Avalonia.FuncUI is a project that provides you with an Elmish DSL for Avalonia Controls\n" +
- "for you to use in an F# idiomatic way. We hope you like the project and spread the word :)\n" +
- "Questions ? Reach to us on Gitter, also check the links below"
- )
+ TextBlock.text
+ ("Avalonia.FuncUI is a project that provides you with an Elmish DSL for Avalonia Controls\n"
+ + "for you to use in an F# idiomatic way. We hope you like the project and spread the word :)\n"
+ + "Questions ? Reach to us on Gitter, also check the links below")
]
]
- ] |> Helpers.generalize
-
-
- let avaloniaLinksView (dock: Dock) (dispatch: Msg -> unit) : IView =
+ ]
+ |> Helpers.generalize
+
+
+ let avaloniaLinksView (dock: Dock) (dispatch: Msg -> unit): IView =
StackPanel.create [
StackPanel.dock dock
StackPanel.horizontalAlignment HorizontalAlignment.Left
@@ -86,28 +89,29 @@ module About =
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaRepository))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaRepository))
TextBlock.text "Avalonia Repository"
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaAwesome))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaAwesome))
TextBlock.text "Awesome Avalonia"
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaGitter))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaGitter))
TextBlock.text "Gitter"
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaCommunity))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaCommunity))
TextBlock.text "Avalonia Community"
]
]
- ] |> Helpers.generalize
-
- let avaloniaFuncUILinksView (dock: Dock) (dispatch: Msg -> unit) : IView =
+ ]
+ |> Helpers.generalize
+
+ let avaloniaFuncUILinksView (dock: Dock) (dispatch: Msg -> unit): IView =
StackPanel.create [
StackPanel.dock dock
StackPanel.horizontalAlignment HorizontalAlignment.Right
@@ -118,27 +122,28 @@ module About =
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUIRepository))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUIRepository))
TextBlock.text "Avalonia.FuncUI Repository"
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUIGitter))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUIGitter))
TextBlock.text "Gitter"
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUINetTemplates))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUINetTemplates))
TextBlock.text ".Net Templates"
]
TextBlock.create [
TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUISamples))
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUISamples))
TextBlock.text "Samples"
- ]
+ ]
]
- ] |> Helpers.generalize
-
+ ]
+ |> Helpers.generalize
+
let view (state: State) (dispatch: Msg -> unit) =
DockPanel.create [
DockPanel.horizontalAlignment HorizontalAlignment.Center
@@ -149,4 +154,4 @@ module About =
avaloniaLinksView Dock.Left dispatch
avaloniaFuncUILinksView Dock.Right dispatch
]
- ]
\ No newline at end of file
+ ]
diff --git a/TemplateBundle/content/FullTemplate/Counter.fs b/TemplateBundle/content/FullTemplate/Counter.fs
index f44135a..0df5366 100644
--- a/TemplateBundle/content/FullTemplate/Counter.fs
+++ b/TemplateBundle/content/FullTemplate/Counter.fs
@@ -4,18 +4,21 @@ module Counter =
open Avalonia.Controls
open Avalonia.FuncUI.DSL
open Avalonia.Layout
-
- type State = { count : int }
+
+ type State = { count: int }
let init = { count = 0 }
- type Msg = Increment | Decrement | Reset
+ type Msg =
+ | Increment
+ | Decrement
+ | Reset
- let update (msg: Msg) (state: State) : State =
+ let update (msg: Msg) (state: State): State =
match msg with
| Increment -> { state with count = state.count + 1 }
| Decrement -> { state with count = state.count - 1 }
| Reset -> init
-
+
let view (state: State) (dispatch) =
DockPanel.create [
DockPanel.children [
@@ -37,7 +40,7 @@ module Counter =
Button.create [
Button.onClick (fun _ -> dispatch Reset)
Button.content "reset"
- ]
+ ]
]
]
@@ -49,4 +52,4 @@ module Counter =
TextBlock.text (string state.count)
]
]
- ]
\ No newline at end of file
+ ]
diff --git a/TemplateBundle/content/FullTemplate/FullTemplate.fsproj b/TemplateBundle/content/FullTemplate/FullTemplate.fsproj
index f10f466..b65b455 100644
--- a/TemplateBundle/content/FullTemplate/FullTemplate.fsproj
+++ b/TemplateBundle/content/FullTemplate/FullTemplate.fsproj
@@ -14,10 +14,10 @@
-
-
-
-
+
+
+
+
diff --git a/TemplateBundle/content/FullTemplate/Program.fs b/TemplateBundle/content/FullTemplate/Program.fs
index f9e3bf9..42a6357 100644
--- a/TemplateBundle/content/FullTemplate/Program.fs
+++ b/TemplateBundle/content/FullTemplate/Program.fs
@@ -24,7 +24,8 @@ module Program =
[]
let main (args: string []) =
- AppBuilder.Configure()
+ AppBuilder
+ .Configure()
.UsePlatformDetect()
.UseSkia()
.StartWithClassicDesktopLifetime(args)
diff --git a/TemplateBundle/content/FullTemplate/Shell.fs b/TemplateBundle/content/FullTemplate/Shell.fs
index 8febee9..0bde718 100644
--- a/TemplateBundle/content/FullTemplate/Shell.fs
+++ b/TemplateBundle/content/FullTemplate/Shell.fs
@@ -18,7 +18,8 @@ module Shell =
type State =
/// store the child state in your main state
- { aboutState: About.State; counterState: Counter.State;}
+ { aboutState: About.State
+ counterState: Counter.State }
type Msg =
| AboutMsg of About.Msg
@@ -27,7 +28,9 @@ module Shell =
let init =
let aboutState, aboutCmd = About.init
let counterState = Counter.init
- { aboutState = aboutState; counterState = counterState },
+
+ { aboutState = aboutState
+ counterState = counterState },
/// If your children controls don't emit any commands
/// in the init function, you can just return Cmd.none
/// otherwise, you can use a batch operation on all of them
@@ -37,32 +40,39 @@ module Shell =
let update (msg: Msg) (state: State): State * Cmd<_> =
match msg with
| AboutMsg bpmsg ->
- let aboutState, cmd =
- About.update bpmsg state.aboutState
+ let aboutState, cmd = About.update bpmsg state.aboutState
+
{ state with aboutState = aboutState },
- /// map the message to the kind of message
+ /// map the message to the kind of message
/// your child control needs to handle
Cmd.map AboutMsg cmd
| CounterMsg countermsg ->
let counterMsg =
Counter.update countermsg state.counterState
+
{ state with counterState = counterMsg },
- /// map the message to the kind of message
+ /// map the message to the kind of message
/// your child control needs to handle
Cmd.none
let view (state: State) (dispatch) =
- DockPanel.create
- [ DockPanel.children
- [ TabControl.create
- [ TabControl.tabStripPlacement Dock.Top
- TabControl.viewItems
- [ TabItem.create
- [ TabItem.header "Counter Sample"
- TabItem.content (Counter.view state.counterState (CounterMsg >> dispatch)) ]
- TabItem.create
- [ TabItem.header "About"
- TabItem.content (About.view state.aboutState (AboutMsg >> dispatch)) ] ] ] ] ]
+ DockPanel.create [
+ DockPanel.children [
+ TabControl.create [
+ TabControl.tabStripPlacement Dock.Top
+ TabControl.viewItems [
+ TabItem.create [
+ TabItem.header "Counter Sample"
+ TabItem.content (Counter.view state.counterState (CounterMsg >> dispatch))
+ ]
+ TabItem.create [
+ TabItem.header "About"
+ TabItem.content (About.view state.aboutState (AboutMsg >> dispatch))
+ ]
+ ]
+ ]
+ ]
+ ]
/// This is the main window of your application
/// you can do all sort of useful things here like setting heights and widths
@@ -70,6 +80,7 @@ module Shell =
/// Avalonia
type MainWindow() as this =
inherit HostWindow()
+
do
base.Title <- "Full App"
base.Width <- 800.0
@@ -79,13 +90,18 @@ module Shell =
//this.VisualRoot.VisualRoot.Renderer.DrawFps <- true
//this.VisualRoot.VisualRoot.Renderer.DrawDirtyRects <- true
+//-:cnd:noEmit
#if DEBUG
this.AttachDevTools(KeyGesture(Key.F12))
#endif
+//+:cnd:noEmit
+
Elmish.Program.mkProgram (fun () -> init) update view
|> Program.withHost this
+//-:cnd:noEmit
#if DEBUG
|> Program.withConsoleTrace
#endif
+//+:cnd:noEmit
|> Program.run
diff --git a/TemplateBundle/content/FullTemplate/Styles.xaml b/TemplateBundle/content/FullTemplate/Styles.xaml
index f85c78a..0b16e78 100644
--- a/TemplateBundle/content/FullTemplate/Styles.xaml
+++ b/TemplateBundle/content/FullTemplate/Styles.xaml
@@ -1,7 +1,7 @@
-
+
@@ -49,4 +49,4 @@
-
\ No newline at end of file
+
diff --git a/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/QuickStart.Core.Tests.fsproj b/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/QuickStart.Core.Tests.fsproj
index a66d4ad..0dfe537 100644
--- a/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/QuickStart.Core.Tests.fsproj
+++ b/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/QuickStart.Core.Tests.fsproj
@@ -2,7 +2,7 @@
Exe
- netcoreapp3.0
+ netcoreapp3.1
false
diff --git a/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/Sample.fs b/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/Sample.fs
index 3f97524..871e010 100644
--- a/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/Sample.fs
+++ b/TemplateBundle/content/QuickStart/QuickStart.Core.Tests/Sample.fs
@@ -8,24 +8,29 @@ module Sample =
[]
let tests =
- testList "samples"
+ testList
+ "samples"
[ test "Hello, World!" {
/// Testing our Core Library
let actual = hello "World!"
Expect.equal actual "Hello, World!" "hello Should say Hello, World!"
}
/// Expecto Tests sample https://github.com/haf/expecto#expecto
- testCase "universe exists (╭ರᴥ•́)" <| fun _ ->
+ testCase "universe exists (╭ರᴥ•́)"
+ <| fun _ ->
let subject = true
Expect.isTrue subject "I compute, therefore I am."
- testCase "when true is not (should fail)" <| fun _ ->
+ testCase "when true is not (should fail)"
+ <| fun _ ->
let subject = false
Expect.isTrue subject "I should fail because the subject is false"
- testCase "I'm skipped (should skip)" <| fun _ -> Tests.skiptest "Yup, waiting for a sunny day..."
+ testCase "I'm skipped (should skip)"
+ <| fun _ -> Tests.skiptest "Yup, waiting for a sunny day..."
- testCase "I'm always fail (should fail)" <| fun _ -> Tests.failtest "This was expected..."
+ testCase "I'm always fail (should fail)"
+ <| fun _ -> Tests.failtest "This was expected..."
testCase "contains things"
<| fun _ -> Expect.containsAll [| 2; 3; 4 |] [| 2; 4 |] "This is the case; {2,3,4} contains {2,4}"
diff --git a/TemplateBundle/content/QuickStart/QuickStart.Core/Users.fs b/TemplateBundle/content/QuickStart/QuickStart.Core/Users.fs
index 0a98d67..e338a45 100644
--- a/TemplateBundle/content/QuickStart/QuickStart.Core/Users.fs
+++ b/TemplateBundle/content/QuickStart/QuickStart.Core/Users.fs
@@ -3,8 +3,8 @@ namespace QuickStart.Core
open System.Net.Http
open System.IO
-/// This is a sample module that grabs users from
-/// https://randomuser.me/ and also showcases how can you leverage
+/// This is a sample module that grabs users from
+/// https://randomuser.me/ and also showcases how can you leverage
/// F# TypeProviders in an idiomatic way that fits F# style
/// Use modules like this to abstract logic and allow yourself to re-use
/// code among projects (other apps, or server side logic)
@@ -15,8 +15,11 @@ module Users =
let getUsers (page: int option) (limit: int option) =
let page = defaultArg page 1
let limit = defaultArg limit 10
+
async {
- let url = sprintf "%s?page=%i&results=%i" baseurl page limit
+ let url =
+ sprintf "%s?page=%i&results=%i" baseurl page limit
+
let! sample = UserEndpoint.AsyncLoad(url)
return sample.Results
}
@@ -37,5 +40,4 @@ module Users =
return user, name
}
- let getFulNameStr (name: UserEndpoint.Name) =
- sprintf "%s %s" name.First name.Last
+ let getFulNameStr (name: UserEndpoint.Name) = sprintf "%s %s" name.First name.Last
diff --git a/TemplateBundle/content/QuickStart/QuickStart/About.fs b/TemplateBundle/content/QuickStart/QuickStart/About.fs
index d477892..e45c12a 100644
--- a/TemplateBundle/content/QuickStart/QuickStart/About.fs
+++ b/TemplateBundle/content/QuickStart/QuickStart/About.fs
@@ -11,8 +11,7 @@ module About =
open Avalonia.FuncUI.DSL
- type State =
- { noop: bool }
+ type State = { noop: bool }
type Links =
| AvaloniaRepository
@@ -31,9 +30,9 @@ module About =
let update (msg: Msg) (state: State) =
match msg with
- | OpenUrl link ->
- let url =
- match link with
+ | OpenUrl link ->
+ let url =
+ match link with
| AvaloniaRepository -> "https://github.com/AvaloniaUI/Avalonia"
| AvaloniaAwesome -> "https://github.com/AvaloniaCommunity/awesome-avalonia"
| AvaloniaGitter -> "https://gitter.im/AvaloniaUI"
@@ -42,77 +41,102 @@ module About =
| FuncUIGitter -> "https://gitter.im/Avalonia-FuncUI"
| FuncUINetTemplates -> "https://github.com/AvaloniaCommunity/Avalonia.FuncUI.ProjectTemplates"
| FuncUISamples -> "https://github.com/AvaloniaCommunity/Avalonia.FuncUI/tree/master/src/Examples"
-
+
if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then
let start = sprintf "/c start %s" url
- Process.Start(ProcessStartInfo("cmd", start)) |> ignore
+
+ Process.Start(ProcessStartInfo("cmd", start))
+ |> ignore
else if RuntimeInformation.IsOSPlatform(OSPlatform.Linux) then
Process.Start("xdg-open", url) |> ignore
else if RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then
Process.Start("open", url) |> ignore
+
+
+
state, Cmd.none
let view (state: State) (dispatch: Msg -> unit) =
- DockPanel.create
- [ DockPanel.horizontalAlignment HorizontalAlignment.Center
- DockPanel.verticalAlignment VerticalAlignment.Top
- DockPanel.children
- [ StackPanel.create
- [ StackPanel.dock Dock.Top
- StackPanel.verticalAlignment VerticalAlignment.Top
- StackPanel.children
- [ TextBlock.create
- [ TextBlock.classes [ "title" ]
- TextBlock.text "Thank you for using Avalonia.FuncUI" ]
- TextBlock.create
- [ TextBlock.classes [ "subtitle" ]
- TextBlock.text
- ("Avalonia.FuncUI is a project that provides you with an Elmish DSL for Avalonia Controls\n" +
- "for you to use in an F# idiomatic way. We hope you like the project and spread the word :)\n" +
- "Do Have questions? Reach to us on gitter, also check the links below") ] ] ]
- StackPanel.create
- [ StackPanel.dock Dock.Left
- StackPanel.horizontalAlignment HorizontalAlignment.Left
- StackPanel.children
- [ TextBlock.create
- [ TextBlock.classes [ "title" ]
- TextBlock.text "Avalonia" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaRepository))
- TextBlock.text "Avalonia Repository" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaAwesome))
- TextBlock.text "Awesome Avalonia" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaGitter))
- TextBlock.text "Gitter" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl AvaloniaCommunity))
- TextBlock.text "Avalonia Community" ] ] ]
- StackPanel.create
- [ StackPanel.dock Dock.Right
- StackPanel.horizontalAlignment HorizontalAlignment.Right
- StackPanel.children
- [ TextBlock.create
- [ TextBlock.classes [ "title" ]
- TextBlock.text "Avalonia.FuncUI" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUIRepository))
- TextBlock.text "Avalonia.FuncUI Repository" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUIGitter))
- TextBlock.text "Gitter" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUINetTemplates))
- TextBlock.text ".Net Templates" ]
- TextBlock.create
- [ TextBlock.classes [ "link" ]
- TextBlock.onTapped(fun _ -> dispatch (OpenUrl FuncUISamples))
- TextBlock.text "Samples" ] ] ] ] ]
+ DockPanel.create [
+ DockPanel.horizontalAlignment HorizontalAlignment.Center
+ DockPanel.verticalAlignment VerticalAlignment.Top
+ DockPanel.children [
+ StackPanel.create [
+ StackPanel.dock Dock.Top
+ StackPanel.verticalAlignment VerticalAlignment.Top
+ StackPanel.children [
+ TextBlock.create [
+ TextBlock.classes [ "title" ]
+ TextBlock.text "Thank you for using Avalonia.FuncUI"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "subtitle" ]
+ TextBlock.text
+ ("Avalonia.FuncUI is a project that provides you with an Elmish DSL for Avalonia Controls\n"
+ + "for you to use in an F# idiomatic way. We hope you like the project and spread the word :)\n"
+ + "Do Have questions? Reach to us on gitter, also check the links below")
+ ]
+ ]
+ ]
+ StackPanel.create [
+ StackPanel.dock Dock.Left
+ StackPanel.horizontalAlignment HorizontalAlignment.Left
+ StackPanel.children [
+ TextBlock.create [
+ TextBlock.classes [ "title" ]
+ TextBlock.text "Avalonia"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaRepository))
+ TextBlock.text "Avalonia Repository"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaAwesome))
+ TextBlock.text "Awesome Avalonia"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaGitter))
+ TextBlock.text "Gitter"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl AvaloniaCommunity))
+ TextBlock.text "Avalonia Community"
+ ]
+ ]
+ ]
+ StackPanel.create [
+ StackPanel.dock Dock.Right
+ StackPanel.horizontalAlignment HorizontalAlignment.Right
+ StackPanel.children [
+ TextBlock.create [
+ TextBlock.classes [ "title" ]
+ TextBlock.text "Avalonia.FuncUI"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUIRepository))
+ TextBlock.text "Avalonia.FuncUI Repository"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUIGitter))
+ TextBlock.text "Gitter"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUINetTemplates))
+ TextBlock.text ".Net Templates"
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "link" ]
+ TextBlock.onTapped (fun _ -> dispatch (OpenUrl FuncUISamples))
+ TextBlock.text "Samples"
+ ]
+ ]
+ ]
+ ]
+ ]
diff --git a/TemplateBundle/content/QuickStart/QuickStart/Program.fs b/TemplateBundle/content/QuickStart/QuickStart/Program.fs
index 712957e..28b3fcd 100644
--- a/TemplateBundle/content/QuickStart/QuickStart/Program.fs
+++ b/TemplateBundle/content/QuickStart/QuickStart/Program.fs
@@ -24,7 +24,8 @@ module Program =
[]
let main (args: string []) =
- AppBuilder.Configure()
+ AppBuilder
+ .Configure()
.UsePlatformDetect()
.UseSkia()
.StartWithClassicDesktopLifetime(args)
diff --git a/TemplateBundle/content/QuickStart/QuickStart/QuickStart.fsproj b/TemplateBundle/content/QuickStart/QuickStart/QuickStart.fsproj
index 69928ba..20ddd0f 100644
--- a/TemplateBundle/content/QuickStart/QuickStart/QuickStart.fsproj
+++ b/TemplateBundle/content/QuickStart/QuickStart/QuickStart.fsproj
@@ -15,10 +15,10 @@
-
-
-
-
+
+
+
+
diff --git a/TemplateBundle/content/QuickStart/QuickStart/Shell.fs b/TemplateBundle/content/QuickStart/QuickStart/Shell.fs
index 182e651..7ffa4ce 100644
--- a/TemplateBundle/content/QuickStart/QuickStart/Shell.fs
+++ b/TemplateBundle/content/QuickStart/QuickStart/Shell.fs
@@ -16,14 +16,13 @@ module Shell =
open Avalonia.FuncUI.DSL
open Avalonia.FuncUI.Elmish
- type State =
- { aboutState: About.State }
+ type State = { aboutState: About.State }
- type Msg =
- | AboutMsg of About.Msg
+ type Msg = AboutMsg of About.Msg
let init =
let aboutState, bpCmd = About.init
+
{ aboutState = aboutState },
/// If your children controls don't emit any commands
/// in the init function, you can just return Cmd.none
@@ -34,32 +33,39 @@ module Shell =
let update (msg: Msg) (state: State): State * Cmd<_> =
match msg with
| AboutMsg bpmsg ->
- let aboutState, cmd =
- About.update bpmsg state.aboutState
+ let aboutState, cmd = About.update bpmsg state.aboutState
+
{ state with aboutState = aboutState },
- /// map the message to the kind of message
+ /// map the message to the kind of message
/// your child control needs to handle
Cmd.map AboutMsg cmd
let view (state: State) (dispatch) =
- DockPanel.create
- [ DockPanel.children
- [ TabControl.create
- [ TabControl.tabStripPlacement Dock.Top
- TabControl.viewItems
- [ TabItem.create
- [ TabItem.header "TreeView Page"
- /// If you don't need to be aware of the child control's state
- /// you can use the ViewBuilder to create the Host element and render it
- TabItem.content (ViewBuilder.Create([])) ]
- TabItem.create
- [ TabItem.header "User Profiles Page"
- TabItem.content (ViewBuilder.Create([])) ]
- TabItem.create
- [ TabItem.header "About"
- /// Use your child control's view function to render it, also don't forget to compose
- /// your dispatch function so it can handle the child control's message
- TabItem.content (About.view state.aboutState (AboutMsg >> dispatch)) ] ] ] ] ]
+ DockPanel.create [
+ DockPanel.children [
+ TabControl.create [
+ TabControl.tabStripPlacement Dock.Top
+ TabControl.viewItems [
+ TabItem.create [
+ TabItem.header "TreeView Page"
+ /// If you don't need to be aware of the child control's state
+ /// you can use the ViewBuilder to create the Host element and render it
+ TabItem.content (ViewBuilder.Create([]))
+ ]
+ TabItem.create [
+ TabItem.header "User Profiles Page"
+ TabItem.content (ViewBuilder.Create([]))
+ ]
+ TabItem.create [
+ TabItem.header "About"
+ /// Use your child control's view function to render it, also don't forget to compose
+ /// your dispatch function so it can handle the child control's message
+ TabItem.content (About.view state.aboutState (AboutMsg >> dispatch))
+ ]
+ ]
+ ]
+ ]
+ ]
/// This is the main window of your application
/// you can do all sort of useful things here like setting heights and widths
@@ -67,6 +73,7 @@ module Shell =
/// Avalonia
type MainWindow() as this =
inherit HostWindow()
+
do
base.Title <- "Quickstart"
base.Width <- 800.0
@@ -76,13 +83,16 @@ module Shell =
//this.VisualRoot.VisualRoot.Renderer.DrawFps <- true
//this.VisualRoot.VisualRoot.Renderer.DrawDirtyRects <- true
+//-:cnd:noEmit
#if DEBUG
this.AttachDevTools(KeyGesture(Key.F12))
#endif
-
+//+:cnd:noEmit
Elmish.Program.mkProgram (fun () -> init) update view
|> Program.withHost this
+//-:cnd:noEmit
#if DEBUG
|> Program.withConsoleTrace
#endif
+//+:cnd:noEmit
|> Program.run
diff --git a/TemplateBundle/content/QuickStart/QuickStart/Styles.xaml b/TemplateBundle/content/QuickStart/QuickStart/Styles.xaml
index 0890604..15cc3da 100644
--- a/TemplateBundle/content/QuickStart/QuickStart/Styles.xaml
+++ b/TemplateBundle/content/QuickStart/QuickStart/Styles.xaml
@@ -1,7 +1,7 @@
-
+
@@ -37,4 +37,4 @@
-
\ No newline at end of file
+
diff --git a/TemplateBundle/content/QuickStart/QuickStart/TreeViewPage.fs b/TemplateBundle/content/QuickStart/QuickStart/TreeViewPage.fs
index f56556f..0843ed9 100644
--- a/TemplateBundle/content/QuickStart/QuickStart/TreeViewPage.fs
+++ b/TemplateBundle/content/QuickStart/QuickStart/TreeViewPage.fs
@@ -21,19 +21,14 @@ module TreeViewPage =
Children =
[ { Name = "Fruit"
Children =
- [ { Name = "Tomato"
- Children = [] }
- { Name = "Apple"
- Children = [] } ] }
+ [ { Name = "Tomato"; Children = [] }
+ { Name = "Apple"; Children = [] } ] }
{ Name = "Vegetables"
Children =
- [ { Name = "Carrot"
- Children = [] }
- { Name = "Salad"
- Children = [] } ] } ] }
+ [ { Name = "Carrot"; Children = [] }
+ { Name = "Salad"; Children = [] } ] } ] }
- type State =
- { detail: Taxonomy option }
+ type State = { detail: Taxonomy option }
let init = { detail = None }
@@ -44,53 +39,68 @@ module TreeViewPage =
| ShowDetail taxonomy -> { state with detail = Some taxonomy }
let view (state: State) (dispatch: Msg -> unit) =
- DockPanel.create
- [ DockPanel.children
- [ yield TreeView.create
- [ TreeView.dock Dock.Left
- /// dataItems refers to the source of your control's data
- /// these are going to be iterated to fill your template's contents
- TreeView.dataItems [ food ]
- TreeView.itemTemplate
- /// You can pass the type of your data collection
- /// to have a safe type reference in the create function
- (DataTemplateView
- .create
- ((fun data -> data.Children),
- (fun data ->
- TextBlock.create
- [ TextBlock.onTapped (fun _ -> dispatch (ShowDetail data))
- TextBlock.text data.Name ]))) ]
- /// Use Pattern Matching to decide what you want to show
- /// based on your state's content
- match state.detail with
- | Some taxonomy ->
- yield StackPanel.create
- [ StackPanel.horizontalAlignment HorizontalAlignment.Center
- StackPanel.spacing 8.0
- StackPanel.children
- [ TextBlock.create [ TextBlock.text (sprintf "Name: %s" taxonomy.Name) ]
- StackPanel.create
- [ StackPanel.spacing 8.0
- StackPanel.orientation Orientation.Horizontal
- StackPanel.children
- [ yield TextBlock.create [ TextBlock.text "Children: " ]
- for child in taxonomy.Children do
- yield TextBlock.create [ TextBlock.text child.Name ] ] ] ] ]
- | None ->
- yield TextBlock.create
- [ StackPanel.horizontalAlignment HorizontalAlignment.Center
- TextBlock.text "Select a taxonomy" ] ] ]
+ DockPanel.create [
+ DockPanel.children [
+ TreeView.create [
+ TreeView.dock Dock.Left
+ /// dataItems refers to the source of your control's data
+ /// these are going to be iterated to fill your template's contents
+ TreeView.dataItems [ food ]
+ TreeView.itemTemplate
+ /// You can pass the type of your data collection
+ /// to have a safe type reference in the create function
+ (DataTemplateView
+ .create((fun data -> data.Children),
+ (fun data ->
+ TextBlock.create [
+ TextBlock.onTapped (fun _ -> dispatch (ShowDetail data))
+ TextBlock.text data.Name
+ ])))
+ ]
+ /// Use Pattern Matching to decide what you want to show
+ /// based on your state's content
+ match state.detail with
+ | Some taxonomy ->
+ StackPanel.create [
+ StackPanel.horizontalAlignment HorizontalAlignment.Center
+ StackPanel.spacing 8.0
+ StackPanel.children [
+ TextBlock.create [
+ TextBlock.text (sprintf "Name: %s" taxonomy.Name)
+ ]
+ StackPanel.create [
+ StackPanel.spacing 8.0
+ StackPanel.orientation Orientation.Horizontal
+ StackPanel.children [
+ TextBlock.create [
+ TextBlock.text "Children: "
+ ]
+ for child in taxonomy.Children do
+ TextBlock.create [
+ TextBlock.text child.Name
+ ]
+ ]
+ ]
+ ]
+ ]
+ | None ->
+ TextBlock.create [
+ StackPanel.horizontalAlignment HorizontalAlignment.Center
+ TextBlock.text "Select a taxonomy"
+ ]
+ ]
+ ]
type Host() as this =
inherit Hosts.HostControl()
+
do
/// You can use `.mkProgram` to pass Commands around
/// if you decide to use it, you have to also return a Command in the initFn
/// (init, Cmd.none)
/// you can learn more at https://elmish.github.io/elmish/basics.html
- let startFn () =
- init
+ let startFn () = init
+
Elmish.Program.mkSimple startFn update view
|> Program.withHost this
#if DEBUG
diff --git a/TemplateBundle/content/QuickStart/QuickStart/UserProfiles.fs b/TemplateBundle/content/QuickStart/QuickStart/UserProfiles.fs
index 10cdc04..29b2330 100644
--- a/TemplateBundle/content/QuickStart/QuickStart/UserProfiles.fs
+++ b/TemplateBundle/content/QuickStart/QuickStart/UserProfiles.fs
@@ -14,8 +14,7 @@ module UserProfiles =
open QuickStart.Core
/// sample function to load the initial data
- let loadInit() =
- Users.getUsers None None
+ let loadInit () = Users.getUsers None None
type State =
@@ -27,67 +26,82 @@ module UserProfiles =
/// you can dispatch commands in your init if you chose to use `Program.mkProgram`
/// instead of `Program.mkSimple`
- let init = { users = Array.empty }, Cmd.OfAsync.perform loadInit () LoadImages
+ let init =
+ { users = Array.empty }, Cmd.OfAsync.perform loadInit () LoadImages
let update (msg: Msg) (state: State): State * Cmd<_> =
match msg with
| LoadImages users ->
- let loadingImgs() =
+ let loadingImgs () =
async {
- let! requests = users
- |> Array.map (fun user -> Users.getImageFromUrl user user.Picture.Large)
- |> Async.Parallel
- return requests |> Array.Parallel.map (fun (user, src) -> user, new Bitmap(src))
+ let! requests =
+ users
+ |> Array.map (fun user -> Users.getImageFromUrl user user.Picture.Large)
+ |> Async.Parallel
+
+ return
+ requests
+ |> Array.Parallel.map (fun (user, src) -> user, new Bitmap(src))
}
/// if you need to do asynchronous requests
- /// F# and Elmish provide nice constructs like in this case async {} blocks
+ /// F# and Elmish provide nice constructs like in this case async {} blocks
/// and Cmd.OfAsync module. Learn more at
/// https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows
/// https://elmish.github.io/elmish/cmd.html
state, Cmd.OfAsync.perform loadingImgs () SetUsers
- | SetUsers users ->
- { state with users = users }, Cmd.none
+ | SetUsers users -> { state with users = users }, Cmd.none
let private userProfile (user: Users.UserEndpoint.Result, img: Bitmap) =
- WrapPanel.create
- [ WrapPanel.classes [ "userprofile" ]
- WrapPanel.children
- [ Image.create
- [ Image.classes [ "profileimg" ]
- Image.source img ]
- DockPanel.create
- [ DockPanel.classes [ "profilepanel" ]
- DockPanel.children
- [ TextBlock.create
- [ TextBlock.classes [ "profiletitle" ]
- TextBlock.dock Dock.Top
- TextBlock.text user.Name.Title ]
- TextBlock.create
- [ TextBlock.classes [ "profilename" ]
- TextBlock.dock Dock.Top
- TextBlock.text (Users.getFulNameStr user.Name) ]
- TextBlock.create
- [ TextBlock.classes [ "profileemail" ]
- TextBlock.dock Dock.Top
- TextBlock.text user.Email ] ] ] ] ]
+ WrapPanel.create [
+ WrapPanel.classes [ "userprofile" ]
+ WrapPanel.children [
+ Image.create [
+ Image.classes [ "profileimg" ]
+ Image.source img
+ ]
+ DockPanel.create [
+ DockPanel.classes [ "profilepanel" ]
+ DockPanel.children [
+ TextBlock.create [
+ TextBlock.classes [ "profiletitle" ]
+ TextBlock.dock Dock.Top
+ TextBlock.text user.Name.Title
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "profilename" ]
+ TextBlock.dock Dock.Top
+ TextBlock.text (Users.getFulNameStr user.Name)
+ ]
+ TextBlock.create [
+ TextBlock.classes [ "profileemail" ]
+ TextBlock.dock Dock.Top
+ TextBlock.text user.Email
+ ]
+ ]
+ ]
+ ]
+ ]
let view (state: State) (dispatch: Msg -> unit) =
- WrapPanel.create
- [ WrapPanel.classes [ "userprofilesgrid" ]
- WrapPanel.children
- [ for user in state.users do
- yield userProfile user ] ]
+ WrapPanel.create [
+ WrapPanel.classes [ "userprofilesgrid" ]
+ WrapPanel.children [
+ for user in state.users do
+ userProfile user
+ ]
+ ]
type Host() as this =
inherit Hosts.HostControl()
+
do
/// You can use `.mkSimple` yo remove the need of passing a command
/// if you choose to do so, you need to remove command from the tuple on your init fn
/// you can learn more at https://elmish.github.io/elmish/basics.html
- let startFn () =
- init
+ let startFn () = init
+
Elmish.Program.mkProgram startFn update view
|> Program.withHost this
#if DEBUG