From 5a80685397abafd92e878dff76622c41e49c3b9e53dfc469082472c54d01d12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Bj=C3=B6rnstam?= Date: Sun, 25 Oct 2026 17:24:32 +0100 Subject: [PATCH] A todo example, and its picture in the Readme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit run-app takes #:screenshot, a path: the window saves a PNG of itself there once it is shown and laid out, at twice its size, and closes. It defaults to the environment variable BJOGUI_SCREENSHOT, so any program can be pictured with no change. docs/todo.png is examples/todo.bjo, taken that way. 🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8) Co-Authored-By: eca-agent --- docs/todo.png | Bin 0 -> 50893 bytes examples/todo.bjo | 103 ++++++++++++++++++++++++++++++++++++++++++++++ src/app.bjo | 49 +++++++++++++++++++++- 3 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 docs/todo.png create mode 100644 examples/todo.bjo diff --git a/docs/todo.png b/docs/todo.png new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..e841f82dff531e782892706610a1dc8ce22d8eb509b23304bbf3123c594a546c GIT binary patch literal 50893 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%0D3iVX0S7Lif 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 XJHEQQqCnNA1Yfr18BIy?g>1~ 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 ZpPeQpZ|bB#(>M$UOIdYajH1C`{|5|~J5&Gw literal 0 HcmV?d00001 diff --git a/examples/todo.bjo b/examples/todo.bjo new file mode 100644 index 0000000..ecdf4ae --- /dev/null +++ b/examples/todo.bjo @@ -0,0 +1,103 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. + +;; bjogui/examples/todo.bjo — a todo list. +;; +;; bjo run examples/todo.bjo +;; +;; The picture in the Readme is this program, taken with +;; +;; BJOGUI_SCREENSHOT=docs/todo.png bjo run examples/todo.bjo + +(import (std prelude)) +(import (bjogui view)) +(import (bjogui app)) + +(type (: Todo (Record (: id int) (: title string) (: done bool)))) + +(type (: Msg (Union (: Typed string) Add (: Toggle int bool) (: Chose int) + ClearDone (: Tab int) (: Size double)))) + +(type (: Model (Record (: todos (List Todo)) (: draft string) (: next-id int) + (: chosen int) (: tab int) (: size double)))) + +(: gui-update (-> Msg Model (Tuple Model (List (Event Msg))))) +(defun (gui-update msg m) + (next + (match msg + ((Typed s) (record-set m (draft s))) + (Add + (if (string-empty? (.draft m)) + m + (record-set m (todos (list-append (.todos m) + (list (Todo (id (.next-id m)) (title (.draft m)) + (done #f))))) + (draft "") + (next-id (+ (.next-id m) 1))))) + ((Toggle id done) + (record-set m (todos (list-map (fun (t) (if (= (.id t) id) (record-set t (done done)) t)) + (.todos m))))) + ((Chose i) (record-set m (chosen i))) + (ClearDone (record-set m (todos (list-filter (fun (t) (not (.done t))) (.todos m))) + (chosen -1))) + ((Tab i) (record-set m (tab i))) + ((Size d) (record-set m (size d)))))) + +(: (-> Model int)) +(defun (done-count m) + (length (list-filter (fun (t) (.done t)) (.todos m)))) + +(: (-> Model double Todo (View Msg))) +(defun (todo-row m size t) + (keyed (int->string (.id t)) + (row #:spacing 8.0 + (checkbox "" (.done t) (fun (b) (Toggle (.id t) b))) + (if (.done t) + (paint (text (.title t) #:size size) #:colour "#7f8c8d") + (text (.title t) #:size size))))) + +(: (-> Model (View Msg))) +(defun (todo-tab m) + (def total (length (.todos m))) + (column #:spacing 10.0 #:margin 12.0 + (grid #:columns "*,Auto" #:spacing 8.0 + (at 0 0 (text-input (.draft m) Typed #:placeholder "What needs doing?")) + (at 0 1 (paint (button "Add" Add #:enabled (not (string-empty? (.draft m)))) + #:background "#27ae60" #:colour "white"))) + (list-box (vec-map (fun (t) (todo-row m (.size m) t)) (list->vec (.todos m))) + (.chosen m) Chose #:height 218.0) + (grid #:columns "*,Auto" #:spacing 8.0 + (at 0 0 (column #:spacing 4.0 + (text #"${(done-count m)} of ${total} done") + (progress-bar (if (= total 0) 0.0 + (/ (cast System.Double (done-count m)) (cast System.Double total)))))) + (at 0 1 (button "Clear done" ClearDone #:enabled (> (done-count m) 0)))))) + +(: (-> Model (View Msg))) +(defun (settings-tab m) + (column #:spacing 10.0 #:margin 12.0 + (text "Text size") + (slider (.size m) 10.0 24.0 Size) + (border (text "Written in Bjolang, drawn by Avalonia." #:wrap #t) + #:colour "#2980b9" #:radius 6.0 #:background "#ecf0f1" #:padding 10.0))) + +(: (-> Model (View Msg))) +(defun (view m) + (column #:margin 8.0 + (paint (text "Things to do" #:size 22.0 #:margin 6.0) #:colour "#2c3e50") + (tabs (.tab m) Tab + (tab "List" (todo-tab m)) + (tab "Settings" (settings-tab m))))) + +(: (-> string bool int Todo)) +(defun (todo title done id) (Todo (id id) (title title) (done done))) + +(defun (main) + (run-app (Model (todos (list (todo "Buy milk" #t 1) + (todo "Write the bjogui Readme" #t 2) + (todo "Add menus and dialogs" #f 3) + (todo "Walk the dog" #f 4))) + (draft "Water the plants") (next-id 5) (chosen 2) (tab 0) (size 14.0)) + gui-update view + #:title "bjogui todo" #:width 420.0 #:height 450.0)) diff --git a/src/app.bjo b/src/app.bjo index fdb7652..d7eb4a6 100644 --- a/src/app.bjo +++ b/src/app.bjo @@ -81,6 +81,13 @@ (ItemCollection (: Avalonia.Controls.ItemCollection)) (IList (: System.Collections.IList)) (ICollection (: System.Collections.ICollection)) + (Timer (: Avalonia.Threading.DispatcherTimer (-> Timer))) + (TimeSpan (: System.TimeSpan)) + (EventArgs (: System.EventArgs)) + (PixelSize (: Avalonia.PixelSize (-> int int PixelSize))) + (Vector (: Avalonia.Vector (-> double double Vector))) + (Visual (: Avalonia.Visual)) + (RenderBitmap (: Avalonia.Media.Imaging.RenderTargetBitmap (-> PixelSize Vector RenderBitmap))) (Controls (: Avalonia.Controls.Controls)) (Panel (: Avalonia.Controls.Panel)) (StackPanel (: Avalonia.Controls.StackPanel (-> StackPanel))) @@ -221,6 +228,16 @@ (start-lifetime (: Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start (-> Lifetime (Array ClrString) int))) (window-title! (: Avalonia.Controls.Window.Title (-> Window string void) #:set)) + (shutdown! (: Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Shutdown + (-> Lifetime int void))) + + ;; A picture of the window, for `#:screenshot`. + (seconds->span (: System.TimeSpan.FromSeconds (-> double TimeSpan))) + (interval! (: Avalonia.Threading.DispatcherTimer.Interval (-> Timer TimeSpan void) #:set)) + (timer-start! (: Avalonia.Threading.DispatcherTimer.Start (-> Timer void))) + (timer-stop! (: Avalonia.Threading.DispatcherTimer.Stop (-> Timer void))) + (render-into! (: Avalonia.Media.Imaging.RenderTargetBitmap.Render (-> RenderBitmap Visual void))) + (save-png! (: Avalonia.Media.Imaging.Bitmap.Save (-> Bitmap string (Nullable int) void))) (window-content! (: Avalonia.Controls.ContentControl.Content (-> ContentControl Object void) #:set))) ;; --------------------------------------------------------------------------- @@ -931,14 +948,40 @@ (step! app '()) app) +;; Saves a picture of the window to `path` once it has been shown and laid +;; out, and closes it. Twice the pixels of the window, so that it is sharp on +;; a screen with a scale of 2. +(: (-> Lifetime Window double double string void)) +(defun (screenshot-later! lifetime w width height path) + (def timer (Timer.)) + (interval! timer (seconds->span 1.0)) + (ignore (add-event-handler! timer "Tick" + (: (fun (sender e) + (timer-stop! timer) + (def bitmap (RenderBitmap. (PixelSize. (cast System.Int32 (* 2.0 width)) + (cast System.Int32 (* 2.0 height))) + (Vector. 192.0 192.0))) + (render-into! bitmap (cast Visual w)) + (save-png! (cast Bitmap bitmap) path (clr-default)) + (shutdown! lifetime 0)) + (-> Object EventArgs void)))) + (timer-start! timer)) + ;; Runs the program in a window, until the window is closed. Then the ;; subscriptions and the commands still running are cancelled. +;; +;; With `#:screenshot`, a path, the window saves a PNG of itself there once it +;; is shown, and closes. It is the environment variable BJOGUI_SCREENSHOT +;; unless told otherwise, so any program can be pictured with no change: +;; +;; BJOGUI_SCREENSHOT=shot.png bjo run examples/todo.bjo (: (-> %model (-> %m %model (Tuple %model (List (Event %m)))) (-> %model (View %m)) (#:subscriptions (-> %model (List (Sub %m)))) - (#:title string) (#:width double) (#:height double) + (#:title string) (#:width double) (#:height double) (#:screenshot string) void)) (defun (run-app init gui-update view #:subscriptions (fun (m) '()) - #:title "bjogui" #:width 400.0 #:height 300.0) + #:title "bjogui" #:width 400.0 #:height 300.0 + #:screenshot (option-ref-or (get-environment-variable "BJOGUI_SCREENSHOT") "")) ;; The Application is made inside the setup, because making one uses the ;; dispatcher, and the dispatcher is the platform's only after the setup. (def lifetime (Lifetime.)) @@ -956,6 +999,8 @@ (fun (c) (window-content! (cast ContentControl w) (cast Object c))) #:subscriptions subscriptions)) (main-window! lifetime w) + (unless (string-empty? screenshot) + (screenshot-later! lifetime w width height screenshot)) (ignore (start-lifetime lifetime (: (make-array 0) (Array ClrString)))) (app-stop! app) (cancel (Requested "the window is closed"))))