Move to raqote for rendering

This commit is contained in:
2024-04-26 21:36:29 -05:00
parent 60aff508bd
commit f7490d00c3
6 changed files with 724 additions and 125 deletions

View File

@@ -0,0 +1,335 @@
use crate::wayland::pixel::{Pixel, Box, BoxMut, PixelEncoding};
use raqote::{DrawTarget, PathBuilder, Source, StrokeStyle, DrawOptions, SolidSource, Color};
struct UIColor {
draw_area: Color,
button: Color,
button_accent: Color,
background: Color,
_text_area: Color,
_symbol: Color,
_text: Color,
}
impl Default for UIColor {
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) struct Window<'a, 'b> {
pub(super) draw: DrawTarget<&'a mut [u32]>,
pub(super) options: DrawOptions,
pub(super) colors: UIColor,
pub(super) widgets: Vec<Widget<'b>>,
pub(super) width: usize,
pub(super) height: usize,
}
impl<'a, 'b> Window<'a, 'b> {
pub(super) fn new(buffer: &'a mut [u32], width: usize, height: usize) -> Self {
Self {
draw: DrawTarget::from_backing(width.try_into().unwrap(), height.try_into().unwrap(), buffer),
options: DrawOptions::new(),
colors: UIColor::default(),
widgets: Vec::new(),
width,
height,
}
}
pub(super) fn add_widget(&mut self, widget: Widget<'b>) {
self.widgets.push(widget);
}
pub(super) fn render(&mut self) {
self.draw.fill_rect(
0.0,
0.0,
self.width as f32,
self.height as f32,
&Source::Solid(self.colors.background.into()),
&self.options
);
for widget in self.widgets.iter() {
match widget {
Widget::Button(button) => button.render(&mut self.draw),
Widget::DrawArea(draw_area) => draw_area.render(&mut self.draw),
Widget::TextArea(text_area) => text_area.render(&mut self.draw),
}
}
}
}
pub(super) struct Position {
pub(super) x: f32,
pub(super) y: f32,
}
impl Position {
pub(super) fn new(x: f32, y: f32) -> Self {
Position { x, y }
}
}
pub(super) enum Widget<'a> {
Button(Button<'a>),
DrawArea(DrawArea<'a>),
TextArea(TextArea<'a>)
}
pub(super) trait Draw {
fn render(&self, area: &mut DrawTarget<&mut [u32]>);
}
pub(super) struct Button<'a> {
pub(super) width: f32,
pub(super) height: f32,
pub(super) position: Position,
pub(super) source: Source<'a>,
pub(super) options: DrawOptions,
}
pub(super) struct ButtonBuilder<'a> {
pub(super) width: Option<f32>,
pub(super) height: Option<f32>,
pub(super) position: Option<Position>,
pub(super) source: Option<Source<'a>>,
pub(super) color: Option<Color>,
pub(super) options: Option<DrawOptions>,
}
impl<'a> ButtonBuilder<'a> {
pub(super) fn new() -> Self {
Self {
width: None,
height: None,
position: None,
source: None,
color: None,
options: None,
}
}
pub(super) fn width(&mut self, width: f32) {
self.width = Some(width)
}
pub(super) fn height(&mut self, height: f32) {
self.height = Some(height)
}
pub(super) fn position(&mut self, x: f32, y: f32) {
self.position = Some(Position::new(x, y))
}
pub(super) fn source(&mut self, source: Source<'a>) {
self.source = Some(source);
}
pub(super) fn color(&mut self, r: u8, g: u8, b: u8) {
self.color = Some(Color::new(0xff, r, g, b))
}
pub(super) fn finish(self) -> Widget<'a> {
Widget::Button(
Button {
width: self.width.expect("Button must have width"),
height: self.height.expect("Button must have height"),
position: self.position.expect("Button must have a position"),
source: self.source.unwrap_or(
Source::Solid(
self.color.unwrap_or(Color::new(0xff, 0x00, 0x00, 0x00)).into()
)
),
options: self.options.unwrap_or(DrawOptions::new()),
}
)
}
}
impl<'a> Draw for Button<'a> {
fn render(&self, area: &mut DrawTarget<&mut [u32]>) {
(*area).fill_rect(
self.position.x,
self.position.y,
self.width,
self.height,
&self.source,
&self.options,
)
}
}
pub(super) struct DrawArea<'a> {
pub(super) width: f32,
pub(super) height: f32,
pub(super) position: Position,
pub(super) source: Source<'a>,
pub(super) options: DrawOptions,
}
pub(super) struct DrawAreaBuilder<'a> {
pub(super) width: Option<f32>,
pub(super) height: Option<f32>,
pub(super) position: Option<Position>,
pub(super) source: Option<Source<'a>>,
pub(super) color: Option<Color>,
pub(super) options: Option<DrawOptions>,
}
impl<'a> DrawAreaBuilder<'a> {
pub(super) fn new() -> Self {
Self {
width: None,
height: None,
position: None,
source: None,
color: None,
options: None,
}
}
pub(super) fn width(&mut self, width: f32) {
self.width = Some(width)
}
pub(super) fn height(&mut self, height: f32) {
self.height = Some(height)
}
pub(super) fn position(&mut self, x: f32, y: f32) {
self.position = Some(Position::new(x, y))
}
pub(super) fn source(&mut self, source: Source<'a>) {
self.source = Some(source);
}
pub(super) fn color(&mut self, r: u8, g: u8, b: u8) {
self.color = Some(Color::new(0xff, r, g, b))
}
pub(super) fn finish(self) -> Widget<'a> {
Widget::DrawArea(
DrawArea {
width: self.width.expect("Draw area must have width"),
height: self.height.expect("Draw area must have height"),
position: self.position.expect("Draw area must have a position"),
source: self.source.unwrap_or(
Source::Solid(
self.color.unwrap_or(Color::new(0xff, 0x00, 0x00, 0x00)).into()
)
),
options: self.options.unwrap_or(DrawOptions::new()),
}
)
}
}
impl<'a> Draw for DrawArea<'a> {
fn render(&self, area: &mut DrawTarget<&mut [u32]>) {
area.fill_rect(
self.position.x,
self.position.y,
self.width,
self.height,
&self.source,
&self.options,
)
}
}
pub(super) struct TextArea<'a> {
pub(super) width: f32,
pub(super) height: f32,
pub(super) position: Position,
pub(super) source: Source<'a>,
pub(super) options: DrawOptions,
}
pub(super) struct TextAreaBuilder<'a> {
pub(super) width: Option<f32>,
pub(super) height: Option<f32>,
pub(super) position: Option<Position>,
pub(super) source: Option<Source<'a>>,
pub(super) color: Option<Color>,
pub(super) options: Option<DrawOptions>,
}
impl<'a> TextAreaBuilder<'a> {
pub(super) fn new() -> Self {
Self {
width: None,
height: None,
position: None,
source: None,
color: None,
options: None,
}
}
pub(super) fn width(&mut self, width: f32) {
self.width = Some(width)
}
pub(super) fn height(&mut self, height: f32) {
self.height = Some(height)
}
pub(super) fn position(&mut self, x: f32, y: f32) {
self.position = Some(Position::new(x, y))
}
pub(super) fn source(&mut self, source: Source<'a>) {
self.source = Some(source);
}
pub(super) fn color(&mut self, r: u8, g: u8, b: u8) {
self.color = Some(Color::new(0xff, r, g, b))
}
pub(super) fn finish(self) -> Widget<'a> {
Widget::TextArea(
TextArea {
width: self.width.expect("Button must have width"),
height: self.height.expect("Button must have height"),
position: self.position.expect("Button must have a position"),
source: self.source.unwrap_or(
Source::Solid(
self.color.unwrap_or(Color::new(0xff, 0x00, 0x00, 0x00)).into()
)
),
options: self.options.unwrap_or(DrawOptions::new()),
}
)
}
}
impl<'a> Draw for TextArea<'a> {
fn render(&self, area: &mut DrawTarget<&mut [u32]>) {
(*area).fill_rect(
self.position.x,
self.position.y,
self.width,
self.height,
&self.source,
&self.options,
)
}
}