Create a cyberpunk-style splash screen with a title and a countdown #39
|
@ -1,4 +1,6 @@
|
||||||
use cairo::{Context, FontFace, Format, ImageSurface, LineCap, Pattern};
|
use cairo::{
|
||||||
|
Context, FontSlant, FontWeight, Format, ImageSurface, LineCap, LinearGradient, Pattern,
|
||||||
|
};
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{prelude::*, subclass::prelude::*};
|
use gtk::{prelude::*, subclass::prelude::*};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
@ -28,24 +30,53 @@ impl SplashPrivate {
|
||||||
context.set_source_rgb(0., 0., 0.);
|
context.set_source_rgb(0., 0., 0.);
|
||||||
let _ = context.paint();
|
let _ = context.paint();
|
||||||
|
|
||||||
|
context.select_font_face("Alegreya Sans SC", FontSlant::Normal, FontWeight::Bold);
|
||||||
context.set_font_size(64.);
|
context.set_font_size(64.);
|
||||||
|
|
||||||
let title_extents = context.text_extents(&self.text.borrow()).unwrap();
|
let center_x = WIDTH as f64 / 2.;
|
||||||
|
let center_y = HEIGHT as f64 / 2.;
|
||||||
|
|
||||||
context.set_source_rgb(0.7, 0., 1.);
|
let (title_width, title_height) = {
|
||||||
context.set_line_width(5.);
|
let title_extents = context.text_extents(&self.text.borrow()).unwrap();
|
||||||
context.set_line_cap(LineCap::Round);
|
|
||||||
AsymLineReturn {
|
let title_baseline_x = center_x - title_extents.width() / 2.;
|
||||||
orientation: gtk::Orientation::Horizontal,
|
let title_baseline_y = center_y - 20.;
|
||||||
start_x: 20.,
|
|
||||||
start_y: 20.,
|
let gradient = LinearGradient::new(
|
||||||
start_length: 200.,
|
title_baseline_x,
|
||||||
center_length: title_extents.y_advance(),
|
title_baseline_y - title_extents.height(),
|
||||||
end_length: 100.,
|
title_baseline_x,
|
||||||
width: title_extents.height(),
|
title_baseline_y,
|
||||||
|
);
|
||||||
|
gradient.add_color_stop_rgb(0.2, 0.7, 0.0, 1.0);
|
||||||
|
gradient.add_color_stop_rgb(0.8, 0.2, 0.0, 1.0);
|
||||||
|
context.move_to(title_baseline_x, title_baseline_y);
|
||||||
|
let _ = context.set_source(gradient);
|
||||||
|
let _ = context.show_text(&self.text.borrow());
|
||||||
|
|
||||||
|
(title_extents.width(), title_extents.height())
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
context.set_source_rgb(0.7, 0., 1.);
|
||||||
|
context.set_line_width(5.);
|
||||||
|
context.set_line_cap(LineCap::Round);
|
||||||
|
|
||||||
|
let start_length = center_x - title_width / 2. - title_height - 20.;
|
||||||
|
|
||||||
|
AsymLineCutout {
|
||||||
|
orientation: gtk::Orientation::Horizontal,
|
||||||
|
start_x: 20.,
|
||||||
|
start_y: center_y - 20. - title_height / 2.,
|
||||||
|
start_length,
|
||||||
|
total_length: WIDTH as f64 - 120.,
|
||||||
|
cutout_length: title_width,
|
||||||
|
height: title_height,
|
||||||
|
invert: false,
|
||||||
|
}
|
||||||
|
.draw(&context);
|
||||||
|
let _ = context.stroke();
|
||||||
}
|
}
|
||||||
.draw(&context);
|
|
||||||
let _ = context.stroke();
|
|
||||||
|
|
||||||
let background = context.pop_group().unwrap();
|
let background = context.pop_group().unwrap();
|
||||||
|
|
||||||
|
@ -106,6 +137,81 @@ impl Splash {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AsymLineCutout {
|
||||||
|
orientation: gtk::Orientation,
|
||||||
|
start_x: f64,
|
||||||
|
start_y: f64,
|
||||||
|
start_length: f64,
|
||||||
|
total_length: f64,
|
||||||
|
cutout_length: f64,
|
||||||
|
height: f64,
|
||||||
|
invert: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsymLineCutout {
|
||||||
|
fn draw(&self, context: &Context) {
|
||||||
|
let dodge = if self.invert {
|
||||||
|
self.height
|
||||||
|
} else {
|
||||||
|
-self.height
|
||||||
|
};
|
||||||
|
match self.orientation {
|
||||||
|
gtk::Orientation::Horizontal => {
|
||||||
|
context.move_to(self.start_x, self.start_y);
|
||||||
|
context.line_to(self.start_x + self.start_length, self.start_y);
|
||||||
|
context.line_to(
|
||||||
|
self.start_x + self.start_length + self.height,
|
||||||
|
self.start_y + dodge,
|
||||||
|
);
|
||||||
|
context.line_to(
|
||||||
|
self.start_x + self.start_length + self.height + self.cutout_length,
|
||||||
|
self.start_y + dodge,
|
||||||
|
);
|
||||||
|
context.line_to(
|
||||||
|
self.start_x
|
||||||
|
+ self.start_length
|
||||||
|
+ self.height
|
||||||
|
+ self.cutout_length
|
||||||
|
+ (self.height / 2.),
|
||||||
|
self.start_y + dodge / 2.,
|
||||||
|
);
|
||||||
|
context.line_to(self.total_length, self.start_y + dodge / 2.);
|
||||||
|
}
|
||||||
|
gtk::Orientation::Vertical => {
|
||||||
|
/*
|
||||||
|
context.move_to(self.start_x, self.start_y);
|
||||||
|
context.line_to(self.start_x, self.start_y + self.start_length);
|
||||||
|
context.line_to(
|
||||||
|
self.start_x + self.height,
|
||||||
|
self.start_y + self.start_length + self.height,
|
||||||
|
);
|
||||||
|
context.line_to(
|
||||||
|
self.start_x + self.height,
|
||||||
|
self.start_y + self.start_length + self.height + self.center_length,
|
||||||
|
);
|
||||||
|
context.line_to(
|
||||||
|
self.start_x + self.height / 2.,
|
||||||
|
self.start_y
|
||||||
|
+ self.start_length
|
||||||
|
+ self.height
|
||||||
|
+ self.center_length
|
||||||
|
+ (self.height / 2.),
|
||||||
|
);
|
||||||
|
context.line_to(
|
||||||
|
self.start_x + self.height / 2.,
|
||||||
|
self.start_y
|
||||||
|
+ self.start_length
|
||||||
|
+ self.height
|
||||||
|
+ self.center_length
|
||||||
|
+ (self.height / 2.)
|
||||||
|
+ self.end_length,
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
_ => panic!("unknown orientation"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
struct AsymLineReturn {
|
struct AsymLineReturn {
|
||||||
orientation: gtk::Orientation,
|
orientation: gtk::Orientation,
|
||||||
start_x: f64,
|
start_x: f64,
|
||||||
|
@ -191,7 +297,7 @@ fn main() {
|
||||||
let window = gtk::ApplicationWindow::new(app);
|
let window = gtk::ApplicationWindow::new(app);
|
||||||
window.present();
|
window.present();
|
||||||
|
|
||||||
window.set_child(Some(&Splash::new("Kifu".to_owned(), "4:23".to_owned())));
|
window.set_child(Some(&Splash::new("GTK Kifu".to_owned(), "4:23".to_owned())));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
|
|
Loading…
Reference in New Issue