Web Rust Desktop-Funktionsbeispiele

Web Rust Desktop-Funktionsbeispiele einschließlich Dateidialoge, Meldungsfelder und Systemintegration

💻 Meldungsfeld rust

🟢 simple ⭐⭐

Alert-, Bestätigungs- und Eingabedialoge mit Browser-APIs anzeigen

⏱️ 15 min 🏷️ rust, web, desktop features
Prerequisites: Basic Rust, Understanding of Web APIs
// Web Rust Message Box Examples
// Alert, confirm, and prompt dialogs using browser Web APIs
//
// This demonstrates message box functionality that would work in WebAssembly (WASM) context
//
// For actual desktop message boxes, consider using:
// - Tauri (https://tauri.app/) for desktop apps
// - egui for custom modal dialogs

use serde::{Deserialize, Serialize};

// 1. Message Box Types

/// Types of message boxes
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum MessageBoxType {
    Info,
    Warning,
    Error,
    Question,
    Success,
}

/// Message box buttons
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum MessageBoxButtons {
    Ok,
    OkCancel,
    YesNo,
    YesNoCancel,
    AbortRetryIgnore,
}

/// Message box result
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum MessageBoxResult {
    Ok,
    Cancel,
    Yes,
    No,
    Abort,
    Retry,
    Ignore,
}

// 2. Message Box Options

/// Options for message box
#[derive(Debug, Clone)]
struct MessageBoxOptions {
    title: String,
    message: String,
    box_type: MessageBoxType,
    buttons: MessageBoxButtons,
    default_button: MessageBoxResult,
}

impl MessageBoxOptions {
    fn new(title: &str, message: &str) -> Self {
        MessageBoxOptions {
            title: title.to_string(),
            message: message.to_string(),
            box_type: MessageBoxType::Info,
            buttons: MessageBoxButtons::Ok,
            default_button: MessageBoxResult::Ok,
        }
    }

    fn with_type(mut self, box_type: MessageBoxType) -> Self {
        self.box_type = box_type;
        self
    }

    fn with_buttons(mut self, buttons: MessageBoxButtons) -> Self {
        self.buttons = buttons;
        self
    }

    fn with_default(mut self, default: MessageBoxResult) -> Self {
        self.default_button = default;
        self
    }
}

// 3. Message Box Implementation (WASM-compatible)

/// Show alert dialog (simple info message)
fn show_alert(title: &str, message: &str) {
    // In WASM, this would call: window.alert(message)
    println!("[ALERT] {}: {}", title, message);
}

/// Show confirm dialog (yes/no)
fn show_confirm(title: &str, message: &str) -> bool {
    // In WASM, this would call: window.confirm(message)
    println!("[CONFIRM] {}: {}", title, message);
    true // Simulated user response
}

/// Show prompt dialog (input field)
fn show_prompt(title: &str, message: &str, default: &str) -> Option<String> {
    // In WASM, this would call: window.prompt(message, default)
    println!("[PROMPT] {}: {} (default: {})", title, message, default);
    Some(default.to_string()) // Simulated user input
}

/// Show custom message box
fn show_message_box(options: &MessageBoxOptions) -> MessageBoxResult {
    // In WASM, this would create a custom modal dialog
    println!("[{} - {}]: {}",
        match options.box_type {
            MessageBoxType::Info => "INFO",
            MessageBoxType::Warning => "WARNING",
            MessageBoxType::Error => "ERROR",
            MessageBoxType::Question => "QUESTION",
            MessageBoxType::Success => "SUCCESS",
        },
        options.title,
        options.message
    );

    println!("Buttons: {:?}", options.buttons);
    options.default_button
}

// 4. Common Message Box Helpers

/// Show information message
fn show_info(title: &str, message: &str) {
    show_alert(title, message);
}

/// Show warning message
fn show_warning(title: &str, message: &str) {
    let options = MessageBoxOptions::new(title, message)
        .with_type(MessageBoxType::Warning);
    show_message_box(&options);
}

/// Show error message
fn show_error(title: &str, message: &str) {
    let options = MessageBoxOptions::new(title, message)
        .with_type(MessageBoxType::Error);
    show_message_box(&options);
}

/// Show success message
fn show_success(title: &str, message: &str) {
    let options = MessageBoxOptions::new(title, message)
        .with_type(MessageBoxType::Success);
    show_message_box(&options);
}

