lol
Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
This commit is contained in:
parent
b1e4921376
commit
6b3a2cfbfc
5 changed files with 202 additions and 28 deletions
|
@ -92,11 +92,22 @@ pub fn start(
|
|||
NonZeroU32::new(height).unwrap(),
|
||||
);
|
||||
|
||||
let surface = unsafe { gl_config.display().create_window_surface(&gl_config, &attrs).unwrap() };
|
||||
let surface = unsafe {
|
||||
gl_config
|
||||
.display()
|
||||
.create_window_surface(&gl_config, &attrs)
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let gl_context = not_current_gl_context.take().unwrap().make_current(&surface).unwrap();
|
||||
let gl_context = not_current_gl_context
|
||||
.take()
|
||||
.unwrap()
|
||||
.make_current(&surface)
|
||||
.unwrap();
|
||||
|
||||
let renderer = unsafe { OpenGl::new_from_function_cstr(|s| gl_display.get_proc_address(s) as *const _) }
|
||||
let renderer = unsafe {
|
||||
OpenGl::new_from_function_cstr(|s| gl_display.get_proc_address(s) as *const _)
|
||||
}
|
||||
.expect("Cannot create renderer");
|
||||
|
||||
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
||||
|
|
|
@ -60,7 +60,12 @@ impl PerfGraph {
|
|||
text_paint.set_font_size(14.0);
|
||||
text_paint.set_text_align(Align::Right);
|
||||
text_paint.set_text_baseline(Baseline::Top);
|
||||
let _ = canvas.fill_text(x + w - 5.0, y, &format!("{:.2} FPS", 1.0 / avg), &text_paint);
|
||||
let _ = canvas.fill_text(
|
||||
x + w - 5.0,
|
||||
y,
|
||||
&format!("{:.2} FPS", 1.0 / avg),
|
||||
&text_paint,
|
||||
);
|
||||
|
||||
let mut text_paint = Paint::color(Color::rgba(240, 240, 240, 200));
|
||||
text_paint.set_font_size(12.0);
|
||||
|
|
121
src/main.rs
121
src/main.rs
|
@ -1,4 +1,9 @@
|
|||
use femtovg::{renderer::OpenGl, Align, Baseline, Canvas, Color, FontId, ImageFlags, ImageId, Paint, Path, Renderer};
|
||||
use core::panic;
|
||||
|
||||
use femtovg::{
|
||||
renderer::OpenGl, Align, Baseline, Canvas, Color, FontId, ImageFlags, ImageId, Paint, Path,
|
||||
Renderer,
|
||||
};
|
||||
use instant::Instant;
|
||||
use resource::resource;
|
||||
use winit::{
|
||||
|
@ -21,6 +26,8 @@ fn main() {
|
|||
|
||||
use glutin::prelude::*;
|
||||
|
||||
mod roundy_math;
|
||||
mod ui;
|
||||
|
||||
fn run(
|
||||
mut canvas: Canvas<OpenGl>,
|
||||
|
@ -36,11 +43,12 @@ fn run(
|
|||
bold: canvas
|
||||
.add_font_mem(&resource!("assets/Roboto-Bold.ttf"))
|
||||
.expect("Cannot add font"),
|
||||
light: canvas
|
||||
.add_font_mem(&resource!("assets/Roboto-Light.ttf"))
|
||||
.expect("Cannot add font"),
|
||||
};
|
||||
|
||||
let beo = ui::Beo::new();
|
||||
for app in &beo.apps {
|
||||
println!("{}", app.name());
|
||||
}
|
||||
|
||||
let flags = ImageFlags::GENERATE_MIPMAPS | ImageFlags::REPEAT_X | ImageFlags::REPEAT_Y;
|
||||
let image_id = canvas
|
||||
|
@ -134,7 +142,6 @@ fn run(
|
|||
_ => (),
|
||||
},
|
||||
Event::RedrawRequested(_) => {
|
||||
println!("Redraw");
|
||||
let dpi_factor = window.scale_factor();
|
||||
let size = window.inner_size();
|
||||
canvas.set_size(size.width, size.height, dpi_factor as f32);
|
||||
|
@ -147,7 +154,8 @@ fn run(
|
|||
|
||||
perf.update(dt);
|
||||
|
||||
|
||||
draw_main_menu(&mut canvas, &fonts, &beo);
|
||||
/*
|
||||
draw_baselines(&mut canvas, &fonts, 5.0, 50.0, font_size);
|
||||
draw_alignments(&mut canvas, &fonts, 120.0, 200.0, font_size);
|
||||
//draw_paragraph(&mut canvas, &fonts, x, y, font_size, LOREM_TEXT);
|
||||
|
@ -176,10 +184,11 @@ fn run(
|
|||
format!("Click to show font atlas texture. Current: {:?}", font_texture_to_show),
|
||||
paint,
|
||||
);
|
||||
*/
|
||||
|
||||
canvas.save();
|
||||
canvas.reset();
|
||||
perf.render(&mut canvas, 5.0, 5.0);
|
||||
perf.render(&mut canvas, 500.0, 5.0);
|
||||
canvas.restore();
|
||||
|
||||
#[cfg(feature = "debug_inspector")]
|
||||
|
@ -202,6 +211,50 @@ fn run(
|
|||
});
|
||||
}
|
||||
|
||||
fn draw_main_menu<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, beo: &ui::Beo) {
|
||||
let canvas_width = canvas.width();
|
||||
let canvas_height = canvas.height();
|
||||
|
||||
// circle is centered on the right side of the screen
|
||||
let main_menu_circle = roundy_math::VirtualCircle {
|
||||
center: roundy_math::Point {
|
||||
x: canvas_width as f64,
|
||||
y: canvas_height as f64 / 2.0 + 10.,
|
||||
},
|
||||
//radius: canvas_width as f64 - 30.0,
|
||||
radius: 400.0,
|
||||
};
|
||||
|
||||
println!("Canvas width: {}, height: {}", canvas_width, canvas_height);
|
||||
|
||||
let canvas_size = roundy_math::Point {
|
||||
x: canvas_width as f64,
|
||||
y: canvas_height as f64,
|
||||
};
|
||||
|
||||
let pts = main_menu_circle.get_equidistant_points(8, canvas_size);
|
||||
for i in 0..pts.len() {
|
||||
println!(">>> {:?}", pts[i]);
|
||||
let mut paint = Paint::color(Color::hex("B7410E"));
|
||||
paint.set_font(&[fonts.bold]);
|
||||
paint.set_text_baseline(Baseline::Top);
|
||||
let _ = canvas.fill_text(pts[i].x as f32, pts[i].y as f32, format!("XX {i}"), &paint);
|
||||
}
|
||||
|
||||
/*
|
||||
let mut y = 40.0;
|
||||
for app in &beo.apps {
|
||||
println!("{}", app.name());
|
||||
let mut paint = Paint::color(Color::hex("B7410E"));
|
||||
paint.set_font(&[fonts.bold]);
|
||||
paint.set_text_baseline(Baseline::Top);
|
||||
paint.set_text_align(Align::Right);
|
||||
let _ = canvas.fill_text(50.0, y, app.name(), &paint);
|
||||
y += 20.0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
fn draw_baselines<T: Renderer>(
|
||||
canvas: &mut Canvas<T>,
|
||||
fonts: &Fonts,
|
||||
|
@ -209,7 +262,12 @@ fn draw_baselines<T: Renderer>(
|
|||
y: f32,
|
||||
font_size: f32,
|
||||
) {
|
||||
let baselines = [Baseline::Top, Baseline::Middle, Baseline::Alphabetic, Baseline::Bottom];
|
||||
let baselines = [
|
||||
Baseline::Top,
|
||||
Baseline::Middle,
|
||||
Baseline::Alphabetic,
|
||||
Baseline::Bottom,
|
||||
];
|
||||
|
||||
let mut paint = Paint::color(Color::black());
|
||||
paint.set_font(&[fonts.sans]);
|
||||
|
@ -227,7 +285,9 @@ fn draw_baselines<T: Renderer>(
|
|||
|
||||
paint.set_text_baseline(*baseline);
|
||||
|
||||
if let Ok(res) = canvas.fill_text(x, y, format!("{base_text} Baseline::{baseline:?}"), &paint) {
|
||||
if let Ok(res) =
|
||||
canvas.fill_text(x, y, format!("{base_text} Baseline::{baseline:?}"), &paint)
|
||||
{
|
||||
//let res = canvas.fill_text(10.0, y, format!("d النص العربي جميل جدا {:?}", baseline), &paint);
|
||||
|
||||
let mut path = Path::new();
|
||||
|
@ -237,7 +297,13 @@ fn draw_baselines<T: Renderer>(
|
|||
}
|
||||
}
|
||||
|
||||
fn draw_alignments<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, x: f32, y: f32, font_size: f32) {
|
||||
fn draw_alignments<T: Renderer>(
|
||||
canvas: &mut Canvas<T>,
|
||||
fonts: &Fonts,
|
||||
x: f32,
|
||||
y: f32,
|
||||
font_size: f32,
|
||||
) {
|
||||
let alignments = [Align::Left, Align::Center, Align::Right];
|
||||
|
||||
let mut path = Path::new();
|
||||
|
@ -252,7 +318,12 @@ fn draw_alignments<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, x: f32, y
|
|||
for (i, alignment) in alignments.iter().enumerate() {
|
||||
paint.set_text_align(*alignment);
|
||||
|
||||
if let Ok(res) = canvas.fill_text(x, y + i as f32 * 30.0, format!("Align::{alignment:?}"), &paint) {
|
||||
if let Ok(res) = canvas.fill_text(
|
||||
x,
|
||||
y + i as f32 * 30.0,
|
||||
format!("Align::{alignment:?}"),
|
||||
&paint,
|
||||
) {
|
||||
let mut path = Path::new();
|
||||
path.rect(res.x, res.y, res.width(), res.height());
|
||||
canvas.stroke_path(&path, &Paint::color(Color::rgba(100, 100, 100, 64)));
|
||||
|
@ -260,9 +331,16 @@ fn draw_alignments<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, x: f32, y
|
|||
}
|
||||
}
|
||||
|
||||
fn draw_paragraph<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, x: f32, y: f32, font_size: f32, text: &str) {
|
||||
fn draw_paragraph<T: Renderer>(
|
||||
canvas: &mut Canvas<T>,
|
||||
fonts: &Fonts,
|
||||
x: f32,
|
||||
y: f32,
|
||||
font_size: f32,
|
||||
text: &str,
|
||||
) {
|
||||
let mut paint = Paint::color(Color::black());
|
||||
paint.set_font(&[fonts.light]);
|
||||
paint.set_font(&[fonts.bold]);
|
||||
//paint.set_text_align(Align::Right);
|
||||
paint.set_font_size(font_size);
|
||||
|
||||
|
@ -308,7 +386,12 @@ fn draw_inc_size<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, x: f32, y:
|
|||
|
||||
let font_metrics = canvas.measure_font(&paint).expect("Error measuring font");
|
||||
|
||||
if let Ok(_res) = canvas.fill_text(x, cursor_y, "The quick brown fox jumps over the lazy dog", &paint) {
|
||||
if let Ok(_res) = canvas.fill_text(
|
||||
x,
|
||||
cursor_y,
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
&paint,
|
||||
) {
|
||||
cursor_y += font_metrics.height();
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +436,14 @@ fn draw_gradient_fill<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, x: f32
|
|||
let _ = canvas.fill_text(x, y, "RUST", &paint);
|
||||
}
|
||||
|
||||
fn draw_image_fill<T: Renderer>(canvas: &mut Canvas<T>, fonts: &Fonts, x: f32, y: f32, image_id: ImageId, t: f32) {
|
||||
fn draw_image_fill<T: Renderer>(
|
||||
canvas: &mut Canvas<T>,
|
||||
fonts: &Fonts,
|
||||
x: f32,
|
||||
y: f32,
|
||||
image_id: ImageId,
|
||||
t: f32,
|
||||
) {
|
||||
let mut paint = Paint::color(Color::hex("#7300AB"));
|
||||
paint.set_line_width(3.0);
|
||||
let mut path = Path::new();
|
||||
|
@ -389,4 +479,3 @@ fn draw_complex<T: Renderer>(canvas: &mut Canvas<T>, x: f32, y: f32, font_size:
|
|||
//let _ = canvas.fill_text(x, y, "اللغة العربية", &paint);
|
||||
//canvas.fill_text(x, y, "Traditionally, text is composed to create a readable, coherent, and visually satisfying", &paint);
|
||||
}
|
||||
|
||||
|
|
63
src/roundy_math.rs
Normal file
63
src/roundy_math.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use std::f64::consts::PI;
|
||||
//use std::f64;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Point {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
}
|
||||
|
||||
pub struct VirtualCircle {
|
||||
pub center: Point,
|
||||
// radius of the circle in pixels
|
||||
pub radius: f64,
|
||||
}
|
||||
|
||||
impl VirtualCircle {
|
||||
pub fn get_equidistant_points(&self, n: usize, viewport_size: Point) -> Vec<Point> {
|
||||
// Note: this only works when the circle's origin is at the middle right of the viewport.
|
||||
// because I'm not clever enough to figure out how to calculate the intersection points
|
||||
// in the general case.
|
||||
|
||||
println!(
|
||||
"center: {:?}, radius: {}, viewport_size: {:?}",
|
||||
self.center, self.radius, viewport_size
|
||||
);
|
||||
// Calculate the angles at which the circle intersects with the viewport
|
||||
let upper_x = self.center.x - (self.radius.powf(2.) - (0. - self.center.y).powf(2.)).sqrt();
|
||||
let lower_x = self.center.x
|
||||
- (self.radius.powf(2.) - (viewport_size.y - self.center.y).powf(2.)).sqrt();
|
||||
|
||||
let upper_point = Point { x: upper_x, y: 0. };
|
||||
|
||||
let lower_point = Point {
|
||||
x: lower_x,
|
||||
y: viewport_size.y,
|
||||
};
|
||||
|
||||
println!("up/low: {:?} {:?}", upper_point, lower_point);
|
||||
|
||||
let intersection_angles = (
|
||||
(upper_point.x - self.center.x).atan2(upper_point.y - self.center.y),
|
||||
(lower_point.x - self.center.x).atan2(lower_point.y - self.center.y),
|
||||
);
|
||||
println!("int angles: {:?}", intersection_angles);
|
||||
|
||||
let mut points = Vec::new();
|
||||
|
||||
// Calculate the angle step to distribute points evenly
|
||||
let angle_step = (intersection_angles.1 - intersection_angles.0) / (n as f64);
|
||||
println!("angle step: {}", angle_step);
|
||||
|
||||
// Generate the points
|
||||
for i in 0..n {
|
||||
let theta = intersection_angles.0 + angle_step * (i as f64 + 0.5);
|
||||
let x = theta.sin() * self.radius + viewport_size.x;
|
||||
let y = theta.cos() * self.radius + viewport_size.y - self.center.y;
|
||||
println!("x: {}, y: {}", x, y);
|
||||
points.push(Point { x: x, y: y });
|
||||
}
|
||||
|
||||
points
|
||||
}
|
||||
}
|
16
src/ui.rs
16
src/ui.rs
|
@ -1,8 +1,8 @@
|
|||
struct Beo {
|
||||
apps: Vec<App>,
|
||||
pub struct Beo {
|
||||
pub apps: Vec<Box<dyn App>>,
|
||||
}
|
||||
|
||||
trait App {
|
||||
pub trait App {
|
||||
fn name(&self) -> &str;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,12 @@ impl App for Radio {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_apps() -> Vec<App> {
|
||||
vec![Stotify{}, Radio{}]
|
||||
impl Beo {
|
||||
pub fn new() -> Beo {
|
||||
Beo { apps: get_apps() }
|
||||
}
|
||||
}
|
||||
|
||||
fn get_apps() -> Vec<Box<dyn App>> {
|
||||
vec![Box::new(Spotify {}), Box::new(Radio {})]
|
||||
}
|
Loading…
Reference in a new issue