initial text wrapping impl (resizing will break)
This commit is contained in:
@@ -14,6 +14,9 @@ pub struct Painter<'a, 'c> {
|
||||
primitives: Vec<PrimitiveHandle>,
|
||||
children: Vec<Id>,
|
||||
sized_children: HashMap<Id, UiVec2>,
|
||||
/// whether this widget depends on region's final pixel size or not
|
||||
/// TODO: decide if point (pt) should be used here instead of px
|
||||
px_dependent: bool,
|
||||
pub layer: usize,
|
||||
id: Id,
|
||||
}
|
||||
@@ -75,8 +78,10 @@ impl<'a> PainterCtx<'a> {
|
||||
text: self.text,
|
||||
textures: self.textures,
|
||||
widgets: self.widgets,
|
||||
region: UiRegion::full(),
|
||||
screen_size: self.screen_size,
|
||||
};
|
||||
let desired = ctx.size_inner(id);
|
||||
let desired = ctx.size_inner(id, active.region);
|
||||
if size != desired {
|
||||
self.redraw(rid);
|
||||
if self.drawing.contains(&id) {
|
||||
@@ -152,6 +157,7 @@ impl<'a> PainterCtx<'a> {
|
||||
ctx: self,
|
||||
children: Vec::new(),
|
||||
sized_children: Default::default(),
|
||||
px_dependent: false,
|
||||
};
|
||||
|
||||
// draw widgets
|
||||
@@ -305,9 +311,16 @@ impl<'a, 'c> Painter<'a, 'c> {
|
||||
textures: self.ctx.textures,
|
||||
widgets: self.ctx.widgets,
|
||||
checked: &mut self.sized_children,
|
||||
screen_size: self.ctx.screen_size,
|
||||
region: self.region,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn px_size(&mut self) -> Vec2 {
|
||||
self.px_dependent = true;
|
||||
self.region.in_size(self.ctx.screen_size)
|
||||
}
|
||||
|
||||
pub fn text_data(&mut self) -> &mut TextData {
|
||||
self.ctx.text
|
||||
}
|
||||
@@ -326,11 +339,16 @@ pub struct SizeCtx<'a> {
|
||||
pub textures: &'a mut Textures,
|
||||
widgets: &'a Widgets,
|
||||
checked: &'a mut HashMap<Id, UiVec2>,
|
||||
region: UiRegion,
|
||||
screen_size: Vec2,
|
||||
}
|
||||
|
||||
impl SizeCtx<'_> {
|
||||
fn size_inner(&mut self, id: Id) -> UiVec2 {
|
||||
fn size_inner(&mut self, id: Id, region: UiRegion) -> UiVec2 {
|
||||
let self_region = self.region;
|
||||
self.region = region;
|
||||
let size = self.widgets.get_dyn_dynamic(id).desired_size(self);
|
||||
self.region = self_region;
|
||||
self.checked.insert(id, size);
|
||||
size
|
||||
}
|
||||
@@ -339,7 +357,13 @@ impl SizeCtx<'_> {
|
||||
// if let Some(size) = self.checked.get(&id.id) {
|
||||
// return Some(*size);
|
||||
// }
|
||||
self.size_inner(id.id)
|
||||
self.size_inner(id.id, self.region)
|
||||
}
|
||||
pub fn size_within<W>(&mut self, id: &WidgetId<W>, region: UiRegion) -> UiVec2 {
|
||||
self.size_inner(id.id, region.within(&self.region))
|
||||
}
|
||||
pub fn px_size(&self) -> Vec2 {
|
||||
self.region.in_size(self.screen_size)
|
||||
}
|
||||
pub fn draw_text(
|
||||
&mut self,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::marker::Destruct;
|
||||
|
||||
use crate::{
|
||||
layout::{Align, Axis, Vec2},
|
||||
layout::{Align, Axis, UiNum, Vec2},
|
||||
util::{LerpUtil, impl_op},
|
||||
};
|
||||
|
||||
@@ -25,16 +27,16 @@ impl UiVec2 {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn abs(abs: Vec2) -> Self {
|
||||
pub const fn abs(abs: impl const Into<Vec2>) -> Self {
|
||||
Self {
|
||||
rel: Vec2::ZERO,
|
||||
abs,
|
||||
abs: abs.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn rel(rel: Vec2) -> Self {
|
||||
pub const fn rel(rel: impl const Into<Vec2>) -> Self {
|
||||
Self {
|
||||
rel,
|
||||
rel: rel.into(),
|
||||
abs: Vec2::ZERO,
|
||||
}
|
||||
}
|
||||
@@ -133,6 +135,15 @@ impl const From<Vec2> for UiVec2 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: const UiNum, U: const UiNum> const From<(T, U)> for UiVec2
|
||||
where
|
||||
(T, U): const Destruct,
|
||||
{
|
||||
fn from(abs: (T, U)) -> Self {
|
||||
Self::abs(abs)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct UiScalar {
|
||||
pub rel: f32,
|
||||
|
||||
@@ -26,11 +26,17 @@ pub struct TextAttrs {
|
||||
pub font_size: f32,
|
||||
pub line_height: f32,
|
||||
pub family: Family<'static>,
|
||||
pub wrap: bool,
|
||||
}
|
||||
|
||||
impl TextAttrs {
|
||||
pub fn apply(&self, font_system: &mut FontSystem, buf: &mut Buffer) {
|
||||
buf.set_metrics(font_system, Metrics::new(self.font_size, self.line_height));
|
||||
pub fn apply(&self, font_system: &mut FontSystem, buf: &mut Buffer, width: Option<f32>) {
|
||||
buf.set_metrics_and_size(
|
||||
font_system,
|
||||
Metrics::new(self.font_size, self.line_height),
|
||||
width,
|
||||
None,
|
||||
);
|
||||
let attrs = Attrs::new().family(self.family);
|
||||
let list = AttrsList::new(&attrs);
|
||||
for line in &mut buf.lines {
|
||||
@@ -49,6 +55,7 @@ impl Default for TextAttrs {
|
||||
font_size: size,
|
||||
line_height: size * 1.2,
|
||||
family: Family::SansSerif,
|
||||
wrap: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,6 +77,7 @@ impl TextData {
|
||||
cosmic_text::Color::rgba(c.r, c.g, c.b, c.a)
|
||||
};
|
||||
let mut max_width = 0.0f32;
|
||||
let mut height = 0.0;
|
||||
for run in buffer.layout_runs() {
|
||||
for glyph in run.glyphs.iter() {
|
||||
let physical_glyph = glyph.physical((0., 0.), 1.0);
|
||||
@@ -95,22 +103,19 @@ impl TextData {
|
||||
);
|
||||
}
|
||||
max_width = max_width.max(run.line_w);
|
||||
height += run.line_height;
|
||||
}
|
||||
let width = (max_x - min_x + 1) as u32;
|
||||
let height = (max_y - min_y + 1) as u32;
|
||||
let mut image = RgbaImage::new(width, height);
|
||||
let img_width = (max_x - min_x + 1) as u32;
|
||||
let img_height = (max_y - min_y + 1) as u32;
|
||||
let mut image = RgbaImage::new(img_width, img_height);
|
||||
for ((x, y), color) in pixels {
|
||||
let x = (x - min_x) as u32;
|
||||
let y = (y - min_y) as u32;
|
||||
image.put_pixel(x, y, color);
|
||||
}
|
||||
let lines = buffer.lines.len();
|
||||
let offset = TextOffset {
|
||||
top_left: Vec2::new(min_x as f32, min_y as f32),
|
||||
bot_right: Vec2::new(
|
||||
max_width - max_x as f32,
|
||||
attrs.line_height * lines as f32 - max_y as f32,
|
||||
),
|
||||
bot_right: Vec2::new(max_width - max_x as f32, height - max_y as f32),
|
||||
};
|
||||
(textures.add(image), offset)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
layout::UiNum,
|
||||
util::{DivOr, impl_op},
|
||||
};
|
||||
use std::ops::*;
|
||||
use std::{marker::Destruct, ops::*};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, PartialEq, Default, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
@@ -79,7 +79,10 @@ impl Neg for Vec2 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UiNum, U: UiNum> From<(T, U)> for Vec2 {
|
||||
impl<T: const UiNum, U: const UiNum> const From<(T, U)> for Vec2
|
||||
where
|
||||
(T, U): const Destruct,
|
||||
{
|
||||
fn from((x, y): (T, U)) -> Self {
|
||||
Self {
|
||||
x: x.to_f32(),
|
||||
|
||||
Reference in New Issue
Block a user