Views, events as messages, and a patch, over plain Avalonia
A program is a model, an update and a view. A view is a Bjolang value; an event finds its message in the view its control was last given, and the next view is compared with the last so only what differs is changed. Controls are made with plain constructors and changed with SetValue, so nothing is subclassed, and a program never names an Avalonia type. Text, button, text input, checkbox, column and row. tests/app.bjo drives an app through its real controls with no window. 🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8) Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
commit
2f4c99ba62
9 changed files with 1415 additions and 0 deletions
88
Readme.org
Normal file
88
Readme.org
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#+TITLE: bjogui
|
||||
|
||||
Desktop programs in Bjolang, written as a model, an ~update~ and a ~view~, and
|
||||
shown with [[https://avaloniaui.net][Avalonia]].
|
||||
|
||||
#+BEGIN_SRC scheme
|
||||
(import (bjogui view))
|
||||
(import (bjogui app))
|
||||
|
||||
(type (: Msg (Union Inc Dec)))
|
||||
|
||||
(: update (-> Msg int int))
|
||||
(defun (update msg n)
|
||||
(match msg (Inc (+ n 1)) (Dec (- n 1))))
|
||||
|
||||
(: view (-> int (View Msg)))
|
||||
(defun (view n)
|
||||
(row #:spacing 8.0 #:margin 16.0
|
||||
(button "-" Dec)
|
||||
(text #"${n}")
|
||||
(button "+" Inc)))
|
||||
|
||||
(defun (main)
|
||||
(run-app 0 update view #:title "Counter"))
|
||||
#+END_SRC
|
||||
|
||||
A program never names an Avalonia type. A view is a Bjolang value, an event
|
||||
is a message, and the controls are made and changed by the package.
|
||||
|
||||
* How it works
|
||||
|
||||
An event finds its message in the view its control was last given.
|
||||
~update~ makes the next model from the message, and ~view~ makes the next
|
||||
view. The next view is compared with the last one, control by control, and
|
||||
only what differs is changed. So a control keeps its focus, its caret and its
|
||||
scroll position when the model changes.
|
||||
|
||||
Children are matched by their place in the list. A child whose kind changes
|
||||
gets a new control.
|
||||
|
||||
A control that is changed raises events of its own: a text input whose text
|
||||
is set says that its text changed. Those events come while the controls are
|
||||
being changed, and they are dropped, so only the user's events are messages.
|
||||
|
||||
* The views: (bjogui view)
|
||||
|
||||
| Constructor | Control | Sends |
|
||||
|--------------------------------------------------+--------------+-----------------------------|
|
||||
| ~(text s)~ | ~TextBlock~ | nothing |
|
||||
| ~(button label msg)~ | ~Button~ | ~msg~ on a click |
|
||||
| ~(text-input value on-input)~ | ~TextBox~ | ~(on-input text)~ on a change |
|
||||
| ~(checkbox label checked? on-toggle)~ | ~CheckBox~ | ~(on-toggle checked)~ |
|
||||
| ~(column child ...)~, ~(row child ...)~ | ~StackPanel~ | nothing |
|
||||
|
||||
They take keywords where they apply: ~#:size~ (the font size of a text),
|
||||
~#:width~, ~#:height~, ~#:margin~, ~#:padding~, ~#:spacing~ (between the
|
||||
children of a column or a row), ~#:enabled~ and ~#:placeholder~. A size of
|
||||
zero, the default, leaves the size to the control.
|
||||
|
||||
* Running: (bjogui app)
|
||||
|
||||
- ~(run-app init update view #:title #:width #:height)~ opens a window and
|
||||
runs until it is closed.
|
||||
- ~(start-app init update view on-root)~ makes the controls with no window,
|
||||
and gives ~on-root~ the control to show. ~app-dispatch!~ sends a message,
|
||||
~app-model~ reads the model, and ~app-control-at~ finds a control by its
|
||||
path of child indices. ~tests/app.bjo~ uses these to drive an app through
|
||||
its real controls.
|
||||
|
||||
* Requirements
|
||||
|
||||
- Avalonia 11.3, which ~bjo~ restores from NuGet. On Linux it needs X11 or
|
||||
XWayland.
|
||||
- A Bjolang with ~(std interop)~, which makes the delegates that Avalonia's
|
||||
events take.
|
||||
|
||||
* Tests
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
bjo run tests/app.bjo # prints "bjogui ok"
|
||||
bjo run examples/counter.bjo
|
||||
#+END_SRC
|
||||
|
||||
* Not yet
|
||||
|
||||
- Keyed children, for lists whose items move.
|
||||
- Messages from fibers and timers, for work that is not a click.
|
||||
- More controls: lists, grids, images, scroll views, menus.
|
||||
Loading…
Add table
Add a link
Reference in a new issue