mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-29 05:14:48 +00:00
148 lines
4.2 KiB
Rust
148 lines
4.2 KiB
Rust
/* LICENSE BEGIN
|
|
This file is part of the SixtyFPS Project -- https://sixtyfps.io
|
|
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
|
|
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
|
|
|
|
SPDX-License-Identifier: GPL-3.0-only
|
|
This file is also available under commercial licensing terms.
|
|
Please contact info@sixtyfps.io for more information.
|
|
LICENSE END */
|
|
/*!
|
|
The module responsible for the code generation.
|
|
|
|
There is one sub module for every language
|
|
*/
|
|
|
|
use crate::diagnostics::BuildDiagnostics;
|
|
use crate::object_tree::{Component, Document, ElementRc};
|
|
|
|
#[cfg(feature = "cpp")]
|
|
mod cpp;
|
|
|
|
#[cfg(feature = "rust")]
|
|
pub mod rust;
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
pub enum OutputFormat {
|
|
#[cfg(feature = "cpp")]
|
|
Cpp,
|
|
#[cfg(feature = "rust")]
|
|
Rust,
|
|
}
|
|
|
|
impl OutputFormat {
|
|
pub fn guess_from_extension(path: &std::path::Path) -> Option<Self> {
|
|
match path.extension().and_then(|ext| ext.to_str()) {
|
|
#[cfg(feature = "cpp")]
|
|
Some("cpp") | Some("cxx") | Some("h") | Some("hpp") => Some(Self::Cpp),
|
|
#[cfg(feature = "rust")]
|
|
Some("rs") => Some(Self::Rust),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::str::FromStr for OutputFormat {
|
|
type Err = String;
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s {
|
|
#[cfg(feature = "cpp")]
|
|
"cpp" => Ok(Self::Cpp),
|
|
#[cfg(feature = "rust")]
|
|
"rust" => Ok(Self::Rust),
|
|
_ => Err(format!("Unknown outpout format {}", s)),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn generate(
|
|
format: OutputFormat,
|
|
destination: &mut impl std::io::Write,
|
|
doc: &Document,
|
|
diag: &mut BuildDiagnostics,
|
|
) -> std::io::Result<()> {
|
|
#![allow(unused_variables)]
|
|
#![allow(unreachable_code)]
|
|
match format {
|
|
#[cfg(feature = "cpp")]
|
|
OutputFormat::Cpp => {
|
|
if let Some(output) = cpp::generate(doc, diag) {
|
|
write!(destination, "{}", output)?;
|
|
}
|
|
}
|
|
#[cfg(feature = "rust")]
|
|
OutputFormat::Rust => {
|
|
if let Some(output) = rust::generate(doc, diag) {
|
|
write!(destination, "{}", output)?;
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Visit each item in order in which they should appear in the children tree array.
|
|
/// The parameter of the visitor are the item, and the first_children_offset, and wether this is the flickable rectangle
|
|
#[allow(dead_code)]
|
|
pub fn build_array_helper(
|
|
component: &Component,
|
|
mut visit_item: impl FnMut(&ElementRc, u32, bool),
|
|
) {
|
|
visit_item(&component.root_element, 1, false);
|
|
visit_children(&component.root_element, 1, &mut visit_item);
|
|
|
|
fn sub_children_count(e: &ElementRc) -> usize {
|
|
let mut count = e.borrow().children.len();
|
|
for i in &e.borrow().children {
|
|
count += sub_children_count(i);
|
|
}
|
|
if is_flickable(e) {
|
|
count += 1;
|
|
}
|
|
count
|
|
}
|
|
|
|
fn visit_children(
|
|
item: &ElementRc,
|
|
children_offset: u32,
|
|
visit_item: &mut impl FnMut(&ElementRc, u32, bool),
|
|
) {
|
|
let mut offset = children_offset + item.borrow().children.len() as u32;
|
|
|
|
if is_flickable(item) {
|
|
visit_item(item, offset, true);
|
|
offset += 1;
|
|
}
|
|
|
|
for i in &item.borrow().children {
|
|
visit_item(i, offset, false);
|
|
offset += sub_children_count(i) as u32;
|
|
}
|
|
|
|
let mut offset = children_offset + item.borrow().children.len() as u32;
|
|
|
|
if is_flickable(item) {
|
|
offset += 1;
|
|
}
|
|
|
|
for e in &item.borrow().children {
|
|
visit_children(e, offset, visit_item);
|
|
offset += sub_children_count(e) as u32;
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn is_flickable(e: &ElementRc) -> bool {
|
|
match &e.borrow().base_type {
|
|
crate::typeregister::Type::Native(n) if n.class_name == "Flickable" => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
|
|
/// If the element is a Flickable and the property is the property of the viewport, returns the property with the prefix stipped
|
|
pub fn as_flickable_viewport_property<'a>(e: &ElementRc, name: &'a str) -> Option<&'a str> {
|
|
if is_flickable(e) {
|
|
name.strip_prefix("viewport_")
|
|
} else {
|
|
None
|
|
}
|
|
}
|