Commit graph

9 commits

Author SHA256 Message Date
52ebd0ace8 Controls that bjogui does not wrap, with (bjogui native)
A native is made with a function that makes the control and hooks its
events, and one that puts a value on it. hosted puts it in a view: the
control is made once for its place, given a value only when the view's
value changes, and what it sends while it is given one is dropped. Its
outputs become the app's messages through on-output and view-map, and
may be sent from any thread.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 21:02:17 +01:00
5237bf3273 Controls of the program's own, drawn with a pen
A component draws itself with (bjogui draw), a pen over Avalonia's
DrawingContext, and hears the pointer, the wheel, the keys and the focus.
It keeps a state of its own between inputs, and sends outputs that drawn
makes the app's messages. It is drawn again only when its value, its state
or its size changes, and no Avalonia class is subclassed: the picture is a
DrawingImage on a canvas.

start-headless! sets Avalonia up with no screen, drawing with Skia, so
tests/components.bjo draws components and reads their pixels. The mixer
example has knobs and a timeline.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 20:34:19 +01:00
66e861351b The Readme on components and canvases
🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 19:26:56 +01:00
8941425f05 Tree views, a styles example, and the Readme for all of it
A tree node is a TreeViewItem: a header and items, patched by key as a
list's items are. The chosen node is chosen by its key, once the nodes are
there, and a click sends the key. SelectedItem is a direct property, which
a clear does not reset, so no choice is set as null.

The Readme now covers menus and keys, dialogs, styles and themes, and the
new controls. docs/styles.png is examples/styles.bjo.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 18:10:53 +01:00
1e46202eef Show the todo picture in the Readme, and say how it was taken
🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 17:24:45 +01:00
e773bc424e List boxes, tabs, colours and borders
A list box's items and a tab control's tabs are views, patched by key as a
column's children are: Panel.Children and ItemsControl.Items are both an
IList, so one patch serves both. A list can choose an item only once its
items are there, so the choice is set after the children.

A routed event bubbles, so each handler now takes only its own control's
events. Before, a dropdown in a list item would have been heard as the
list's choice too.

paint gives any view a text and a background colour, and border a frame. A
colour that cannot be read leaves the theme's.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 17:21:40 +01:00
95b6707cc1 Keyed children, and eight more controls
A child is now known by its key, or by its place among the children with no
key. One whose identity was there before keeps its control, and the
controls are put in the new order by moving only those out of place. So a
list that is sorted, or has an item put in front, keeps its controls.

Text areas, sliders, progress bars, dropdowns, images, grids with cells and
spans, and scroll views. A grid's sizes are .NET properties and not
Avalonia's, so they are set by a setter of their own. A text is centred in
its height, so a label lines up with the control beside it.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 17:13:35 +01:00
4f48282314 Commands and subscriptions, and gui-update
gui-update is a plain function, so it cannot wait. It returns the work to do
as values. A command is an (Event %m), synced in a fiber of its own, whose
answer is the next message. A subscription is a source of messages that the
model asks for: after each update the app starts the new ones and cancels the
ones that are gone, by key. every sends a message on a timer, and
subscription takes a source of one's own.

The fibers belong to the app's scope and post their messages to the UI
thread, so gui-update and view only run there. Closing the window cancels
them. The prelude's path macros already use the name update, hence
gui-update.

🤖 Generated with [ECA](https://eca.dev) (anthropic/claude-opus-4-8)

Co-Authored-By: eca-agent <git@eca.dev>
2026-10-25 17:02:02 +01:00
2f4c99ba62 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>
2026-10-25 16:18:09 +01:00