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,12 +92,23 @@ pub fn start(
|
||||||
NonZeroU32::new(height).unwrap(),
|
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 {
|
||||||
.expect("Cannot create renderer");
|
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");
|
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
||||||
canvas.set_size(width, height, window.scale_factor() as f32);
|
canvas.set_size(width, height, window.scale_factor() as f32);
|
||||||
|
|
|
@ -60,7 +60,12 @@ impl PerfGraph {
|
||||||
text_paint.set_font_size(14.0);
|
text_paint.set_font_size(14.0);
|
||||||
text_paint.set_text_align(Align::Right);
|
text_paint.set_text_align(Align::Right);
|
||||||
text_paint.set_text_baseline(Baseline::Top);
|
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));
|
let mut text_paint = Paint::color(Color::rgba(240, 240, 240, 200));
|
||||||
text_paint.set_font_size(12.0);
|
text_paint.set_font_size(12.0);
|
||||||
|
|
123
src/main.rs
123
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 instant::Instant;
|
||||||
use resource::resource;
|
use resource::resource;
|
||||||
use winit::{
|
use winit::{
|
||||||
|
@ -21,6 +26,8 @@ fn main() {
|
||||||
|
|
||||||
use glutin::prelude::*;
|
use glutin::prelude::*;
|
||||||
|
|
||||||
|
mod roundy_math;
|
||||||
|
mod ui;
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
mut canvas: Canvas<OpenGl>,
|
mut canvas: Canvas<OpenGl>,
|
||||||
|
@ -36,11 +43,12 @@ fn run(
|
||||||
bold: canvas
|
bold: canvas
|
||||||
.add_font_mem(&resource!("assets/Roboto-Bold.ttf"))
|
.add_font_mem(&resource!("assets/Roboto-Bold.ttf"))
|
||||||
.expect("Cannot add font"),
|
.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 flags = ImageFlags::GENERATE_MIPMAPS | ImageFlags::REPEAT_X | ImageFlags::REPEAT_Y;
|
||||||
let image_id = canvas
|
let image_id = canvas
|
||||||
|
@ -100,7 +108,7 @@ fn run(
|
||||||
x += 0.1;
|
x += 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if *keycode == VirtualKeyCode::NumpadAdd || *keycode == VirtualKeyCode::B{
|
if *keycode == VirtualKeyCode::NumpadAdd || *keycode == VirtualKeyCode::B {
|
||||||
println!("Add");
|
println!("Add");
|
||||||
font_size += 1.0;
|
font_size += 1.0;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +142,6 @@ fn run(
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
Event::RedrawRequested(_) => {
|
Event::RedrawRequested(_) => {
|
||||||
println!("Redraw");
|
|
||||||
let dpi_factor = window.scale_factor();
|
let dpi_factor = window.scale_factor();
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
canvas.set_size(size.width, size.height, dpi_factor as f32);
|
canvas.set_size(size.width, size.height, dpi_factor as f32);
|
||||||
|
@ -147,7 +154,8 @@ fn run(
|
||||||
|
|
||||||
perf.update(dt);
|
perf.update(dt);
|
||||||
|
|
||||||
|
draw_main_menu(&mut canvas, &fonts, &beo);
|
||||||
|
/*
|
||||||
draw_baselines(&mut canvas, &fonts, 5.0, 50.0, font_size);
|
draw_baselines(&mut canvas, &fonts, 5.0, 50.0, font_size);
|
||||||
draw_alignments(&mut canvas, &fonts, 120.0, 200.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);
|
//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),
|
format!("Click to show font atlas texture. Current: {:?}", font_texture_to_show),
|
||||||
paint,
|
paint,
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.reset();
|
canvas.reset();
|
||||||
perf.render(&mut canvas, 5.0, 5.0);
|
perf.render(&mut canvas, 500.0, 5.0);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
|
||||||
#[cfg(feature = "debug_inspector")]
|
#[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>(
|
fn draw_baselines<T: Renderer>(
|
||||||
canvas: &mut Canvas<T>,
|
canvas: &mut Canvas<T>,
|
||||||
fonts: &Fonts,
|
fonts: &Fonts,
|
||||||
|
@ -209,7 +262,12 @@ fn draw_baselines<T: Renderer>(
|
||||||
y: f32,
|
y: f32,
|
||||||
font_size: 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());
|
let mut paint = Paint::color(Color::black());
|
||||||
paint.set_font(&[fonts.sans]);
|
paint.set_font(&[fonts.sans]);
|
||||||
|
@ -227,7 +285,9 @@ fn draw_baselines<T: Renderer>(
|
||||||
|
|
||||||
paint.set_text_baseline(*baseline);
|
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 res = canvas.fill_text(10.0, y, format!("d النص العربي جميل جدا {:?}", baseline), &paint);
|
||||||
|
|
||||||
let mut path = Path::new();
|
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 alignments = [Align::Left, Align::Center, Align::Right];
|
||||||
|
|
||||||
let mut path = Path::new();
|
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() {
|
for (i, alignment) in alignments.iter().enumerate() {
|
||||||
paint.set_text_align(*alignment);
|
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();
|
let mut path = Path::new();
|
||||||
path.rect(res.x, res.y, res.width(), res.height());
|
path.rect(res.x, res.y, res.width(), res.height());
|
||||||
canvas.stroke_path(&path, &Paint::color(Color::rgba(100, 100, 100, 64)));
|
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());
|
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_text_align(Align::Right);
|
||||||
paint.set_font_size(font_size);
|
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");
|
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();
|
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);
|
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"));
|
let mut paint = Paint::color(Color::hex("#7300AB"));
|
||||||
paint.set_line_width(3.0);
|
paint.set_line_width(3.0);
|
||||||
let mut path = Path::new();
|
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);
|
//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);
|
//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
|
||||||
|
}
|
||||||
|
}
|
18
src/ui.rs
18
src/ui.rs
|
@ -1,8 +1,8 @@
|
||||||
struct Beo {
|
pub struct Beo {
|
||||||
apps: Vec<App>,
|
pub apps: Vec<Box<dyn App>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait App {
|
pub trait App {
|
||||||
fn name(&self) -> &str;
|
fn name(&self) -> &str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,12 @@ impl App for Radio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_apps() -> Vec<App> {
|
impl Beo {
|
||||||
vec![Stotify{}, Radio{}]
|
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