Skip to content

Commit

Permalink
GITBOOK-63: No subject
Browse files Browse the repository at this point in the history
  • Loading branch information
JaggerJo authored and gitbook-bot committed Mar 11, 2024
1 parent 7a0f14a commit b60789f
Show file tree
Hide file tree
Showing 45 changed files with 2,493 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions docs/.gitbook/assets/file.excalidraw (1).svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions docs/.gitbook/assets/file.excalidraw (2).svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions docs/.gitbook/assets/file.excalidraw.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
121 changes: 121 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Getting Started

<div align="center">

<figure><img src=".gitbook/assets/Screenshot 2023-02-17 at 21.16.10.png" alt=""><figcaption><p>Screenshot of the example app. (Simple counter app with a text block and two buttons)</p></figcaption></figure>

</div>

## Step 1: Empty Console App

Create a new F# console application targeting .net 6 or higher.&#x20;

## Step 2: Packages

&#x20;Reference the following packages [Avalonia.Desktop](https://www.nuget.org/packages/Avalonia.Desktop/11.0.0-preview5), [Avalonia.Themes.Fluent](https://www.nuget.org/packages/Avalonia.Themes.Fluent/11.0.0-preview5) and [Avalonia.FuncUI](https://www.nuget.org/packages/Avalonia.FuncUI/0.6.0-preview7).

{% tabs %}
{% tab title="dotnet CLI" %}
Run the following commands in your project directory:

```bash
dotnet add package Avalonia.Desktop --version 11.0.0
dotnet add package Avalonia.Themes.Fluent --version 11.0.0
dotnet add package Avalonia.FuncUI --version 1.0.0
```
{% endtab %}

{% tab title="edit Project file" %}
Paste the following package references to your fsproject file:

```html
<PackageReference Include="Avalonia.Desktop" Version="11.0.0" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0" />
<PackageReference Include="Avalonia.FuncUI" Version="1.0.0" />
```
{% endtab %}
{% endtabs %}

## Step 3: Add code to `Program.fs`

```fsharp
namespace CounterApp
open Avalonia
open Avalonia.Controls.ApplicationLifetimes
open Avalonia.Themes.Fluent
open Avalonia.FuncUI.Hosts
open Avalonia.Controls
open Avalonia.FuncUI
open Avalonia.FuncUI.DSL
open Avalonia.Layout
module Main =
let view () =
Component(fun ctx ->
let state = ctx.useState 0
DockPanel.create [
DockPanel.children [
Button.create [
Button.dock Dock.Bottom
Button.onClick (fun _ -> state.Set(state.Current - 1))
Button.content "-"
Button.horizontalAlignment HorizontalAlignment.Stretch
Button.horizontalContentAlignment HorizontalAlignment.Center
]
Button.create [
Button.dock Dock.Bottom
Button.onClick (fun _ -> state.Set(state.Current + 1))
Button.content "+"
Button.horizontalAlignment HorizontalAlignment.Stretch
Button.horizontalContentAlignment HorizontalAlignment.Center
]
TextBlock.create [
TextBlock.dock Dock.Top
TextBlock.fontSize 48.0
TextBlock.verticalAlignment VerticalAlignment.Center
TextBlock.horizontalAlignment HorizontalAlignment.Center
TextBlock.text (string state.Current)
]
]
]
)
type MainWindow() =
inherit HostWindow()
do
base.Title <- "Counter Example"
base.Content <- Main.view ()
type App() =
inherit Application()
override this.Initialize() =
this.Styles.Add (FluentTheme())
this.RequestedThemeVariant <- Styling.ThemeVariant.Dark
override this.OnFrameworkInitializationCompleted() =
match this.ApplicationLifetime with
| :? IClassicDesktopStyleApplicationLifetime as desktopLifetime ->
desktopLifetime.MainWindow <- MainWindow()
| _ -> ()
module Program =
[<EntryPoint>]
let main(args: string[]) =
AppBuilder
.Configure<App>()
.UsePlatformDetect()
.UseSkia()
.StartWithClassicDesktopLifetime(args)
```

## Step 4: build and run 🎉

```bash
dotnet run
```
37 changes: 37 additions & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Table of contents

* [Getting Started](README.md)
* [View Basics](view-basics/README.md)
* [Creating views](view-basics/creating-views.md)
* [Lifetime](view-basics/lifetime.md)
* [Attributes](view-basics/attributes.md)
* [How to create bindings](view-basics/how-to-create-bindings.md)
* [Components](components/README.md)
* [Component basics](components/component-basics.md)
* [Component lifetime](components/component-lifetime.md)
* [Hooks](components/hooks.md)
* [Common Questions](common-questions.md)
* [Controls](controls/README.md)
* [Button](controls/button.md)
* [Border](controls/border.md)
* [Calendar](controls/calendar.md)
* [CalendarDatePicker](controls/calendardatepicker.md)
* [CheckBox](controls/checkbox.md)
* [DatePicker](controls/datepicker.md)
* [DockPanel](controls/dockpanel.md)
* [Expander](controls/expander.md)
* [ListBox](controls/listbox.md)
* [Menu](controls/menu.md)
* [NativeMenu](controls/nativemenu.md)
* [NumericUpDown](controls/numericupdown.md)
* [ProgressBar](controls/progressbar.md)
* [RadioButton](controls/radiobutton.md)
* [RepeatButton](controls/repeatbutton.md)
* [Slider](controls/slider.md)
* [StackPanel](controls/stackpanel.md)
* [Tabs](controls/tabs.md)
* [TextBlock](controls/textblock.md)
* [TextBox](controls/textbox.md)
* [TimePicker](controls/timepicker.md)
* [ToggleButton](controls/togglebutton.md)
* [ToggleSwitch](controls/toggleswitch.md)
114 changes: 114 additions & 0 deletions docs/common-questions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Common Questions