/// Show question dialog
fn show_question(title: &str, message: &str) -> MessageBoxResult {
    let options = MessageBoxOptions::new(title, message)
        .with_type(MessageBoxType::Question)
        .with_buttons(MessageBoxButtons::YesNo)
        .with_default(MessageBoxResult::Yes);
    show_message_box(&options)
}

/// Show confirmation dialog
fn show_confirmation(title: &str, message: &str) -> bool {
    matches!(show_question(title, message), MessageBoxResult::Yes)
}

// 5. Progress Dialog

/// Progress dialog state
struct ProgressDialog {
    title: String,
    message: String,
    progress: f64,
}

impl ProgressDialog {
    fn new(title: &str, message: &str) -> Self {
        ProgressDialog {
            title: title.to_string(),
            message: message.to_string(),
            progress: 0.0,
        }
    }

    fn set_message(&mut self, message: &str) {
        self.message = message.to_string();
        println!("[PROGRESS] {} - {} ({}%)", self.title, message, self.progress);
    }

    fn set_progress(&mut self, progress: f64) {
        self.progress = progress.max(0.0).min(100.0);
        println!("[PROGRESS] {} - {} ({}%)", self.title, self.message, self.progress);
    }

    fn increment(&mut self, amount: f64) {
        self.set_progress(self.progress + amount);
    }

    fn close(self) {
        println!("[PROGRESS] Closed: {}", self.title);
    }
}

// 6. Input Dialog

/// Input dialog result
enum InputResult {
    Text(String),
    Cancelled,
}

/// Show input dialog
fn show_input_dialog(title: &str, message: &str) -> InputResult {
    match show_prompt(title, message, "") {
        Some(input) => InputResult::Text(input),
        None => InputResult::Cancelled,
    }
}

/// Show password input dialog
fn show_password_dialog(title: &str, message: &str) -> InputResult {
    // In real implementation, this would use a password field
    match show_prompt(title, message, "") {
        Some(input) => InputResult::Text(input),
        None => InputResult::Cancelled,
    }
}

// 7. Selection Dialog

/// Show selection dialog
fn show_selection_dialog(title: &str, message: &str, options: &[&str]) -> Option<usize> {
    println!("[SELECTION] {}: {}", title, message);
    for (i, option) in options.iter().enumerate() {
        println!("  {}. {}", i + 1, option);
    }
    Some(0) // Simulated selection
}

// 8. Toast Notifications

/// Toast notification type
#[derive(Debug, Clone, Copy)]
enum ToastType {
    Info,
    Success,
    Warning,
    Error,
}

/// Show toast notification
fn show_toast(message: &str, toast_type: ToastType) {
    println!("[TOAST - {:?}] {}", toast_type, message);
}

/// Show info toast
fn toast_info(message: &str) {
    show_toast(message, ToastType::Info);
}

/// Show success toast
fn toast_success(message: &str) {
    show_toast(message, ToastType::Success);
}

/// Show warning toast
fn toast_warning(message: &str) {
    show_toast(message, ToastType::Warning);
}

/// Show error toast
fn toast_error(message: &str) {
    show_toast(message, ToastType::Error);
}

// 9. Dialog Builder

/// Builder for message box
struct MessageBoxBuilder {
    options: MessageBoxOptions,
}

impl MessageBoxBuilder {
    fn new(title: &str, message: &str) -> Self {
        MessageBoxBuilder {
            options: MessageBoxOptions::new(title, message),
        }
    }

    fn info(mut self) -> Self {
        self.options.box_type = MessageBoxType::Info;
        self
    }

    fn warning(mut self) -> Self {
        self.options.box_type = MessageBoxType::Warning;
        self
    }

    fn error(mut self) -> Self {
        self.options.box_type = MessageBoxType::Error;
        self
    }

    fn question(mut self) -> Self {
        self.options.box_type = MessageBoxType::Question;
        self
    }

    fn success(mut self) -> Self {
        self.options.box_type = MessageBoxType::Success;
        self
    }

    fn ok_cancel(mut self) -> Self {
        self.options.buttons = MessageBoxButtons::OkCancel;
        self
    }

    fn yes_no(mut self) -> Self {
        self.options.buttons = MessageBoxButtons::YesNo;
        self
    }

    fn show(self) -> MessageBoxResult {
        show_message_box(&self.options)
    }
}

// 10. Batch Operations

