183 lines
4.3 KiB
Rust
183 lines
4.3 KiB
Rust
use raqote::{DrawTarget, Source, DrawOptions, Color};
|
|
|
|
use crate::wayland::{
|
|
draw::{Draw, DrawArea},
|
|
Position,
|
|
};
|
|
|
|
pub(super) struct UIColors {
|
|
draw_area: Color,
|
|
button: Color,
|
|
button_accent: Color,
|
|
background: Color,
|
|
_text_area: Color,
|
|
_symbol: Color,
|
|
_text: Color,
|
|
}
|
|
|
|
impl Default for UIColors {
|
|
fn default() -> Self {
|
|
Self {
|
|
draw_area: Color::new(0xff, 0x15, 0x15, 0x15),
|
|
button: Color::new(0xff, 0x22, 0x22, 0x22),
|
|
button_accent: Color::new(0xff, 0x33, 0x33, 0x33),
|
|
background: Color::new(0xff, 0x11, 0x11, 0x11),
|
|
_text_area: Color::new(0xff, 0x33, 0x33, 0x33),
|
|
_symbol: Color::new(0xff, 0xcc, 0xcc, 0xcc),
|
|
_text: Color::new(0xff, 0xdd, 0xdd, 0xdd),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(super) enum Widget {
|
|
Button(Button),
|
|
TextArea(TextArea)
|
|
}
|
|
|
|
pub(super) struct Window {
|
|
pub(super) width: usize,
|
|
pub(super) height: usize,
|
|
pub(super) widgets: Vec<Widget>,
|
|
pub(super) draw_area: DrawArea,
|
|
pub(super) colors: UIColors,
|
|
pub(super) options: DrawOptions,
|
|
}
|
|
|
|
impl Window {
|
|
pub(super) fn new(width: usize, height: usize, draw_area: DrawArea) -> Self {
|
|
Self {
|
|
width,
|
|
height,
|
|
widgets: Vec::new(),
|
|
draw_area,
|
|
colors: UIColors::default(),
|
|
options: DrawOptions::new(),
|
|
}
|
|
}
|
|
|
|
pub(super) fn add_widget(&mut self, widget: Widget) {
|
|
self.widgets.push(widget);
|
|
}
|
|
|
|
pub(super) fn render(&self, canvas: &mut [u8]) {
|
|
|
|
// TODO: Make sure this is actually safe
|
|
let draw_buffer: &mut [u32] = unsafe {canvas.align_to_mut::<u32>().1};
|
|
|
|
let mut target = DrawTarget::from_backing(self.width as i32, self.height as i32, draw_buffer);
|
|
|
|
target.fill_rect(
|
|
0.0,
|
|
0.0,
|
|
self.width as f32,
|
|
self.height as f32,
|
|
&Source::Solid(self.colors.background.into()),
|
|
&self.options
|
|
);
|
|
|
|
self.draw_area.render(&mut target);
|
|
|
|
for widget in self.widgets.iter() {
|
|
match widget {
|
|
Widget::Button(button) => button.render(&mut target),
|
|
Widget::TextArea(text_area) => text_area.render(&mut target),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
pub(super) struct ButtonColors {
|
|
background: Color,
|
|
border: Color,
|
|
glyph: Color,
|
|
}
|
|
|
|
impl Default for ButtonColors {
|
|
fn default() -> Self {
|
|
Self {
|
|
background: Color::new(0xff, 0x25, 0x2c, 0x33),
|
|
border: Color::new(0xff, 0x77, 0x7f, 0x97),
|
|
glyph: Color::new(0xff, 0xea, 0xea, 0xe6),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(super) struct Button {
|
|
pub(super) width: f32,
|
|
pub(super) height: f32,
|
|
pub(super) position: Position,
|
|
pub(super) shape: raqote::Path,
|
|
pub(super) colors: ButtonColors,
|
|
pub(super) options: DrawOptions,
|
|
}
|
|
|
|
impl Button {
|
|
fn background_source(&self) -> Source {
|
|
Source::Solid(self.colors.background.into())
|
|
}
|
|
|
|
pub(crate) fn contains_point(&self, point: Position) -> bool {
|
|
self.shape.contains_point(0.1, point.x, point.y)
|
|
}
|
|
}
|
|
|
|
|
|
impl Draw for Button {
|
|
fn render(&self, area: &mut DrawTarget<&mut [u32]>) {
|
|
|
|
area.fill(
|
|
&self.shape,
|
|
&self.background_source(),
|
|
&self.options,
|
|
);
|
|
}
|
|
}
|
|
|
|
pub(super) struct TextAreaColors {
|
|
pub(super) background: Color,
|
|
pub(super) text: Color,
|
|
}
|
|
|
|
impl Default for TextAreaColors {
|
|
fn default() -> Self {
|
|
Self {
|
|
background: Color::new(0xff, 0x25, 0x2c, 0x33),
|
|
text: Color::new(0xff, 0xfc, 0xf8, 0xef),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(super) struct TextArea {
|
|
pub(super) width: f32,
|
|
pub(super) height: f32,
|
|
pub(super) position: Position,
|
|
pub(super) colors: TextAreaColors,
|
|
pub(super) options: DrawOptions,
|
|
}
|
|
|
|
impl TextArea {
|
|
pub(super) fn text_source(&self) -> Source {
|
|
Source::Solid(self.colors.text.into())
|
|
}
|
|
|
|
pub(super) fn background_source(&self) -> Source {
|
|
Source::Solid(self.colors.background.into())
|
|
}
|
|
}
|
|
|
|
impl Draw for TextArea {
|
|
fn render(&self, area: &mut DrawTarget<&mut [u32]>) {
|
|
|
|
area.fill_rect(
|
|
self.position.x,
|
|
self.position.y,
|
|
self.width,
|
|
self.height,
|
|
&self.background_source(),
|
|
&self.options,
|
|
);
|
|
}
|
|
}
|
|
|