Add a slash meter
This commit is contained in:
parent
d8ac8fba01
commit
a2eec878a2
|
@ -1,5 +1,6 @@
|
||||||
use cairo::{
|
use cairo::{
|
||||||
Context, FontSlant, FontWeight, Format, ImageSurface, LineCap, LinearGradient, Pattern,
|
Context, FontSlant, FontWeight, Format, ImageSurface, LineCap, LinearGradient, Pattern,
|
||||||
|
TextExtents,
|
||||||
};
|
};
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{prelude::*, subclass::prelude::*};
|
use gtk::{prelude::*, subclass::prelude::*};
|
||||||
|
@ -16,6 +17,7 @@ pub struct SplashPrivate {
|
||||||
text: Rc<RefCell<String>>,
|
text: Rc<RefCell<String>>,
|
||||||
time: Rc<RefCell<Duration>>,
|
time: Rc<RefCell<Duration>>,
|
||||||
background: Rc<RefCell<Pattern>>,
|
background: Rc<RefCell<Pattern>>,
|
||||||
|
time_extents: Rc<RefCell<Option<TextExtents>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SplashPrivate {
|
impl SplashPrivate {
|
||||||
|
@ -137,6 +139,7 @@ impl ObjectSubclass for SplashPrivate {
|
||||||
text: Rc::new(RefCell::new(String::from(""))),
|
text: Rc::new(RefCell::new(String::from(""))),
|
||||||
time: Rc::new(RefCell::new(Duration::ZERO)),
|
time: Rc::new(RefCell::new(Duration::ZERO)),
|
||||||
background: Rc::new(RefCell::new(background)),
|
background: Rc::new(RefCell::new(background)),
|
||||||
|
time_extents: Rc::new(RefCell::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,10 +168,14 @@ impl Splash {
|
||||||
let _ = context.set_source(&*background);
|
let _ = context.set_source(&*background);
|
||||||
let _ = context.paint();
|
let _ = context.paint();
|
||||||
|
|
||||||
{
|
let time = s.imp().time.borrow().clone();
|
||||||
let center_x = width as f64 / 2.;
|
let minutes = time.as_secs() / 60;
|
||||||
let center_y = height as f64 / 2.;
|
let seconds = time.as_secs() % 60;
|
||||||
|
|
||||||
|
let center_x = width as f64 / 2.;
|
||||||
|
let center_y = height as f64 / 2.;
|
||||||
|
|
||||||
|
{
|
||||||
context.select_font_face(
|
context.select_font_face(
|
||||||
"Alegreya Sans SC",
|
"Alegreya Sans SC",
|
||||||
FontSlant::Normal,
|
FontSlant::Normal,
|
||||||
|
@ -176,12 +183,15 @@ impl Splash {
|
||||||
);
|
);
|
||||||
context.set_font_size(128.);
|
context.set_font_size(128.);
|
||||||
|
|
||||||
let time = s.imp().time.borrow().clone();
|
|
||||||
let minutes = time.as_secs() / 60;
|
|
||||||
let seconds = time.as_secs() % 60;
|
|
||||||
let time = format!("{:02}' {:02}\"", minutes, seconds);
|
let time = format!("{:02}' {:02}\"", minutes, seconds);
|
||||||
|
|
||||||
let time_extents = context.text_extents(&time).unwrap();
|
let time_extents = context.text_extents(&time).unwrap();
|
||||||
|
|
||||||
|
let mut saved_extents = s.imp().time_extents.borrow_mut();
|
||||||
|
if saved_extents.is_none() {
|
||||||
|
*saved_extents = Some(time_extents.clone());
|
||||||
|
}
|
||||||
|
|
||||||
let time_baseline_x = center_x - time_extents.width() / 2.;
|
let time_baseline_x = center_x - time_extents.width() / 2.;
|
||||||
let time_baseline_y = center_y + 100.;
|
let time_baseline_y = center_y + 100.;
|
||||||
|
|
||||||
|
@ -196,6 +206,23 @@ impl Splash {
|
||||||
context.move_to(time_baseline_x, time_baseline_y);
|
context.move_to(time_baseline_x, time_baseline_y);
|
||||||
let _ = context.set_source(gradient);
|
let _ = context.set_source(gradient);
|
||||||
let _ = context.show_text(&time);
|
let _ = context.show_text(&time);
|
||||||
|
};
|
||||||
|
|
||||||
|
match *s.imp().time_extents.borrow() {
|
||||||
|
Some(extents) => {
|
||||||
|
context.set_source_rgb(0.7, 0.0, 1.0);
|
||||||
|
let time_meter = SlashMeter {
|
||||||
|
orientation: gtk::Orientation::Horizontal,
|
||||||
|
start_x: center_x + extents.width() / 2. + 50.,
|
||||||
|
start_y: center_y + 100.,
|
||||||
|
count: 5,
|
||||||
|
fill_count: minutes as u8,
|
||||||
|
height: 60.,
|
||||||
|
length: 100.,
|
||||||
|
};
|
||||||
|
time_meter.draw(&context);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -308,6 +335,46 @@ impl AsymLine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SlashMeter {
|
||||||
|
orientation: gtk::Orientation,
|
||||||
|
start_x: f64,
|
||||||
|
start_y: f64,
|
||||||
|
count: u8,
|
||||||
|
fill_count: u8,
|
||||||
|
height: f64,
|
||||||
|
length: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SlashMeter {
|
||||||
|
fn draw(&self, context: &Context) {
|
||||||
|
match self.orientation {
|
||||||
|
gtk::Orientation::Horizontal => {
|
||||||
|
let angle: f64 = 0.8;
|
||||||
|
let run = self.height / angle.tan();
|
||||||
|
let width = self.length as f64 / (self.count as f64 * 2.);
|
||||||
|
|
||||||
|
for c in 0..self.count {
|
||||||
|
context.set_line_width(1.);
|
||||||
|
|
||||||
|
let start_x = self.start_x + c as f64 * width * 2.;
|
||||||
|
context.move_to(start_x, self.start_y);
|
||||||
|
context.line_to(start_x + run, self.start_y - self.height);
|
||||||
|
context.line_to(start_x + run + width, self.start_y - self.height);
|
||||||
|
context.line_to(start_x + width, self.start_y);
|
||||||
|
context.line_to(start_x, self.start_y);
|
||||||
|
if c < self.fill_count {
|
||||||
|
let _ = context.fill();
|
||||||
|
} else {
|
||||||
|
let _ = context.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtk::Orientation::Vertical => {}
|
||||||
|
_ => panic!("unknown orientation"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let app = gtk::Application::builder()
|
let app = gtk::Application::builder()
|
||||||
.application_id("com.luminescent-dreams.cyberpunk-splash")
|
.application_id("com.luminescent-dreams.cyberpunk-splash")
|
||||||
|
|
Loading…
Reference in New Issue