1#![allow(clippy::too_many_arguments)]
7#![allow(dead_code)]
8
9use super::core::{Position, Size};
10use crate::error::{MetricsError, Result};
11use serde::{Deserialize, Serialize};
12use serde_json::Value;
13use std::collections::HashMap;
14use std::time::{Duration, Instant};
15
16pub trait InteractiveWidget: std::fmt::Debug + Send + Sync {
18 fn id(&self) -> &str;
20
21 fn widget_type(&self) -> WidgetType;
23
24 fn update_data(&mut self, data: Value) -> Result<()>;
26
27 fn handle_interaction(&mut self, event: WidgetEvent) -> Result<Option<WidgetEventResponse>>;
29
30 fn render(&self, context: &RenderContext) -> Result<WidgetRender>;
32
33 fn config(&self) -> &WidgetConfig;
35
36 fn update_config(&mut self, config: WidgetConfig) -> Result<()>;
38
39 fn state(&self) -> Value;
41
42 fn restore_state(&mut self, state: Value) -> Result<()>;
44
45 fn validate_data(&self, data: &Value) -> Result<()>;
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
51pub enum WidgetType {
52 Chart(ChartType),
54 Table,
56 Text,
58 Input(InputType),
60 Container,
62 Custom(String),
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
68pub enum ChartType {
69 Line,
71 Bar,
73 Scatter,
75 Heatmap,
77 Pie,
79 Area,
81 Histogram,
83 BoxPlot,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub enum InputType {
90 Slider,
92 Dropdown,
94 TextInput,
96 Checkbox,
98 RadioButton,
100 DatePicker,
102 FileUpload,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct WidgetConfig {
109 pub id: String,
111 pub title: String,
113 pub position: Position,
115 pub size: Size,
117 pub style: StyleConfig,
119 pub data_binding: DataBindingConfig,
121 pub interactions_enabled: bool,
123 pub animation_enabled: bool,
125 pub visible: bool,
127 pub z_index: i32,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct StyleConfig {
134 pub background_color: String,
136 pub border: BorderConfig,
138 pub shadow: ShadowConfig,
140 pub font: FontConfig,
142 pub css_classes: Vec<String>,
144 pub css_properties: HashMap<String, String>,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct BorderConfig {
151 pub width: u32,
153 pub color: String,
155 pub style: BorderStyle,
157 pub radius: u32,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
163pub enum BorderStyle {
164 Solid,
166 Dashed,
168 Dotted,
170 None,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct ShadowConfig {
177 pub enabled: bool,
179 pub offset_x: i32,
181 pub offset_y: i32,
183 pub blur_radius: u32,
185 pub color: String,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize)]
191pub struct FontConfig {
192 pub family: String,
194 pub size: u32,
196 pub weight: FontWeight,
198 pub style: FontStyle,
200 pub color: String,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub enum FontWeight {
207 Normal,
209 Bold,
211 Light,
213 Custom(u32),
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize)]
219pub enum FontStyle {
220 Normal,
222 Italic,
224 Oblique,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct DataBindingConfig {
231 pub source_id: String,
233 pub field_mappings: HashMap<String, String>,
235 pub update_frequency: UpdateFrequency,
237 pub transformations: Vec<DataTransformation>,
239 pub filters: HashMap<String, Value>,
241 pub aggregation: Option<AggregationMethod>,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
247pub enum UpdateFrequency {
248 RealTime,
250 Interval(Duration),
252 Manual,
254 OnDemand,
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize)]
260pub enum DataTransformation {
261 Filter(String),
263 Sort(String, bool), Group(String),
267 Aggregate(String, AggregationMethod),
269 Custom(String),
271}
272
273#[derive(Debug, Clone, Serialize, Deserialize)]
275pub enum AggregationMethod {
276 Sum,
278 Average,
280 Count,
282 Min,
284 Max,
286 StdDev,
288 Custom(String),
290}
291
292#[derive(Debug, Clone)]
294pub struct RenderContext {
295 pub canvas_id: String,
297 pub device: DeviceCapabilities,
299 pub options: RenderOptions,
301 pub timestamp: Instant,
303 pub theme: super::core::ThemeConfig,
305}
306
307#[derive(Debug, Clone)]
309pub struct DeviceCapabilities {
310 pub screen_width: u32,
312 pub screen_height: u32,
314 pub pixel_ratio: f64,
316 pub webgl_supported: bool,
318 pub touch_supported: bool,
320 pub max_texture_size: u32,
322}
323
324#[derive(Debug, Clone)]
326pub struct RenderOptions {
327 pub quality: RenderQuality,
329 pub antialiasing: bool,
331 pub transparency: bool,
333 pub preserve_buffer: bool,
335 pub power_preference: String,
337}
338
339#[derive(Debug, Clone, Serialize, Deserialize)]
341pub enum RenderQuality {
342 Low,
344 Medium,
346 High,
348 Ultra,
350}
351
352#[derive(Debug, Clone)]
354pub struct WidgetRender {
355 pub content: RenderContent,
357 pub metadata: RenderMetadata,
359 pub resources: Vec<String>,
361}
362
363#[derive(Debug, Clone)]
365pub enum RenderContent {
366 Html(String),
368 Svg(String),
370 Canvas(Vec<CanvasCommand>),
372 WebGL(ShaderProgram),
374}
375
376#[derive(Debug, Clone)]
378pub enum CanvasCommand {
379 DrawLine {
381 from: Position,
382 to: Position,
383 color: String,
384 width: f64,
385 },
386 DrawRect {
388 position: Position,
389 size: Size,
390 color: String,
391 },
392 DrawCircle {
394 center: Position,
395 radius: f64,
396 color: String,
397 },
398 DrawText {
400 position: Position,
401 text: String,
402 font: FontConfig,
403 },
404 Custom(String, HashMap<String, Value>),
406}
407
408#[derive(Debug, Clone)]
410pub struct ShaderProgram {
411 pub vertex_shader: String,
413 pub fragment_shader: String,
415 pub uniforms: HashMap<String, UniformValue>,
417 pub attributes: HashMap<String, AttributeBinding>,
419}
420
421#[derive(Debug, Clone)]
423pub enum UniformValue {
424 Float(f32),
426 Vec2([f32; 2]),
428 Vec3([f32; 3]),
430 Vec4([f32; 4]),
432 Mat4([[f32; 4]; 4]),
434 Texture(String),
436}
437
438#[derive(Debug, Clone)]
440pub struct AttributeBinding {
441 pub buffer: String,
443 pub components: u32,
445 pub data_type: AttributeType,
447 pub normalized: bool,
449}
450
451#[derive(Debug, Clone)]
453pub enum AttributeType {
454 Float,
456 UnsignedByte,
458 Short,
460 UnsignedShort,
462}
463
464#[derive(Debug, Clone)]
466pub struct RenderMetadata {
467 pub render_time: Duration,
469 pub frame_rate: f64,
471 pub memory_usage: u64,
473 pub error_count: u32,
475}
476
477#[derive(Debug, Clone)]
479pub struct WidgetEvent {
480 pub id: String,
482 pub event_type: EventType,
484 pub timestamp: Instant,
486 pub data: HashMap<String, Value>,
488 pub source_widget: String,
490 pub target: Option<String>,
492}
493
494#[derive(Debug, Clone)]
496pub enum EventType {
497 Click { position: Position, button: u32 },
499 DoubleClick { position: Position },
501 MouseMove { position: Position, delta: Position },
503 MouseEnter { position: Position },
505 MouseLeave { position: Position },
507 KeyPress { key: String, modifiers: Vec<String> },
509 Touch { touches: Vec<TouchPoint> },
511 Resize { new_size: Size },
513 Focus,
515 Blur,
517 Custom { name: String, data: Value },
519}
520
521#[derive(Debug, Clone)]
523pub struct TouchPoint {
524 pub id: u32,
526 pub position: Position,
528 pub pressure: f64,
530 pub radius: f64,
532}
533
534#[derive(Debug, Clone)]
536pub struct WidgetEventResponse {
537 pub id: String,
539 pub actions: Vec<ResponseAction>,
541 pub data_updates: HashMap<String, Value>,
543 pub state_changes: HashMap<String, Value>,
545}
546
547#[derive(Debug, Clone)]
549pub enum ResponseAction {
550 UpdateData { widget_id: String, data: Value },
552 TriggerEvent { event: WidgetEvent },
554 Navigate { url: String },
556 ShowNotification {
558 message: String,
559 level: NotificationLevel,
560 },
561 Custom {
563 action: String,
564 params: HashMap<String, Value>,
565 },
566}
567
568#[derive(Debug, Clone)]
570pub enum NotificationLevel {
571 Info,
573 Success,
575 Warning,
577 Error,
579}
580
581impl Default for WidgetConfig {
582 fn default() -> Self {
583 Self {
584 id: "widget".to_string(),
585 title: "Widget".to_string(),
586 position: Position::default(),
587 size: Size::default(),
588 style: StyleConfig::default(),
589 data_binding: DataBindingConfig::default(),
590 interactions_enabled: true,
591 animation_enabled: true,
592 visible: true,
593 z_index: 0,
594 }
595 }
596}
597
598impl Default for StyleConfig {
599 fn default() -> Self {
600 Self {
601 background_color: "#ffffff".to_string(),
602 border: BorderConfig::default(),
603 shadow: ShadowConfig::default(),
604 font: FontConfig::default(),
605 css_classes: Vec::new(),
606 css_properties: HashMap::new(),
607 }
608 }
609}
610
611impl Default for BorderConfig {
612 fn default() -> Self {
613 Self {
614 width: 1,
615 color: "#cccccc".to_string(),
616 style: BorderStyle::Solid,
617 radius: 4,
618 }
619 }
620}
621
622impl Default for ShadowConfig {
623 fn default() -> Self {
624 Self {
625 enabled: false,
626 offset_x: 2,
627 offset_y: 2,
628 blur_radius: 4,
629 color: "rgba(0,0,0,0.1)".to_string(),
630 }
631 }
632}
633
634impl Default for FontConfig {
635 fn default() -> Self {
636 Self {
637 family: "Arial, sans-serif".to_string(),
638 size: 14,
639 weight: FontWeight::Normal,
640 style: FontStyle::Normal,
641 color: "#333333".to_string(),
642 }
643 }
644}
645
646impl Default for DataBindingConfig {
647 fn default() -> Self {
648 Self {
649 source_id: "default".to_string(),
650 field_mappings: HashMap::new(),
651 update_frequency: UpdateFrequency::RealTime,
652 transformations: Vec::new(),
653 filters: HashMap::new(),
654 aggregation: None,
655 }
656 }
657}