Terminal.Gui.Elmish 2.1.172

There is a newer version of this package available.
See the version list below for details.
dotnet add package Terminal.Gui.Elmish --version 2.1.172                
NuGet\Install-Package Terminal.Gui.Elmish -Version 2.1.172                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Terminal.Gui.Elmish" Version="2.1.172" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Terminal.Gui.Elmish --version 2.1.172                
#r "nuget: Terminal.Gui.Elmish, 2.1.172"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Terminal.Gui.Elmish as a Cake Addin
#addin nuget:?package=Terminal.Gui.Elmish&version=2.1.172

// Install Terminal.Gui.Elmish as a Cake Tool
#tool nuget:?package=Terminal.Gui.Elmish&version=2.1.172                

Terminal.Gui.Elmish

Build Status

An elmish wrapper around Miguel de Icaza's 'Gui.cs' https://github.com/migueldeicaza/gui.cs including a Feliz-like like view DSL.

20220614_terminal_gui_2

Major Changes

I decided to rework the DSL to a Feliz-style. Thank you Zaid Ajaj (https://github.com/Zaid-Ajaj/Feliz) for that awesome idea! You can leverage now more the Intellisense of your IDE.
I also introduced a diffing mechanism, so that the elements are not recreated on every cycle. I try actually to update the current elements.

This can be end up sometimes in some weird behavior or exceptions. I try to find all the quirks, but help me out and open an issue if you find something.

Documentation

It's missing again!

Almost all properties from the View-Elements should be available. Some events I extended. For example the Toggled-Event from a checkbox returns the old value in the event.
I mapped the event to return both.

Example

In the examples you find the old project, which I converted to the new DSL

Usage:

Program.mkProgram init update view  
|> Program.run
    

Some fable-elmish DSL:


module Counter

open Terminal.Gui
open Terminal.Gui.Elmish
open System

type Model = {
    Counter:int
    IsSpinning: bool
}

type Msg =
    | Increment
    | Decrement
    | Reset
    | StartSpin
    | StopSpin
    | Spinned

let init () : Model * Cmd<Msg> =
    let model = {
        Counter = 0
        IsSpinning = false
    }
    model, Cmd.none


module Commands =
    let startSpinning isSpinning =
        fun dispatch ->
            async {
                do! Async.Sleep 20
                if isSpinning then
                    dispatch Increment
                    dispatch Spinned
            }
            |> Async.StartImmediate
        |> Cmd.ofSub

let update (msg:Msg) (model:Model) =
    match msg with
    | Increment ->
        {model with Counter = model.Counter + 1}, Cmd.none
    | Decrement ->
        {model with Counter = model.Counter - 1}, Cmd.none
    | Reset ->
        {model with Counter = 0}, Cmd.none
    | StartSpin ->
        {model with IsSpinning = true}, Commands.startSpinning true
    | StopSpin ->
        {model with IsSpinning = false}, Cmd.none
    | Spinned ->
        model, Commands.startSpinning model.IsSpinning
        


let view (model:Model) (dispatch:Msg->unit) =
    View.page [
        page.menuBar [
            menubar.menus [
                menu.menuBarItem [
                    menu.prop.title "Menu 1"
                    menu.prop.children [
                        menu.submenuItem [
                            menu.prop.title "Sub Menu 1"
                            menu.prop.children [
                                menu.menuItem ("Sub Item 1", (fun () -> System.Diagnostics.Debug.WriteLine($"Sub menu 1 triggered")))
                                menu.menuItem [
                                    menu.prop.title "Sub Item 2"
                                    menu.item.action (fun () -> System.Diagnostics.Debug.WriteLine($"Sub menu 2 triggered"))
                                    menu.item.itemstyle.check
                                    menu.item.isChecked true
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
        prop.children [
            View.label [
                prop.position.x.center
                prop.position.y.at 1
                prop.textAlignment.centered
                prop.color (Color.BrightYellow, Color.Green)
                prop.text "'F#ncy' Counter!"
            ] 

            View.button [
                prop.position.x.center
                prop.position.y.at 5
                prop.text "Up"
                button.onClick (fun () -> dispatch Increment)
            ] 

            View.label [
                let c = (model.Counter |> float) / 100.0
                let x = (16.0 * Math.Cos(c)) |> int 
                let y = (8.0 * Math.Sin(c)) |> int

                prop.position.x.at (x + 20)
                prop.position.y.at (y + 10)
                prop.textAlignment.centered
                prop.color (Color.Magenta, Color.BrightYellow)
                prop.text $"The Count of 'Fancyness' is {model.Counter}"
            ] 


            View.button [
                prop.position.x.center
                prop.position.y.at 7
                prop.text "Down"
                button.onClick (fun () -> dispatch Decrement)
            ] 

            View.button [
                prop.position.x.center
                prop.position.y.at 9
                prop.text "Start Spinning"
                button.onClick (fun () -> dispatch StartSpin)
            ] 

            View.button [
                prop.position.x.center
                prop.position.y.at 11
                prop.text "Stop Spinning"
                button.onClick (fun () -> dispatch StopSpin)
            ] 

            View.button [
                prop.position.x.center
                prop.position.y.at 13
                prop.text "Reset"
                button.onClick (fun () -> dispatch Reset)
            ]
        ]
    ]



Install via Nuget:

https://www.nuget.org/packages/Terminal.Gui.Elmish

dotnet add package Terminal.Gui.Elmish

Referencing the underlying Element

You can reference the underlying element. Also use this to influcence further setting when the element is created!

use prop.ref (fun view -> ...)

View.button [
    prop.position.x.center
    prop.position.y.at 13
    prop.text "Reset"
    button.onClick (fun () -> dispatch Reset)
    prop.ref (fun view -> myButtonRef <- (view :?> Terminal.Gui.Button).xxxx // do your stuff here)
]

A lot of Thanks to Miguel de Icaza. Nice Project!.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.0-v2-develop.2329-v1 63 9/21/2024
2.2.1140 240 9/24/2023
2.1.172 618 8/21/2022
2.0.172 408 8/20/2022
2.0.164-preview1 189 6/14/2022
0.1.8-preview1 634 8/2/2020
0.1.7 734 8/1/2020
0.1.6 621 10/8/2019
0.1.5 1,504 8/25/2019
0.1.3 1,606 5/9/2019
0.1.2 1,542 4/29/2019
0.1.1 1,546 4/28/2019
0.1.0 627 4/27/2019

- Bugfixes for event sigantures