on-deck/src/slides/projects.rs

122 lines
3.3 KiB
Rust

use crate::effects::star_field;
use crate::slide::Slide;
use crate::slide_show_config::Context;
use crate::text_drawer::{Justified, TextConfigBuilder};
use crate::utils::{draw_rectangle_with_border, screen_center};
use macroquad::color::{BLACK, DARKGREEN, GREEN};
use macroquad::math::Vec2;
use macroquad::prelude::{clear_background, screen_height, screen_width};
use rand::prelude::IndexedRandom;
use rand::rng;
use serde::Deserialize;
use std::f32::consts::PI;
#[derive(Debug, Deserialize)]
#[allow(dead_code)]
struct GiteaRepo {
pub id: u64,
pub name: String,
}
#[derive(Debug, Deserialize)]
#[allow(dead_code)]
struct GiteaResponse {
pub ok: bool,
pub data: Vec<GiteaRepo>,
}
#[derive(Debug)]
struct FloatingText {
pos: Vec2,
vel: Vec2,
text: String,
}
#[derive(Debug)]
pub struct Projects {
repos: Vec<FloatingText>,
}
impl Projects {
pub fn new() -> Box<Self> {
let resp: GiteaResponse =
reqwest::blocking::get("https://git.ahines.net/api/v1/repos/search")
.unwrap()
.json()
.unwrap();
let repos: Vec<FloatingText> = resp
.data
.into_iter()
.filter_map(|r| {
if !r.name.starts_with("_") {
Some(FloatingText {
pos: Default::default(),
vel: Default::default(),
text: r.name,
})
} else {
None
}
})
.collect();
Box::new(Self { repos })
}
}
impl Slide for Projects {
fn display(&mut self, ctx: &Context<'_>) {
clear_background(BLACK);
star_field();
let text_cfg = TextConfigBuilder::new(ctx.slide_show_theme.body_config.clone())
.font_size(75)
.justification(Justified::Center)
.build();
for repo in &mut self.repos {
if repo.pos.x <= 0.0
|| repo.pos.y <= 0.0
|| repo.pos.x > screen_width()
|| repo.pos.y > screen_height()
{
repo.pos = screen_center();
let vel: f32 = rand::random_range(1.0..1.5);
let angle: f32 = rand::random_range(0.0..2.0 * PI);
repo.vel = Vec2::new(vel, 0.0).rotate(Vec2::from(angle.sin_cos()));
repo.vel = Vec2::new(rand::random_range(0.1..1.5), rand::random_range(0.1..1.5));
repo.vel.x *= [-1.0, 1.0].choose(&mut rng()).unwrap();
repo.vel.y *= [-1.0, 1.0].choose(&mut rng()).unwrap();
}
text_cfg.draw_text(&repo.text, repo.pos);
repo.pos += repo.vel
}
let dim = ctx
.slide_show_theme
.heading_config
.measure_text("https://git.ahines.net");
let background_rectangle_size = Vec2::new(dim.width * 1.2, dim.height * 1.2);
let pos =
screen_center() - background_rectangle_size * 0.5 - Vec2::new(0.0, dim.offset_y * 0.5);
draw_rectangle_with_border(
pos,
background_rectangle_size,
background_rectangle_size.x * 0.01,
GREEN,
DARKGREEN,
);
ctx.slide_show_theme
.heading_config
.draw_text("https://git.ahines.net", screen_center());
}
}