text size calculation and very primitive row layout
This commit is contained in:
parent
f0d752570b
commit
f491fce00b
|
@ -69,6 +69,14 @@ impl Renderer {
|
||||||
self.renderer.fill_rect(rect)
|
self.renderer.fill_rect(rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_text_size(&self, text: &str) -> (u32, u32) {
|
||||||
|
self.renderer.get_text_size(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn position(&self) -> (u32, u32) {
|
||||||
|
(self.x, self.y)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn position_at(&mut self, x: u32, y: u32) {
|
pub fn position_at(&mut self, x: u32, y: u32) {
|
||||||
self.x = x;
|
self.x = x;
|
||||||
self.y = y
|
self.y = y
|
||||||
|
|
|
@ -91,6 +91,21 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_text_size(&self, text: &str) -> (u32, u32) {
|
||||||
|
let metrics = unsafe {
|
||||||
|
let layout = self.dw_factory.CreateTextLayout(
|
||||||
|
// fixme: make this not hacky
|
||||||
|
&text.as_bytes().iter().map(|b| *b as u16).collect::<Vec<_>>(),
|
||||||
|
&self.text_format,
|
||||||
|
f32::INFINITY,
|
||||||
|
f32::INFINITY,
|
||||||
|
).unwrap();
|
||||||
|
layout.GetMetrics().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
(metrics.widthIncludingTrailingWhitespace as u32, metrics.height as u32)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resized(&mut self, width: u32, height: u32) {
|
pub fn resized(&mut self, width: u32, height: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(target) = self.target.as_ref() {
|
if let Some(target) = self.target.as_ref() {
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub mod prelude {
|
||||||
pub use crate::event::window::Event as WindowEvent;
|
pub use crate::event::window::Event as WindowEvent;
|
||||||
pub use crate::platform::Platform;
|
pub use crate::platform::Platform;
|
||||||
pub use crate::widget::Label;
|
pub use crate::widget::Label;
|
||||||
|
pub use crate::widget::Row;
|
||||||
pub use crate::widget::Widget;
|
pub use crate::widget::Widget;
|
||||||
pub use crate::window::*;
|
pub use crate::window::*;
|
||||||
pub use crate::rgb;
|
pub use crate::rgb;
|
||||||
|
|
|
@ -14,6 +14,9 @@ fn launch() -> _ {
|
||||||
Application::new()
|
Application::new()
|
||||||
.apply_plugin(QuitPlugin)
|
.apply_plugin(QuitPlugin)
|
||||||
.add_window(Window::builder(
|
.add_window(Window::builder(
|
||||||
Label::new("Hello, AbleTK!")
|
Row::new()
|
||||||
.color(rgb!(0xFF00FFFF))))
|
.add(Label::new("Hello, AbleTK! ")
|
||||||
|
.color(rgb!(0xFF00FFFF)))
|
||||||
|
.add(Label::new("Hello, World!")
|
||||||
|
.color(rgb!(0x64CAFEFF)))))
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use abletk_common::{Renderer, brush::Brush, color::Color};
|
use abletk_common::{Renderer, brush::Brush, color::Color, rgb};
|
||||||
use crate::{widget::Widget, layout::position::Position};
|
use crate::{widget::Widget, layout::position::Position};
|
||||||
|
|
||||||
pub struct Label {
|
pub struct Label {
|
||||||
|
@ -20,8 +20,9 @@ impl Widget for Label {
|
||||||
renderer.draw_text(&self.text);
|
renderer.draw_text(&self.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn position(&self) -> Position {
|
fn position(&self, renderer: &mut Renderer) -> Position {
|
||||||
Position::new(100, 0, 0, 0)
|
let (width, height) = renderer.get_text_size(&self.text);
|
||||||
|
Position::new(0, 0, width, height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ impl Label {
|
||||||
pub fn new<S: Into<String>>(text: S) -> Self {
|
pub fn new<S: Into<String>>(text: S) -> Self {
|
||||||
Self {
|
Self {
|
||||||
text: text.into(),
|
text: text.into(),
|
||||||
color: Color(1.0, 1.0, 1.0, 1.0),
|
color: rgb!(0xFFFFFFFF),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mod label;
|
mod label;
|
||||||
|
mod row;
|
||||||
|
|
||||||
use abletk_common::Renderer;
|
use abletk_common::Renderer;
|
||||||
pub use label::*;
|
pub use label::*;
|
||||||
|
pub use row::*;
|
||||||
|
|
||||||
use crate::layout::position::Position;
|
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;
|
// fixme: don't pass renderer
|
||||||
|
fn position(&self, renderer: &mut Renderer) -> Position;
|
||||||
}
|
}
|
||||||
|
|
56
src/widget/row.rs
Executable file
56
src/widget/row.rs
Executable file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::{layout::position::Position, widget::Widget};
|
||||||
|
use abletk_common::Renderer;
|
||||||
|
|
||||||
|
pub struct Row {
|
||||||
|
widgets: Vec<Box<dyn Widget>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Widget for Row {
|
||||||
|
fn draw(&self, renderer: &mut Renderer) {
|
||||||
|
self.widgets.iter().for_each(|widget| {
|
||||||
|
let pos = widget.position(renderer);
|
||||||
|
renderer.position_at(
|
||||||
|
renderer.position().0 + pos.x(),
|
||||||
|
renderer.position().1 + pos.y()
|
||||||
|
);
|
||||||
|
widget.draw(renderer);
|
||||||
|
renderer.position_at(
|
||||||
|
renderer.position().0 + pos.width(),
|
||||||
|
renderer.position().1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn position(&self, renderer: &mut Renderer) -> Position {
|
||||||
|
let (width, height) = self.widgets.iter()
|
||||||
|
.map(|widget| widget.position(renderer))
|
||||||
|
.map(|pos| (pos.width(), pos.height()))
|
||||||
|
.fold((0, 0), |accum, item| (
|
||||||
|
accum.0 + item.0,
|
||||||
|
if item.1 > accum.1 { item.1 } else { accum.1 }
|
||||||
|
));
|
||||||
|
|
||||||
|
Position::new(0, 0, width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Row {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
widgets: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add<T: Widget + 'static>(mut self, widget: T) -> Self {
|
||||||
|
self.widgets.push(Box::new(widget));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
|
@ -72,7 +72,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
let position = self.root.position();
|
let position = self.root.position(&mut self.renderer);
|
||||||
eprintln!("Rendering window with id {:?}", self.id());
|
eprintln!("Rendering window with id {:?}", self.id());
|
||||||
eprintln!("Root widget position: {position:?}");
|
eprintln!("Root widget position: {position:?}");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue