Tidy views
This commit is contained in:
12
src/colors.rs
Normal file
12
src/colors.rs
Normal file
@ -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;
|
||||
@ -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<MaybeUninit<Bmp<'static, Rgb565>>> = const { UnsafeCell::new(MaybeUninit::zeroed()) };
|
||||
}
|
||||
|
||||
pub type StaticImage = std::thread::LocalKey<UnsafeCell<MaybeUninit<Bmp<'static, Rgb565>>>>;
|
||||
|
||||
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<Bmp<Rgb565>>, *mut Bmp<Rgb565>>(
|
||||
$image.with(|g| g.get()),
|
||||
)
|
||||
|
||||
87
src/main.rs
87
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<Rgb565> = 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<Rgb565> {
|
||||
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<Rgb565> {
|
||||
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,
|
||||
|
||||
3
src/views.rs
Normal file
3
src/views.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod detail;
|
||||
pub mod icon;
|
||||
pub mod menu;
|
||||
52
src/views/detail.rs
Normal file
52
src/views/detail.rs
Normal file
@ -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<Rgb565> {
|
||||
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)
|
||||
}
|
||||
18
src/views/icon.rs
Normal file
18
src/views/icon.rs
Normal file
@ -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<Rgb565> {
|
||||
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)
|
||||
}
|
||||
85
src/views/menu.rs
Normal file
85
src/views/menu.rs
Normal file
@ -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<Rgb565> {
|
||||
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<Rgb565> {
|
||||
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<Rgb565> {
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user