start work on early layout stuff

This layout stuff works by letting widgets calculate their bounding
boxes, which will be used to position the rest of the widgets. Currently
only used to position labels.
master
TheOddGarlic 2022-04-22 20:00:03 +03:00
parent 86cdd411a4
commit 889aef5cdc
8 changed files with 88 additions and 15 deletions

View File

@ -20,6 +20,8 @@ use abletk_direct2d as backend;
pub struct Renderer {
renderer: backend::Renderer,
x: u32,
y: u32,
}
impl Renderer {
@ -30,7 +32,9 @@ impl Renderer {
};
Self {
renderer: backend::Renderer::new(handle)
renderer: backend::Renderer::new(handle),
x: 0,
y: 0,
}
}
@ -43,7 +47,18 @@ impl Renderer {
}
pub fn draw_text<S: AsRef<str>>(&self, text: S) {
self.renderer.draw_text(text.as_ref())
eprintln!("drawing text at ({}, {})", self.x, self.y);
self.renderer.draw_text(
text.as_ref(),
Rect {
left: self.x as f32,
top: self.y as f32,
// these two need to be as big as possible to make sure that
// text is not cut off or wrapped
right: f32::INFINITY,
bottom: f32::INFINITY,
}
)
}
pub fn end_draw(&self) {
@ -54,6 +69,11 @@ impl Renderer {
self.renderer.fill_rect(rect)
}
pub fn position_at(&mut self, x: u32, y: u32) {
self.x = x;
self.y = y
}
pub fn resized(&mut self, width: u32, height: u32) {
self.renderer.resized(width, height)
}

View File

@ -61,21 +61,15 @@ impl Renderer {
unsafe { self.target.as_ref().unwrap().Clear(&color.into()) }
}
pub fn draw_text(&self, text: &str) {
pub fn draw_text<R: Into<D2D_RECT_F>>(&self, text: &str, layoutrect: R) {
unsafe {
self.target.as_ref().unwrap().DrawText(
// fixme: make this not hacky
&text.as_bytes().iter().map(|b| *b as u16).collect::<Vec<_>>(),
&self.text_format,
// fixme: unhardcode this (needs layout stuff probably)
&D2D_RECT_F {
left: 0.0,
top: 0.0,
right: 100.0,
bottom: 100.0,
},
&layoutrect.into(),
self.brush.as_ref().unwrap(),
D2D1_DRAW_TEXT_OPTIONS_NONE,
D2D1_DRAW_TEXT_OPTIONS_NO_SNAP,
DWRITE_MEASURING_MODE_NATURAL,
);
}
@ -196,7 +190,7 @@ fn create_text_format(factory: &IDWriteFactory, fonts: &IDWriteFontCollection)
-> IDWriteTextFormat
{
unsafe {
factory.CreateTextFormat(
let format = factory.CreateTextFormat(
"Arial",
fonts,
DWRITE_FONT_WEIGHT_NORMAL,
@ -204,6 +198,8 @@ fn create_text_format(factory: &IDWriteFactory, fonts: &IDWriteFontCollection)
DWRITE_FONT_STRETCH_NORMAL,
10.0 * 96.0 / 72.0,
"en-US",
).unwrap()
).unwrap();
format.SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP).unwrap();
format
}
}

9
src/layout/mod.rs Executable file
View File

@ -0,0 +1,9 @@
/*
* Copyright (C) 2022 Umut İnan Erdoğan <umutinanerdogan@pm.me>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
pub mod position;

37
src/layout/position.rs Executable file
View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2022 Umut İnan Erdoğan <umutinanerdogan@pm.me>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Position {
x: u32,
y: u32,
width: u32,
height: u32,
}
impl Position {
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
Position { x, y, width, height }
}
pub fn x(&self) -> u32 {
self.x
}
pub fn y(&self) -> u32 {
self.y
}
pub fn width(&self) -> u32 {
self.width
}
pub fn height(&self) -> u32 {
self.height
}
}

View File

@ -12,6 +12,7 @@ pub use abletk_common::color;
pub mod application;
pub mod context;
pub mod event;
pub mod layout;
pub mod platform;
pub mod plugin;
pub mod widget;

View File

@ -7,7 +7,7 @@
*/
use abletk_common::{Renderer, brush::Brush, color::Color};
use crate::widget::Widget;
use crate::{widget::Widget, layout::position::Position};
pub struct Label {
text: String,
@ -17,7 +17,11 @@ pub struct Label {
impl Widget for Label {
fn draw(&self, renderer: &mut Renderer) {
renderer.set_brush(Brush::Solid(self.color));
renderer.draw_text(&self.text)
renderer.draw_text(&self.text);
}
fn position(&self) -> Position {
Position::new(100, 0, 0, 0)
}
}

View File

@ -11,6 +11,9 @@ mod label;
use abletk_common::Renderer;
pub use label::*;
use crate::layout::position::Position;
pub trait Widget {
fn draw(&self, renderer: &mut Renderer);
fn position(&self) -> Position;
}

View File

@ -72,10 +72,13 @@ impl Window {
}
pub fn render(&mut self) {
let position = self.root.position();
eprintln!("Rendering window with id {:?}", self.id());
eprintln!("Root widget position: {position:?}");
self.renderer.begin_draw();
self.renderer.clear(self.background);
self.renderer.position_at(position.x(), position.y());
self.root.draw(&mut self.renderer);
self.renderer.end_draw()
}