diff --git a/assets/indic-falling.bmp b/assets/indic-falling.bmp
index c56a035..859d6ad 100644
Binary files a/assets/indic-falling.bmp and b/assets/indic-falling.bmp differ
diff --git a/assets/indic-falling.svg b/assets/indic-falling.svg
index ef69cb6..8d10fc3 100644
--- a/assets/indic-falling.svg
+++ b/assets/indic-falling.svg
@@ -28,8 +28,8 @@
inkscape:document-units="mm"
inkscape:export-bgcolor="#080808ff"
inkscape:zoom="32"
- inkscape:cx="3.46875"
- inkscape:cy="9.140625"
+ inkscape:cx="3.640625"
+ inkscape:cy="8.328125"
inkscape:window-width="1916"
inkscape:window-height="1032"
inkscape:window-x="0"
@@ -50,18 +50,9 @@
height="197.24825"
x="-44.312061"
y="-1.4580333" />
-
+
diff --git a/assets/indic-rising.bmp b/assets/indic-rising.bmp
index 0fb32f0..bc67411 100644
Binary files a/assets/indic-rising.bmp and b/assets/indic-rising.bmp differ
diff --git a/assets/indic-rising.svg b/assets/indic-rising.svg
index 2507ddb..6a6818a 100644
--- a/assets/indic-rising.svg
+++ b/assets/indic-rising.svg
@@ -28,8 +28,8 @@
inkscape:document-units="mm"
inkscape:export-bgcolor="#080808ff"
inkscape:zoom="32"
- inkscape:cx="3.46875"
- inkscape:cy="9.140625"
+ inkscape:cx="3.640625"
+ inkscape:cy="8.328125"
inkscape:window-width="1916"
inkscape:window-height="1032"
inkscape:window-x="0"
@@ -50,18 +50,9 @@
height="197.24825"
x="-44.312061"
y="-1.4580333" />
-
+
diff --git a/assets/indic-steady.bmp b/assets/indic-steady.bmp
index af79bb9..9f35aee 100644
Binary files a/assets/indic-steady.bmp and b/assets/indic-steady.bmp differ
diff --git a/assets/indic-steady.svg b/assets/indic-steady.svg
index a5e3a98..4ac30f3 100644
--- a/assets/indic-steady.svg
+++ b/assets/indic-steady.svg
@@ -28,8 +28,8 @@
inkscape:document-units="mm"
inkscape:export-bgcolor="#080808ff"
inkscape:zoom="32"
- inkscape:cx="3.46875"
- inkscape:cy="9.140625"
+ inkscape:cx="3.640625"
+ inkscape:cy="8.328125"
inkscape:window-width="1916"
inkscape:window-height="1032"
inkscape:window-x="0"
@@ -50,18 +50,9 @@
height="197.24825"
x="-44.312061"
y="-1.4580333" />
-
+
diff --git a/src/colors.rs b/src/colors.rs
new file mode 100644
index 0000000..03d9bc8
--- /dev/null
+++ b/src/colors.rs
@@ -0,0 +1,12 @@
+use embedded_graphics::pixelcolor::Rgb565;
+use embedded_graphics::prelude::RgbColor;
+use embedded_graphics::prelude::WebColors;
+
+pub const BACKGROUND_COLOR: Rgb565 = Rgb565::BLACK;
+pub const FRAME_BACKGROUD_COLOR: Rgb565 = Rgb565::new(1, 2, 1);
+pub const FRAME_STROKE_COLOR: Rgb565 = Rgb565::new(4, 9, 4);
+
+pub const MAIN_TEXT_COLOR: Rgb565 = Rgb565::WHITE;
+pub const SUB_TEXT_COLOR: Rgb565 = Rgb565::CSS_DARK_GRAY;
+
+pub const FRAME_STROKE: u32 = 3;
diff --git a/src/images.rs b/src/images.rs
index a8b4a9f..e698aa3 100644
--- a/src/images.rs
+++ b/src/images.rs
@@ -1,4 +1,5 @@
-use std::{cell::UnsafeCell, mem::MaybeUninit};
+use std::cell::UnsafeCell;
+use std::mem::MaybeUninit;
use embedded_graphics::pixelcolor::Rgb565;
use tinybmp::Bmp;
@@ -15,6 +16,8 @@ thread_local! {
pub static TENDENCY_FALLING: UnsafeCell>> = const { UnsafeCell::new(MaybeUninit::zeroed()) };
}
+pub type StaticImage = std::thread::LocalKey>>>;
+
macro_rules! load_image {
($stat:expr, $path:expr) => {
$stat
@@ -26,6 +29,8 @@ macro_rules! load_image {
macro_rules! get_image {
($image:expr) => {
unsafe {
+ use std::mem::MaybeUninit;
+ use tinybmp::Bmp;
&*std::mem::transmute::<*mut MaybeUninit>, *mut Bmp>(
$image.with(|g| g.get()),
)
diff --git a/src/main.rs b/src/main.rs
index 0672883..6833498 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,27 +1,19 @@
//#![feature(unsafe_cell_access)]
+mod colors;
mod images;
+mod views;
-use core::fmt::Write;
use std::cell::UnsafeCell;
use std::mem::MaybeUninit;
-use buoyant::primitives::Point;
-use buoyant::render::StrokedShape;
use buoyant::view::prelude::*;
use embedded_graphics::pixelcolor::Rgb565;
-use embedded_graphics::pixelcolor::Rgb888;
use embedded_graphics::prelude::*;
use embedded_graphics_simulator::OutputSettings;
use embedded_graphics_simulator::SimulatorDisplay;
use embedded_graphics_simulator::Window;
-use embedded_sprites::include_image;
-use embedded_sprites::sprite::Sprite;
use heapless::format;
-use profont::PROFONT_12_POINT;
-use profont::PROFONT_14_POINT;
-use profont::PROFONT_18_POINT;
-use profont::PROFONT_24_POINT;
use tinybmp::Bmp;
const BACKGROUND_COLOR: Rgb565 = Rgb565::BLACK;
@@ -34,7 +26,12 @@ fn main() {
let mut display: SimulatorDisplay = SimulatorDisplay::new(Size::new(320, 240));
display.clear(BACKGROUND_COLOR);
- hello_view()
+ // views::menu::menu_view()
+ // .as_drawable(display.size(), DEFAULT_COLOR)
+ // .draw(&mut display)
+ // .unwrap();
+
+ views::detail::detailed_view(MenuIndicatorType::Temperature(38.3), Tendency::Steady)
.as_drawable(display.size(), DEFAULT_COLOR)
.draw(&mut display)
.unwrap();
@@ -42,25 +39,6 @@ fn main() {
window.show_static(&display);
}
-fn hello_view() -> impl View {
- VStack::new((
- HStack::new((
- main_menu_indicator(MenuIndicatorType::Temperature(31.5), Tendency::Falling),
- main_menu_indicator(MenuIndicatorType::Humidity(36.2), Tendency::Steady),
- ))
- .with_spacing(5),
- HStack::new((
- main_menu_indicator(MenuIndicatorType::Co2(1329), Tendency::Rising),
- main_menu_indicator(MenuIndicatorType::Voc(29), Tendency::Falling),
- ))
- .with_spacing(5),
- ))
- .with_spacing(5)
-}
-
-const FRAME_STROKE: u32 = 2;
-const FRAME_COLOR: Rgb565 = Rgb565::new(5, 9, 5);
-
pub enum MenuIndicatorType {
Temperature(f32),
Humidity(f32),
@@ -99,55 +77,6 @@ impl MenuIndicatorType {
}
}
-fn main_menu_indicator(indicator_type: MenuIndicatorType, tendency: Tendency) -> impl View {
- Rectangle
- .corner_radius(10)
- .stroked(FRAME_STROKE)
- .foreground_color(FRAME_COLOR)
- .background(Alignment::Center, || {
- ZStack::new((
- Rectangle
- .corner_radius(15)
- .foreground_color(Rgb565::new(1, 2, 1)),
- VStack::new((
- HStack::new((
- Spacer::default(),
- ZStack::new((
- Rectangle
- .corner_radius(10)
- //.stroked_offset(5, StrokeOffset::Outer)
- .foreground_color(Rgb565::new(4, 9, 4)),
- buoyant::view::Image::new(get_image!(
- indicator_type.get_corresponding_icon()
- )),
- ))
- .flex_frame()
- .with_max_size(53, 53)
- .with_min_size(53, 53),
- Spacer::default(),
- )),
- HStack::new((
- Spacer::default(),
- tendency_indicator(tendency),
- Text::new(indicator_type.get_value_str(), &PROFONT_24_POINT),
- Text::new(
- indicator_type.get_corresponding_unit_string(),
- &PROFONT_18_POINT,
- )
- .foreground_color(Rgb565::CSS_DARK_GRAY)
- .flex_frame()
- .with_infinite_max_height()
- .with_vertical_alignment(VerticalAlignment::Bottom)
- .with_max_height(25),
- Spacer::default(),
- )),
- ))
- .with_alignment(HorizontalAlignment::Center)
- .flex_frame(),
- ))
- })
-}
-
pub enum Tendency {
Rising,
Steady,
diff --git a/src/views.rs b/src/views.rs
new file mode 100644
index 0000000..38dde75
--- /dev/null
+++ b/src/views.rs
@@ -0,0 +1,3 @@
+pub mod detail;
+pub mod icon;
+pub mod menu;
diff --git a/src/views/detail.rs b/src/views/detail.rs
new file mode 100644
index 0000000..0bcf0ff
--- /dev/null
+++ b/src/views/detail.rs
@@ -0,0 +1,52 @@
+use buoyant::layout::HorizontalAlignment;
+use buoyant::layout::VerticalAlignment;
+use buoyant::view::HStack;
+use buoyant::view::Spacer;
+use buoyant::view::Text;
+use buoyant::view::VStack;
+use buoyant::view::View;
+use buoyant::view::ViewExt;
+use embedded_graphics::pixelcolor::Rgb565;
+use profont::PROFONT_18_POINT;
+use profont::PROFONT_24_POINT;
+
+use crate::MenuIndicatorType;
+use crate::Tendency;
+use crate::colors::FRAME_STROKE_COLOR;
+use crate::colors::MAIN_TEXT_COLOR;
+use crate::colors::SUB_TEXT_COLOR;
+use crate::tendency_indicator;
+use crate::views::icon::icon_box_view;
+
+pub fn detailed_view(indicator: MenuIndicatorType, tendency: Tendency) -> impl View {
+ VStack::new((
+ // Header
+ HStack::new((
+ icon_box_view(FRAME_STROKE_COLOR, indicator.get_corresponding_icon()),
+ Spacer::default().flex_frame().with_max_width(10),
+ tendency_indicator(tendency),
+ Text::new(indicator.get_value_str(), &PROFONT_24_POINT)
+ .foreground_color(MAIN_TEXT_COLOR),
+ Text::new(indicator.get_corresponding_unit_string(), &PROFONT_18_POINT)
+ .foreground_color(SUB_TEXT_COLOR)
+ .flex_frame()
+ .with_infinite_max_height()
+ .with_vertical_alignment(VerticalAlignment::Bottom)
+ .with_max_height(25),
+ Spacer::default(),
+ Text::new("Temperature", &PROFONT_18_POINT)
+ .foreground_color(SUB_TEXT_COLOR)
+ .flex_frame()
+ .with_infinite_max_height()
+ .with_vertical_alignment(VerticalAlignment::Bottom)
+ .with_max_height(25),
+ Spacer::default().flex_frame().with_max_width(10),
+ )),
+ // Window
+ Spacer::default()
+ .flex_frame()
+ .with_infinite_max_width()
+ .with_infinite_max_height(),
+ ))
+ .with_alignment(HorizontalAlignment::Leading)
+}
diff --git a/src/views/icon.rs b/src/views/icon.rs
new file mode 100644
index 0000000..8d0f5c1
--- /dev/null
+++ b/src/views/icon.rs
@@ -0,0 +1,18 @@
+use buoyant::view::View;
+use buoyant::view::ViewExt;
+use buoyant::view::ZStack;
+use buoyant::view::shape::Rectangle;
+use embedded_graphics::pixelcolor::Rgb565;
+
+use crate::get_image;
+use crate::images::StaticImage;
+
+pub fn icon_box_view(box_color: Rgb565, icon: &'static StaticImage) -> impl View {
+ ZStack::new((
+ Rectangle.corner_radius(10).foreground_color(box_color),
+ buoyant::view::Image::new(get_image!(icon)),
+ ))
+ .flex_frame()
+ .with_max_size(53, 53)
+ .with_min_size(53, 53)
+}
diff --git a/src/views/menu.rs b/src/views/menu.rs
new file mode 100644
index 0000000..23d7a7a
--- /dev/null
+++ b/src/views/menu.rs
@@ -0,0 +1,85 @@
+use buoyant::view::VStack;
+use buoyant::view::View;
+
+use buoyant::view::prelude::*;
+use embedded_graphics::pixelcolor::Rgb565;
+use embedded_graphics::prelude::*;
+use profont::PROFONT_18_POINT;
+use profont::PROFONT_24_POINT;
+
+use crate::MenuIndicatorType;
+use crate::Tendency;
+use crate::colors::FRAME_BACKGROUD_COLOR;
+use crate::colors::FRAME_STROKE;
+use crate::colors::FRAME_STROKE_COLOR;
+use crate::colors::MAIN_TEXT_COLOR;
+use crate::colors::SUB_TEXT_COLOR;
+use crate::get_image;
+use crate::views::icon::icon_box_view;
+
+pub fn menu_view() -> impl View {
+ VStack::new((
+ HStack::new((
+ main_menu_indicator(MenuIndicatorType::Temperature(31.5), Tendency::Falling),
+ main_menu_indicator(MenuIndicatorType::Humidity(36.2), Tendency::Steady),
+ ))
+ .with_spacing(5),
+ HStack::new((
+ main_menu_indicator(MenuIndicatorType::Co2(1329), Tendency::Rising),
+ main_menu_indicator(MenuIndicatorType::Voc(29), Tendency::Falling),
+ ))
+ .with_spacing(5),
+ ))
+ .with_spacing(5)
+}
+
+fn main_menu_indicator(indicator_type: MenuIndicatorType, tendency: Tendency) -> impl View {
+ Rectangle
+ .corner_radius(10)
+ .stroked(FRAME_STROKE)
+ .foreground_color(FRAME_STROKE_COLOR)
+ .background(Alignment::Center, || {
+ ZStack::new((
+ Rectangle
+ .corner_radius(15)
+ .foreground_color(FRAME_BACKGROUD_COLOR),
+ VStack::new((
+ HStack::new((
+ Spacer::default(),
+ icon_box_view(FRAME_STROKE_COLOR, indicator_type.get_corresponding_icon()),
+ Spacer::default(),
+ )),
+ HStack::new((
+ Spacer::default(),
+ tendency_indicator(tendency),
+ Text::new(indicator_type.get_value_str(), &PROFONT_24_POINT)
+ .foreground_color(MAIN_TEXT_COLOR),
+ Text::new(
+ indicator_type.get_corresponding_unit_string(),
+ &PROFONT_18_POINT,
+ )
+ .foreground_color(SUB_TEXT_COLOR)
+ .flex_frame()
+ .with_infinite_max_height()
+ .with_vertical_alignment(VerticalAlignment::Bottom)
+ .with_max_height(25),
+ Spacer::default(),
+ )),
+ ))
+ .with_alignment(HorizontalAlignment::Center)
+ .flex_frame(),
+ ))
+ })
+}
+
+fn tendency_indicator(tendency: Tendency) -> impl View {
+ HStack::new((
+ Image::new(get_image!(tendency.get_corresponding_icon()))
+ .flex_frame()
+ .with_min_size(10, 20)
+ .with_max_size(10, 20),
+ Spacer::default(),
+ ))
+ .flex_frame()
+ .with_max_width(15)
+}