/// Show multiple confirmations
fn show_multiple_confirmations(messages: &[(&str, &str)]) -> Vec<bool> {
    messages.iter()
        .map(|(title, msg)| show_confirmation(title, msg))
        .collect()
}

/// Chain of dialogs
fn show_dialog_chain(dialogs: Vec<MessageBoxOptions>) -> Vec<MessageBoxResult> {
    dialogs.iter()
        .map(|options| show_message_box(options))
        .collect()
}

// Usage Examples
fn main() {
    println!("=== Web Rust Message Box Examples ===\n");

    // 1. Simple alert
    println!("--- 1. Simple Alert ---");
    show_alert("Welcome", "Application started successfully");

    // 2. Confirm dialog
    println!("
--- 2. Confirm Dialog ---");
    let confirmed = show_confirm("Confirm", "Do you want to continue?");
    println!("User confirmed: {}", confirmed);

    // 3. Prompt dialog
    println!("
--- 3. Prompt Dialog ---");
    match show_prompt("Input", "Enter your name:", "John") {
        Some(name) => println!("User entered: {}", name),
        None => println!("User cancelled"),
    }

    // 4. Different message types
    println!("
--- 4. Message Types ---");
    show_info("Info", "This is an information message");
    show_warning("Warning", "This is a warning message");
    show_error("Error", "This is an error message");
    show_success("Success", "Operation completed successfully");

    // 5. Question dialog
    println!("
--- 5. Question Dialog ---");
    let answer = show_question("Question", "Do you agree to the terms?");
    println!("Answer: {:?}", answer);

    // 6. Confirmation
    println!("
--- 6. Confirmation ---");
    let proceed = show_confirmation("Confirm Action", "Delete selected files?");
    println!("Proceed: {}", proceed);

    // 7. Progress dialog
    println!("
--- 7. Progress Dialog ---");
    let mut progress = ProgressDialog::new("Downloading", "Initializing...");
    for i in 0..=10 {
        progress.set_progress((i * 10) as f64);
        progress.set_message(&format!("Downloading file {}...", i));
    }
    progress.close();

    // 8. Toast notifications
    println!("
--- 8. Toast Notifications ---");
    toast_info("Application started");
    toast_success("File saved successfully");
    toast_warning("Low disk space");
    toast_error("Connection failed");

    // 9. Input dialog
    println!("
--- 9. Input Dialog ---");
    match show_input_dialog("Name", "Enter your name:") {
        InputResult::Text(name) => println!("Name: {}", name),
        InputResult::Cancelled => println!("Cancelled"),
    }

    // 10. Selection dialog
    println!("
--- 10. Selection Dialog ---");
    let options = vec!["Option 1", "Option 2", "Option 3"];
    match show_selection_dialog("Choose", "Select an option:", &options) {
        Some(index) => println!("Selected: {}", options[index]),
        None => println!("Cancelled"),
    }

    // 11. Builder pattern
    println!("
--- 11. Builder Pattern ---");
    let result = MessageBoxBuilder::new("Delete", "Are you sure?")
        .question()
        .yes_no()
        .show();
    println!("Result: {:?}", result);

    println!("
=== Note ===");
    println!("For actual desktop message boxes in Rust, consider:");
    println!("- Tauri: https://tauri.app/");
    println!("- egui: https://github.com/emilk/egui");
    println!("- native-dialog: https://github.com/babdul/national");

    println!("
=== All Message Box Examples Completed ===");
}

💻 Dateidialog rust

🟡 intermediate ⭐⭐⭐

Dateidialoge öffnen und speichern mit Web APIs (mit WASM)

⏱️ 20 min 🏷️ rust, web, desktop features
Prerequisites: Intermediate Rust, Understanding of Web APIs
// Web Rust File Dialog Examples
// File open/save dialogs using browser Web APIs
//
// This demonstrates file dialog functionality that would work in WebAssembly (WASM) context
//
// For actual desktop file dialogs, consider using:
// - Tauri (https://tauri.app/) for desktop apps
// - egui + rfd (https://github.com/PolyMeilex/rfd) for native dialogs

use std::path::PathBuf;
use serde::{Deserialize, Serialize};

// 1. File Selection Result

/// Result of file selection
#[derive(Debug, Clone, Serialize, Deserialize)]
struct FileSelection {
    name: String,
    size: u64,
    content_type: Option<String>,
}

// 2. File Dialog Simulation
// Note: In WASM, you would use JavaScript interop for actual file dialogs

/// Simulated file dialog options
#[derive(Debug, Clone)]
struct FileDialogOptions {
    title: String,
    filters: Vec<FileFilter>,
    multi_select: bool,
    directory: bool,
}

impl Default for FileDialogOptions {
    fn default() -> Self {
        FileDialogOptions {
            title: "Select File".to_string(),
            filters: Vec::new(),
            multi_select: false,
            directory: false,
        }
    }
}

/// File filter for dialog
#[derive(Debug, Clone)]
struct FileFilter {
    name: String,
    extensions: Vec<String>,
}

impl FileFilter {
    fn new(name: &str, extensions: &[&str]) -> Self {
        FileFilter {
            name: name.to_string(),
            extensions: extensions.iter().map(|s| s.to_string()).collect(),
        }
    }
}

// 3. File Dialog Functions (WASM-compatible)

/// Open file dialog (returns selected file paths)
/// In WASM, this would call JavaScript's File API
fn open_file_dialog(options: &FileDialogOptions) -> Result<Vec<PathBuf>, String> {
    // Simulated implementation
    // In real WASM, you would use wasm-bindgen with web-sys
    let mut selected = Vec::new();

    // This is a placeholder - actual implementation requires JS interop
    if options.directory {
        // Would use <input type="file" webkitdirectory>
    } else if options.multi_select {
        // Would use <input type="file" multiple>
    } else {
        // Would use <input type="file">
    }

    if selected.is_empty() {
        Err("No file selected".to_string())
    } else {
        Ok(selected)
    }
}

/// Save file dialog
fn save_file_dialog(options: &FileDialogOptions) -> Result<PathBuf, String> {
    // In WASM, this would trigger browser download
    Ok(PathBuf::from("saved_file.txt"))
}

// 4. File Reading

/// Read file content as text
fn read_file_text(path: &PathBuf) -> Result<String, String> {
    std::fs::read_to_string(path).map_err(|e| e.to_string())
}

/// Read file content as bytes
fn read_file_bytes(path: &PathBuf) -> Result<Vec<u8>, String> {
    std::fs::read(path).map_err(|e| e.to_string())
}

// 5. File Writing

/// Write text to file
fn write_file_text(path: &PathBuf, content: &str) -> Result<(), String> {
    std::fs::write(path, content).map_err(|e| e.to_string())
}

/// Write bytes to file
fn write_file_bytes(path: &PathBuf, content: &[u8]) -> Result<(), String> {
    std::fs::write(path, content).map_err(|e| e.to_string())
}

// 6. File Validation

/// Check if file exists
fn file_exists(path: &PathBuf) -> bool {
    path.exists()
}

/// Get file metadata
fn get_file_info(path: &PathBuf) -> Result<FileSelection, String> {
    let metadata = std::fs::metadata(path).map_err(|e| e.to_string())?;
    let name = path.file_name()
        .and_then(|n| n.to_str())
        .unwrap_or("unknown")
        .to_string();

    Ok(FileSelection {
        name,
        size: metadata.len(),
        content_type: None, // Would detect from extension
    })
}

// 7. File Type Detection

/// Get file extension
fn get_file_extension(path: &PathBuf) -> Option<String> {
    path.extension()
        .and_then(|ext| ext.to_str())
        .map(|s| s.to_string())
}

/// Get MIME type from extension
fn get_mime_type(path: &PathBuf) -> Option<&'static str> {
    match get_file_extension(path)?.as_str() {
        "txt" => Some("text/plain"),
        "html" => Some("text/html"),
        "css" => Some("text/css"),
        "js" => Some("application/javascript"),
        "json" => Some("application/json"),
        "png" => Some("image/png"),
        "jpg" | "jpeg" => Some("image/jpeg"),
        "gif" => Some("image/gif"),
        "pdf" => Some("application/pdf"),
        "zip" => Some("application/zip"),
        _ => Some("application/octet-stream"),
    }
}

// 8. Common File Filters

/// Create image file filter
fn image_filter() -> FileFilter {
    FileFilter::new("Images", &["png", "jpg", "jpeg", "gif", "bmp", "webp"])
}

/// Create text file filter
fn text_filter() -> FileFilter {
    FileFilter::new("Text Files", &["txt", "md", "csv", "json", "xml"])
}

/// Create document file filter
fn document_filter() -> FileFilter {
    FileFilter::new("Documents", &["pdf", "doc", "docx", "odt"])
}

/// Create all files filter
fn all_files_filter() -> FileFilter {
    FileFilter::new("All Files", &["*"])
}

// 9. File Dialog Builder

/// Builder for file dialog options
struct FileDialogBuilder {
    options: FileDialogOptions,
}

impl FileDialogBuilder {
    fn new() -> Self {
        FileDialogBuilder {
            options: FileDialogOptions::default(),
        }
    }

    fn title(mut self, title: &str) -> Self {
        self.options.title = title.to_string();
        self
    }

    fn add_filter(mut self, filter: FileFilter) -> Self {
        self.options.filters.push(filter);
        self
    }

    fn multi_select(mut self, multi: bool) -> Self {
        self.options.multi_select = multi;
        self
    }

    fn directory(mut self, dir: bool) -> Self {
        self.options.directory = dir;
        self
    }

    fn build(self) -> FileDialogOptions {
        self.options
    }
}

impl Default for FileDialogBuilder {
    fn default() -> Self {
        Self::new()
    }
}

// 10. File Operations

/// Batch file reading
fn read_multiple_files(paths: &[PathBuf]) -> Vec<Result<String, String>> {
    paths.iter().map(|p| read_file_text(p)).collect()
}

/// Batch file writing
fn write_multiple_files(data: &[(PathBuf, String)]) -> Vec<Result<(), String>> {
    data.iter().map(|(path, content)| write_file_text(path, content)).collect()
}

// 11. File Dialog Result Processing

/// Process selected files
fn process_selected_files(paths: Vec<PathBuf>) -> Vec<FileSelection> {
    paths.into_iter()
        .filter_map(|path| {
            if file_exists(&path) {
                get_file_info(&path).ok()
            } else {
                None
            }
        })
        .collect()
}

/// Validate file types
fn validate_file_type(path: &PathBuf, allowed_extensions: &[&str]) -> bool {
    if let Some(ext) = get_file_extension(path) {
        allowed_extensions.contains(&ext.as_str())
    } else {
        false
    }
}

// Usage Examples
fn main() {
    println!("=== Web Rust File Dialog Examples ===\n");

    // 1. Create file dialog options
    println!("--- 1. File Dialog Options ---");
    let options = FileDialogBuilder::new()
        .title("Open Image")
        .add_filter(image_filter())
        .add_filter(all_files_filter())
        .multi_select(true)
        .build();

    println!("Dialog options: {:?}", options);

    // 2. Simulate file dialog
    println!("
--- 2. Open File Dialog ---");
    match open_file_dialog(&options) {
        Ok(paths) => println!("Selected {} files", paths.len()),
        Err(e) => println!("Error: {}", e),
    }

    // 3. Save file dialog
    println!("
--- 3. Save File Dialog ---");
    let save_options = FileDialogBuilder::new()
        .title("Save Document")
        .add_filter(text_filter())
        .build();

    match save_file_dialog(&save_options) {
        Ok(path) => println!("Save path: {:?}", path),
        Err(e) => println!("Error: {}", e),
    }

    // 4. File filters
    println!("
--- 4. File Filters ---");
    println!("Image filter: {:?}", image_filter());
    println!("Text filter: {:?}", text_filter());
    println!("Document filter: {:?}", document_filter());

    // 5. File type detection
    println!("
--- 5. File Type Detection ---");
    let test_path = PathBuf::from("test.png");
    println!("Extension: {:?}", get_file_extension(&test_path));
    println!("MIME type: {:?}", get_mime_type(&test_path));

    // 6. File validation
    println!("
--- 6. File Validation ---");
    let allowed = vec!["png", "jpg", "jpeg"];
    println!("Is valid image: {}", validate_file_type(&test_path, &allowed));

    let invalid_path = PathBuf::from("test.txt");
    println!("Is valid image: {}", validate_file_type(&invalid_path, &allowed));

    println!("
=== Note ===");
    println!("For actual desktop file dialogs in Rust, consider:");
    println!("- Tauri: https://tauri.app/");
    println!("- rfd: https://github.com/PolyMeilex/rfd");
    println!("- egui: https://github.com/emilk/egui");

    println!("
=== All File Dialog Examples Completed ===");
}

💻 Systemleiste rust

🔴 complex ⭐⭐⭐⭐

Systemleisten-Symbole und Menüs (Desktop-Frameworks)

⏱️ 30 min 🏷️ rust, web, desktop features
Prerequisites: Advanced Rust, Desktop Framework Knowledge
// Web Rust System Tray Examples
// System tray icons and menu functionality
//
// This demonstrates system tray patterns. Note: System tray is NOT available in web browsers.
// For actual system tray functionality, you need desktop frameworks like:
// - Tauri (https://tauri.app/) - Desktop apps with web technologies
// - Tray-icon crate (https://github.com/tauri-apps/tray-icon) - Rust tray library
//
// The following examples show the API patterns for desktop framework integration

use std::sync::{Arc, Mutex};

// 1. Tray Icon Types

/// Tray icon state
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum TrayIconState {
    Normal,
    Active,
    Disabled,
    Busy,
}

/// Tray icon theme
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum TrayIconTheme {
    Light,
    Dark,
    Auto,
}

// 2. Tray Menu Items

/// Menu item type
#[derive(Debug, Clone)]
enum MenuItemType {
    Separator,
    Action(String),
    Checkbox(String, bool),
    Submenu(String, Vec<MenuItem>),
}

/// Menu item
#[derive(Debug, Clone)]
struct MenuItem {
    id: String,
    item_type: MenuItemType,
    enabled: bool,
    visible: bool,
}

impl MenuItem {
    fn separator() -> Self {
        MenuItem {
            id: format!("sep_{}", std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos()),
            item_type: MenuItemType::Separator,
            enabled: true,
            visible: true,
        }
    }

    fn action(id: &str, label: &str) -> Self {
        MenuItem {
            id: id.to_string(),
            item_type: MenuItemType::Action(label.to_string()),
            enabled: true,
            visible: true,
        }
    }

    fn checkbox(id: &str, label: &str, checked: bool) -> Self {
        MenuItem {
            id: id.to_string(),
            item_type: MenuItemType::Checkbox(label.to_string(), checked),
            enabled: true,
            visible: true,
        }
    }

    fn submenu(id: &str, label: &str, items: Vec<MenuItem>) -> Self {
        MenuItem {
            id: id.to_string(),
            item_type: MenuItemType::Submenu(label.to_string(), items),
            enabled: true,
            visible: true,
        }
    }

    fn set_enabled(mut self, enabled: bool) -> Self {
        self.enabled = enabled;
        self
    }

    fn set_visible(mut self, visible: bool) -> Self {
        self.visible = visible;
        self
    }
}

// 3. Tray Icon Configuration

/// Tray icon configuration
#[derive(Debug, Clone)]
struct TrayIconConfig {
    icon_path: String,
    tooltip: String,
    theme: TrayIconTheme,
    state: TrayIconState,
}

impl TrayIconConfig {
    fn new(icon_path: &str, tooltip: &str) -> Self {
        TrayIconConfig {
            icon_path: icon_path.to_string(),
            tooltip: tooltip.to_string(),
            theme: TrayIconTheme::Auto,
            state: TrayIconState::Normal,
        }
    }

    fn with_theme(mut self, theme: TrayIconTheme) -> Self {
        self.theme = theme;
        self
    }

    fn with_state(mut self, state: TrayIconState) -> Self {
        self.state = state;
        self
    }
}

// 4. System Tray Implementation (Mock)

/// System tray (mock implementation for API demonstration)
struct SystemTray {
    config: TrayIconConfig,
    menu: Vec<MenuItem>,
    on_click: Option<Box<dyn Fn()>>,
    on_double_click: Option<Box<dyn Fn()>>,
}

impl SystemTray {
    fn new(config: TrayIconConfig) -> Self {
        SystemTray {
            config,
            menu: Vec::new(),
            on_click: None,
            on_double_click: None,
        }
    }

    fn set_menu(&mut self, menu: Vec<MenuItem>) {
        self.menu = menu;
        println!("Tray menu updated with {} items", menu.len());
    }

    fn set_tooltip(&mut self, tooltip: &str) {
        self.config.tooltip = tooltip.to_string();
        println!("Tray tooltip updated: {}", tooltip);
    }

    fn set_icon(&mut self, icon_path: &str) {
        self.config.icon_path = icon_path.to_string();
        println!("Tray icon updated: {}", icon_path);
    }

    fn set_state(&mut self, state: TrayIconState) {
        self.config.state = state;
        println!("Tray state updated: {:?}", state);
    }

    fn show(&self) {
        println!("Tray icon shown: {}", self.config.tooltip);
    }

    fn hide(&self) {
        println!("Tray icon hidden");
    }

    fn on_click<F: Fn() + 'static>(mut self, callback: F) -> Self {
        self.on_click = Some(Box::new(callback));
        self
    }

    fn on_double_click<F: Fn() + 'static>(mut self, callback: F) -> Self {
        self.on_double_click = Some(Box::new(callback));
        self
    }

    fn handle_menu_action(&self, item_id: &str) {
        println!("Menu action triggered: {}", item_id);
        // Would dispatch to event handler
    }
}

// 5. Tray Menu Builder

/// Builder for tray menu
struct TrayMenuBuilder {
    items: Vec<MenuItem>,
}

impl TrayMenuBuilder {
    fn new() -> Self {
        TrayMenuBuilder {
            items: Vec::new(),
        }
    }

    fn add_item(mut self, item: MenuItem) -> Self {
        self.items.push(item);
        self
    }

    fn add_separator(mut self) -> Self {
        self.items.push(MenuItem::separator());
        self
    }

    fn add_action(mut self, id: &str, label: &str) -> Self {
        self.items.push(MenuItem::action(id, label));
        self
    }

    fn add_checkbox(mut self, id: &str, label: &str, checked: bool) -> Self {
        self.items.push(MenuItem::checkbox(id, label, checked));
        self
    }

    fn add_submenu(mut self, id: &str, label: &str, items: Vec<MenuItem>) -> Self {
        self.items.push(MenuItem::submenu(id, label, items));
        self
    }

    fn build(self) -> Vec<MenuItem> {
        self.items
    }
}

impl Default for TrayMenuBuilder {
    fn default() -> Self {
        Self::new()
    }
}

// 6. Notification Handler

/// Tray notification
#[derive(Debug, Clone)]
struct TrayNotification {
    title: String,
    body: String,
    icon: Option<String>,
    timeout: Option<u32>,
}

impl TrayNotification {
    fn new(title: &str, body: &str) -> Self {
        TrayNotification {
            title: title.to_string(),
            body: body.to_string(),
            icon: None,
            timeout: None,
        }
    }

    fn with_icon(mut self, icon: &str) -> Self {
        self.icon = Some(icon.to_string());
        self
    }

    fn with_timeout(mut self, seconds: u32) -> Self {
        self.timeout = Some(seconds);
        self
    }
}

// 7. Tray State Manager

/// Manages tray icon state
struct TrayStateManager {
    state: Arc<Mutex<TrayIconState>>,
}

impl TrayStateManager {
    fn new() -> Self {
        TrayStateManager {
            state: Arc::new(Mutex::new(TrayIconState::Normal)),
        }
    }

    fn set_state(&self, new_state: TrayIconState) {
        let mut state = self.state.lock().unwrap();
        *state = new_state;
        println!("Tray state changed to: {:?}", new_state);
    }

    fn get_state(&self) -> TrayIconState {
        *self.state.lock().unwrap()
    }
}

// 8. Common Tray Menu Patterns

/// Create default application menu
fn create_app_menu() -> Vec<MenuItem> {
    TrayMenuBuilder::new()
        .add_action("show", "Show")
        .add_action("hide", "Hide")
        .add_separator()
        .add_action("settings", "Settings")
        .add_action("about", "About")
        .add_separator()
        .add_action("quit", "Quit")
        .build()
}

/// Create status toggle menu
fn create_status_menu(is_active: bool) -> Vec<MenuItem> {
    TrayMenuBuilder::new()
        .add_checkbox("status", "Active", is_active)
        .add_separator()
        .add_action("refresh", "Refresh Status")
        .add_separator()
        .add_action("quit", "Quit")
        .build()
}

/// Create media player menu
fn create_media_menu() -> Vec<MenuItem> {
    TrayMenuBuilder::new()
        .add_action("play_pause", "Play/Pause")
        .add_action("next", "Next Track")
        .add_action("prev", "Previous Track")
        .add_separator()
        .add_submenu("playlist", "Playlist", vec![
            MenuItem::action("shuffle", "Shuffle"),
            MenuItem::action("repeat", "Repeat"),
        ])
        .add_separator()
        .add_action("quit", "Quit")
        .build()
}

// 9. Tray Event Handler

/// Tray events
#[derive(Debug, Clone)]
enum TrayEvent {
    Click,
    DoubleClick,
    MenuAction(String),
    BalloonClick,
}

/// Handle tray events
fn handle_tray_event(event: TrayEvent) {
    match event {
        TrayEvent::Click => println!("Tray icon clicked"),
        TrayEvent::DoubleClick => println!("Tray icon double-clicked"),
        TrayEvent::MenuAction(id) => println!("Menu action: {}", id),
        TrayEvent::BalloonClick => println!("Balloon notification clicked"),
    }
}

// 10. Dynamic Menu Updates

/// Update menu item dynamically
fn update_menu_item(menu: &mut Vec<MenuItem>, id: &str, updater: impl FnOnce(&mut MenuItem)) {
    if let Some(item) = menu.iter_mut().find(|i| i.id == id) {
        updater(item);
    }
}

/// Toggle checkbox in menu
fn toggle_menu_checkbox(menu: &mut Vec<MenuItem>, id: &str) -> bool {
    if let Some(item) = menu.iter_mut().find(|i| i.id == id) {
        if let MenuItemType::Checkbox(label, checked) = &mut item.item_type {
            *checked = !*checked;
            return *checked;
        }
    }
    false
}

// Usage Examples
fn main() {
    println!("=== Web Rust System Tray Examples ===\n");

    // 1. Create tray icon
    println!("--- 1. Create Tray Icon ---");
    let config = TrayIconConfig::new("icon.png", "My Application")
        .with_state(TrayIconState::Normal);

    let mut tray = SystemTray::new(config);
    tray.show();

    // 2. Set up menu
    println!("
--- 2. Set Up Menu ---");
    let menu = create_app_menu();
    tray.set_menu(menu);
    for item in &tray.menu {
        println!("  - {:?}", item.item_type);
    }

    // 3. Update tooltip
    println!("
--- 3. Update Tooltip ---");
    tray.set_tooltip("Application running - 3 notifications");

    // 4. Change state
    println!("
--- 4. Change State ---");
    tray.set_state(TrayIconState::Busy);

    // 5. Menu builder
    println!("
--- 5. Menu Builder ---");
    let custom_menu = TrayMenuBuilder::new()
        .add_action("file_open", "Open File")
        .add_action("file_save", "Save File")
        .add_separator()
        .add_submenu("recent", "Recent Files", vec![
            MenuItem::action("recent_1", "document1.txt"),
            MenuItem::action("recent_2", "document2.txt"),
        ])
        .build();

    // 6. Status menu
    println!("
--- 6. Status Menu ---");
    let status_menu = create_status_menu(true);
    println!("Status menu items: {}", status_menu.len());

    // 7. Media menu
    println!("
--- 7. Media Player Menu ---");
    let media_menu = create_media_menu();
    println!("Media menu items: {}", media_menu.len());

    // 8. Menu updates
    println!("
--- 8. Dynamic Menu Updates ---");
    let mut menu = create_app_menu();
    update_menu_item(&mut menu, "show", |item| {
        item.enabled = false;
    });
    println!("Updated 'show' item: enabled={}",
        menu.iter().find(|i| i.id == "show").map(|i| i.enabled).unwrap_or(false)
    );

    // 9. Toggle checkbox
    println!("
--- 9. Toggle Checkbox ---");
    let mut menu = create_status_menu(false);
    let new_state = toggle_menu_checkbox(&mut menu, "status");
    println!("Checkbox toggled to: {}", new_state);

    // 10. Event handling
    println!("
--- 10. Event Handling ---");
    handle_tray_event(TrayEvent::Click);
    handle_tray_event(TrayEvent::MenuAction("quit".to_string()));

    // 11. Notification
    println!("
--- 11. Notification ---");
    let notification = TrayNotification::new("Update Available", "Version 2.0 is ready to install")
        .with_icon("update-icon.png")
        .with_timeout(10);
    println!("Notification: {:?} - {:?}", notification.title, notification.body);

    // 12. State manager
    println!("
--- 12. State Manager ---");
    let state_manager = TrayStateManager::new();
    state_manager.set_state(TrayIconState::Active);
    println!("Current state: {:?}", state_manager.get_state());

    println!("
=== IMPORTANT NOTE ===");
    println!("System tray functionality is NOT available in web browsers.");
    println!("This code demonstrates API patterns for desktop frameworks.");
    println!("");
    println!("For actual system tray implementation in Rust:");
    println!("- Tauri: https://tauri.app/ (recommended for web developers)");
    println!("- tray-icon: https://github.com/tauri-apps/tray-icon");
    println!("- egui: https://github.com/emilk/egui (with tray-icon)");

    println!("
=== All System Tray Examples Completed ===");
}