mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-03 21:24:17 +00:00
live-preview: Only pass information on the component previewed once
This commit is contained in:
parent
229fdb73ec
commit
d0d0327049
5 changed files with 69 additions and 47 deletions
|
|
@ -345,14 +345,20 @@ fn navigate(nav_direction: i32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// triggered from the UI, running in UI thread
|
// triggered from the UI, running in UI thread
|
||||||
fn show_component(name: slint::SharedString, file: slint::SharedString) {
|
fn show_component(name: slint::SharedString, url: slint::SharedString) {
|
||||||
let name = name.to_string();
|
let name = name.to_string();
|
||||||
let file = PathBuf::from(file.to_string());
|
let Ok(url) = Url::parse(&url.to_string()) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(file) = url.to_file_path() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let Some(document_cache) = document_cache() else {
|
let Some(document_cache) = document_cache() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(document) = document_cache.get_document_by_path(&file) else {
|
let Some(document) = document_cache.get_document(&url) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(document) = document.node.as_ref() else {
|
let Some(document) = document.node.as_ref() else {
|
||||||
|
|
@ -955,26 +961,8 @@ fn set_preview_factory(
|
||||||
|
|
||||||
Some(instance)
|
Some(instance)
|
||||||
});
|
});
|
||||||
let (name, file, pretty_location) = {
|
|
||||||
let cache = CONTENT_CACHE.get_or_init(Default::default).lock().unwrap();
|
|
||||||
if let Some(current) = cache.current_component() {
|
|
||||||
let file = current.url.to_file_path().unwrap_or_default();
|
|
||||||
(
|
|
||||||
current.component.as_ref().cloned().unwrap_or_else(|| "Default".to_string()),
|
|
||||||
file.to_string_lossy().to_string(),
|
|
||||||
file.file_name().unwrap_or_default().to_string_lossy().to_string(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(String::new(), String::new(), String::new())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ui.set_preview_area(ui::Preview {
|
ui.set_preview_area(factory);
|
||||||
factory,
|
|
||||||
name: name.into(),
|
|
||||||
pretty_location: pretty_location.into(),
|
|
||||||
file: file.into(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Highlight the element pointed at the offset in the path.
|
/// Highlight the element pointed at the offset in the path.
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ use std::{collections::HashMap, iter::once, rc::Rc};
|
||||||
use slint::{Model, SharedString, VecModel};
|
use slint::{Model, SharedString, VecModel};
|
||||||
use slint_interpreter::{DiagnosticLevel, PlatformError};
|
use slint_interpreter::{DiagnosticLevel, PlatformError};
|
||||||
|
|
||||||
|
use crate::common::ComponentInformation;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
use crate::wasm_prelude::*;
|
||||||
|
|
||||||
slint::include_modules!();
|
slint::include_modules!();
|
||||||
|
|
||||||
pub fn create_ui(style: String, experimental: bool) -> Result<PreviewUi, PlatformError> {
|
pub fn create_ui(style: String, experimental: bool) -> Result<PreviewUi, PlatformError> {
|
||||||
|
|
@ -81,6 +86,19 @@ pub fn convert_diagnostics(diagnostics: &[slint_interpreter::Diagnostic]) -> Vec
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extract_definition_location(
|
||||||
|
ci: &ComponentInformation,
|
||||||
|
) -> (slint::SharedString, slint::SharedString) {
|
||||||
|
let Some(url) = ci.defined_at.as_ref().map(|da| &da.url) else {
|
||||||
|
return (Default::default(), Default::default());
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = url.to_file_path().unwrap_or_default();
|
||||||
|
let file_name = path.file_name().unwrap_or_default().to_string_lossy().to_string();
|
||||||
|
|
||||||
|
(url.to_string().into(), file_name.into())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ui_set_known_components(
|
pub fn ui_set_known_components(
|
||||||
ui: &PreviewUi,
|
ui: &PreviewUi,
|
||||||
known_components: &[crate::common::ComponentInformation],
|
known_components: &[crate::common::ComponentInformation],
|
||||||
|
|
@ -91,14 +109,11 @@ pub fn ui_set_known_components(
|
||||||
if ci.is_global {
|
if ci.is_global {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
let (url, pretty_location) = extract_definition_location(ci);
|
||||||
map.entry(ci.category.clone()).or_default().push(ComponentItem {
|
map.entry(ci.category.clone()).or_default().push(ComponentItem {
|
||||||
name: ci.name.clone().into(),
|
name: ci.name.clone().into(),
|
||||||
defined_at: ci
|
defined_at: url,
|
||||||
.defined_at
|
pretty_location,
|
||||||
.as_ref()
|
|
||||||
.map(|da| da.url.to_string())
|
|
||||||
.unwrap_or_default()
|
|
||||||
.into(),
|
|
||||||
is_user_defined: !(ci.is_builtin || ci.is_std_widget),
|
is_user_defined: !(ci.is_builtin || ci.is_std_widget),
|
||||||
is_currently_shown: idx == current_component_index,
|
is_currently_shown: idx == current_component_index,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { Button, Palette, ScrollView, VerticalBox, GroupBox, LineEdit } from "st
|
||||||
export struct ComponentItem {
|
export struct ComponentItem {
|
||||||
name: string,
|
name: string,
|
||||||
defined_at: string,
|
defined_at: string,
|
||||||
|
pretty_location: string,
|
||||||
is_user_defined: bool,
|
is_user_defined: bool,
|
||||||
is_currently_shown: bool,
|
is_currently_shown: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -23,6 +24,15 @@ export component ComponentList {
|
||||||
in property <length> preview-area-width;
|
in property <length> preview-area-width;
|
||||||
in property <length> preview-area-height;
|
in property <length> preview-area-height;
|
||||||
|
|
||||||
|
in-out property <ComponentItem> visible-component: empty-component-item;
|
||||||
|
|
||||||
|
private property <ComponentItem> empty-component-item: {
|
||||||
|
name: "",
|
||||||
|
defined_at: "",
|
||||||
|
is_user_defined: false,
|
||||||
|
is_currently_shown: false,
|
||||||
|
};
|
||||||
|
|
||||||
private property <length> list-spacing: 6px;
|
private property <length> list-spacing: 6px;
|
||||||
|
|
||||||
out property <bool> over-target;
|
out property <bool> over-target;
|
||||||
|
|
@ -77,13 +87,22 @@ export component ComponentList {
|
||||||
drop-x >= 0 && drop-x <= root.preview-area-width && drop-y >= 0 && drop-y <= root.preview-area-height;
|
drop-x >= 0 && drop-x <= root.preview-area-width && drop-y >= 0 && drop-y <= root.preview-area-height;
|
||||||
private property <bool> can-drop-here: !self.data.is-currently-shown && root.can-drop(self.data.name, drop-x, drop-y, on-drop-area);
|
private property <bool> can-drop-here: !self.data.is-currently-shown && root.can-drop(self.data.name, drop-x, drop-y, on-drop-area);
|
||||||
private property <ComponentItem> data: ci;
|
private property <ComponentItem> data: ci;
|
||||||
private property <int> my-index: index;
|
private property <int> my-index: index;
|
||||||
|
|
||||||
enabled: root.preview-visible;
|
enabled: root.preview-visible;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
private property <bool> edit-me: self.data.is-user-defined && root.editing-in-category == category.my-category-index && category.editing-component-index == self.my-index;
|
private property <bool> edit-me: self.data.is-user-defined && root.editing-in-category == category.my-category-index && category.editing-component-index == self.my-index;
|
||||||
|
|
||||||
|
// Hack to initialize currently visible component:
|
||||||
|
if ci.is_currently_shown: Rectangle {
|
||||||
|
visible: false;
|
||||||
|
|
||||||
|
init() => {
|
||||||
|
root.visible-component = ci;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
if component.edit-me: LineEdit {
|
if component.edit-me: LineEdit {
|
||||||
horizontal-alignment: center;
|
horizontal-alignment: center;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
// cSpell: ignore resizer
|
// cSpell: ignore resizer
|
||||||
|
|
||||||
import { Button, ComboBox, HorizontalBox, ListView, ScrollView, Palette, VerticalBox } from "std-widgets.slint";
|
import { Button, ComboBox, HorizontalBox, LineEdit, ListView, ScrollView, Palette, VerticalBox } from "std-widgets.slint";
|
||||||
import { Diagnostics, DiagnosticsOverlay } from "diagnostics-overlay.slint";
|
import { Diagnostics, DiagnosticsOverlay } from "diagnostics-overlay.slint";
|
||||||
|
import { ComponentItem } from "component-list.slint";
|
||||||
import { Resizer } from "resizer.slint";
|
import { Resizer } from "resizer.slint";
|
||||||
|
|
||||||
export enum LayoutKind {
|
export enum LayoutKind {
|
||||||
|
|
@ -42,13 +43,6 @@ export struct DropMark {
|
||||||
y2: length,
|
y2: length,
|
||||||
}
|
}
|
||||||
|
|
||||||
export struct Preview {
|
|
||||||
factory: component-factory,
|
|
||||||
name: string,
|
|
||||||
pretty-location: string,
|
|
||||||
file: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
component SelectionFrame {
|
component SelectionFrame {
|
||||||
in property <Selection> selection;
|
in property <Selection> selection;
|
||||||
in property <bool> interactive: true;
|
in property <bool> interactive: true;
|
||||||
|
|
@ -177,8 +171,9 @@ export enum DrawAreaMode {
|
||||||
export component DrawArea {
|
export component DrawArea {
|
||||||
in property <[Diagnostics]> diagnostics;
|
in property <[Diagnostics]> diagnostics;
|
||||||
in property <[Selection]> selections;
|
in property <[Selection]> selections;
|
||||||
|
in property <ComponentItem> visible-component;
|
||||||
in property <DropMark> drop-mark;
|
in property <DropMark> drop-mark;
|
||||||
in property <Preview> preview-area;
|
in property <component-factory> preview-area;
|
||||||
in property <bool> design-mode;
|
in property <bool> design-mode;
|
||||||
|
|
||||||
out property <bool> preview-visible: preview-area-container.has-component && !diagnostics.diagnostics-open;
|
out property <bool> preview-visible: preview-area-container.has-component && !diagnostics.diagnostics-open;
|
||||||
|
|
@ -253,7 +248,7 @@ export component DrawArea {
|
||||||
// is called every time the condition is dirty, to make sure that the size
|
// is called every time the condition is dirty, to make sure that the size
|
||||||
// is within the bounds.
|
// is within the bounds.
|
||||||
// Query the preview-area to make sure this is evaluated when it changes
|
// Query the preview-area to make sure this is evaluated when it changes
|
||||||
if preview-area-container.has-component && root.preview-area.factory == preview-area-container.component-factory: Rectangle {
|
if preview-area-container.has-component && root.preview-area == preview-area-container.component-factory: Rectangle {
|
||||||
init => {
|
init => {
|
||||||
preview-area-container.width = clamp(preview-area-container.width, max(preview-area-container.min-width, 16px), max(preview-area-container.max-width, 16px));
|
preview-area-container.width = clamp(preview-area-container.width, max(preview-area-container.min-width, 16px), max(preview-area-container.max-width, 16px));
|
||||||
preview-area-container.height = clamp(preview-area-container.height, max(preview-area-container.min-height, 16px), max(preview-area-container.max-height, 16px));
|
preview-area-container.height = clamp(preview-area-container.height, max(preview-area-container.min-height, 16px), max(preview-area-container.max-height, 16px));
|
||||||
|
|
@ -263,7 +258,7 @@ export component DrawArea {
|
||||||
preview-area-container := ComponentContainer {
|
preview-area-container := ComponentContainer {
|
||||||
property <bool> is-resizable: (self.min-width != self.max-width && self.min-height != self.max-height) && self.has-component;
|
property <bool> is-resizable: (self.min-width != self.max-width && self.min-height != self.max-height) && self.has-component;
|
||||||
|
|
||||||
component-factory: root.preview-area.factory;
|
component-factory: root.preview-area;
|
||||||
|
|
||||||
// The width and the height can't depend on the layout info of the inner item otherwise this would
|
// The width and the height can't depend on the layout info of the inner item otherwise this would
|
||||||
// cause a recursion if this happens (#3989)
|
// cause a recursion if this happens (#3989)
|
||||||
|
|
@ -335,6 +330,8 @@ export component DrawArea {
|
||||||
}
|
}
|
||||||
|
|
||||||
component-label := Rectangle {
|
component-label := Rectangle {
|
||||||
|
visible: root.visible-component.is_currently_shown;
|
||||||
|
|
||||||
property <length> offset: 10px;
|
property <length> offset: 10px;
|
||||||
width: self.min-width;
|
width: self.min-width;
|
||||||
height: self.min-height;
|
height: self.min-height;
|
||||||
|
|
@ -352,7 +349,7 @@ export component DrawArea {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
horizontal-alignment: left;
|
horizontal-alignment: left;
|
||||||
text: root.preview-area.name;
|
text: root.visible-component.name;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
HorizontalLayout {
|
HorizontalLayout {
|
||||||
|
|
@ -362,10 +359,10 @@ export component DrawArea {
|
||||||
Text {
|
Text {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
horizontal-alignment: left;
|
horizontal-alignment: left;
|
||||||
text: root.preview-area.pretty-location;
|
text: root.visible-component.defined_at;
|
||||||
}
|
}
|
||||||
clicked() => {
|
clicked() => {
|
||||||
root.show-component(root.preview-area.name, root.preview-area.file);
|
root.show-component(root.visible-component.name, root.visible-component.defined-at);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
// cSpell: ignore Heade
|
// cSpell: ignore Heade
|
||||||
|
|
||||||
import { Button, ComboBox, ListView, ScrollView, VerticalBox } from "std-widgets.slint";
|
import { Button, ComboBox, ListView, ScrollView, VerticalBox } from "std-widgets.slint";
|
||||||
import { ComponentList, ComponentListItem } from "component-list.slint";
|
import { ComponentItem, ComponentList, ComponentListItem } from "component-list.slint";
|
||||||
import { DrawArea, DrawAreaMode, DropMark, LayoutKind, Preview, Selection } from "draw-area.slint";
|
import { DrawArea, DrawAreaMode, DropMark, LayoutKind, Selection } from "draw-area.slint";
|
||||||
import { HeaderBar } from "header-bar.slint";
|
import { HeaderBar } from "header-bar.slint";
|
||||||
import { Diagnostics, DiagnosticsOverlay } from "diagnostics-overlay.slint";
|
import { Diagnostics, DiagnosticsOverlay } from "diagnostics-overlay.slint";
|
||||||
|
|
||||||
|
|
@ -13,13 +13,14 @@ export { Diagnostics, DropMark, LayoutKind }
|
||||||
|
|
||||||
export component PreviewUi inherits Window {
|
export component PreviewUi inherits Window {
|
||||||
in property <[ComponentListItem]> known-components;
|
in property <[ComponentListItem]> known-components;
|
||||||
|
in-out property <ComponentItem> visible-component;
|
||||||
in property <[Diagnostics]> diagnostics;
|
in property <[Diagnostics]> diagnostics;
|
||||||
in property <[Selection]> selections;
|
in property <[Selection]> selections;
|
||||||
in-out property <DropMark> drop-mark;
|
in-out property <DropMark> drop-mark;
|
||||||
in property <[string]> known-styles;
|
in property <[string]> known-styles;
|
||||||
in property <bool> experimental: false;
|
in property <bool> experimental: false;
|
||||||
in property <bool> show-preview-ui: true;
|
in property <bool> show-preview-ui: true;
|
||||||
in property <Preview> preview-area;
|
in property <component-factory> preview-area;
|
||||||
in property <string> status-text;
|
in property <string> status-text;
|
||||||
in-out property <string> current-style;
|
in-out property <string> current-style;
|
||||||
in property <bool> can-navigate-back: false;
|
in property <bool> can-navigate-back: false;
|
||||||
|
|
@ -57,7 +58,7 @@ export component PreviewUi inherits Window {
|
||||||
if (!show-preview-ui): no-ui-drawing-rect := Rectangle {
|
if (!show-preview-ui): no-ui-drawing-rect := Rectangle {
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
ComponentContainer {
|
ComponentContainer {
|
||||||
component-factory: root.preview-area.factory;
|
component-factory: root.preview-area;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,6 +127,7 @@ export component PreviewUi inherits Window {
|
||||||
VerticalBox {
|
VerticalBox {
|
||||||
ComponentList {
|
ComponentList {
|
||||||
known-components <=> root.known-components;
|
known-components <=> root.known-components;
|
||||||
|
visible-component <=> root.visible-component;
|
||||||
preview-area-position-x: draw-area.preview-area-position-x;
|
preview-area-position-x: draw-area.preview-area-position-x;
|
||||||
preview-area-position-y: draw-area.preview-area-position-y;
|
preview-area-position-y: draw-area.preview-area-position-y;
|
||||||
preview-area-width: draw-area.preview-area-width;
|
preview-area-width: draw-area.preview-area-width;
|
||||||
|
|
@ -165,6 +167,7 @@ export component PreviewUi inherits Window {
|
||||||
preview-area <=> root.preview-area;
|
preview-area <=> root.preview-area;
|
||||||
selections <=> root.selections;
|
selections <=> root.selections;
|
||||||
drop-mark <=> root.drop-mark;
|
drop-mark <=> root.drop-mark;
|
||||||
|
visible-component <=> root.visible-component;
|
||||||
|
|
||||||
select-at(x, y, enter_component) => {
|
select-at(x, y, enter_component) => {
|
||||||
root.select-at(x, y, enter_component);
|
root.select-at(x, y, enter_component);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue