mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-29 05:14:48 +00:00
Implement property declarations for the C++ backend
This commit is contained in:
parent
5a7a95dbc8
commit
0932953ac8
4 changed files with 88 additions and 13 deletions
|
@ -77,7 +77,8 @@ Hello := Rectangle {
|
|||
color: black;
|
||||
}
|
||||
}
|
||||
counter := Text { x: 100; y: 300; text: "0"; color: black; }
|
||||
property<int32> counter;
|
||||
counter_label := Text { x: 100; y: 300; text: "0"; color: black; }
|
||||
ButtonRectangle {
|
||||
color: 4289374890;
|
||||
x: 50;
|
||||
|
|
|
@ -4,24 +4,24 @@
|
|||
int main() {
|
||||
static Hello component;
|
||||
|
||||
static int counter = 0;
|
||||
|
||||
component._foobar.set_handler([](auto...){
|
||||
std::cout << "Hello from C++" << std::endl;
|
||||
});
|
||||
|
||||
component._plus_clicked.set_handler([](auto...){
|
||||
counter += 1;
|
||||
auto &counter = component.property_0_counter;
|
||||
counter.set(counter.get() + 1);
|
||||
// FIXME: this _13 is an internal detail and should be private anyway. We muse use some
|
||||
// alias or way to expose the property (same for the _ before signals)
|
||||
component.counter_13.text.set(std::string_view(std::to_string(counter)));
|
||||
std::cout << "PLUS: " << std::string_view(component.counter_13.text.get()) << std::endl;
|
||||
component.counter_label_13.text.set(std::string_view(std::to_string(counter.get())));
|
||||
std::cout << "PLUS: " << std::string_view(component.counter_label_13.text.get()) << std::endl;
|
||||
});
|
||||
|
||||
component._minus_clicked.set_handler([](auto...){
|
||||
counter -= 1;
|
||||
component.counter_13.text.set(std::string_view(std::to_string(counter)));
|
||||
std::cout << "MINUS: " << std::string_view(component.counter_13.text.get()) << std::endl;
|
||||
auto &counter = component.property_0_counter;
|
||||
counter.set(counter.get() - 1);
|
||||
component.counter_label_13.text.set(std::string_view(std::to_string(counter.get())));
|
||||
std::cout << "MINUS: " << std::string_view(component.counter_label_13.text.get()) << std::endl;
|
||||
});
|
||||
|
||||
sixtyfps::run(&component);
|
||||
|
|
|
@ -121,12 +121,35 @@ mod cpp_ast {
|
|||
writeln!(f, ";")
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CppType {
|
||||
fn cpp_type(&self) -> Option<&str>;
|
||||
}
|
||||
}
|
||||
|
||||
use crate::lower::{LoweredComponent, LoweredItem};
|
||||
use crate::typeregister::Type;
|
||||
use cpp_ast::*;
|
||||
|
||||
fn handle_item(item: &LoweredItem, main_struct: &mut Struct, init: &mut Vec<String>) {
|
||||
impl CppType for Type {
|
||||
fn cpp_type(&self) -> Option<&str> {
|
||||
match self {
|
||||
Type::Float32 => Some("float"),
|
||||
Type::Int32 => Some("int"),
|
||||
Type::String => Some("sixtyfps::SharedString"),
|
||||
Type::Color => Some("uint32_t"),
|
||||
Type::Bool => Some("bool"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_item(
|
||||
item: &LoweredItem,
|
||||
global_properties: &Vec<String>,
|
||||
main_struct: &mut Struct,
|
||||
init: &mut Vec<String>,
|
||||
) {
|
||||
main_struct.members.push(Declaration::Var(Var {
|
||||
ty: format!("sixtyfps::{}", item.native_type.class_name),
|
||||
name: item.id.clone(),
|
||||
|
@ -135,13 +158,19 @@ fn handle_item(item: &LoweredItem, main_struct: &mut Struct, init: &mut Vec<Stri
|
|||
|
||||
let id = &item.id;
|
||||
init.extend(item.init_properties.iter().map(|(s, i)| {
|
||||
let cpp_prop = item
|
||||
.property_declarations
|
||||
.get(s)
|
||||
.map(|idx| global_properties[*idx].clone())
|
||||
.unwrap_or_else(|| format!("{id}.{prop}", id = id, prop = s.clone()));
|
||||
|
||||
use crate::expression_tree::Expression::*;
|
||||
let init = match &i {
|
||||
StringLiteral(s) => format!(r#"sixtyfps::SharedString("{}")"#, s.escape_default()),
|
||||
NumberLiteral(n) => n.to_string(),
|
||||
_ => format!("\n#error: unsupported expression {:?}\n", i),
|
||||
};
|
||||
format!("{id}.{prop}.set({init});", id = id, prop = s, init = init)
|
||||
format!("{cpp_prop}.set({init});", cpp_prop = cpp_prop, init = init)
|
||||
}));
|
||||
init.extend(item.connect_signals.iter().map(|(s, fwd)| {
|
||||
format!(
|
||||
|
@ -151,7 +180,7 @@ fn handle_item(item: &LoweredItem, main_struct: &mut Struct, init: &mut Vec<Stri
|
|||
}));
|
||||
|
||||
for i in &item.children {
|
||||
handle_item(i, main_struct, init)
|
||||
handle_item(i, global_properties, main_struct, init)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,8 +192,31 @@ pub fn generate(component: &LoweredComponent) -> impl std::fmt::Display {
|
|||
|
||||
let mut main_struct = Struct { name: component.id.clone(), ..Default::default() };
|
||||
|
||||
let (declared_property_members, declared_property_vars): (Vec<String>, Vec<Declaration>) =
|
||||
component
|
||||
.property_declarations
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, property)| {
|
||||
let cpp_name: String = format!("property_{}_{}", index, property.name_hint).into();
|
||||
(
|
||||
cpp_name.clone(),
|
||||
Declaration::Var(Var {
|
||||
ty: format!(
|
||||
"sixtyfps::Property<{}>",
|
||||
property.property_type.cpp_type().expect("cannot convert type to C++")
|
||||
),
|
||||
name: cpp_name,
|
||||
init: None,
|
||||
}),
|
||||
)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
main_struct.members.extend(declared_property_vars);
|
||||
|
||||
let mut init = Vec::new();
|
||||
handle_item(&component.root_item, &mut main_struct, &mut init);
|
||||
handle_item(&component.root_item, &declared_property_members, &mut main_struct, &mut init);
|
||||
|
||||
main_struct.members.extend(component.signals_declarations.iter().map(|s| {
|
||||
Declaration::Var(Var { ty: "sixtyfps::Signal".into(), name: s.clone(), init: None })
|
||||
|
|
|
@ -15,6 +15,8 @@ pub struct NativeItemType {
|
|||
pub class_name: String,
|
||||
}
|
||||
|
||||
pub type LoweredPropertyDeclarationIndex = usize;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct LoweredItem {
|
||||
pub id: String,
|
||||
|
@ -22,6 +24,7 @@ pub struct LoweredItem {
|
|||
pub init_properties: HashMap<String, Expression>,
|
||||
/// Right now we only allow forwarding and this connect with the signal in the root
|
||||
pub connect_signals: HashMap<String, String>,
|
||||
pub property_declarations: HashMap<String, LoweredPropertyDeclarationIndex>,
|
||||
pub children: Vec<LoweredItem>,
|
||||
}
|
||||
|
||||
|
@ -31,6 +34,7 @@ pub struct LoweredComponent {
|
|||
pub root_item: LoweredItem,
|
||||
|
||||
pub signals_declarations: Vec<String>,
|
||||
pub property_declarations: Vec<LoweredPropertyDeclaration>,
|
||||
}
|
||||
|
||||
impl LoweredComponent {
|
||||
|
@ -40,6 +44,7 @@ impl LoweredComponent {
|
|||
id: component.id.clone(),
|
||||
root_item: LoweredComponent::lower_item(&*component.root_element.borrow(), &mut state),
|
||||
signals_declarations: state.signals,
|
||||
property_declarations: state.property_declarations,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,6 +77,16 @@ impl LoweredComponent {
|
|||
let current_component_id = state.current_component_id.clone();
|
||||
let format_signal = |name| format!("{}_{}", current_component_id, name);
|
||||
state.signals.extend(element.signals_declaration.iter().map(format_signal));
|
||||
|
||||
for (prop_name, property_type) in element.property_declarations.iter() {
|
||||
let component_global_index = state.property_declarations.len();
|
||||
lowered.property_declarations.insert(prop_name.clone(), component_global_index);
|
||||
state.property_declarations.push(LoweredPropertyDeclaration {
|
||||
property_type: property_type.clone(),
|
||||
name_hint: prop_name.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
for (k, e) in element.bindings.iter() {
|
||||
if let Expression::SignalReference { name, .. } = e {
|
||||
lowered.connect_signals.insert(
|
||||
|
@ -89,6 +104,12 @@ impl LoweredComponent {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoweredPropertyDeclaration {
|
||||
pub property_type: Type,
|
||||
pub name_hint: String,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct LowererState {
|
||||
/// The count of item to create the ids
|
||||
|
@ -97,4 +118,5 @@ struct LowererState {
|
|||
current_component_id: String,
|
||||
|
||||
signals: Vec<String>,
|
||||
property_declarations: Vec<LoweredPropertyDeclaration>,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue