Compare commits

1 Commits

Author SHA1 Message Date
5785352ac0 max size + better scrolling size fn 2025-11-21 02:44:59 -05:00
7 changed files with 89 additions and 11 deletions

4
TODO
View File

@@ -4,6 +4,7 @@ images
text
figure out ways to speed up / what costs the most
resizing (per frame) is really slow (assuming painter isn't griefing)
j is weird / fix x offset
masks r just made to bare minimum work
@@ -29,6 +30,9 @@ really weird limitation:
but the child gets drawn during that, so it will think the child is still active !!!
or something like that idk, maybe I need a special enum for parent that includes a undecided state where it may or may not get redrawn by the parent
or just do ref counting and ensure all drawn things == 1 afterwards (seems like best way)
ok so I'm removing the limit for now
don't forget I'm streaming
tags
vecs for each widget type?

View File

@@ -151,7 +151,7 @@ impl Client {
})
.add(&mut ui);
let text_edit_scroll = (
msg_area,
msg_area.height(rest(1)),
(
Rect::new(Color::WHITE.darker(0.9)),
(

View File

@@ -0,0 +1,48 @@
use crate::prelude::*;
pub struct MaxSize {
pub inner: WidgetId,
pub x: Option<Len>,
pub y: Option<Len>,
}
impl MaxSize {
fn apply_to_outer(&self, ctx: &mut SizeCtx) {
if let Some(x) = self.x {
ctx.outer.x.select_len(x.apply_rest());
}
if let Some(y) = self.y {
ctx.outer.y.select_len(y.apply_rest());
}
}
}
impl Widget for MaxSize {
fn draw(&mut self, painter: &mut Painter) {
painter.widget(&self.inner);
}
fn desired_width(&mut self, ctx: &mut SizeCtx) -> Len {
self.apply_to_outer(ctx);
let width = ctx.width(&self.inner);
if let Some(x) = self.x {
let width_px = width.apply_rest().to_abs(ctx.output_size().x);
let x_px = x.apply_rest().to_abs(ctx.output_size().x);
if width_px > x_px { x } else { width }
} else {
width
}
}
fn desired_height(&mut self, ctx: &mut SizeCtx) -> Len {
self.apply_to_outer(ctx);
let height = ctx.height(&self.inner);
if let Some(y) = self.y {
let height_px = height.apply_rest().to_abs(ctx.output_size().y);
let y_px = y.apply_rest().to_abs(ctx.output_size().y);
if height_px > y_px { y } else { height }
} else {
height
}
}
}

View File

@@ -1,4 +1,5 @@
mod align;
mod max_size;
mod offset;
mod pad;
mod scroll;
@@ -7,6 +8,7 @@ mod span;
mod stack;
pub use align::*;
pub use max_size::*;
pub use offset::*;
pub use pad::*;
pub use scroll::*;

View File

@@ -28,12 +28,12 @@ impl Widget for Scroll {
painter.widget_within(&self.inner, region);
}
fn desired_width(&mut self, _: &mut SizeCtx) -> Len {
Len::default()
fn desired_width(&mut self, ctx: &mut SizeCtx) -> Len {
ctx.width(&self.inner)
}
fn desired_height(&mut self, _: &mut SizeCtx) -> Len {
Len::default()
fn desired_height(&mut self, ctx: &mut SizeCtx) -> Len {
ctx.height(&self.inner)
}
}

View File

@@ -9,6 +9,8 @@ pub trait CoreWidget<W, Tag> {
fn sized(self, size: impl Into<Size>) -> impl WidgetFn<Sized>;
fn width(self, len: impl Into<Len>) -> impl WidgetFn<Sized>;
fn height(self, len: impl Into<Len>) -> impl WidgetFn<Sized>;
fn max_width(self, width: impl Into<Len>) -> impl WidgetFn<MaxSize>;
fn max_height(self, height: impl Into<Len>) -> impl WidgetFn<MaxSize>;
fn offset(self, amt: impl Into<UiVec2>) -> impl WidgetFn<Offset>;
fn scroll(self) -> impl WidgetIdFn<Scroll>;
fn masked(self) -> impl WidgetFn<Masked>;
@@ -52,6 +54,24 @@ impl<W: WidgetLike<Tag>, Tag> CoreWidget<W::Widget, Tag> for W {
}
}
fn max_width(self, len: impl Into<Len>) -> impl WidgetFn<MaxSize> {
let len = len.into();
move |ui| MaxSize {
inner: self.add(ui).any(),
x: Some(len),
y: None,
}
}
fn max_height(self, len: impl Into<Len>) -> impl WidgetFn<MaxSize> {
let len = len.into();
move |ui| MaxSize {
inner: self.add(ui).any(),
x: None,
y: Some(len),
}
}
fn width(self, len: impl Into<Len>) -> impl WidgetFn<Sized> {
let len = len.into();
move |ui| Sized {

View File

@@ -184,12 +184,12 @@ impl<'a> PainterCtx<'a> {
// but this has a very weird issue where you can't move widgets unless u remove first
// so swapping is impossible rn I think?
// there's definitely better solutions like a counter (>1 = panic) but don't care rn
if self.draw_started.contains(&id) {
panic!(
"Cannot draw the same widget ({}) twice (1)",
self.widgets.data(&id).unwrap().label
);
}
// if self.draw_started.contains(&id) {
// panic!(
// "Cannot draw the same widget ({}) twice (1)",
// self.widgets.data(&id).unwrap().label
// );
// }
let mut old_children = old_children.unwrap_or_default();
let mut resize = ResizeRef::default();
if let Some(active) = self.active.get_mut(&id)
@@ -580,6 +580,10 @@ impl SizeCtx<'_> {
self.outer.to_abs(self.output_size)
}
pub fn output_size(&mut self) -> Vec2 {
self.output_size
}
pub fn draw_text(&mut self, buffer: &mut TextBuffer, attrs: &TextAttrs) -> TextTexture {
self.text.draw(buffer, attrs, self.textures)
}