A todo example, and its picture in the Readme
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 <git@eca.dev>
This commit is contained in:
parent
e773bc424e
commit
5a80685397
3 changed files with 150 additions and 2 deletions
49
src/app.bjo
49
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"))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue