viewer: use the new Compiler API and add a --component command line arg

This commit is contained in:
Olivier Goffart 2024-07-03 16:49:22 +02:00 committed by GitHub
parent 875d20f1ac
commit 708ab9f7c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 70 additions and 27 deletions

View file

@ -248,9 +248,9 @@ impl Document {
self.exports
.iter()
.filter_map(|e| Some((&e.0.name_ident, e.1.as_ref().left()?)))
.filter(|(_, c)| !c.is_global())
.max_by_key(|(n, _)| n.text_range().end())
.map(|(_, c)| c.clone())
.or_else(|| self.exported_roots().last())
}
/// visit all root and used component (including globals)

View file

@ -60,13 +60,26 @@ pub fn check_public_api(
}
}),
// Only keep the component with the given name
ComponentsToGenerate::ComponentWithName(name) => doc.exports.retain(|export| {
if let Either::Left(c) = &export.1 {
c.is_global() || &c.id == name
} else {
true
ComponentsToGenerate::ComponentWithName(name) => {
doc.exports.retain(|export| {
if let Either::Left(c) = &export.1 {
c.is_global() || &c.id == name
} else {
true
}
});
if doc.last_exported_component().is_none() {
// We maybe requested to preview a non-exported component.
if let Ok(ElementType::Component(c)) = doc.local_registry.lookup_element(&name) {
if let Some(name_ident) = c.node.clone() {
doc.exports.add_reexports(
[(ExportedName{ name: name.clone(), name_ident }, Either::Left(c))],
diag,
);
}
}
}
}),
},
}
for c in doc.exported_roots() {

View file

@ -493,8 +493,8 @@ impl FromIterator<(String, Value)> for Struct {
}
}
/// ComponentCompiler is deprecated, use `Compiler` instead
//#[deprecated(note = "Use Complier instead")]
/// ComponentCompiler is deprecated, use [`Compiler`] instead
// #[deprecated(note = "Use slint_interpreter::Complier instead")]
pub struct ComponentCompiler {
config: i_slint_compiler::CompilerConfiguration,
diagnostics: Vec<Diagnostic>,
@ -705,6 +705,11 @@ impl Default for Compiler {
}
impl Compiler {
/// Returns a new Compiler.
pub fn new() -> Self {
Self::default()
}
/// Allow access to the underlying `CompilerConfiguration`
///
/// This is an internal function without and ABI or API stability guarantees.

View file

@ -40,6 +40,7 @@ slint-viewer path/to/myfile.slint
- `--style <style>`: Set the style. Defaults to `native` if the Qt backend is compiled, otherwise `fluent`
- `--backend <backend>`: Override the Slint rendering backend
- `--on <callback> <handler>`: Set a callback handler, see [callback handler](#callback-handlers)
- `--component <name>`: Load the component with the given name. If not specified, load the last exported component
Instead of a path to a file, one can use `-` for the standard input or the standard output.

View file

@ -3,8 +3,11 @@
#![doc = include_str!("README.md")]
use clap::Parser;
use i_slint_compiler::ComponentsToGenerate;
use i_slint_core::model::{Model, ModelRc};
use i_slint_core::SharedVector;
use itertools::Itertools;
use slint_interpreter::{
ComponentDefinition, ComponentHandle, ComponentInstance, SharedString, Value,
};
@ -14,9 +17,6 @@ use std::path::PathBuf;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::{Arc, Mutex};
use clap::Parser;
use itertools::Itertools;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[derive(Clone, clap::Parser)]
@ -38,6 +38,11 @@ struct Cli {
#[arg(long, value_name = "style name", action)]
style: Option<String>,
/// The name of the component to view. If unset, the last exported component of the file is used.
/// If the component name is not in the .slint file , nothing will be shown
#[arg(long, value_name = "component name", action)]
component: Option<String>,
/// The rendering backend
#[arg(long, value_name = "backend", action)]
backend: Option<String>,
@ -97,14 +102,22 @@ fn main() -> Result<()> {
};
let fswatcher = if args.auto_reload { Some(start_fswatch_thread(args.clone())?) } else { None };
let mut compiler = init_compiler(&args, fswatcher);
let c = spin_on::spin_on(compiler.build_from_path(args.path));
slint_interpreter::print_diagnostics(compiler.diagnostics());
let c = match c {
Some(c) => c,
None => std::process::exit(-1),
let compiler = init_compiler(&args, fswatcher);
let r = spin_on::spin_on(compiler.build_from_path(&args.path));
slint_interpreter::print_diagnostics(&r.diagnostics().collect::<Vec<_>>());
if r.has_error() {
std::process::exit(-1);
}
let Some(c) = r.component_names().next().and_then(|n| r.component(n)) else {
match args.component {
Some(name) => {
eprintln!("Component '{name}' not found in file '{}'", args.path.display());
}
None => {
eprintln!("No component found in file '{}'", args.path.display());
}
}
std::process::exit(-1);
};
let component = c.create().unwrap();
@ -166,8 +179,8 @@ fn main() -> Result<()> {
fn init_compiler(
args: &Cli,
fswatcher: Option<Arc<Mutex<notify::RecommendedWatcher>>>,
) -> slint_interpreter::ComponentCompiler {
let mut compiler = slint_interpreter::ComponentCompiler::default();
) -> slint_interpreter::Compiler {
let mut compiler = slint_interpreter::Compiler::new();
#[cfg(feature = "gettext")]
if let Some(domain) = args.translation_domain.clone() {
compiler.set_translation_domain(domain);
@ -192,6 +205,13 @@ fn init_compiler(
Box::pin(async { None })
})
}
compiler.compiler_configuration(i_slint_core::InternalToken).components_to_generate =
match &args.component {
Some(component) => ComponentsToGenerate::ComponentWithName(component.clone()),
None => ComponentsToGenerate::LastComponent,
};
compiler
}
@ -275,11 +295,10 @@ fn start_fswatch_thread(args: Cli) -> Result<Arc<Mutex<notify::RecommendedWatche
}
async fn reload(args: Cli, fswatcher: Arc<Mutex<notify::RecommendedWatcher>>) {
let mut compiler = init_compiler(&args, Some(fswatcher));
let c = compiler.build_from_path(&args.path).await;
slint_interpreter::print_diagnostics(compiler.diagnostics());
if let Some(c) = c {
let compiler = init_compiler(&args, Some(fswatcher));
let r = compiler.build_from_path(&args.path).await;
slint_interpreter::print_diagnostics(&r.diagnostics().collect::<Vec<_>>());
if let Some(c) = r.component_names().next().and_then(|n| r.component(n)) {
CURRENT_INSTANCE.with(|current| {
let mut current = current.borrow_mut();
if let Some(handle) = current.take() {
@ -298,6 +317,11 @@ async fn reload(args: Cli, fswatcher: Arc<Mutex<notify::RecommendedWatcher>>) {
}
eprintln!("Successful reload of {}", args.path.display());
});
} else if !r.has_error() {
match &args.component {
Some(name) => println!("Component {name} not found"),
None => println!("No component found"),
}
}
PENDING_EVENTS.fetch_sub(1, Ordering::SeqCst);