use crate::runtime::values::Value;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct Window {
pub id: String,
pub title: String,
pub width: i64,
pub height: i64,
pub x: i64,
pub y: i64,
pub visible: bool,
pub maximized: bool,
pub minimized: bool,
pub resizable: bool,
pub decorated: bool,
pub always_on_top: bool,
pub fullscreen: bool,
pub components: Vec<UIComponent>,
pub event_handlers: HashMap<String, String>, }
#[derive(Debug, Clone)]
pub struct WindowConfig {
pub title: String,
pub width: i64,
pub height: i64,
pub x: Option<i64>,
pub y: Option<i64>,
pub resizable: bool,
pub decorated: bool,
pub always_on_top: bool,
pub fullscreen: bool,
pub icon_path: Option<String>,
pub theme: String,
}
#[derive(Debug, Clone)]
pub enum UIComponent {
Button(ButtonComponent),
Label(LabelComponent),
TextField(TextFieldComponent),
TextArea(TextAreaComponent),
CheckBox(CheckBoxComponent),
RadioButton(RadioButtonComponent),
ComboBox(ComboBoxComponent),
ListBox(ListBoxComponent),
TreeView(TreeViewComponent),
TableView(TableViewComponent),
MenuBar(MenuBarComponent),
ToolBar(ToolBarComponent),
StatusBar(StatusBarComponent),
TabView(TabViewComponent),
ScrollView(ScrollViewComponent),
Container(ContainerComponent),
ImageView(ImageViewComponent),
ProgressBar(ProgressBarComponent),
Slider(SliderComponent),
Spinner(SpinnerComponent),
}
#[derive(Debug, Clone)]
pub struct ComponentProperties {
pub id: String,
pub x: i64,
pub y: i64,
pub width: i64,
pub height: i64,
pub visible: bool,
pub enabled: bool,
pub tooltip: Option<String>,
pub style: HashMap<String, Value>,
pub event_handlers: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct ButtonComponent {
pub properties: ComponentProperties,
pub text: String,
pub icon_path: Option<String>,
pub button_type: ButtonType,
}
#[derive(Debug, Clone)]
pub enum ButtonType {
Normal,
Default,
Cancel,
Toggle,
}
#[derive(Debug, Clone)]
pub struct LabelComponent {
pub properties: ComponentProperties,
pub text: String,
pub alignment: TextAlignment,
pub word_wrap: bool,
}
#[derive(Debug, Clone)]
pub enum TextAlignment {
Left,
Center,
Right,
Justify,
}
#[derive(Debug, Clone)]
pub struct TextFieldComponent {
pub properties: ComponentProperties,
pub text: String,
pub placeholder: Option<String>,
pub max_length: Option<i64>,
pub password_mode: bool,
pub read_only: bool,
}
#[derive(Debug, Clone)]
pub struct TextAreaComponent {
pub properties: ComponentProperties,
pub text: String,
pub placeholder: Option<String>,
pub word_wrap: bool,
pub read_only: bool,
pub line_numbers: bool,
}
#[derive(Debug, Clone)]
pub struct CheckBoxComponent {
pub properties: ComponentProperties,
pub text: String,
pub checked: bool,
pub indeterminate: bool,
}
#[derive(Debug, Clone)]
pub struct RadioButtonComponent {
pub properties: ComponentProperties,
pub text: String,
pub checked: bool,
pub group: String,
}
#[derive(Debug, Clone)]
pub struct ComboBoxComponent {
pub properties: ComponentProperties,
pub items: Vec<String>,
pub selected_index: Option<i64>,
pub editable: bool,
}
#[derive(Debug, Clone)]
pub struct ListBoxComponent {
pub properties: ComponentProperties,
pub items: Vec<ListItem>,
pub selection_mode: SelectionMode,
pub selected_indices: Vec<i64>,
}
#[derive(Debug, Clone)]
pub struct ListItem {
pub text: String,
pub icon_path: Option<String>,
pub data: Option<Value>,
pub enabled: bool,
}
#[derive(Debug, Clone)]
pub enum SelectionMode {
Single,
Multiple,
None,
}
#[derive(Debug, Clone)]
pub struct TreeViewComponent {
pub properties: ComponentProperties,
pub root_nodes: Vec<TreeNode>,
pub selection_mode: SelectionMode,
pub selected_nodes: Vec<String>, }
#[derive(Debug, Clone)]
pub struct TreeNode {
pub id: String,
pub text: String,
pub icon_path: Option<String>,
pub children: Vec<TreeNode>,
pub expanded: bool,
pub data: Option<Value>,
}
#[derive(Debug, Clone)]
pub struct TableViewComponent {
pub properties: ComponentProperties,
pub columns: Vec<TableColumn>,
pub rows: Vec<TableRow>,
pub selection_mode: SelectionMode,
pub selected_rows: Vec<i64>,
pub sortable: bool,
pub filterable: bool,
}
#[derive(Debug, Clone)]
pub struct TableColumn {
pub id: String,
pub title: String,
pub width: i64,
pub resizable: bool,
pub sortable: bool,
pub data_type: String, }
#[derive(Debug, Clone)]
pub struct TableRow {
pub cells: Vec<TableCell>,
pub data: Option<Value>,
}
#[derive(Debug, Clone)]
pub struct TableCell {
pub value: Value,
pub formatted_text: String,
}
#[derive(Debug, Clone)]
pub struct MenuBarComponent {
pub properties: ComponentProperties,
pub menus: Vec<Menu>,
}
#[derive(Debug, Clone)]
pub struct Menu {
pub id: String,
pub text: String,
pub items: Vec<MenuItem>,
pub enabled: bool,
}
#[derive(Debug, Clone)]
pub struct MenuItem {
pub id: String,
pub text: String,
pub shortcut: Option<String>,
pub icon_path: Option<String>,
pub enabled: bool,
pub checked: Option<bool>,
pub separator: bool,
pub submenu: Option<Vec<MenuItem>>,
pub action: Option<String>, }
#[derive(Debug, Clone)]
pub struct ToolBarComponent {
pub properties: ComponentProperties,
pub buttons: Vec<ToolBarButton>,
pub orientation: Orientation,
}
#[derive(Debug, Clone)]
pub struct ToolBarButton {
pub id: String,
pub text: String,
pub icon_path: Option<String>,
pub tooltip: Option<String>,
pub enabled: bool,
pub action: Option<String>,
}
#[derive(Debug, Clone)]
pub enum Orientation {
Horizontal,
Vertical,
}
#[derive(Debug, Clone)]
pub struct StatusBarComponent {
pub properties: ComponentProperties,
pub sections: Vec<StatusBarSection>,
}
#[derive(Debug, Clone)]
pub struct StatusBarSection {
pub text: String,
pub width: Option<i64>,
pub alignment: TextAlignment,
}
#[derive(Debug, Clone)]
pub struct TabViewComponent {
pub properties: ComponentProperties,
pub tabs: Vec<Tab>,
pub selected_tab: Option<i64>,
}
#[derive(Debug, Clone)]
pub struct Tab {
pub id: String,
pub title: String,
pub icon_path: Option<String>,
pub closable: bool,
pub content: Vec<UIComponent>,
}
#[derive(Debug, Clone)]
pub struct ScrollViewComponent {
pub properties: ComponentProperties,
pub content: Vec<UIComponent>,
pub horizontal_scroll: bool,
pub vertical_scroll: bool,
pub scroll_position_x: i64,
pub scroll_position_y: i64,
}
#[derive(Debug, Clone)]
pub struct ContainerComponent {
pub properties: ComponentProperties,
pub layout: LayoutType,
pub children: Vec<UIComponent>,
pub padding: i64,
pub spacing: i64,
}
#[derive(Debug, Clone)]
pub enum LayoutType {
Absolute,
Flow,
Grid,
Border,
Stack,
}
#[derive(Debug, Clone)]
pub struct ImageViewComponent {
pub properties: ComponentProperties,
pub image_path: Option<String>,
pub image_data: Option<Vec<u8>>,
pub scale_mode: ImageScaleMode,
pub aspect_ratio_locked: bool,
}
#[derive(Debug, Clone)]
pub enum ImageScaleMode {
Fit,
Fill,
Stretch,
None,
}
#[derive(Debug, Clone)]
pub struct ProgressBarComponent {
pub properties: ComponentProperties,
pub minimum: i64,
pub maximum: i64,
pub value: i64,
pub indeterminate: bool,
pub show_percentage: bool,
}
#[derive(Debug, Clone)]
pub struct SliderComponent {
pub properties: ComponentProperties,
pub minimum: i64,
pub maximum: i64,
pub value: i64,
pub step: i64,
pub orientation: Orientation,
pub show_ticks: bool,
pub show_labels: bool,
}
#[derive(Debug, Clone)]
pub struct SpinnerComponent {
pub properties: ComponentProperties,
pub minimum: Option<i64>,
pub maximum: Option<i64>,
pub value: i64,
pub step: i64,
pub wrap: bool,
}
#[derive(Debug, Clone)]
pub struct UIEvent {
pub event_type: String,
pub source_component: String,
pub timestamp: String,
pub data: HashMap<String, Value>,
}
#[derive(Debug, Clone)]
pub struct EventHandler {
pub event_type: String,
pub component_id: String,
pub handler_function: String,
pub priority: i64,
}
#[derive(Debug, Clone)]
pub struct Theme {
pub name: String,
pub colors: HashMap<String, String>,
pub fonts: HashMap<String, FontDefinition>,
pub spacing: HashMap<String, i64>,
pub borders: HashMap<String, BorderDefinition>,
pub animations: HashMap<String, AnimationDefinition>,
}
#[derive(Debug, Clone)]
pub struct FontDefinition {
pub family: String,
pub size: i64,
pub weight: String,
pub style: String,
}
#[derive(Debug, Clone)]
pub struct BorderDefinition {
pub width: i64,
pub color: String,
pub radius: i64,
}
#[derive(Debug, Clone)]
pub struct AnimationDefinition {
pub duration: i64,
pub easing: String,
pub keyframes: Vec<Keyframe>,
}
#[derive(Debug, Clone)]
pub struct Keyframe {
pub time: f64,
pub properties: HashMap<String, Value>,
}
#[derive(Debug, Clone)]
pub struct FileDialogOptions {
pub title: String,
pub filters: Vec<FileFilter>,
pub multiple_selection: bool,
pub default_path: Option<String>,
}
#[derive(Debug, Clone)]
pub struct FileFilter {
pub name: String,
pub extensions: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct MessageDialogOptions {
pub title: String,
pub message: String,
pub dialog_type: MessageDialogType,
pub buttons: Vec<String>,
}
#[derive(Debug, Clone)]
pub enum MessageDialogType {
Info,
Warning,
Error,
Question,
}
#[derive(Debug, Clone)]
pub struct SystemTrayIcon {
pub icon_path: String,
pub tooltip: String,
pub menu: Vec<MenuItem>,
pub visible: bool,
}
#[derive(Debug, Clone)]
pub struct NotificationOptions {
pub title: String,
pub message: String,
pub icon_path: Option<String>,
pub sound: bool,
pub timeout: Option<i64>,
}
pub fn create_window(config: WindowConfig) -> Result<Window, String> {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("title".to_string(), Value::String(config.title.clone()));
data.insert("width".to_string(), Value::Int(config.width));
data.insert("height".to_string(), Value::Int(config.height));
data.insert(
"message".to_string(),
Value::String("Creating desktop window".to_string()),
);
data
},
Some("desktop"),
);
let window = Window {
id: format!("window_{}", generate_id()),
title: config.title,
width: config.width,
height: config.height,
x: config.x.unwrap_or(100),
y: config.y.unwrap_or(100),
visible: false,
maximized: false,
minimized: false,
resizable: config.resizable,
decorated: config.decorated,
always_on_top: config.always_on_top,
fullscreen: config.fullscreen,
components: Vec::new(),
event_handlers: HashMap::new(),
};
Ok(window)
}
pub fn show_window(window: &mut Window) -> Result<bool, String> {
window.visible = true;
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"message".to_string(),
Value::String("Showing desktop window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn hide_window(window: &mut Window) -> Result<bool, String> {
window.visible = false;
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"message".to_string(),
Value::String("Hiding desktop window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn close_window(window: &mut Window) -> Result<bool, String> {
window.visible = false;
window.components.clear();
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"message".to_string(),
Value::String("Closing desktop window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn maximize_window(window: &mut Window) -> Result<bool, String> {
window.maximized = true;
window.minimized = false;
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"message".to_string(),
Value::String("Maximizing desktop window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn minimize_window(window: &mut Window) -> Result<bool, String> {
window.minimized = true;
window.maximized = false;
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"message".to_string(),
Value::String("Minimizing desktop window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn restore_window(window: &mut Window) -> Result<bool, String> {
window.maximized = false;
window.minimized = false;
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"message".to_string(),
Value::String("Restoring desktop window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn create_button(text: String, x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("button_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let button = ButtonComponent {
properties,
text,
icon_path: None,
button_type: ButtonType::Normal,
};
UIComponent::Button(button)
}
pub fn create_label(text: String, x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("label_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let label = LabelComponent {
properties,
text,
alignment: TextAlignment::Left,
word_wrap: false,
};
UIComponent::Label(label)
}
pub fn create_text_field(
placeholder: Option<String>,
x: i64,
y: i64,
width: i64,
height: i64,
) -> UIComponent {
let properties = ComponentProperties {
id: format!("textfield_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let text_field = TextFieldComponent {
properties,
text: String::new(),
placeholder,
max_length: None,
password_mode: false,
read_only: false,
};
UIComponent::TextField(text_field)
}
pub fn create_text_area(
placeholder: Option<String>,
x: i64,
y: i64,
width: i64,
height: i64,
) -> UIComponent {
let properties = ComponentProperties {
id: format!("textarea_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let text_area = TextAreaComponent {
properties,
text: String::new(),
placeholder,
word_wrap: true,
read_only: false,
line_numbers: false,
};
UIComponent::TextArea(text_area)
}
pub fn create_checkbox(text: String, x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("checkbox_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let checkbox = CheckBoxComponent {
properties,
text,
checked: false,
indeterminate: false,
};
UIComponent::CheckBox(checkbox)
}
pub fn create_combobox(items: Vec<String>, x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("combobox_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let combobox = ComboBoxComponent {
properties,
items,
selected_index: None,
editable: false,
};
UIComponent::ComboBox(combobox)
}
pub fn create_listbox(items: Vec<String>, x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("listbox_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let list_items: Vec<ListItem> = items
.into_iter()
.map(|text| ListItem {
text,
icon_path: None,
data: None,
enabled: true,
})
.collect();
let listbox = ListBoxComponent {
properties,
items: list_items,
selection_mode: SelectionMode::Single,
selected_indices: Vec::new(),
};
UIComponent::ListBox(listbox)
}
pub fn create_table(columns: Vec<String>, x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("table_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let table_columns: Vec<TableColumn> = columns
.clone()
.into_iter()
.enumerate()
.map(|(i, title)| TableColumn {
id: format!("col_{}", i),
title,
width: width / columns.len() as i64,
resizable: true,
sortable: true,
data_type: "text".to_string(),
})
.collect();
let table = TableViewComponent {
properties,
columns: table_columns,
rows: Vec::new(),
selection_mode: SelectionMode::Single,
selected_rows: Vec::new(),
sortable: true,
filterable: true,
};
UIComponent::TableView(table)
}
pub fn create_menu_bar() -> UIComponent {
let properties = ComponentProperties {
id: format!("menubar_{}", generate_id()),
x: 0,
y: 0,
width: 800,
height: 30,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let menu_bar = MenuBarComponent {
properties,
menus: Vec::new(),
};
UIComponent::MenuBar(menu_bar)
}
pub fn create_toolbar(
orientation: Orientation,
x: i64,
y: i64,
width: i64,
height: i64,
) -> UIComponent {
let properties = ComponentProperties {
id: format!("toolbar_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let toolbar = ToolBarComponent {
properties,
buttons: Vec::new(),
orientation,
};
UIComponent::ToolBar(toolbar)
}
pub fn create_status_bar(x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("statusbar_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let status_bar = StatusBarComponent {
properties,
sections: Vec::new(),
};
UIComponent::StatusBar(status_bar)
}
pub fn create_tab_view(x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("tabview_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let tab_view = TabViewComponent {
properties,
tabs: Vec::new(),
selected_tab: None,
};
UIComponent::TabView(tab_view)
}
pub fn create_progress_bar(
minimum: i64,
maximum: i64,
x: i64,
y: i64,
width: i64,
height: i64,
) -> UIComponent {
let properties = ComponentProperties {
id: format!("progressbar_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let progress_bar = ProgressBarComponent {
properties,
minimum,
maximum,
value: minimum,
indeterminate: false,
show_percentage: true,
};
UIComponent::ProgressBar(progress_bar)
}
pub fn create_image_view(x: i64, y: i64, width: i64, height: i64) -> UIComponent {
let properties = ComponentProperties {
id: format!("imageview_{}", generate_id()),
x,
y,
width,
height,
visible: true,
enabled: true,
tooltip: None,
style: HashMap::new(),
event_handlers: HashMap::new(),
};
let image_view = ImageViewComponent {
properties,
image_path: None,
image_data: None,
scale_mode: ImageScaleMode::Fit,
aspect_ratio_locked: true,
};
UIComponent::ImageView(image_view)
}
pub fn add_component_to_window(
window: &mut Window,
component: UIComponent,
) -> Result<bool, String> {
window.components.push(component);
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"component_count".to_string(),
Value::Int(window.components.len() as i64),
);
data.insert(
"message".to_string(),
Value::String("Added component to window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn remove_component_from_window(
window: &mut Window,
component_id: &str,
) -> Result<bool, String> {
let initial_count = window.components.len();
window
.components
.retain(|comp| get_component_id(comp) != component_id);
let removed = window.components.len() < initial_count;
if removed {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert(
"component_id".to_string(),
Value::String(component_id.to_string()),
);
data.insert(
"message".to_string(),
Value::String("Removed component from window".to_string()),
);
data
},
Some("desktop"),
);
}
Ok(removed)
}
pub fn get_component_id(component: &UIComponent) -> String {
match component {
UIComponent::Button(btn) => btn.properties.id.clone(),
UIComponent::Label(lbl) => lbl.properties.id.clone(),
UIComponent::TextField(tf) => tf.properties.id.clone(),
UIComponent::TextArea(ta) => ta.properties.id.clone(),
UIComponent::CheckBox(cb) => cb.properties.id.clone(),
UIComponent::RadioButton(rb) => rb.properties.id.clone(),
UIComponent::ComboBox(cb) => cb.properties.id.clone(),
UIComponent::ListBox(lb) => lb.properties.id.clone(),
UIComponent::TreeView(tv) => tv.properties.id.clone(),
UIComponent::TableView(tv) => tv.properties.id.clone(),
UIComponent::MenuBar(mb) => mb.properties.id.clone(),
UIComponent::ToolBar(tb) => tb.properties.id.clone(),
UIComponent::StatusBar(sb) => sb.properties.id.clone(),
UIComponent::TabView(tv) => tv.properties.id.clone(),
UIComponent::ScrollView(sv) => sv.properties.id.clone(),
UIComponent::Container(cnt) => cnt.properties.id.clone(),
UIComponent::ImageView(iv) => iv.properties.id.clone(),
UIComponent::ProgressBar(pb) => pb.properties.id.clone(),
UIComponent::Slider(sl) => sl.properties.id.clone(),
UIComponent::Spinner(sp) => sp.properties.id.clone(),
}
}
pub fn add_event_handler(
window: &mut Window,
component_id: String,
event_type: String,
handler_function: String,
) -> Result<bool, String> {
window
.event_handlers
.insert(format!("{}_{}", component_id, event_type), handler_function);
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert("component_id".to_string(), Value::String(component_id));
data.insert("event_type".to_string(), Value::String(event_type));
data.insert(
"message".to_string(),
Value::String("Added event handler to window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn remove_event_handler(
window: &mut Window,
component_id: String,
event_type: String,
) -> Result<bool, String> {
let key = format!("{}_{}", component_id, event_type);
let removed = window.event_handlers.remove(&key).is_some();
if removed {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert("component_id".to_string(), Value::String(component_id));
data.insert("event_type".to_string(), Value::String(event_type));
data.insert(
"message".to_string(),
Value::String("Removed event handler from window".to_string()),
);
data
},
Some("desktop"),
);
}
Ok(removed)
}
pub fn trigger_event(
window: &Window,
component_id: String,
event_type: String,
_event_data: HashMap<String, Value>,
) -> Result<Vec<String>, String> {
let mut triggered_handlers = Vec::new();
let specific_key = format!("{}_{}", component_id, event_type);
if let Some(handler) = window.event_handlers.get(&specific_key) {
triggered_handlers.push(handler.clone());
}
let general_key = format!("{}_{}", "*", event_type);
if let Some(handler) = window.event_handlers.get(&general_key) {
triggered_handlers.push(handler.clone());
}
let wildcard_key = format!("{}_{}", "*", "*");
if let Some(handler) = window.event_handlers.get(&wildcard_key) {
triggered_handlers.push(handler.clone());
}
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert("component_id".to_string(), Value::String(component_id));
data.insert("event_type".to_string(), Value::String(event_type));
data.insert(
"handlers_triggered".to_string(),
Value::Int(triggered_handlers.len() as i64),
);
data.insert(
"message".to_string(),
Value::String("Event triggered".to_string()),
);
data
},
Some("desktop"),
);
Ok(triggered_handlers)
}
pub fn show_file_dialog(options: FileDialogOptions) -> Result<Vec<String>, String> {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("title".to_string(), Value::String(options.title.clone()));
data.insert(
"multiple_selection".to_string(),
Value::Bool(options.multiple_selection),
);
data.insert(
"message".to_string(),
Value::String("Showing file dialog".to_string()),
);
data
},
Some("desktop"),
);
if options.multiple_selection {
Ok(vec![
"/home/user/document1.txt".to_string(),
"/home/user/document2.pdf".to_string(),
])
} else {
Ok(vec!["/home/user/document1.txt".to_string()])
}
}
pub fn show_save_dialog(options: FileDialogOptions) -> Result<String, String> {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("title".to_string(), Value::String(options.title.clone()));
data.insert(
"message".to_string(),
Value::String("Showing save dialog".to_string()),
);
data
},
Some("desktop"),
);
Ok("/home/user/new_document.txt".to_string())
}
pub fn show_message_dialog(options: MessageDialogOptions) -> Result<String, String> {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("title".to_string(), Value::String(options.title.clone()));
data.insert(
"message".to_string(),
Value::String(options.message.clone()),
);
data.insert(
"message".to_string(),
Value::String("Showing message dialog".to_string()),
);
data
},
Some("desktop"),
);
Ok(options.buttons.get(0).unwrap_or(&"OK".to_string()).clone())
}
pub fn create_system_tray_icon(icon_path: String, tooltip: String) -> SystemTrayIcon {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("icon_path".to_string(), Value::String(icon_path.clone()));
data.insert("tooltip".to_string(), Value::String(tooltip.clone()));
data.insert(
"message".to_string(),
Value::String("Creating system tray icon".to_string()),
);
data
},
Some("desktop"),
);
SystemTrayIcon {
icon_path,
tooltip,
menu: Vec::new(),
visible: true,
}
}
pub fn show_notification(options: NotificationOptions) -> Result<bool, String> {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("title".to_string(), Value::String(options.title.clone()));
data.insert(
"message".to_string(),
Value::String(options.message.clone()),
);
data.insert("sound".to_string(), Value::Bool(options.sound));
data.insert(
"message".to_string(),
Value::String("Showing desktop notification".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn create_theme(name: String) -> Theme {
let mut colors = HashMap::new();
colors.insert("primary".to_string(), "#007acc".to_string());
colors.insert("secondary".to_string(), "#6c757d".to_string());
colors.insert("success".to_string(), "#28a745".to_string());
colors.insert("danger".to_string(), "#dc3545".to_string());
colors.insert("warning".to_string(), "#ffc107".to_string());
colors.insert("info".to_string(), "#17a2b8".to_string());
colors.insert("background".to_string(), "#ffffff".to_string());
colors.insert("foreground".to_string(), "#212529".to_string());
let mut fonts = HashMap::new();
fonts.insert(
"default".to_string(),
FontDefinition {
family: "Arial".to_string(),
size: 12,
weight: "normal".to_string(),
style: "normal".to_string(),
},
);
let mut spacing = HashMap::new();
spacing.insert("small".to_string(), 4);
spacing.insert("medium".to_string(), 8);
spacing.insert("large".to_string(), 16);
Theme {
name,
colors,
fonts,
spacing,
borders: HashMap::new(),
animations: HashMap::new(),
}
}
pub fn apply_theme_to_window(window: &mut Window, theme: Theme) -> Result<bool, String> {
for component in &mut window.components {
apply_theme_to_component(component, &theme);
}
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert("window_id".to_string(), Value::String(window.id.clone()));
data.insert("theme_name".to_string(), Value::String(theme.name.clone()));
data.insert(
"message".to_string(),
Value::String("Applied theme to window".to_string()),
);
data
},
Some("desktop"),
);
Ok(true)
}
pub fn apply_theme_to_component(component: &mut UIComponent, theme: &Theme) {
match component {
UIComponent::Button(btn) => {
btn.properties.style.insert(
"background-color".to_string(),
Value::String(
theme
.colors
.get("primary")
.unwrap_or(&"#007acc".to_string())
.clone(),
),
);
btn.properties.style.insert(
"color".to_string(),
Value::String(
theme
.colors
.get("background")
.unwrap_or(&"#ffffff".to_string())
.clone(),
),
);
}
UIComponent::Label(lbl) => {
lbl.properties.style.insert(
"color".to_string(),
Value::String(
theme
.colors
.get("foreground")
.unwrap_or(&"#212529".to_string())
.clone(),
),
);
}
_ => {
}
}
}
pub fn generate_id() -> String {
format!("{}", rand::random::<u64>())
}
pub fn run_event_loop() -> Result<(), String> {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert(
"message".to_string(),
Value::String("Starting desktop event loop".to_string()),
);
data
},
Some("desktop"),
);
Ok(())
}
pub fn exit_application() -> Result<(), String> {
crate::stdlib::log::info(
"desktop",
{
let mut data = std::collections::HashMap::new();
data.insert(
"message".to_string(),
Value::String("Exiting desktop application".to_string()),
);
data
},
Some("desktop"),
);
Ok(())
}