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.
This commit is contained in:
parent
86cdd411a4
commit
889aef5cdc
|
@ -20,6 +20,8 @@ use abletk_direct2d as backend;
|
||||||
|
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
renderer: backend::Renderer,
|
renderer: backend::Renderer,
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
|
@ -30,7 +32,9 @@ impl Renderer {
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
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) {
|
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) {
|
pub fn end_draw(&self) {
|
||||||
|
@ -54,6 +69,11 @@ impl Renderer {
|
||||||
self.renderer.fill_rect(rect)
|
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) {
|
pub fn resized(&mut self, width: u32, height: u32) {
|
||||||
self.renderer.resized(width, height)
|
self.renderer.resized(width, height)
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,21 +61,15 @@ impl Renderer {
|
||||||
unsafe { self.target.as_ref().unwrap().Clear(&color.into()) }
|
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 {
|
unsafe {
|
||||||
self.target.as_ref().unwrap().DrawText(
|
self.target.as_ref().unwrap().DrawText(
|
||||||
// fixme: make this not hacky
|
// fixme: make this not hacky
|
||||||
&text.as_bytes().iter().map(|b| *b as u16).collect::<Vec<_>>(),
|
&text.as_bytes().iter().map(|b| *b as u16).collect::<Vec<_>>(),
|
||||||
&self.text_format,
|
&self.text_format,
|
||||||
// fixme: unhardcode this (needs layout stuff probably)
|
&layoutrect.into(),
|
||||||
&D2D_RECT_F {
|
|
||||||
left: 0.0,
|
|
||||||
top: 0.0,
|
|
||||||
right: 100.0,
|
|
||||||
bottom: 100.0,
|
|
||||||
},
|
|
||||||
self.brush.as_ref().unwrap(),
|
self.brush.as_ref().unwrap(),
|
||||||
D2D1_DRAW_TEXT_OPTIONS_NONE,
|
D2D1_DRAW_TEXT_OPTIONS_NO_SNAP,
|
||||||
DWRITE_MEASURING_MODE_NATURAL,
|
DWRITE_MEASURING_MODE_NATURAL,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +190,7 @@ fn create_text_format(factory: &IDWriteFactory, fonts: &IDWriteFontCollection)
|
||||||
-> IDWriteTextFormat
|
-> IDWriteTextFormat
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
factory.CreateTextFormat(
|
let format = factory.CreateTextFormat(
|
||||||
"Arial",
|
"Arial",
|
||||||
fonts,
|
fonts,
|
||||||
DWRITE_FONT_WEIGHT_NORMAL,
|
DWRITE_FONT_WEIGHT_NORMAL,
|
||||||
|
@ -204,6 +198,8 @@ fn create_text_format(factory: &IDWriteFactory, fonts: &IDWriteFontCollection)
|
||||||
DWRITE_FONT_STRETCH_NORMAL,
|
DWRITE_FONT_STRETCH_NORMAL,
|
||||||
10.0 * 96.0 / 72.0,
|
10.0 * 96.0 / 72.0,
|
||||||
"en-US",
|
"en-US",
|
||||||
).unwrap()
|
).unwrap();
|
||||||
|
format.SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP).unwrap();
|
||||||
|
format
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
src/layout/mod.rs
Executable file
9
src/layout/mod.rs
Executable 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
37
src/layout/position.rs
Executable 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ pub use abletk_common::color;
|
||||||
pub mod application;
|
pub mod application;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
|
pub mod layout;
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
pub mod widget;
|
pub mod widget;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use abletk_common::{Renderer, brush::Brush, color::Color};
|
use abletk_common::{Renderer, brush::Brush, color::Color};
|
||||||
use crate::widget::Widget;
|
use crate::{widget::Widget, layout::position::Position};
|
||||||
|
|
||||||
pub struct Label {
|
pub struct Label {
|
||||||
text: String,
|
text: String,
|
||||||
|
@ -17,7 +17,11 @@ pub struct Label {
|
||||||
impl Widget for Label {
|
impl Widget for Label {
|
||||||
fn draw(&self, renderer: &mut Renderer) {
|
fn draw(&self, renderer: &mut Renderer) {
|
||||||
renderer.set_brush(Brush::Solid(self.color));
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ mod label;
|
||||||
use abletk_common::Renderer;
|
use abletk_common::Renderer;
|
||||||
pub use label::*;
|
pub use label::*;
|
||||||
|
|
||||||
|
use crate::layout::position::Position;
|
||||||
|
|
||||||
pub trait Widget {
|
pub trait Widget {
|
||||||
fn draw(&self, renderer: &mut Renderer);
|
fn draw(&self, renderer: &mut Renderer);
|
||||||
|
fn position(&self) -> Position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,10 +72,13 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
|
let position = self.root.position();
|
||||||
eprintln!("Rendering window with id {:?}", self.id());
|
eprintln!("Rendering window with id {:?}", self.id());
|
||||||
|
eprintln!("Root widget position: {position:?}");
|
||||||
|
|
||||||
self.renderer.begin_draw();
|
self.renderer.begin_draw();
|
||||||
self.renderer.clear(self.background);
|
self.renderer.clear(self.background);
|
||||||
|
self.renderer.position_at(position.x(), position.y());
|
||||||
self.root.draw(&mut self.renderer);
|
self.root.draw(&mut self.renderer);
|
||||||
self.renderer.end_draw()
|
self.renderer.end_draw()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue