mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-29 21:34:50 +00:00
Layout for rust
This commit is contained in:
parent
96a372e45d
commit
907bea3d3b
7 changed files with 122 additions and 30 deletions
|
@ -71,11 +71,15 @@ pub mod re_exports {
|
||||||
pub use const_field_offset::{self, FieldOffsets};
|
pub use const_field_offset::{self, FieldOffsets};
|
||||||
pub use once_cell::sync::Lazy;
|
pub use once_cell::sync::Lazy;
|
||||||
pub use sixtyfps_corelib::abi::datastructures::{
|
pub use sixtyfps_corelib::abi::datastructures::{
|
||||||
Component, ComponentTO, ComponentVTable, ItemTreeNode, LayoutInfo,
|
Component, ComponentRef, ComponentTO, ComponentVTable, ItemTreeNode, LayoutInfo,
|
||||||
};
|
};
|
||||||
pub use sixtyfps_corelib::abi::primitives::*;
|
pub use sixtyfps_corelib::abi::primitives::*;
|
||||||
pub use sixtyfps_corelib::abi::properties::Property;
|
pub use sixtyfps_corelib::abi::properties::Property;
|
||||||
pub use sixtyfps_corelib::abi::signals::Signal;
|
pub use sixtyfps_corelib::abi::signals::Signal;
|
||||||
|
pub use sixtyfps_corelib::abi::slice::Slice;
|
||||||
|
pub use sixtyfps_corelib::layout::{
|
||||||
|
solve_grid_layout, Constraint, GridLayoutCellData, GridLayoutData,
|
||||||
|
};
|
||||||
pub use sixtyfps_corelib::ComponentVTable_static;
|
pub use sixtyfps_corelib::ComponentVTable_static;
|
||||||
pub use sixtyfps_corelib::EvaluationContext;
|
pub use sixtyfps_corelib::EvaluationContext;
|
||||||
pub use sixtyfps_corelib::Resource;
|
pub use sixtyfps_corelib::Resource;
|
||||||
|
|
|
@ -84,7 +84,7 @@ pub fn compile(path: impl AsRef<std::path::Path>) -> Result<(), CompileError> {
|
||||||
CompileError::CompileError(vec)
|
CompileError::CompileError(vec)
|
||||||
})?;
|
})?;
|
||||||
write!(file, "{}", generated).map_err(CompileError::SaveError)?;
|
write!(file, "{}", generated).map_err(CompileError::SaveError)?;
|
||||||
println!("cargo:rerun-if-changed={}", path.to_string_lossy());
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
println!("cargo:rustc-env=SIXTYFPS_INCLUDE_GENERATED={}", output_file_path.to_string_lossy());
|
println!("cargo:rustc-env=SIXTYFPS_INCLUDE_GENERATED={}", output_file_path.display());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,8 @@ component ButtonRectangle := Rectangle {
|
||||||
height: 75;
|
height: 75;
|
||||||
color: button_area.pressed ? red : button_color;
|
color: button_area.pressed ? red : button_color;
|
||||||
button_area := TouchArea {
|
button_area := TouchArea {
|
||||||
width: 100;
|
width: root.width;
|
||||||
height: 75;
|
height: root.height;
|
||||||
clicked => { root.clicked() }
|
clicked => { root.clicked() }
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
|
@ -72,22 +72,34 @@ Hello := Rectangle {
|
||||||
source: img!"../graphicstest/logo.png";
|
source: img!"../graphicstest/logo.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonRectangle {
|
property<int32> counter;
|
||||||
button_color: 4289374890;
|
|
||||||
|
Rectangle {
|
||||||
x: 50;
|
x: 50;
|
||||||
y: 225;
|
y: 225;
|
||||||
|
width: 100;
|
||||||
|
height: 225;
|
||||||
|
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
Row {
|
||||||
|
ButtonRectangle {
|
||||||
|
button_color: 4289374890;
|
||||||
clicked => { counter += 1 }
|
clicked => { counter += 1 }
|
||||||
button_text: "+";
|
button_text: "+";
|
||||||
}
|
}
|
||||||
property<int32> counter;
|
}
|
||||||
counter_label := Text { x: 100; y: 300; text: counter; color: black; }
|
Row {
|
||||||
|
counter_label := Text { text: counter; color: black; }
|
||||||
|
}
|
||||||
|
Row {
|
||||||
ButtonRectangle {
|
ButtonRectangle {
|
||||||
button_color: 4289374890;
|
button_color: 4289374890;
|
||||||
x: 50;
|
|
||||||
y: 350;
|
|
||||||
clicked => { minus_clicked() }
|
clicked => { minus_clicked() }
|
||||||
button_text: "-";
|
button_text: "-";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,8 @@ pub fn generate(component: &Component, diag: &mut Diagnostics) -> Option<TokenSt
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let layouts = compute_layout(component);
|
||||||
|
|
||||||
Some(quote!(
|
Some(quote!(
|
||||||
#(#resource_symbols)*
|
#(#resource_symbols)*
|
||||||
|
|
||||||
|
@ -158,11 +160,8 @@ pub fn generate(component: &Component, diag: &mut Diagnostics) -> Option<TokenSt
|
||||||
fn create() -> Self {
|
fn create() -> Self {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
fn layout_info(&self) -> sixtyfps::re_exports::LayoutInfo {
|
|
||||||
todo!("Implement in rust.rs")
|
|
||||||
}
|
|
||||||
fn compute_layout(&self) { todo!("Implement in rust.rs") }
|
|
||||||
|
|
||||||
|
#layouts
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #component_id{
|
impl #component_id{
|
||||||
|
@ -255,3 +254,71 @@ fn compile_expression(e: &Expression, component: &Component) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_layout(component: &Component) -> TokenStream {
|
||||||
|
let mut layouts = vec![];
|
||||||
|
for x in component.layout_constraints.borrow().0.iter() {
|
||||||
|
let within = quote::format_ident!("{}", x.within.borrow().id);
|
||||||
|
let row_constraint = vec![quote!(Constraint::default()); x.row_count()];
|
||||||
|
let col_constraint = vec![quote!(Constraint::default()); x.col_count()];
|
||||||
|
let cells = x
|
||||||
|
.elems
|
||||||
|
.iter()
|
||||||
|
.map(|x| {
|
||||||
|
x.iter()
|
||||||
|
.map(|y| {
|
||||||
|
y.as_ref()
|
||||||
|
.map(|elem| {
|
||||||
|
let e = quote::format_ident!("{}", elem.borrow().id);
|
||||||
|
let p = |n: &str| {
|
||||||
|
if elem.borrow().lookup_property(n) == Type::Float32 {
|
||||||
|
let n = quote::format_ident!("{}", n);
|
||||||
|
quote! {&self.#e.#n}
|
||||||
|
} else {
|
||||||
|
quote! {&dummy}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let width = p("width");
|
||||||
|
let height = p("height");
|
||||||
|
let x = p("x");
|
||||||
|
let y = p("y");
|
||||||
|
quote!(Some(GridLayoutCellData {
|
||||||
|
x: #x,
|
||||||
|
y: #y,
|
||||||
|
width: #width,
|
||||||
|
height: #height,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| quote!(None))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
layouts.push(quote! {
|
||||||
|
solve_grid_layout(&GridLayoutData {
|
||||||
|
row_constraint: Slice::from_slice(&[#(#row_constraint),*]),
|
||||||
|
col_constraint: Slice::from_slice(&[#(#col_constraint),*]),
|
||||||
|
width: self.#within.width.get(&eval_context),
|
||||||
|
height: self.#within.height.get(&eval_context),
|
||||||
|
x: 0.,
|
||||||
|
y: 0.,
|
||||||
|
cells: Slice::from_slice(&[#( Slice::from_slice(&[#( #cells ),*])),*]),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
fn layout_info(&self) -> sixtyfps::re_exports::LayoutInfo {
|
||||||
|
todo!("Implement in rust.rs")
|
||||||
|
}
|
||||||
|
fn compute_layout(&self) {
|
||||||
|
#![allow(unused)]
|
||||||
|
use sixtyfps::re_exports::*;
|
||||||
|
let eval_context = EvaluationContext{ component: ComponentRef::new(self) };
|
||||||
|
let dummy = Property::<f32>::default();
|
||||||
|
|
||||||
|
#(#layouts)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,3 +17,12 @@ pub struct GridLayout {
|
||||||
/// This is like a matrix of elements.
|
/// This is like a matrix of elements.
|
||||||
pub elems: Vec<Vec<Option<Rc<RefCell<Element>>>>>,
|
pub elems: Vec<Vec<Option<Rc<RefCell<Element>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GridLayout {
|
||||||
|
pub fn col_count(&self) -> usize {
|
||||||
|
self.elems.iter().map(|x| x.len()).max().unwrap_or(0)
|
||||||
|
}
|
||||||
|
pub fn row_count(&self) -> usize {
|
||||||
|
self.elems.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -105,6 +105,9 @@ impl<GraphicsBackend: graphics::GraphicsBackend> MainWindow<GraphicsBackend> {
|
||||||
..
|
..
|
||||||
} => *control_flow = winit::event_loop::ControlFlow::Exit,
|
} => *control_flow = winit::event_loop::ControlFlow::Exit,
|
||||||
winit::event::Event::RedrawRequested(_) => {
|
winit::event::Event::RedrawRequested(_) => {
|
||||||
|
// FIXME: we should do that only if some property change
|
||||||
|
component.compute_layout();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut rendering_primitives_builder =
|
let mut rendering_primitives_builder =
|
||||||
graphics_backend.new_rendering_primitives_builder();
|
graphics_backend.new_rendering_primitives_builder();
|
||||||
|
@ -124,8 +127,6 @@ impl<GraphicsBackend: graphics::GraphicsBackend> MainWindow<GraphicsBackend> {
|
||||||
let context = EvaluationContext { component: component };
|
let context = EvaluationContext { component: component };
|
||||||
let mut frame =
|
let mut frame =
|
||||||
graphics_backend.new_frame(size.width, size.height, &Color::WHITE);
|
graphics_backend.new_frame(size.width, size.height, &Color::WHITE);
|
||||||
// FIXME: we should do that only if some property change
|
|
||||||
component.compute_layout();
|
|
||||||
render_function(component, &context, &mut frame, &mut rendering_cache);
|
render_function(component, &context, &mut frame, &mut rendering_cache);
|
||||||
graphics_backend.present_frame(frame);
|
graphics_backend.present_frame(frame);
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,9 +335,8 @@ unsafe extern "C" fn compute_layout(component: ComponentRef) {
|
||||||
let mut col_constraint = vec![];
|
let mut col_constraint = vec![];
|
||||||
//let mut cells = vec![];
|
//let mut cells = vec![];
|
||||||
|
|
||||||
row_constraint.resize_with(it.elems.len(), Default::default);
|
row_constraint.resize_with(it.row_count(), Default::default);
|
||||||
col_constraint
|
col_constraint.resize_with(it.col_count(), Default::default);
|
||||||
.resize_with(it.elems.iter().map(|x| x.len()).max().unwrap_or(0), Default::default);
|
|
||||||
|
|
||||||
// Fixme: i guess we should use Option in the layout data
|
// Fixme: i guess we should use Option in the layout data
|
||||||
let dummy = Property::<f32>::default();
|
let dummy = Property::<f32>::default();
|
||||||
|
@ -386,8 +385,8 @@ unsafe extern "C" fn compute_layout(component: ComponentRef) {
|
||||||
col_constraint: Slice::from(col_constraint.as_slice()),
|
col_constraint: Slice::from(col_constraint.as_slice()),
|
||||||
width: within_prop("width"),
|
width: within_prop("width"),
|
||||||
height: within_prop("height"),
|
height: within_prop("height"),
|
||||||
x: within_prop("x"),
|
x: 0.,
|
||||||
y: within_prop("y"),
|
y: 0.,
|
||||||
cells: Slice::from(cells.as_slice()),
|
cells: Slice::from(cells.as_slice()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue