mirror of
https://github.com/FliegendeWurst/raspi-oled.git
synced 2024-12-04 23:29:07 +00:00
Tweak github draw
This commit is contained in:
parent
beee5fe970
commit
8ffaf1f809
@ -1,13 +1,15 @@
|
|||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, collections::HashSet};
|
||||||
|
|
||||||
use color_space::{Hsv, ToRgb};
|
use color_space::{Hsv, ToRgb};
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
mono_font::{iso_8859_10::FONT_8X13, MonoTextStyleBuilder},
|
mono_font::{iso_8859_10::FONT_8X13, MonoTextStyleBuilder},
|
||||||
pixelcolor::Rgb565,
|
pixelcolor::Rgb565,
|
||||||
prelude::{DrawTarget, Point, RgbColor},
|
prelude::{DrawTarget, Point, RgbColor},
|
||||||
|
primitives::Rectangle,
|
||||||
text::Text,
|
text::Text,
|
||||||
Drawable,
|
Drawable, Pixel,
|
||||||
};
|
};
|
||||||
|
use rand_xoshiro::rand_core::RngCore;
|
||||||
use raspi_oled::github::get_new_notifications;
|
use raspi_oled::github::get_new_notifications;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -42,7 +44,6 @@ impl<D: DrawTarget<Color = Rgb565>> Schedule<D> for GithubNotifications {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let max_lines = 8;
|
let max_lines = 8;
|
||||||
let max_line_length = 16;
|
|
||||||
let mut lines = vec![];
|
let mut lines = vec![];
|
||||||
let mut relevant = relevant.into_iter();
|
let mut relevant = relevant.into_iter();
|
||||||
while lines.len() < max_lines {
|
while lines.len() < max_lines {
|
||||||
@ -59,9 +60,7 @@ impl<D: DrawTarget<Color = Rgb565>> Schedule<D> for GithubNotifications {
|
|||||||
}
|
}
|
||||||
lines.push(format!("{} #{}", parts[5], parts[7]));
|
lines.push(format!("{} #{}", parts[5], parts[7]));
|
||||||
if lines.len() < max_lines {
|
if lines.len() < max_lines {
|
||||||
let mut desc = format!(" {}", x.subject.title);
|
lines.push(x.subject.title.clone());
|
||||||
desc.truncate(desc.floor_char_boundary(max_line_length));
|
|
||||||
lines.push(desc);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -75,6 +74,7 @@ impl<D: DrawTarget<Color = Rgb565>> Schedule<D> for GithubNotifications {
|
|||||||
calls: RefCell::new(0),
|
calls: RefCell::new(0),
|
||||||
screen: &GITHUB,
|
screen: &GITHUB,
|
||||||
lines,
|
lines,
|
||||||
|
circles: RefCell::new(vec![]),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,36 +84,108 @@ struct GithubNotificationsDraw {
|
|||||||
calls: RefCell<usize>,
|
calls: RefCell<usize>,
|
||||||
screen: &'static SimpleScreensaver,
|
screen: &'static SimpleScreensaver,
|
||||||
lines: Vec<String>,
|
lines: Vec<String>,
|
||||||
|
circles: RefCell<Vec<((u32, u32), u32, Rgb565, Vec<(u32, u32)>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DrawTarget<Color = Rgb565>> Draw<D> for GithubNotificationsDraw {
|
impl<D: DrawTarget<Color = Rgb565>> Draw<D> for GithubNotificationsDraw {
|
||||||
fn draw(&self, disp: &mut D, _rng: &mut crate::Rng) -> Result<bool, D::Error> {
|
fn draw(&self, disp: &mut D, rng: &mut crate::Rng) -> Result<bool, D::Error> {
|
||||||
let calls = *self.calls.borrow();
|
let calls = *self.calls.borrow();
|
||||||
if calls < 40 {
|
if calls == 0 {
|
||||||
|
self.screen
|
||||||
|
.draw_all_colored(disp, Rgb565::new(0xff >> 3, 0xff >> 2, 0xff >> 3))?;
|
||||||
|
}
|
||||||
|
if calls < 70 {
|
||||||
let hue = calls as f64 / 40.0 * 360.0;
|
let hue = calls as f64 / 40.0 * 360.0;
|
||||||
let hsv = Hsv::new(hue, 1.0, 1.0);
|
let hsv = Hsv::new(hue, 1.0, 1.0);
|
||||||
let rgb = hsv.to_rgb();
|
let rgb = hsv.to_rgb();
|
||||||
let r = rgb.r as u8 >> 3;
|
let r = rgb.r as u8 >> 3;
|
||||||
let g = rgb.g as u8 >> 2;
|
let g = rgb.g as u8 >> 2;
|
||||||
let b = rgb.b as u8 >> 3;
|
let b = rgb.b as u8 >> 3;
|
||||||
self.screen.draw_all_colored(disp, Rgb565::new(r, g, b))?;
|
let rgb = Rgb565::new(r, g, b);
|
||||||
|
let mut x;
|
||||||
|
let mut y;
|
||||||
|
loop {
|
||||||
|
x = rng.next_u32() % 128;
|
||||||
|
y = rng.next_u32() % 128;
|
||||||
|
if self.screen.get_pixel(x, y) == Rgb565::WHITE {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disp.fill_contiguous(&Rectangle::new((x as i32, y as i32).into(), (1, 1).into()), Some(rgb))?;
|
||||||
|
// advance other circles
|
||||||
|
let mut circles = self.circles.borrow_mut();
|
||||||
|
for ((ox, oy), radius, color, points) in &mut *circles {
|
||||||
|
*radius += 1;
|
||||||
|
let mut seen = HashSet::new();
|
||||||
|
let mut next_points = vec![];
|
||||||
|
loop {
|
||||||
|
let mut new_points = vec![];
|
||||||
|
for (x, y) in &*points {
|
||||||
|
for (dx, dy) in [(-1, 0), (0, -1), (1, 0), (0, 1)] {
|
||||||
|
let Some(x) = x.checked_add_signed(dx) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(y) = y.checked_add_signed(dy) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if x >= 128 || y >= 128 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if self.screen.get_pixel(x, y) != Rgb565::WHITE {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if seen.contains(&(x, y)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
seen.insert((x, y));
|
||||||
|
let dist2 = x.abs_diff(*ox).pow(2) + y.abs_diff(*oy).pow(2);
|
||||||
|
if dist2 > (*radius - 1).pow(2) && dist2 <= (*radius).pow(2) {
|
||||||
|
new_points.push((x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if new_points.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next_points.extend_from_slice(&new_points);
|
||||||
|
*points = new_points;
|
||||||
|
}
|
||||||
|
disp.draw_iter(
|
||||||
|
next_points
|
||||||
|
.iter()
|
||||||
|
.map(|&x| Pixel(Point::new(x.0 as _, x.1 as _), *color)),
|
||||||
|
)?;
|
||||||
|
*points = next_points;
|
||||||
|
}
|
||||||
|
circles.push(((x, y), 0, rgb, vec![(x, y)]));
|
||||||
} else {
|
} else {
|
||||||
|
let idx = calls - 70;
|
||||||
disp.clear(Rgb565::BLACK)?;
|
disp.clear(Rgb565::BLACK)?;
|
||||||
// fit 9 lines
|
// fit 9 lines
|
||||||
|
let max_line_length = 16;
|
||||||
let text_style_clock = MonoTextStyleBuilder::new()
|
let text_style_clock = MonoTextStyleBuilder::new()
|
||||||
.font(&FONT_8X13)
|
.font(&FONT_8X13)
|
||||||
.text_color(Rgb565::WHITE)
|
.text_color(Rgb565::WHITE)
|
||||||
.build();
|
.build();
|
||||||
for (y, line) in self.lines.iter().enumerate() {
|
for (y, line) in self.lines.iter().enumerate() {
|
||||||
Text::new(line, Point::new(0, (12 + y * 14) as _), text_style_clock).draw(disp)?;
|
let mut line = if calls >= 139 {
|
||||||
|
format!(" {line}")
|
||||||
|
} else if line.len() > max_line_length {
|
||||||
|
let line = format!(" {line} ");
|
||||||
|
line[line.ceil_char_boundary(idx % line.len())..].to_string()
|
||||||
|
} else {
|
||||||
|
line.clone()
|
||||||
|
};
|
||||||
|
line.truncate(line.floor_char_boundary(max_line_length));
|
||||||
|
Text::new(&line, Point::new(0, (12 + y * 14) as _), text_style_clock).draw(disp)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*self.calls.borrow_mut() += 1;
|
*self.calls.borrow_mut() += 1;
|
||||||
Ok(calls < 90)
|
Ok(calls < 140)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expired(&self) -> bool {
|
fn expired(&self) -> bool {
|
||||||
*self.calls.borrow() > 90
|
*self.calls.borrow() > 140
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
|
@ -105,6 +105,12 @@ impl SimpleScreensaver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_pixel(&self, x: u32, y: u32) -> Rgb565 {
|
||||||
|
let idx = y as usize * 128 + x as usize;
|
||||||
|
let (red, green, blue) = (self.data[3 * idx], self.data[3 * idx + 1], self.data[3 * idx + 2]);
|
||||||
|
Rgb565::new(red >> 3, green >> 2, blue >> 3)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw_all_colored<D: DrawTarget<Color = Rgb565>>(&self, disp: &mut D, color: Rgb565) -> Result<(), D::Error> {
|
pub fn draw_all_colored<D: DrawTarget<Color = Rgb565>>(&self, disp: &mut D, color: Rgb565) -> Result<(), D::Error> {
|
||||||
disp.fill_contiguous(
|
disp.fill_contiguous(
|
||||||
&Rectangle::new((0, 0).into(), (128, 128).into()),
|
&Rectangle::new((0, 0).into(), (128, 128).into()),
|
||||||
|
Loading…
Reference in New Issue
Block a user