Browse Source

Add component trait and vsplit

master
Ilya 4 years ago
parent
commit
4194e63541
  1. 15
      examples/test.rs
  2. 30
      src/calendar.rs
  3. 109
      src/frame.rs
  4. 2
      src/lib.rs
  5. 39
      src/list_item.rs

15
examples/test.rs

@ -1,5 +1,5 @@
use embedded_components::{
Calendar, ComponentStyle, Gauge, List, ListItem, ListItemData, ScrollingCalendar,
Calendar, ComponentStyle, Gauge, List, ListItem, ListItemData, ScrollingCalendar, VSplit,
};
use embedded_graphics::{
pixelcolor::{raw::RawU2, BinaryColor, Rgb888},
@ -85,8 +85,6 @@ fn main() -> Result<(), core::convert::Infallible> {
//calendar.draw(&mut display)?;
let list = List {
top_left: Point::new(320, 0),
size: Size::new(280, 448),
style: calendar_style.clone(),
items_shown: 10,
list_items: vec![
@ -94,18 +92,19 @@ fn main() -> Result<(), core::convert::Infallible> {
ListItemData::new("O", "Other test task"),
],
};
list.draw(&mut display)?;
//list.draw(&mut display)?;
let calendar_week = ScrollingCalendar {
top_left: Point::new(0, 0),
size: Size::new(320, 448),
style: calendar_style,
day: chrono::Local::now().naive_local().date(),
//.checked_add_signed(chrono::Duration::days(28 * 4 * 0 - 14))
//.unwrap(),
weeks: 5,
prev_weeks: 2,
next_weeks: 5,
};
calendar_week.draw(&mut display)?;
//calendar_week.draw(&mut display)?;
VSplit::new(calendar_week, list).draw(&mut display)?;
let output_settings = OutputSettingsBuilder::new()
.theme(BinaryColorTheme::Default)

30
src/calendar.rs

@ -311,11 +311,21 @@ impl ScrollingWeek {
}
pub struct ScrollingCalendar<C> {
pub top_left: Point,
pub size: Size,
pub style: ComponentStyle<C>,
pub day: chrono::NaiveDate,
pub weeks: u32,
pub prev_weeks: u32,
pub next_weeks: u32,
}
impl<C> ScrollingCalendar<C> {
pub fn new(style: ComponentStyle<C>, prev_weeks: u32, next_weeks: u32) -> Self {
Self {
style,
day: chrono::Local::now().naive_local().date(),
prev_weeks,
next_weeks,
}
}
}
impl<C> Drawable for ScrollingCalendar<C>
@ -329,20 +339,24 @@ where
where
D: DrawTarget<Color = C>,
{
let height = self.size.height / (1 + self.weeks * 2);
let top_left = target.bounding_box().top_left;
let size = target.bounding_box().size;
let total_weeks = self.prev_weeks + 1 + self.next_weeks;
let height = size.height / total_weeks;
let mut week = ScrollingWeek::from_date(
self
.day
.checked_sub_signed(chrono::Duration::days(self.weeks as i64 * 7))
.checked_sub_signed(chrono::Duration::days(self.prev_weeks as i64 * 7))
.unwrap(),
);
for i in 0..(1 + self.weeks * 2) {
for i in 0..total_weeks {
week = week.succ();
let calendar_week = CalendarWeek {
top_left: Point::new(self.top_left.x, self.top_left.y + (height * i) as i32),
size: Size::new(self.size.width, height),
top_left: Point::new(top_left.x, top_left.y + (height * i) as i32),
size: Size::new(size.width, height),
style: self.style.clone(),
year: week.year(),
month: week.month(),

109
src/frame.rs

@ -0,0 +1,109 @@
use embedded_graphics::{pixelcolor::BinaryColor, prelude::*, primitives::Rectangle};
use embedded_layout::View;
pub trait Component {
fn set_top_left(&mut self, top_left: Point);
fn set_size(&mut self, size: Size);
}
pub struct Frame<D> {
drawtarget: D,
pub weight: f32,
}
pub struct VSplit<T, U> {
pub left: T,
pub right: U,
pub ratio: f32,
}
impl<T, U> VSplit<T, U> {
pub fn new(left: T, right: U) -> Self {
VSplit {
left,
right,
ratio: 0.5,
}
}
}
impl<T, U> VSplit<T, U> {
pub fn with_ratio(self, ratio: f32) -> Self {
VSplit { ratio, ..self }
}
}
impl<C, T, U> Drawable for VSplit<T, U>
where
C: PixelColor + From<BinaryColor>,
T: Drawable<Color = C>,
U: Drawable<Color = C>,
{
type Color = C;
type Output = ();
fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
where
D: DrawTarget<Color = C>,
{
let top_left = target.bounding_box().top_left;
let size = target.bounding_box().size;
let left_width = (size.width as f32 * self.ratio) as u32;
self.left.draw(&mut target.clipped(&Rectangle::new(
top_left,
Size::new(left_width, size.height),
)))?;
self.right.draw(&mut target.clipped(&Rectangle::new(
top_left + Point::new(left_width as i32, 0),
Size::new(size.width - left_width, size.height),
)))?;
Ok(())
}
}
pub struct HSplit<T, U> {
pub top_left: Point,
pub size: Size,
pub top: T,
pub bottom: U,
pub ratio: f32,
}
impl<T, U> HSplit<T, U> {
pub fn with_ratio(self, ratio: f32) -> Self {
HSplit { ratio, ..self }
}
}
impl<C, T, U> Drawable for HSplit<T, U>
where
C: PixelColor + From<BinaryColor>,
T: Drawable<Color = C>,
U: Drawable<Color = C>,
{
type Color = C;
type Output = ();
fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
where
D: DrawTarget<Color = C>,
{
let top_left = target.bounding_box().top_left;
let size = target.bounding_box().size;
let top_height = (size.height as f32 * self.ratio) as u32;
self
.top
.draw(&mut target.clipped(&Rectangle::new(top_left, Size::new(size.width, top_height))))?;
self.bottom.draw(&mut target.clipped(&Rectangle::new(
top_left + Point::new(0, top_height as i32),
Size::new(size.width, size.height - top_height),
)))?;
Ok(())
}
}

2
src/lib.rs

@ -1,11 +1,13 @@
mod bullet_counter;
mod calendar;
mod frame;
mod gauge;
mod list_item;
mod style;
pub use bullet_counter::BulletCounter;
pub use calendar::{Calendar, ScrollingCalendar};
pub use frame::{Component, HSplit, VSplit};
pub use gauge::Gauge;
pub use list_item::{List, ListItem, ListItemData};
pub use style::ComponentStyle;

39
src/list_item.rs

@ -33,12 +33,20 @@ impl<'a> ListItemData {
pub struct List<C> {
pub style: ComponentStyle<C>,
pub top_left: Point,
pub size: Size,
pub items_shown: usize,
pub list_items: Vec<ListItemData>,
}
impl<C> List<C> {
pub fn new(style: ComponentStyle<C>, list_items: Vec<ListItemData>, items_shown: usize) -> Self {
Self {
style,
items_shown,
list_items,
}
}
}
impl<C> Drawable for List<C>
where
C: PixelColor + From<BinaryColor>,
@ -50,7 +58,10 @@ where
where
D: DrawTarget<Color = C>,
{
let rect = Rectangle::new(self.top_left, self.size);
let top_left = target.bounding_box().top_left;
let size = target.bounding_box().size;
let rect = Rectangle::new(top_left, size);
rect
.into_styled(PrimitiveStyle::with_stroke(
self.style.bg_color,
@ -61,13 +72,22 @@ where
.into_styled(PrimitiveStyle::with_fill(self.style.bg_color))
.draw(target)?;
let height = self.size.height / self.items_shown as u32;
let height = size.height / self.items_shown as u32;
for (i, item) in self.list_items.iter().enumerate().take(self.items_shown) {
let (fg_color, bg_color) = match item.progress >= 100f32 {
true => (self.style.bg_color, self.style.hi_color),
_ => (self.style.fg_color, self.style.bg_color),
};
let item_style = ComponentStyle {
fg_color,
bg_color,
..self.style.clone()
};
let list_item = ListItem {
style: self.style.clone(),
top_left: self.top_left + Point::new(0, (height as usize * i) as i32),
size: Size::new(self.size.width, height),
style: item_style,
top_left: top_left + Point::new(0, (height as usize * i) as i32),
size: Size::new(size.width, height),
text: &item.text,
icon: &item.icon,
progress: item.progress,
@ -114,6 +134,9 @@ where
.draw(target)?;
let icon_square = Rectangle::new(self.top_left, Size::new(rect.size.height, rect.size.height));
icon_square
.into_styled(PrimitiveStyle::with_fill(self.style.fg_color))
.draw(target)?;
icon_square
.into_styled(PrimitiveStyle::with_stroke(
self.style.border_color,
@ -121,7 +144,7 @@ where
))
.draw(target)?;
let icon_style = MonoTextStyle::new(&FONT_10X20, self.style.hi_color);
let icon_style = MonoTextStyle::new(&FONT_10X20, self.style.bg_color);
let mut icon = Text::with_baseline(self.icon, self.top_left, icon_style, Baseline::Middle);
let icon_box = icon.bounding_box();

Loading…
Cancel
Save