2020-08-27 20:37:04 +03:00
# widgetry notes
Rustwarts School of Glitchcraft and Widgetry.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
This is a GUI + 2D drawing + data viz library I've built up for A/B Street. I'm
considering cleaning up the API surface and making it a proper standalone crate.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
## Running the demo
2020-03-04 03:24:27 +03:00
2020-10-06 01:09:12 +03:00
Because of wasm-pack issues, normal Rust example binaries don't work. The example code is instead in the [widgetry_demo crate ](../widgetry_demo/src/lib.rs ).
2020-03-06 23:32:12 +03:00
2020-03-06 23:21:36 +03:00
```
git clone https://github.com/dabreegster/abstreet.git
2020-10-06 01:09:12 +03:00
cd abstreet/widgetry_demo
cargo run
2020-08-08 05:49:43 +03:00
# Or for web
2020-10-06 01:09:12 +03:00
cd abstreet/widgetry_demo
./run_web.sh
2020-03-06 23:21:36 +03:00
```
2020-03-04 03:24:27 +03:00
2020-03-06 23:32:12 +03:00
![demo ](demo.gif )
If you want a more thorough idea of what this crate can do, see
[A/B Street ](https://abstreet.org ).
2020-03-06 23:21:36 +03:00
## Features
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
### Runs in lots of places
2020-03-04 03:24:27 +03:00
2020-08-21 02:59:54 +03:00
Runs on Linux, Mac, Windows via [glow ](https://github.com/grovesNL/glow/ ). Also
works in the browser using WebAssembly, but text support still coming in
2020-03-06 23:21:36 +03:00
[a few months ](https://github.com/RazrFalcon/resvg/issues/229 ).
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
Why OpenGL? My requirements are super simple; I don't need the power of Vulkan
or other new stuff. I want something simple that runs everywhere. If you want to
2020-08-21 01:58:51 +03:00
make this work with WGPU or something else, it should be easy. The backends are
2020-08-21 02:59:54 +03:00
a few hundred lines -- [Glow ](src/backend_glow.rs ) running either
[on native ](src/backend_glow_native.rs ) or [on wasm ](src/backend_glow_wasm.rs ).
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
### 2D drawing
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
Everything is a colored polygon. Upload stuff once, redraw many times with a
simple camera transform. Panning and smooth zooming. One extremely simple
shader.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
Thanks to [usvg ](https://github.com/RazrFalcon/resvg ) and
[lyon ](https://github.com/nical/lyon/ ), SVGs and text are transformed into
colored polygons. Programatically swap colors, rotate, scale stuff. Find bounds
for precise mouseover.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
### GUI
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
Widgets like buttons (with keybindings), checkboxes, sliders, pop-up menus, text
2020-08-27 22:12:44 +03:00
entry, and some data viz things. You can combine these in `Panel` s to dispatch
event handling and drawing. Styling (background colors, outline, padding) and
Flexbox-ish layouting via [stretch ](https://vislyhq.github.io/stretch/ ).
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
The API / programming style is kind of funny; see the [demo ](examples/demo.rs )
2020-08-27 22:12:44 +03:00
to get a sense of it. No callbacks. You manually feed events into your `Panel` s
of widgets and ask about what happened. There's no smart diffing of widget
trees; most of the time it's fine to completely recreate a `Panel` from scratch
when something changes, or replace a single widget in an existing `Panel` .
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
(This is not a performance critical library. The perf bottlenecks in A/B Street
are not in the GUI, and I probably won't invest much time speeding things up
here until they are. (Or if somebody else winds up using this library and hits a
2020-03-06 23:32:12 +03:00
problem.))
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
### Data visualization
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
Not exactly sure how this wound up in here too, but at some point I needed
histograms and line plots that update live over time and show some info when you
mouseover points, so here it is.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
## Big problems to solve before release
2020-03-04 03:24:27 +03:00
2020-08-27 22:12:44 +03:00
When you ask a `Panel` what action happened (what button was clicked), it hands
you back `Option<String>` . Not so typesafe. How boilerplatey is it to associate
buttons with a user-provided enum?
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
There are hardcoded colors / padding in lots of places. Need to make style
easily configurable, with good defaults.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
The error handling is pretty bad; lots of unwraps and panics to clean up.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
## Why another Rust GUI library?
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
When I started, nothing did what I needed, or it required awkward callbacks.
Today, [iced ](https://github.com/hecrj/iced ) looks awesome, but wgpu doesn't
2020-03-06 23:32:12 +03:00
work on my laptop. This is a dealbreaker -- I want to build stuff that runs
~anywhere. I looked into adding an OpenGL backend, but the current structure of
iced has a
2020-03-06 23:21:36 +03:00
[huge ](https://github.com/hecrj/iced/blob/master/native/src/renderer/null.rs )
API surface to implement for a new backend.
2020-03-04 03:24:27 +03:00
2020-03-06 23:21:36 +03:00
For the moment, I don't have enough time to get something else on-par with this
library and port A/B Street over, so I'll continue to invest in this library. If
there's lots of interest in other people using this library, I'll invest much
more and make it a real contender.
2020-03-04 03:24:27 +03:00
2020-03-26 05:54:33 +03:00
## Future work
- Draggable panels