This commit is contained in:
me
2026-01-27 21:06:08 +08:00
parent 79fd98899e
commit 91f24cb462
5 changed files with 586 additions and 419 deletions

775
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,17 +4,13 @@ version = "0.0.1"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
slint = { version = "1.14", default-features = false, features = ["backend-winit", "renderer-winit-skia", "compat-1-2"] } slint = { version = "1.14", default-features = false, features = ["backend-winit", "renderer-femtovg-wgpu", "compat-1-2"] }
[build-dependencies] [build-dependencies]
slint-build = "1.14" slint-build = "1.14"
[features]
default = []
lite = [] # Lightweight demo with minimal memory footprint
[profile.release] [profile.release]
opt-level = 'z' # 优化代码体积 opt-level = 'z'
lto = true # 开启链接时优化 lto = true
codegen-units = 1 # 牺牲编译速度换取更好的代码质量 codegen-units = 1
strip = true # 自动移除调试符号 strip = true

View File

@@ -1,12 +1,3 @@
fn main() { fn main() {
// Use SLINT_DEMO environment variable to choose demo version slint_build::compile("ui/demo.slint").unwrap();
// cargo build -> full demo
// cargo build --features lite -> lite demo
let demo_file = if cfg!(feature = "lite") {
"ui/demo-lite.slint"
} else {
"ui/demo.slint"
};
slint_build::compile(demo_file).unwrap();
} }

View File

@@ -1,72 +1,59 @@
slint::include_modules!(); slint::include_modules!();
#[cfg(not(feature = "lite"))]
use slint::{ComponentHandle, Model, ModelRc, VecModel}; use slint::{ComponentHandle, Model, ModelRc, VecModel};
#[cfg(not(feature = "lite"))]
use std::rc::Rc; use std::rc::Rc;
fn main() -> Result<(), slint::PlatformError> { fn main() -> Result<(), slint::PlatformError> {
#[cfg(feature = "lite")] // Full version with all features
{ let ui = Demo::new()?;
// Lite version - minimal memory footprint
let ui = DemoLite::new()?;
ui.run()
}
#[cfg(not(feature = "lite"))] // Toast management
{ let toasts: Rc<VecModel<ToastMessage>> = Rc::new(VecModel::default());
// Full version with all features ui.set_toasts(ModelRc::from(toasts.clone()));
let ui = Demo::new()?;
// Toast management // Handle add-task callback
let toasts: Rc<VecModel<ToastMessage>> = Rc::new(VecModel::default()); let ui_weak = ui.as_weak();
ui.set_toasts(ModelRc::from(toasts.clone())); let toasts_clone = toasts.clone();
ui.on_add_task(move |task_title| {
let ui = ui_weak.unwrap();
// Handle add-task callback // Show success toast
let ui_weak = ui.as_weak(); toasts_clone.push(ToastMessage {
let toasts_clone = toasts.clone(); message: format!("Task '{}' added successfully!", task_title).into(),
ui.on_add_task(move |task_title| { variant: "success".into(),
let ui = ui_weak.unwrap(); show: true,
// Show success toast
toasts_clone.push(ToastMessage {
message: format!("Task '{}' added successfully!", task_title).into(),
variant: "success".into(),
show: true,
});
// Auto-dismiss after 3 seconds
let toasts_clone2 = toasts_clone.clone();
let index = toasts_clone.row_count() - 1;
slint::Timer::single_shot(std::time::Duration::from_secs(3), move || {
if index < toasts_clone2.row_count() {
toasts_clone2.remove(index);
}
});
// Clear input
ui.set_new_task_title("".into());
}); });
// Handle show-toast callback // Auto-dismiss after 3 seconds
let toasts_clone = toasts.clone(); let toasts_clone2 = toasts_clone.clone();
ui.on_show_toast(move |message, variant| { let index = toasts_clone.row_count() - 1;
toasts_clone.push(ToastMessage { slint::Timer::single_shot(std::time::Duration::from_secs(3), move || {
message: message.clone(), if index < toasts_clone2.row_count() {
variant: variant.clone(), toasts_clone2.remove(index);
show: true, }
});
// Auto-dismiss after 3 seconds
let toasts_clone2 = toasts_clone.clone();
let index = toasts_clone.row_count() - 1;
slint::Timer::single_shot(std::time::Duration::from_secs(3), move || {
if index < toasts_clone2.row_count() {
toasts_clone2.remove(index);
}
});
}); });
ui.run() // Clear input
} ui.set_new_task_title("".into());
});
// Handle show-toast callback
let toasts_clone = toasts.clone();
ui.on_show_toast(move |message, variant| {
toasts_clone.push(ToastMessage {
message: message.clone(),
variant: variant.clone(),
show: true,
});
// Auto-dismiss after 3 seconds
let toasts_clone2 = toasts_clone.clone();
let index = toasts_clone.row_count() - 1;
slint::Timer::single_shot(std::time::Duration::from_secs(3), move || {
if index < toasts_clone2.row_count() {
toasts_clone2.remove(index);
}
});
});
ui.run()
} }

View File

@@ -1,102 +0,0 @@
// Lightweight Demo Application
// Minimal memory footprint version
import { Theme, Typography, SpacingSystem } from "theme/theme.slint";
import { Button } from "components/button.slint";
import { Input } from "components/input.slint";
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "components/card.slint";
import { Badge } from "components/badge.slint";
export component DemoLite inherits Window {
title: "Slint Shadcn UI - Lite Demo";
background: Theme.colors.background;
// Smaller window size
min-width: 500px;
min-height: 400px;
preferred-width: 700px;
preferred-height: 500px;
// Minimal state
in-out property <string> input-text: "";
VerticalLayout {
padding: SpacingSystem.spacing.s4;
spacing: SpacingSystem.spacing.s4;
// Header
HorizontalLayout {
spacing: SpacingSystem.spacing.s3;
alignment: space-between;
Text {
text: "Shadcn UI Demo";
font-size: Typography.sizes.xl;
font-weight: Typography.weights.bold;
color: Theme.colors.foreground;
}
Button {
text: Theme.is-dark-mode ? "☀" : "🌙";
variant: "outline";
size: "sm";
clicked => { Theme.toggle-theme(); }
}
}
// Main card
Card {
CardHeader {
CardTitle { text: "Button Showcase"; }
CardDescription { text: "Various button styles"; }
}
CardContent {
VerticalLayout {
spacing: SpacingSystem.spacing.s3;
// Button variants
HorizontalLayout {
spacing: SpacingSystem.spacing.s2;
Button { text: "Default"; }
Button { text: "Secondary"; variant: "secondary"; }
Button { text: "Outline"; variant: "outline"; }
Button { text: "Ghost"; variant: "ghost"; }
}
// Destructive button
HorizontalLayout {
spacing: SpacingSystem.spacing.s2;
Button { text: "Destructive"; variant: "destructive"; }
Button { text: "Disabled"; disabled: true; }
}
}
}
}
// Input card
Card {
CardHeader {
CardTitle { text: "Input & Badge"; }
}
CardContent {
VerticalLayout {
spacing: SpacingSystem.spacing.s3;
Input {
value <=> input-text;
placeholder: "Type something...";
}
HorizontalLayout {
spacing: SpacingSystem.spacing.s2;
Badge { text: "Default"; }
Badge { text: "Secondary"; variant: "secondary"; }
Badge { text: "Outline"; variant: "outline"; }
}
}
}
}
}
}