![]() Remove coordinates rounding code from Align and Flex. Remove rounding from BoxConstraints: instead, widgets do layout under the assumption that they're in a full f64 coordinate space, and rounding only happens at the end of layout. Document pixel snapping. Pixel-snap the baseline as well. Remove `invalid_screenshot_2` test (which relied on placing a child widget with sub-pixel boundaries to produce a slightly incorrect image, which we can no longer do). Update all screenshot tests. See [#masonry > Aligning layout boxes to pixel boundaries](https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Aligning.20layout.20boxes.20to.20pixel.20boundaries) for details. |
||
---|---|---|
.. | ||
examples | ||
screenshots | ||
src | ||
tests | ||
.gitignore | ||
Cargo.toml | ||
LICENSE | ||
README.md |
README.md
Masonry gives you a platform to create windows (using winit as a backend) each with a tree of widgets. It also gives you tools to inspect that widget tree at runtime, write unit tests on it, and generally have an easier time debugging and maintaining your app.
The framework is not opinionated about what your user-facing abstraction will be: you can implement immediate-mode GUI, the Elm architecture, functional reactive GUI, etc, on top of Masonry.
See Xilem as an example of reactive UI built on top of Masonry.
Masonry was originally a fork of Druid that emerged from discussions within the Linebender community about what it would look like to turn Druid into a foundational library.
Masonry can currently be considered to be in an alpha state. Lots of things need improvements, e.g. text input is janky and snapshot testing is not consistent across platforms.
Example
The to-do-list example looks like this:
use masonry::core::{ErasedAction, NewWidget, Widget, WidgetId, WidgetPod};
use masonry::dpi::LogicalSize;
use masonry::theme::default_property_set;
use masonry::widgets::{Button, ButtonPress, Flex, Label, Portal, TextAction, TextInput};
use masonry_winit::app::{AppDriver, DriverCtx, WindowId};
use masonry_winit::winit::window::Window;
struct Driver {
next_task: String,
window_id: WindowId,
}
impl AppDriver for Driver {
fn on_action(
&mut self,
window_id: WindowId,
ctx: &mut DriverCtx<'_, '_>,
_widget_id: WidgetId,
action: ErasedAction,
) {
debug_assert_eq!(window_id, self.window_id, "unknown window");
if action.is::<ButtonPress>() {
ctx.render_root(window_id).edit_root_widget(|mut root| {
let mut portal = root.downcast::<Portal<Flex>>();
let mut flex = Portal::child_mut(&mut portal);
Flex::add_child(&mut flex, Label::new(self.next_task.clone()).with_auto_id());
});
} else if action.is::<TextAction>() {
let action = *action.downcast::<TextAction>().unwrap();
match action {
TextAction::Changed(new_text) => {
self.next_task = new_text.clone();
}
_ => {}
}
}
}
}
fn main() {
const WIDGET_SPACING: f64 = 5.0;
let main_widget = Portal::new(
Flex::column()
.with_child(NewWidget::new(
Flex::row()
.with_flex_child(TextInput::new("").with_auto_id(), 1.0)
.with_child(
Button::new(
Label::new("Add task").with_auto_id()
).with_auto_id()
),
))
.with_spacer(WIDGET_SPACING)
.with_auto_id(),
);
let window_size = LogicalSize::new(400.0, 400.0);
let window_attributes = Window::default_attributes()
.with_title("To-do list")
.with_resizable(true)
.with_min_inner_size(window_size);
let driver = Driver {
next_task: String::new(),
window_id: WindowId::next(),
};
let event_loop = masonry_winit::app::EventLoop::with_user_event()
.build()
.unwrap();
masonry_winit::app::run_with(
event_loop,
vec![(
driver.window_id,
window_attributes,
NewWidget::new(main_widget).erased(),
)],
driver,
default_property_set(),
)
.unwrap();
}
For more information, see the Masonry documentation.
Crate feature flags
The following feature flags are available:
tracy
: Enables creating output for the Tracy profiler usingtracing-tracy
. This can be used by installing Tracy and connecting to a Masonry with this feature enabled.
Debugging features
Masonry apps currently ship with two debugging features built in:
- A rudimentary widget inspector - toggled by F11 key.
- A debug mode painting widget layout rectangles - toggled by F12 key.
Minimum supported Rust Version (MSRV)
This version of Masonry Winit has been verified to compile with Rust 1.88 and later.
Future versions of Masonry Winit might increase the Rust version requirement. It will not be treated as a breaking change and as such can even happen with small patch releases.
Community
Discussion of Masonry Winit development happens in the Linebender Zulip, specifically the #masonry channel. All public content can be read without logging in.
Contributions are welcome by pull request. The Rust code of conduct applies.
License
Licensed under the Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0)