mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-01 12:24:16 +00:00
live-preview: Explicitly set live-data values on reload
Set all values that are changed compared to the initial set of values right after loading a new component. This also includes a small change to the printerdemo, so that it exposes more data to the business logic, so that we have something to demonstrate;-)
This commit is contained in:
parent
e1b85bbb93
commit
081452bee9
4 changed files with 390 additions and 228 deletions
|
|
@ -126,6 +126,8 @@ struct PreviewState {
|
|||
workspace_edit_sent: bool,
|
||||
known_components: Vec<ComponentInformation>,
|
||||
preview_loading_delay_timer: Option<slint::Timer>,
|
||||
initial_live_data: preview_data::PreviewDataMap,
|
||||
current_live_data: preview_data::PreviewDataMap,
|
||||
}
|
||||
|
||||
impl PreviewState {
|
||||
|
|
@ -182,6 +184,49 @@ fn delete_document(url: &lsp_types::Url) {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_current_live_data(mut result: preview_data::PreviewDataMap) {
|
||||
PREVIEW_STATE.with(|preview_state| {
|
||||
let mut preview_state = preview_state.borrow_mut();
|
||||
preview_state.current_live_data.append(&mut result);
|
||||
})
|
||||
}
|
||||
|
||||
fn apply_live_preview_data() {
|
||||
let Some(instance) = component_instance() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let new_initial_data = preview_data::query_preview_data_properties_and_callbacks(&instance);
|
||||
|
||||
let (mut previous_initial, mut previous_current) = PREVIEW_STATE.with(|preview_state| {
|
||||
let mut preview_state = preview_state.borrow_mut();
|
||||
(
|
||||
std::mem::replace(&mut preview_state.initial_live_data, new_initial_data),
|
||||
std::mem::take(&mut preview_state.current_live_data),
|
||||
)
|
||||
});
|
||||
|
||||
while let Some((kc, vc)) = previous_current.pop_last() {
|
||||
let prev = previous_initial.pop_last();
|
||||
|
||||
let vc = vc.value.unwrap_or_default();
|
||||
|
||||
if matches!(vc, slint_interpreter::Value::Void) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some((ki, vi)) = prev {
|
||||
let vi = vi.value.unwrap_or_default();
|
||||
|
||||
if ki == kc && vi == vc {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let _ = preview_data::set_preview_data(&instance, &kc.container, &kc.property_name, vc);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_contents(url: &common::VersionedUrl, content: String) {
|
||||
let mut cache = CONTENT_CACHE.get_or_init(Default::default).lock().unwrap();
|
||||
let old = cache.source_code.insert(
|
||||
|
|
@ -932,9 +977,14 @@ fn extract_resources(
|
|||
result
|
||||
}
|
||||
|
||||
fn finish_parsing(preview_url: &Url, previewed_component: Option<String>) {
|
||||
fn finish_parsing(preview_url: &Url, previewed_component: Option<String>, success: bool) {
|
||||
set_status_text("");
|
||||
|
||||
if !success {
|
||||
// No need to update everything...
|
||||
return;
|
||||
}
|
||||
|
||||
let (previewed_url, component, source_code) = {
|
||||
let cache = CONTENT_CACHE.get_or_init(Default::default).lock().unwrap();
|
||||
let pc = cache.current_component();
|
||||
|
|
@ -996,6 +1046,8 @@ fn finish_parsing(preview_url: &Url, previewed_component: Option<String>) {
|
|||
usize::MAX
|
||||
};
|
||||
|
||||
apply_live_preview_data();
|
||||
|
||||
PREVIEW_STATE.with(|preview_state| {
|
||||
let mut preview_state = preview_state.borrow_mut();
|
||||
preview_state.known_components = components;
|
||||
|
|
@ -1301,6 +1353,12 @@ async fn reload_preview_impl(
|
|||
) -> Result<(), PlatformError> {
|
||||
start_parsing();
|
||||
|
||||
if let Some(component_instance) = component_instance() {
|
||||
let live_preview_data =
|
||||
preview_data::query_preview_data_properties_and_callbacks(&component_instance);
|
||||
set_current_live_data(live_preview_data);
|
||||
}
|
||||
|
||||
let path = component.url.to_file_path().unwrap_or(PathBuf::from(&component.url.to_string()));
|
||||
let (version, source) = get_url_from_cache(&component.url);
|
||||
|
||||
|
|
@ -1324,6 +1382,8 @@ async fn reload_preview_impl(
|
|||
)
|
||||
.await;
|
||||
|
||||
let success = compiled.is_some();
|
||||
|
||||
let loaded_component_name = compiled.as_ref().map(|c| c.name().to_string());
|
||||
|
||||
{
|
||||
|
|
@ -1340,7 +1400,7 @@ async fn reload_preview_impl(
|
|||
|
||||
update_preview_area(compiled, behavior, open_import_fallback, source_file_versions)?;
|
||||
|
||||
finish_parsing(&component.url, loaded_component_name);
|
||||
finish_parsing(&component.url, loaded_component_name, success);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -1745,7 +1805,6 @@ fn update_preview_area(
|
|||
native::open_ui_impl(&mut preview_state)?;
|
||||
|
||||
let ui = preview_state.ui.as_ref().unwrap();
|
||||
|
||||
let shared_handle = preview_state.handle.clone();
|
||||
let shared_document_cache = preview_state.document_cache.clone();
|
||||
|
||||
|
|
@ -1766,6 +1825,7 @@ fn update_preview_area(
|
|||
),
|
||||
)));
|
||||
}
|
||||
|
||||
shared_handle.replace(Some(instance));
|
||||
}),
|
||||
behavior,
|
||||
|
|
@ -1786,6 +1846,7 @@ fn update_preview_area(
|
|||
Ok(())
|
||||
})
|
||||
})?;
|
||||
|
||||
element_selection::reselect_element();
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
use std::{collections::HashMap, fmt::Display};
|
||||
use std::fmt::Display;
|
||||
|
||||
use slint_interpreter::ComponentInstance;
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub enum PropertyContainer {
|
||||
Main,
|
||||
Global(String),
|
||||
|
|
@ -45,9 +45,14 @@ fn is_property(ty: &i_slint_compiler::langtype::Type) -> bool {
|
|||
)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub struct PreviewDataKey {
|
||||
pub container: PropertyContainer,
|
||||
pub property_name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PreviewData {
|
||||
pub name: String,
|
||||
pub ty: i_slint_compiler::langtype::Type,
|
||||
pub visibility: i_slint_compiler::object_tree::PropertyVisibility,
|
||||
pub value: Option<slint_interpreter::Value>,
|
||||
|
|
@ -67,10 +72,12 @@ impl PreviewData {
|
|||
}
|
||||
}
|
||||
|
||||
pub type PreviewDataMap = std::collections::BTreeMap<PreviewDataKey, PreviewData>;
|
||||
|
||||
pub fn get_preview_data(
|
||||
component_instance: &ComponentInstance,
|
||||
container: PropertyContainer,
|
||||
property_name: String,
|
||||
container: &PropertyContainer,
|
||||
property_name: &str,
|
||||
) -> Option<PreviewData> {
|
||||
fn find_preview_data(
|
||||
property_name: &str,
|
||||
|
|
@ -88,19 +95,19 @@ pub fn get_preview_data(
|
|||
it.find(|(name, (_, _))| name == property_name).map(|(name, (ty, visibility))| {
|
||||
let value = value_query(&name);
|
||||
|
||||
PreviewData { name, ty, visibility, value }
|
||||
PreviewData { ty, visibility, value }
|
||||
})
|
||||
}
|
||||
|
||||
let definition = &component_instance.definition();
|
||||
match &container {
|
||||
PropertyContainer::Main => {
|
||||
find_preview_data(&property_name, &mut definition.properties_and_callbacks(), &|name| {
|
||||
find_preview_data(property_name, &mut definition.properties_and_callbacks(), &|name| {
|
||||
component_instance.get_property(name).ok()
|
||||
})
|
||||
}
|
||||
PropertyContainer::Global(g) => find_preview_data(
|
||||
&property_name,
|
||||
property_name,
|
||||
&mut definition.global_properties_and_callbacks(g)?,
|
||||
&|name| component_instance.get_global_property(g, name).ok(),
|
||||
),
|
||||
|
|
@ -109,13 +116,12 @@ pub fn get_preview_data(
|
|||
|
||||
pub fn query_preview_data_properties_and_callbacks(
|
||||
component_instance: &ComponentInstance,
|
||||
) -> HashMap<PropertyContainer, Vec<PreviewData>> {
|
||||
) -> PreviewDataMap {
|
||||
let definition = &component_instance.definition();
|
||||
|
||||
let mut result = HashMap::new();
|
||||
|
||||
fn collect_preview_data(
|
||||
it: &mut dyn Iterator<
|
||||
fn collect_preview_data<'a>(
|
||||
container: PropertyContainer,
|
||||
it: &'a mut dyn Iterator<
|
||||
Item = (
|
||||
String,
|
||||
(
|
||||
|
|
@ -124,37 +130,33 @@ pub fn query_preview_data_properties_and_callbacks(
|
|||
),
|
||||
),
|
||||
>,
|
||||
value_query: &dyn Fn(&str) -> Option<slint_interpreter::Value>,
|
||||
) -> Vec<PreviewData> {
|
||||
let mut v = it
|
||||
.map(|(name, (ty, visibility))| {
|
||||
let value = value_query(&name);
|
||||
value_query: &'a dyn Fn(&str) -> Option<slint_interpreter::Value>,
|
||||
) -> impl Iterator<Item = (PreviewDataKey, PreviewData)> + use<'a> {
|
||||
it.map(move |(name, (ty, visibility))| {
|
||||
let value = value_query(&name);
|
||||
|
||||
PreviewData { name, ty, visibility, value }
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
v.sort_by_key(|p| p.name.clone());
|
||||
v
|
||||
(
|
||||
PreviewDataKey { container: container.clone(), property_name: name },
|
||||
PreviewData { ty, visibility, value },
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
result.insert(
|
||||
let mut result = collect_preview_data(
|
||||
PropertyContainer::Main,
|
||||
collect_preview_data(&mut definition.properties_and_callbacks(), &|name| {
|
||||
component_instance.get_property(name).ok()
|
||||
}),
|
||||
);
|
||||
&mut definition.properties_and_callbacks(),
|
||||
&|name| component_instance.get_property(name).ok(),
|
||||
)
|
||||
.collect::<PreviewDataMap>();
|
||||
|
||||
for global in definition.globals() {
|
||||
result.insert(
|
||||
result.extend(collect_preview_data(
|
||||
PropertyContainer::Global(global.clone()),
|
||||
collect_preview_data(
|
||||
&mut definition
|
||||
.global_properties_and_callbacks(&global)
|
||||
.expect("Global was just valid"),
|
||||
&|name| component_instance.get_global_property(&global, name).ok(),
|
||||
),
|
||||
);
|
||||
&mut definition
|
||||
.global_properties_and_callbacks(&global)
|
||||
.expect("Global was just valid"),
|
||||
&|name| component_instance.get_global_property(&global, name).ok(),
|
||||
));
|
||||
}
|
||||
|
||||
result
|
||||
|
|
@ -187,15 +189,42 @@ fn find_component_properties_and_callbacks<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_preview_data(
|
||||
component_instance: &ComponentInstance,
|
||||
container: &PropertyContainer,
|
||||
property_name: &str,
|
||||
value: slint_interpreter::Value,
|
||||
) -> Result<(PreviewDataKey, slint_interpreter::Value), String> {
|
||||
let result = match &container {
|
||||
PropertyContainer::Main => component_instance.set_property(property_name, value.clone()),
|
||||
PropertyContainer::Global(g) => {
|
||||
component_instance.set_global_property(g, property_name, value.clone())
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(msg) = result {
|
||||
Err(format!("Could not set property {property_name}: {msg}"))
|
||||
} else {
|
||||
Ok((
|
||||
PreviewDataKey {
|
||||
container: container.clone(),
|
||||
property_name: property_name.to_string(),
|
||||
},
|
||||
value,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_json_preview_data(
|
||||
component_instance: &ComponentInstance,
|
||||
container: PropertyContainer,
|
||||
property_name: Option<String>,
|
||||
json: serde_json::Value,
|
||||
) -> Result<(), Vec<String>> {
|
||||
) -> Result<PreviewDataMap, Vec<String>> {
|
||||
let mut result = PreviewDataMap::default();
|
||||
|
||||
let definition = &component_instance.definition();
|
||||
|
||||
let mut properties_set = 0_usize;
|
||||
let mut failed_properties = vec![];
|
||||
|
||||
let it =
|
||||
|
|
@ -209,8 +238,8 @@ pub fn set_json_preview_data(
|
|||
}
|
||||
};
|
||||
|
||||
for (name, (ty, _)) in it {
|
||||
let (name, json_value) = if let Some(pn) = &property_name {
|
||||
for (name, (ty, visibility)) in it {
|
||||
let (property_name, json_value) = if let Some(pn) = &property_name {
|
||||
(pn.clone(), Some(&json))
|
||||
} else {
|
||||
let json_value = match &json {
|
||||
|
|
@ -239,20 +268,18 @@ pub fn set_json_preview_data(
|
|||
continue;
|
||||
};
|
||||
let Ok(value) = slint_interpreter::json::value_from_json(&ty, json_value) else {
|
||||
failed_properties.push(format!("Could not convert JSON value for property {name}"));
|
||||
failed_properties
|
||||
.push(format!("Could not convert JSON value for property {property_name}"));
|
||||
continue;
|
||||
};
|
||||
|
||||
let result = match &container {
|
||||
PropertyContainer::Main => component_instance.set_property(&name, value),
|
||||
PropertyContainer::Global(g) => component_instance.set_global_property(g, &name, value),
|
||||
};
|
||||
|
||||
if let Err(msg) = result {
|
||||
failed_properties.push(format!("Could not set property {name}: {msg}"));
|
||||
continue;
|
||||
} else {
|
||||
properties_set += 1;
|
||||
match set_preview_data(component_instance, &container, &property_name, value) {
|
||||
Err(msg) => {
|
||||
failed_properties.push(msg);
|
||||
}
|
||||
Ok((key, value)) => {
|
||||
result.insert(key, PreviewData { ty, visibility, value: Some(value) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,10 +287,10 @@ pub fn set_json_preview_data(
|
|||
return Err(failed_properties);
|
||||
}
|
||||
|
||||
if properties_set == 0 {
|
||||
if result.is_empty() {
|
||||
Err(vec![format!("No property set")])
|
||||
} else {
|
||||
Ok(())
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -335,131 +362,203 @@ mod tests {
|
|||
|
||||
let properties = query_preview_data_properties_and_callbacks(&component_instance);
|
||||
|
||||
assert_eq!(properties.len(), 4);
|
||||
assert_eq!(properties.len(), 12);
|
||||
|
||||
let main = properties.get(&PropertyContainer::Main).unwrap();
|
||||
let main = properties
|
||||
.iter()
|
||||
.filter(|(k, _)| k.container == PropertyContainer::Main)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(main.len(), 3);
|
||||
assert_eq!(
|
||||
main[0],
|
||||
PreviewData {
|
||||
name: "main-component-in".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(65.0)),
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Main,
|
||||
property_name: "main-component-in".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(65.0)),
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
main[1],
|
||||
PreviewData {
|
||||
name: "main-component-in-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(260.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Main,
|
||||
property_name: "main-component-in-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(260.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
main[2],
|
||||
PreviewData {
|
||||
name: "main-component-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(130.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Main,
|
||||
property_name: "main-component-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(130.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let global = properties.get(&PropertyContainer::Global("MainGlobal".into())).unwrap();
|
||||
let global = properties
|
||||
.iter()
|
||||
.filter(|(k, _)| k.container == PropertyContainer::Global("MainGlobal".into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(global.len(), 3);
|
||||
assert_eq!(
|
||||
global[0],
|
||||
PreviewData {
|
||||
name: "main-global-in".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(1.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("MainGlobal".into()),
|
||||
property_name: "main-global-in".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(1.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
global[1],
|
||||
PreviewData {
|
||||
name: "main-global-in-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(4.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("MainGlobal".into()),
|
||||
property_name: "main-global-in-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(4.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
global[2],
|
||||
PreviewData {
|
||||
name: "main-global-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(2.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("MainGlobal".into()),
|
||||
property_name: "main-global-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(2.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let user1 = properties.get(&PropertyContainer::Global("User1".into())).unwrap();
|
||||
let user1 = properties
|
||||
.iter()
|
||||
.filter(|(k, _)| k.container == PropertyContainer::Global("User1".into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(user1.len(), 3);
|
||||
|
||||
assert_eq!(
|
||||
user1[0],
|
||||
PreviewData {
|
||||
name: "user1-in".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(8.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("User1".into()),
|
||||
property_name: "user1-in".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(8.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
user1[1],
|
||||
PreviewData {
|
||||
name: "user1-in-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(32.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("User1".into()),
|
||||
property_name: "user1-in-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(32.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
user1[2],
|
||||
PreviewData {
|
||||
name: "user1-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(16.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("User1".into()),
|
||||
property_name: "user1-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(16.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let user2 = properties.get(&PropertyContainer::Global("User2".into())).unwrap();
|
||||
let user2 = properties
|
||||
.iter()
|
||||
.filter(|(k, _)| k.container == PropertyContainer::Global("User2".into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(user2.len(), 3);
|
||||
assert_eq!(
|
||||
user2[0],
|
||||
PreviewData {
|
||||
name: "user2-in".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(64.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("User2".into()),
|
||||
property_name: "user2-in".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Input,
|
||||
value: Some(slint_interpreter::Value::Number(64.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
user2[1],
|
||||
PreviewData {
|
||||
name: "user2-in-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(256.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("User2".into()),
|
||||
property_name: "user2-in-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::InOut,
|
||||
value: Some(slint_interpreter::Value::Number(256.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
user2[2],
|
||||
PreviewData {
|
||||
name: "user2-out".into(),
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(128.0))
|
||||
}
|
||||
(
|
||||
&PreviewDataKey {
|
||||
container: PropertyContainer::Global("User2".into()),
|
||||
property_name: "user2-out".into(),
|
||||
},
|
||||
&PreviewData {
|
||||
ty: i_slint_compiler::langtype::Type::Int32,
|
||||
visibility: i_slint_compiler::object_tree::PropertyVisibility::Output,
|
||||
value: Some(slint_interpreter::Value::Number(128.0))
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use std::{collections::HashMap, iter::once, rc::Rc};
|
|||
|
||||
use i_slint_compiler::parser::{syntax_nodes, SyntaxKind, TextRange};
|
||||
use i_slint_compiler::{expression_tree, langtype, literals};
|
||||
|
||||
use itertools::Itertools;
|
||||
use lsp_types::Url;
|
||||
use slint::{Model, ModelRc, SharedString, ToSharedString, VecModel};
|
||||
|
|
@ -114,7 +115,7 @@ pub fn create_ui(style: String, experimental: bool) -> Result<PreviewUi, Platfor
|
|||
r: c.red() as i32,
|
||||
g: c.green() as i32,
|
||||
b: c.blue() as i32,
|
||||
text: color_to_string(c).into(),
|
||||
text: color_to_string(c),
|
||||
short_text: color_to_short_string(c).into(),
|
||||
});
|
||||
api.on_rgba_to_color(|r, g, b, a| {
|
||||
|
|
@ -143,7 +144,7 @@ pub fn create_ui(style: String, experimental: bool) -> Result<PreviewUi, Platfor
|
|||
}
|
||||
let row = row as usize;
|
||||
if row < model.row_count() {
|
||||
model.as_any().downcast_ref::<VecModel<GradientStop>>().unwrap().remove(row as usize);
|
||||
model.as_any().downcast_ref::<VecModel<GradientStop>>().unwrap().remove(row);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -283,10 +284,10 @@ pub fn ui_set_known_components(
|
|||
let mut all_components = Vec::with_capacity(
|
||||
builtin_components.len() + library_components.len() + file_components.len(),
|
||||
);
|
||||
all_components.extend_from_slice(&builtin_components);
|
||||
all_components.extend_from_slice(&std_widgets_components);
|
||||
all_components.extend_from_slice(&library_components);
|
||||
all_components.extend_from_slice(&file_components);
|
||||
all_components.extend_from_slice(&builtin_components[..]);
|
||||
all_components.extend_from_slice(&std_widgets_components[..]);
|
||||
all_components.extend_from_slice(&library_components[..]);
|
||||
all_components.extend_from_slice(&file_components[..]);
|
||||
|
||||
let result = Rc::new(VecModel::from(all_components));
|
||||
let api = ui.global::<Api>();
|
||||
|
|
@ -516,7 +517,7 @@ fn set_default_brush(
|
|||
}
|
||||
value.brush_kind = BrushKind::Solid;
|
||||
let text = "#00000000";
|
||||
let color = string_to_color(&text).unwrap();
|
||||
let color = string_to_color(text).unwrap();
|
||||
value.gradient_stops =
|
||||
Rc::new(VecModel::from(vec![GradientStop { color, position: 0.5 }])).into();
|
||||
value.display_string = text.into();
|
||||
|
|
@ -926,7 +927,7 @@ fn map_value_and_type(
|
|||
gradient_stops: Rc::new(VecModel::from(vec![GradientStop { color, position: 0.5 }]))
|
||||
.into(),
|
||||
code,
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -941,7 +942,7 @@ fn map_value_and_type(
|
|||
kind: PropertyValueKind::Float,
|
||||
value_float: get_value::<f32>(value),
|
||||
code: get_code(value),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -953,7 +954,7 @@ fn map_value_and_type(
|
|||
kind: PropertyValueKind::Integer,
|
||||
value_int: get_value::<i32>(value),
|
||||
code: get_code(value),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -967,7 +968,7 @@ fn map_value_and_type(
|
|||
value_int: 0,
|
||||
code: get_code(value),
|
||||
default_selection: 1,
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -981,7 +982,7 @@ fn map_value_and_type(
|
|||
value_int: 0,
|
||||
code: get_code(value),
|
||||
default_selection: 0,
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -995,7 +996,7 @@ fn map_value_and_type(
|
|||
value_int: 0,
|
||||
code: get_code(value),
|
||||
default_selection: 0,
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -1009,7 +1010,7 @@ fn map_value_and_type(
|
|||
value_int: 0,
|
||||
code: get_code(value),
|
||||
default_selection: 0,
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -1023,7 +1024,7 @@ fn map_value_and_type(
|
|||
value_int: 0,
|
||||
code: get_code(value),
|
||||
default_selection: 0,
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -1037,7 +1038,7 @@ fn map_value_and_type(
|
|||
value_int: 0,
|
||||
code: get_code(value),
|
||||
default_selection: 0,
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -1048,7 +1049,7 @@ fn map_value_and_type(
|
|||
kind: PropertyValueKind::String,
|
||||
value_string: get_value::<SharedString>(value),
|
||||
code: get_code(value),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
|
@ -1080,7 +1081,7 @@ fn map_value_and_type(
|
|||
.collect::<Vec<_>>(),
|
||||
))
|
||||
.into(),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
code: get_code(value),
|
||||
..Default::default()
|
||||
});
|
||||
|
|
@ -1098,7 +1099,7 @@ fn map_value_and_type(
|
|||
.collect::<Vec<_>>(),
|
||||
))
|
||||
.into(),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
code: get_code(value),
|
||||
..Default::default()
|
||||
});
|
||||
|
|
@ -1109,7 +1110,7 @@ fn map_value_and_type(
|
|||
display_string: SharedString::from("Unknown Brush"),
|
||||
kind: PropertyValueKind::Code,
|
||||
value_string: SharedString::from("???"),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
code: get_code(value),
|
||||
..Default::default()
|
||||
});
|
||||
|
|
@ -1122,7 +1123,7 @@ fn map_value_and_type(
|
|||
display_string: get_value::<bool>(value).to_shared_string(),
|
||||
kind: PropertyValueKind::Boolean,
|
||||
value_bool: get_value::<bool>(value),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
code: get_code(value),
|
||||
..Default::default()
|
||||
});
|
||||
|
|
@ -1143,8 +1144,7 @@ fn map_value_and_type(
|
|||
"{}.{}",
|
||||
enumeration.name,
|
||||
enumeration.values[selected_value]
|
||||
)
|
||||
.into(),
|
||||
),
|
||||
kind: PropertyValueKind::Enum,
|
||||
value_string: enumeration.name.as_str().into(),
|
||||
default_selection: i32::try_from(enumeration.default_value).unwrap_or_default(),
|
||||
|
|
@ -1157,7 +1157,7 @@ fn map_value_and_type(
|
|||
.collect::<Vec<_>>(),
|
||||
))
|
||||
.into(),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
code: get_code(value),
|
||||
..Default::default()
|
||||
});
|
||||
|
|
@ -1167,9 +1167,9 @@ fn map_value_and_type(
|
|||
let model = get_value::<ModelRc<slint_interpreter::Value>>(value);
|
||||
|
||||
for (idx, sub_value) in model.iter().enumerate() {
|
||||
let mut sub_mapping = ValueMapping::default();
|
||||
sub_mapping.name_prefix = mapping.name_prefix.clone();
|
||||
map_value_and_type(&array_ty, &Some(sub_value), &mut sub_mapping);
|
||||
let mut sub_mapping =
|
||||
ValueMapping { name_prefix: mapping.name_prefix.clone(), ..Default::default() };
|
||||
map_value_and_type(array_ty, &Some(sub_value), &mut sub_mapping);
|
||||
|
||||
let sub_mapping_too_complex = sub_mapping.is_array || sub_mapping.is_too_complex;
|
||||
mapping.is_too_complex = mapping.is_too_complex || sub_mapping_too_complex;
|
||||
|
|
@ -1203,7 +1203,7 @@ fn map_value_and_type(
|
|||
sub_mapping.name_prefix = header_name.clone();
|
||||
|
||||
map_value_and_type(
|
||||
&field_ty,
|
||||
field_ty,
|
||||
&struct_data.get_field(&field).cloned(),
|
||||
&mut sub_mapping,
|
||||
);
|
||||
|
|
@ -1231,7 +1231,7 @@ fn map_value_and_type(
|
|||
display_string: "Unsupported type".into(),
|
||||
kind: PropertyValueKind::Code,
|
||||
value_string: "???".into(),
|
||||
accessor_path: mapping.name_prefix.clone().into(),
|
||||
accessor_path: mapping.name_prefix.clone(),
|
||||
code: get_code(value),
|
||||
..Default::default()
|
||||
});
|
||||
|
|
@ -1265,22 +1265,25 @@ fn map_preview_data_to_property_value(
|
|||
}
|
||||
}
|
||||
|
||||
fn map_preview_data_property(preview_data: &preview_data::PreviewData) -> Option<PreviewData> {
|
||||
if !preview_data.is_property() {
|
||||
fn map_preview_data_property(
|
||||
key: &preview_data::PreviewDataKey,
|
||||
value: &preview_data::PreviewData,
|
||||
) -> Option<PreviewData> {
|
||||
if !value.is_property() {
|
||||
return None;
|
||||
};
|
||||
|
||||
let has_getter = preview_data.has_getter();
|
||||
let has_setter = preview_data.has_setter();
|
||||
let has_getter = value.has_getter();
|
||||
let has_setter = value.has_setter();
|
||||
|
||||
let mut mapping = ValueMapping::default();
|
||||
map_value_and_type(&preview_data.ty, &preview_data.value, &mut mapping);
|
||||
map_value_and_type(&value.ty, &value.value, &mut mapping);
|
||||
|
||||
let is_array = mapping.array_values.len() != 1 || mapping.array_values[0].len() != 1;
|
||||
let is_too_complex = mapping.is_too_complex;
|
||||
|
||||
Some(PreviewData {
|
||||
name: preview_data.name.clone().into(),
|
||||
name: SharedString::from(&key.property_name),
|
||||
has_getter,
|
||||
has_setter,
|
||||
kind: match (is_array, is_too_complex) {
|
||||
|
|
@ -1293,41 +1296,45 @@ fn map_preview_data_property(preview_data: &preview_data::PreviewData) -> Option
|
|||
|
||||
pub fn ui_set_preview_data(
|
||||
ui: &PreviewUi,
|
||||
preview_data: HashMap<preview_data::PropertyContainer, Vec<preview_data::PreviewData>>,
|
||||
preview_data: preview_data::PreviewDataMap,
|
||||
previewed_component: Option<String>,
|
||||
) {
|
||||
fn fill_container(
|
||||
fn create_container(
|
||||
container_name: String,
|
||||
container_id: String,
|
||||
properties: &[preview_data::PreviewData],
|
||||
) -> PropertyContainer {
|
||||
let properties =
|
||||
properties.iter().filter_map(map_preview_data_property).collect::<Vec<_>>();
|
||||
|
||||
PropertyContainer {
|
||||
it: &mut dyn Iterator<Item = (&preview_data::PreviewDataKey, &preview_data::PreviewData)>,
|
||||
) -> Option<PropertyContainer> {
|
||||
let (id, props) = it.filter_map(|(k, v)| Some((k, map_preview_data_property(k, v)?))).fold(
|
||||
(None, vec![]),
|
||||
move |mut acc, (key, value)| {
|
||||
acc.0 = Some(acc.0.unwrap_or_else(|| key.container.clone()));
|
||||
acc.1.push(value);
|
||||
acc
|
||||
},
|
||||
);
|
||||
Some(PropertyContainer {
|
||||
container_name: container_name.into(),
|
||||
container_id: container_id.into(),
|
||||
properties: Rc::new(VecModel::from(properties)).into(),
|
||||
}
|
||||
container_id: id?.to_string().into(),
|
||||
properties: Rc::new(VecModel::from(props)).into(),
|
||||
})
|
||||
}
|
||||
|
||||
let mut result: Vec<PropertyContainer> = vec![];
|
||||
|
||||
if let Some(main) = preview_data.get(&preview_data::PropertyContainer::Main) {
|
||||
let c = fill_container(
|
||||
previewed_component.unwrap_or_else(|| "<MAIN>".to_string()),
|
||||
String::new(),
|
||||
main,
|
||||
);
|
||||
if let Some(c) = create_container(
|
||||
previewed_component.unwrap_or_else(|| "<MAIN>".to_string()),
|
||||
&mut preview_data
|
||||
.iter()
|
||||
.filter(|(k, _)| k.container == preview_data::PropertyContainer::Main),
|
||||
) {
|
||||
result.push(c);
|
||||
}
|
||||
|
||||
for component_key in
|
||||
preview_data.keys().filter(|k| **k != preview_data::PropertyContainer::Main)
|
||||
for (k, mut chunk) in &preview_data
|
||||
.iter()
|
||||
.filter(|(k, _)| k.container != preview_data::PropertyContainer::Main)
|
||||
.chunk_by(|(k, _)| k.container.clone())
|
||||
{
|
||||
if let Some(component) = preview_data.get(component_key) {
|
||||
let component_key = component_key.to_string();
|
||||
let c = fill_container(component_key.clone(), component_key, component);
|
||||
if let Some(c) = create_container(k.to_string(), &mut chunk) {
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
|
|
@ -1338,7 +1345,7 @@ pub fn ui_set_preview_data(
|
|||
}
|
||||
|
||||
fn to_property_container(container: SharedString) -> preview_data::PropertyContainer {
|
||||
if container.is_empty() {
|
||||
if container.is_empty() || container == "<MAIN>" {
|
||||
preview_data::PropertyContainer::Main
|
||||
} else {
|
||||
preview_data::PropertyContainer::Global(container.to_string())
|
||||
|
|
@ -1350,12 +1357,12 @@ fn get_property_value(container: SharedString, property_name: SharedString) -> P
|
|||
.and_then(|component_instance| {
|
||||
preview_data::get_preview_data(
|
||||
&component_instance,
|
||||
to_property_container(container),
|
||||
property_name.to_string(),
|
||||
&to_property_container(container),
|
||||
property_name.as_str(),
|
||||
)
|
||||
})
|
||||
.and_then(|pd| map_preview_data_to_property_value(&pd))
|
||||
.unwrap_or_else(Default::default)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn map_preview_data_to_property_value_table(
|
||||
|
|
@ -1375,19 +1382,18 @@ fn get_property_value_table(
|
|||
container: SharedString,
|
||||
property_name: SharedString,
|
||||
) -> PropertyValueTable {
|
||||
let (is_array, mut headers, mut values) = preview::component_instance()
|
||||
let (is_array, headers, mut values) = preview::component_instance()
|
||||
.and_then(|component_instance| {
|
||||
preview_data::get_preview_data(
|
||||
&component_instance,
|
||||
to_property_container(container),
|
||||
property_name.to_string(),
|
||||
&to_property_container(container),
|
||||
property_name.as_str(),
|
||||
)
|
||||
})
|
||||
.map(|pd| map_preview_data_to_property_value_table(&pd))
|
||||
.unwrap_or_else(|| (false, Default::default(), Default::default()));
|
||||
|
||||
let headers =
|
||||
Rc::new(VecModel::from(headers.drain(..).map(|s| s.into()).collect::<Vec<_>>())).into();
|
||||
let headers = Rc::new(VecModel::from(headers)).into();
|
||||
let values = Rc::new(VecModel::from(
|
||||
values.drain(..).map(|cv| Rc::new(VecModel::from(cv)).into()).collect::<Vec<_>>(),
|
||||
))
|
||||
|
|
@ -1439,12 +1445,12 @@ fn table_row_to_struct(row: ModelRc<PropertyValue>, indent_level: usize) -> Opti
|
|||
0 => None,
|
||||
1 => {
|
||||
let prev = map
|
||||
.insert(accessor_path.get(0).unwrap().to_string(), NodeKind::Leaf(value));
|
||||
.insert(accessor_path.first().unwrap().to_string(), NodeKind::Leaf(value));
|
||||
prev.is_none().then_some(())
|
||||
}
|
||||
_ => {
|
||||
let n = map
|
||||
.entry(accessor_path.get(0).unwrap().to_string())
|
||||
.entry(accessor_path.first().unwrap().to_string())
|
||||
.or_insert_with(|| NodeKind::Inner(BTreeMap::default()));
|
||||
|
||||
match n {
|
||||
|
|
@ -1624,7 +1630,7 @@ fn remove_row_from_value_table(table: PropertyValueTable, to_remove: i32) {
|
|||
};
|
||||
|
||||
if to_remove < vec_model.row_count() {
|
||||
vec_model.remove(to_remove as usize);
|
||||
vec_model.remove(to_remove);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1653,7 +1659,7 @@ fn set_json_preview_data(
|
|||
property_name,
|
||||
json,
|
||||
) {
|
||||
Ok(()) => SharedString::new(),
|
||||
Ok(_) => SharedString::new(),
|
||||
Err(v) => v.first().cloned().unwrap_or_default().into(),
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1754,7 +1760,7 @@ fn as_slint_brush(
|
|||
}
|
||||
|
||||
match kind {
|
||||
BrushKind::Solid => color_to_string(color).into(),
|
||||
BrushKind::Solid => color_to_string(color),
|
||||
BrushKind::Linear => {
|
||||
format!("@linear-gradient({angle}deg{})", stops_as_string(stops)).into()
|
||||
}
|
||||
|
|
@ -2382,7 +2388,8 @@ export component X {
|
|||
type_def: &str,
|
||||
type_name: &str,
|
||||
code: &str,
|
||||
) -> crate::preview::preview_data::PreviewData {
|
||||
) -> (crate::preview::preview_data::PreviewDataKey, crate::preview::preview_data::PreviewData)
|
||||
{
|
||||
let component_instance = crate::preview::test::interpret_test(
|
||||
"fluent",
|
||||
&format!(
|
||||
|
|
@ -2394,9 +2401,10 @@ export component Tester {{
|
|||
"#
|
||||
),
|
||||
);
|
||||
let preview_data =
|
||||
let mut data =
|
||||
preview_data::query_preview_data_properties_and_callbacks(&component_instance);
|
||||
return preview_data.get(&preview_data::PropertyContainer::Main).unwrap()[0].clone();
|
||||
assert_eq!(data.len(), 1);
|
||||
data.pop_first().unwrap()
|
||||
}
|
||||
|
||||
fn compare_pv(r: &super::PropertyValue, e: &PropertyValue) {
|
||||
|
|
@ -2427,10 +2435,9 @@ export component Tester {{
|
|||
type_name: &str,
|
||||
code: &str,
|
||||
expected_data: super::PreviewData,
|
||||
) -> preview_data::PreviewData {
|
||||
let raw_data = generate_preview_data(visibility, type_def, type_name, code);
|
||||
|
||||
let rp = super::map_preview_data_property(&raw_data).unwrap();
|
||||
) -> (preview_data::PreviewDataKey, preview_data::PreviewData) {
|
||||
let (key, value) = generate_preview_data(visibility, type_def, type_name, code);
|
||||
let rp = super::map_preview_data_property(&key, &value).unwrap();
|
||||
|
||||
eprintln!("*** Validating PreviewData: Received: {rp:?}");
|
||||
eprintln!("*** Validating PreviewData: Expected: {expected_data:?}");
|
||||
|
|
@ -2442,7 +2449,7 @@ export component Tester {{
|
|||
|
||||
eprintln!("*** PreviewData is as expected...");
|
||||
|
||||
raw_data
|
||||
(key, value)
|
||||
}
|
||||
|
||||
fn validate_rp(
|
||||
|
|
@ -2453,15 +2460,15 @@ export component Tester {{
|
|||
expected_data: super::PreviewData,
|
||||
expected_value: super::PropertyValue,
|
||||
) {
|
||||
let rp = validate_rp_impl(visibility, type_def, type_name, code, expected_data);
|
||||
let (_, value) = validate_rp_impl(visibility, type_def, type_name, code, expected_data);
|
||||
|
||||
let pv = super::map_preview_data_to_property_value(&rp).unwrap();
|
||||
let pv = super::map_preview_data_to_property_value(&value).unwrap();
|
||||
compare_pv(&pv, &expected_value);
|
||||
|
||||
let (is_array, headers, values) = super::map_preview_data_to_property_value_table(&rp);
|
||||
let (is_array, headers, values) = super::map_preview_data_to_property_value_table(&value);
|
||||
assert!(!is_array);
|
||||
assert!(headers.len() == 1);
|
||||
assert!(headers[0] == "");
|
||||
assert!(headers[0].is_empty());
|
||||
assert_eq!(values.len(), 1);
|
||||
assert_eq!(values.first().unwrap().len(), 1);
|
||||
}
|
||||
|
|
@ -2477,9 +2484,9 @@ export component Tester {{
|
|||
expected_headers: Vec<String>,
|
||||
expected_table: Vec<Vec<super::PropertyValue>>,
|
||||
) {
|
||||
let rp = validate_rp_impl(visibility, type_def, type_name, code, expected_data);
|
||||
let (_, value) = validate_rp_impl(visibility, type_def, type_name, code, expected_data);
|
||||
|
||||
let pv = super::map_preview_data_to_property_value(&rp).unwrap();
|
||||
let pv = super::map_preview_data_to_property_value(&value).unwrap();
|
||||
compare_pv(
|
||||
&pv,
|
||||
&super::PropertyValue {
|
||||
|
|
@ -2489,7 +2496,7 @@ export component Tester {{
|
|||
},
|
||||
);
|
||||
|
||||
let (is_array, headers, values) = super::map_preview_data_to_property_value_table(&rp);
|
||||
let (is_array, headers, values) = super::map_preview_data_to_property_value_table(&value);
|
||||
|
||||
assert_eq!(is_array, expected_is_array);
|
||||
|
||||
|
|
@ -2734,7 +2741,6 @@ export component Tester {{
|
|||
has_getter: true,
|
||||
has_setter: true,
|
||||
kind: super::PreviewDataKind::Value,
|
||||
..Default::default()
|
||||
},
|
||||
super::PropertyValue {
|
||||
display_string: "false".into(),
|
||||
|
|
@ -2760,7 +2766,6 @@ export component Tester {{
|
|||
has_getter: true,
|
||||
has_setter: true,
|
||||
kind: super::PreviewDataKind::Json,
|
||||
..Default::default()
|
||||
},
|
||||
super::PropertyValue {
|
||||
kind: super::PropertyValueKind::Code,
|
||||
|
|
@ -2784,7 +2789,6 @@ export component Tester {{
|
|||
has_getter: true,
|
||||
has_setter: true,
|
||||
kind: super::PreviewDataKind::Table,
|
||||
..Default::default()
|
||||
},
|
||||
"{\n \"bar\": true,\n \"count\": 23\n}",
|
||||
false,
|
||||
|
|
@ -2824,7 +2828,6 @@ export component Tester {{
|
|||
has_getter: true,
|
||||
has_setter: true,
|
||||
kind: super::PreviewDataKind::Table,
|
||||
..Default::default()
|
||||
},
|
||||
"{\n \"first\": {\n \"c1-1\": \"first of a kind\",\n \"c1-2\": 23\n },\n \"second\": {\n \"c2-1\": \"second of a kind\",\n \"c2-2\": 42\n }\n}",
|
||||
false,
|
||||
|
|
@ -2884,7 +2887,6 @@ export component Tester {{
|
|||
has_getter: true,
|
||||
has_setter: true,
|
||||
kind: super::PreviewDataKind::Table,
|
||||
..Default::default()
|
||||
},
|
||||
"[\n {\n \"first\": {\n \"c1-1\": \"first of a kind\",\n \"c1-2\": 23\n },\n \"second\": {\n \"c2-1\": \"second of a kind\",\n \"c2-2\": 42\n }\n },\n {\n \"first\": {\n \"c1-1\": \"row 2, 1\",\n \"c1-2\": 3\n },\n \"second\": {\n \"c2-1\": \"row 2, 2\",\n \"c2-2\": 2\n }\n }\n]",
|
||||
true,
|
||||
|
|
@ -2969,7 +2971,6 @@ export component Tester {{
|
|||
has_getter: true,
|
||||
has_setter: true,
|
||||
kind: super::PreviewDataKind::Table,
|
||||
..Default::default()
|
||||
},
|
||||
"[\n true,\n false\n]",
|
||||
true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue