···11# vxim
2233-vxim is currently just an experiment to make an immediate-mode framework for [libvaxis](https://github.com/rockorager/libvaxis).
33+vxim is currently an experiment to make an immediate-mode framework for [libvaxis](https://github.com/rockorager/libvaxis). If it turns out to be viable — and it's very promising so far! — I plan to use this for writing the TUI for my editor project: [Fönn](https://tangled.org/@reykjalin.org/fn).
4455-Doesn't do much yet, but here's a demo of the current capabilities:
55+## Demo
6677
8899+Code for the recording is in [src/demo.zig](./src/demo.zig).
1010+1111+## Features
1212+1313+The framework isn't very feature complete, and likely won't be for some time. I plan to add widgets as I need them while working on [Fönn](https://tangled.org/@reykjalin.org/fn), but contributions are welcome!
1414+1515+Current widgets included:
1616+ * `button`
1717+ * `text`
1818+ * `window`
1919+ * `padding`
2020+ * `menuBar`
2121+2222+All widgets handle mouse events and focus automatically. They have some minor customization options, but for the most part they're pretty limited at the moment.
2323+2424+## Contributing
2525+2626+Contributions are welcome through [GitHub pull requests](https://github.com/reykjalin/vxim), [Tangled pulls](https://tangled.org/@reykjalin.org/vxim), or email patches.
2727+2828+## Implementation details
2929+3030+The implementation of `vxim` draws heavily from [DVUI](https://github.com/david-vanderson/dvui), but with a distinct flavor that fits better with how `libvaxis` works.
3131+3232+The biggest difference is that `vxim` does not render frames in a continuous loop, queue up events, and then send them all at once to the update function. Instead, the update function you pass to `vxim` will only get called when the terminal receives an event you've subscribed to.
3333+3434+This means `vxim` doesn't operate on a "frame", and as such isn't like (most?) other immediate mode UI libraries, like DVUI, Dear Imgui, and others. Instead it's entirely event based and connected to interactions with the terminal. That said, using `vxim` still feels like using a regular immediate mode library.
3535+3636+### Widget IDs
3737+3838+Every focusable widget must have an ID. Unlike DVUI — which uses [@src()](https://ziglang.org/documentation/0.15.2/#toc-src) and the widget hierarchy to generate widget IDs — you can make up a type for your widget IDs and pass it to `vxim`. It'll then be used by all the widget functions in `vxim`.
3939+4040+I recommend a simple enum:
4141+4242+```zig
4343+enum Widget {
4444+ AppWindow,
4545+ OkButton,
4646+ CancelButton,
4747+}
4848+```
4949+5050+but you can go as crazy with this as you'd like.
5151+5252+### Mouse focus and clicks
5353+5454+To handle clicks properly, without them bleeding through elements stacked on top of one another, I borrowed the concept of what I've called "mouse focus" from DVUI — a different name, but same concept.
5555+5656+Whenever a mouse click is performed each widget will receive a `.mouse_focus` event. If a widget receives this event it'll be set as the currently mouse-focused widget. Once the `.mouse_focus` event has been sent, it'll be immediately followed by the `.mouse` click event.
5757+5858+What this does is ensure that the last element drawn in the update loop will be mouse-focused by the time we send the `.mouse` click event on the next call to the update function. Clicks are only processed for the element that currently has mouse focus.
5959+6060+#### Known bugs with mouse focus and clicks
6161+6262+There is currently [a bug](https://tangled.org/@reykjalin.org/vxim/issues/8) in the implementation that means you must subscribe to `.mouse_focus` by including it in your event struct so that the event gets delivered to all the widgets you're using. If you don't, focus won't be handled correctly and clicks won't be delivered at all. This should be a compile-time error, but it currently is not.
6363+6464+I plan to fix this soon.