embedded_charts/dashboard/
layout.rs1use super::{GridLayout, GridPosition, MAX_DASHBOARD_CHARTS};
4use crate::error::ChartResult;
5use embedded_graphics::primitives::Rectangle;
6use heapless::Vec;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum DashboardLayout {
11 Grid(GridLayout),
13 Flexible,
15}
16
17impl DashboardLayout {
18 pub fn calculate_viewports(
20 &self,
21 total_viewport: Rectangle,
22 panel_count: usize,
23 spacing: u32,
24 ) -> ChartResult<Vec<Rectangle, MAX_DASHBOARD_CHARTS>> {
25 match self {
26 DashboardLayout::Grid(grid) => {
27 let mut positions: Vec<GridPosition, MAX_DASHBOARD_CHARTS> = Vec::new();
29 let mut index = 0;
30
31 'outer: for row in 0..grid.rows {
32 for col in 0..grid.cols {
33 if index >= panel_count {
34 break 'outer;
35 }
36 positions
37 .push(GridPosition::new(row, col))
38 .map_err(|_| crate::error::ChartError::MemoryFull)?;
39 index += 1;
40 }
41 }
42
43 grid.calculate_viewports(total_viewport, &positions, spacing)
44 }
45 DashboardLayout::Flexible => {
46 Err(crate::error::ChartError::ConfigurationError)
48 }
49 }
50 }
51}
52
53pub enum LayoutPreset {
55 Single,
57 SideBySide,
59 Stacked,
61 Quadrants,
63 ThreeColumns,
65 ThreeRows,
67 Grid3x3,
69 Grid4x4,
71}
72
73impl LayoutPreset {
74 pub fn to_layout(self) -> DashboardLayout {
76 match self {
77 LayoutPreset::Single => DashboardLayout::Grid(GridLayout::new(1, 1)),
78 LayoutPreset::SideBySide => DashboardLayout::Grid(GridLayout::new(1, 2)),
79 LayoutPreset::Stacked => DashboardLayout::Grid(GridLayout::new(2, 1)),
80 LayoutPreset::Quadrants => DashboardLayout::Grid(GridLayout::new(2, 2)),
81 LayoutPreset::ThreeColumns => DashboardLayout::Grid(GridLayout::new(1, 3)),
82 LayoutPreset::ThreeRows => DashboardLayout::Grid(GridLayout::new(3, 1)),
83 LayoutPreset::Grid3x3 => DashboardLayout::Grid(GridLayout::new(3, 3)),
84 LayoutPreset::Grid4x4 => DashboardLayout::Grid(GridLayout::new(4, 4)),
85 }
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use embedded_graphics::prelude::*;
93
94 #[test]
95 fn test_layout_preset_conversion() {
96 let layout = LayoutPreset::Quadrants.to_layout();
97 match layout {
98 DashboardLayout::Grid(grid) => {
99 assert_eq!(grid.rows, 2);
100 assert_eq!(grid.cols, 2);
101 }
102 _ => panic!("Expected grid layout"),
103 }
104 }
105
106 #[test]
107 fn test_dashboard_layout_calculate_viewports() {
108 let layout = DashboardLayout::Grid(GridLayout::new(2, 2));
109 let viewport = Rectangle::new(Point::new(0, 0), Size::new(200, 200));
110
111 let viewports = layout.calculate_viewports(viewport, 3, 10).unwrap();
112 assert_eq!(viewports.len(), 3);
113
114 assert_eq!(viewports[0].top_left, Point::new(0, 0));
116 assert_eq!(viewports[0].size, Size::new(95, 95));
117
118 assert_eq!(viewports[1].top_left, Point::new(105, 0));
120 assert_eq!(viewports[1].size, Size::new(95, 95));
121
122 assert_eq!(viewports[2].top_left, Point::new(0, 105));
124 assert_eq!(viewports[2].size, Size::new(95, 95));
125 }
126}