use crate::compat::HashMap;
#[cfg(not(feature = "mini"))]
use serde::{Deserialize, Serialize};
use crate::core::ObjectId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(not(feature = "mini"), derive(Serialize, Deserialize))]
pub enum WidgetKind {
Window,
Button,
Label,
CheckBox,
RadioButton,
LineEdit,
TextEdit,
ComboBox,
ListBox,
Slider,
ScrollBar,
ProgressBar,
Panel,
TabWidget,
GridWidget,
Frame,
Dialog,
SpinBox,
ListView,
ScrollArea,
MessageBox,
FileDialog,
ColorDialog,
FontDialog,
}
#[derive(Debug, Clone)]
#[cfg_attr(not(feature = "mini"), derive(Serialize, Deserialize))]
pub struct WidgetEntry {
pub id: ObjectId,
pub kind: WidgetKind,
pub parent: Option<ObjectId>,
pub label: String,
}
#[derive(Debug, Clone)]
#[cfg_attr(not(feature = "mini"), derive(Serialize, Deserialize))]
pub struct WidgetRegistry {
entries: HashMap<ObjectId, WidgetEntry>,
by_kind: HashMap<WidgetKind, Vec<ObjectId>>,
}
impl WidgetRegistry {
pub fn new() -> Self {
Self { entries: HashMap::new(), by_kind: HashMap::new() }
}
pub fn register(&mut self, entry: WidgetEntry) {
let kind = entry.kind;
let id = entry.id;
if let Some(old) = self.entries.get(&id) {
if let Some(list) = self.by_kind.get_mut(&old.kind) {
list.retain(|&x| x != id);
}
}
self.by_kind.entry(kind).or_default().push(id);
self.entries.insert(id, entry);
}
pub fn unregister(&mut self, id: ObjectId) {
if let Some(entry) = self.entries.remove(&id) {
if let Some(list) = self.by_kind.get_mut(&entry.kind) {
list.retain(|&x| x != id);
}
}
}
pub fn get(&self, id: ObjectId) -> Option<&WidgetEntry> {
self.entries.get(&id)
}
pub fn find_by_kind(&self, kind: WidgetKind) -> &[ObjectId] {
self.by_kind.get(&kind).map_or(&[], |v| v.as_slice())
}
pub fn children_of(&self, parent_id: ObjectId) -> Vec<&WidgetEntry> {
self.entries.values().filter(|entry| entry.parent == Some(parent_id)).collect()
}
#[cfg(not(feature = "mini"))]
pub fn save(&self, path: &str) -> Result<(), String> {
let json = serde_json::to_string_pretty(self)
.map_err(|e| format!("serialization error: {}", e))?;
std::fs::write(path, &json).map_err(|e| format!("write error: {}", e))
}
#[cfg(not(feature = "mini"))]
pub fn load(&mut self, path: &str) -> Result<(), String> {
let json = std::fs::read_to_string(path).map_err(|e| format!("read error: {}", e))?;
let loaded: WidgetRegistry =
serde_json::from_str(&json).map_err(|e| format!("parse error: {}", e))?;
*self = loaded;
Ok(())
}
pub fn all_ids(&self) -> impl Iterator<Item = ObjectId> + '_ {
self.entries.keys().copied()
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn clear(&mut self) {
self.entries.clear();
self.by_kind.clear();
}
}
impl Default for WidgetRegistry {
fn default() -> Self {
Self::new()
}
}