Browse Source

Add component trait and vsplit

Ilya 4 years ago
parent
commit
d3f07468e9
  1. 15
      examples/test.rs
  2. 30
      src/calendar.rs
  3. 65
      src/frame.rs
  4. 2
      src/lib.rs
  5. 27
      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(),

65
src/frame.rs

@ -0,0 +1,65 @@
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<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 size = target.bounding_box().size;
let left_width = (size.width as f32 * self.ratio) as u32;
self.left.draw(&mut target.clipped(&Rectangle::new(
Point::default(),
Size::new(left_width, size.height),
)))?;
self.right.draw(&mut target.clipped(&Rectangle::new(
Point::new(left_width as i32, 0),
Size::new(size.width - left_width, size.height),
)))?;
Ok(())
}
}
pub struct HSplit<T> {
pub top_left: Point,
pub size: Size,
pub top: T,
pub bottom: T,
}

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;

27
src/list_item.rs

@ -11,6 +11,7 @@ use embedded_graphics::{
};
use embedded_layout::prelude::*;
#[derive(Clone)]
pub struct ListItemData {
pub text: String,
pub icon: String,
@ -31,14 +32,23 @@ impl<'a> ListItemData {
}
}
#[derive(Clone)]
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 +60,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 +74,13 @@ 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 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),
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,
@ -127,7 +140,7 @@ where
let icon_box = icon.bounding_box();
icon.position = self.top_left
+ Point::new(
(self.size.height / 2 - icon_box.size.width / 2) as i32,
self.size.height as i32 / 2 - icon_box.size.width as i32 / 2,
(self.size.height / 2) as i32,
);

Loading…
Cancel
Save