## How do I obtain the reference of a Control?

There are 2 recommended ways of obtaining the reference of an underlaying control. \


### 1. Execute code on control creation

Use the Control.init attribute to run code on control creation.

```fsharp
ListBox.create [
ListBox.init (fun listBox ->
listBox.Items <- [ 1 .. 3 ]
)
]
```

### 2. Obtain a view reference via an outlet

Calls the `listBox.Set` function when the control is created.

```fsharp
Component(fun ctx ->
let listBox = ctx.useState<ListBox>(null)
ctx.useEffect (
handler = (fun _ ->
listBox.Current.Items <- [ 1 .. 3 ]
),
triggers = [ EffectTrigger.AfterInit ]
)
View.createWithOutlet listBox.Set ListBox.create [ ]
)
```

## How do I obtain the reference of a Component?

The Component reference can be accessed via `ctx.control`.

```fsharp
Component(fun ctx ->
ctx.useEffect (
handler = (fun _ ->
ctx.control.Tag <- 0
),
triggers = [ EffectTrigger.AfterInit ]
)
Button.create []
)
```

## How to set attributes on Component level?

```fsharp
Component(fun ctx ->
ctx.attrs [
Component.background "transparent"
Component.borderThickness 1
]
Button.create []
)
```



## How do I restrict what a user can input in a TextBox / AutoCompleteBox / InputElement ?

This is possible by intercepting the [TextInputEvent](https://reference.avaloniaui.net/api/Avalonia.Input/InputElement/FEA4DB21) and modifying its event args. It's important to attache the handler to the tunnelled event. More details about event routing can be found [here](https://docs.avaloniaui.net/docs/input/routed-events#routing-strategies). \
\
In the example below whatever a user types in a TextBox will end up as uppercase text.&#x20;

```fsharp
TextBox.create [
TextBox.init (fun control ->
control.AddHandler(
TextBox.TextInputEvent,
(fun sender args ->
args.Text <- args.Text.ToUpper()
),
RoutingStrategies.Tunnel
)
)
]
```

Here another example that prevents users from entering anything but numbers.

```fsharp
TextBox.create [
TextBox.init (fun control ->
control.AddHandler(
TextBox.TextInputEvent,
(fun sender args -> args.Text <- String.filter Char.IsNumber args.Text),
RoutingStrategies.Tunnel
)
)
]
```

## How to render a Control to an Image?

```fsharp
let renderToFile (target : Control, path : string) =
let pixelSize = PixelSize(int target.Bounds.Width, int target.Bounds.Height)
let size = Size(target.Bounds.Width, target.Bounds.Height)
use bitmap = new RenderTargetBitmap(pixelSize, new Vector(96.0, 96.0))
target.Measure(size)
target.Arrange(Rect(size))
bitmap.Render(target)
bitmap.Save(path)
```
2 changes: 2 additions & 0 deletions docs/components/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Components

54 changes: 54 additions & 0 deletions docs/components/component-basics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Component basics

FuncUI offers a Component inspired by ReactJS. Components allow you to organize views into reusable pieces.&#x20;

There are two ways of creating a component.&#x20;

## Component (fun ctx -> ...)

Creating a component using the regular constructor of the `Component` class. `Component` inherits from `Border` and therefor can be used like any other Avalonia control.

```fsharp
// create a Component that can be directly used in a Avalonia app
let component: Component = Component (fun ctx ->
TextBlock.create [
TextBlock.text "Hello World!"
]
)
// use component as main view of an app
type MainWindow() as this =
inherit HostWindow()
do
this.Content <- component
// embedd component in avalonia app
let control: ContentControl = ..
control.Content <- component
// Creating a component using the View DSL.
// The resulting IView can be used inside other components and with the View DSL.
```

## Component.create ("key", fun ctx -> ...)

Declaratlvely describes a component. Can be embedded in other views as this returns an `IView`

```fsharp
let greetingView (): IView =
Component.create ("greetingView", fun ctx ->
TextBlock.create [
TextBlock.text "Hello World!"
]
)
let view (): IView =
Component.create ("mainView", fun ctx ->
DockPanel.create [
DockPanel.children [
// use other component
greetingView ()
]
]
)
```
Loading

0 comments on commit b60789f

Please sign in to comment.