sizing actually working correctly now
This commit is contained in:
1 parent
b48acccb8d
commit
f9097807a2
17 files changed
+333
-194
No files matched your search
+2
-2
@@ -7,11 +7,11 @@ pub struct Aligned {
|
||||
|
||||
impl Widget for Aligned {
|
||||
fn draw(&mut self, painter: &mut Painter) {
|
||||
let region = UiRegion::from_size_align(painter.size(&self.inner), self.align);
|
||||
let region = UiRegion::from_ui_size_align(painter.size(&self.inner), self.align);
|
||||
painter.widget_within(&self.inner, region);
|
||||
}
|
||||
|
||||
fn get_size(&mut self, ctx: &mut SizeCtx) -> Vec2 {
|
||||
fn desired_size(&mut self, ctx: &mut SizeCtx) -> UiVec2 {
|
||||
ctx.size(&self.inner)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -10,8 +10,8 @@ impl Widget for Image {
|
||||
painter.texture(&self.handle);
|
||||
}
|
||||
|
||||
fn get_size(&mut self, _: &mut SizeCtx) -> Vec2 {
|
||||
self.handle.size()
|
||||
fn desired_size(&mut self, _: &mut SizeCtx) -> UiVec2 {
|
||||
UiVec2::abs(self.handle.size())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
mod align;
|
||||
mod frame;
|
||||
mod image;
|
||||
mod pad;
|
||||
mod rect;
|
||||
mod sense;
|
||||
mod sized;
|
||||
@@ -11,8 +11,8 @@ mod text_edit;
|
||||
mod trait_fns;
|
||||
|
||||
pub use align::*;
|
||||
pub use frame::*;
|
||||
pub use image::*;
|
||||
pub use pad::*;
|
||||
pub use rect::*;
|
||||
pub use sense::*;
|
||||
pub use sized::*;
|
||||
|
||||
@@ -10,10 +10,10 @@ impl Widget for Padded {
|
||||
painter.widget_within(&self.inner, self.padding.region());
|
||||
}
|
||||
|
||||
fn get_size(&mut self, ctx: &mut SizeCtx) -> Vec2 {
|
||||
fn desired_size(&mut self, ctx: &mut SizeCtx) -> UiVec2 {
|
||||
let mut size = ctx.size(&self.inner);
|
||||
size.x += self.padding.left + self.padding.right;
|
||||
size.y += self.padding.top + self.padding.bottom;
|
||||
size.abs.x += self.padding.left + self.padding.right;
|
||||
size.abs.y += self.padding.top + self.padding.bottom;
|
||||
size
|
||||
}
|
||||
}
|
||||
@@ -36,10 +36,10 @@ impl Padding {
|
||||
}
|
||||
pub fn region(&self) -> UiRegion {
|
||||
let mut region = UiRegion::full();
|
||||
region.top_left.offset.x += self.left;
|
||||
region.top_left.offset.y += self.top;
|
||||
region.bot_right.offset.x -= self.right;
|
||||
region.bot_right.offset.y -= self.bottom;
|
||||
region.top_left.abs.x += self.left;
|
||||
region.top_left.abs.y += self.top;
|
||||
region.bot_right.abs.x -= self.right;
|
||||
region.bot_right.abs.y -= self.bottom;
|
||||
region
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -10,7 +10,7 @@ impl Widget for Sized {
|
||||
painter.widget(&self.inner);
|
||||
}
|
||||
|
||||
fn get_size(&mut self, _: &mut SizeCtx) -> Vec2 {
|
||||
self.size
|
||||
fn desired_size(&mut self, _: &mut SizeCtx) -> UiVec2 {
|
||||
UiVec2::abs(self.size)
|
||||
}
|
||||
}
|
||||
+27
-27
@@ -8,34 +8,30 @@ pub struct Span {
|
||||
impl Widget for Span {
|
||||
fn draw(&mut self, painter: &mut Painter) {
|
||||
let total = self.setup(&mut painter.size_ctx());
|
||||
let mut start = UIScalar::min();
|
||||
let mut start = UiScalar::rel_min();
|
||||
for (child, length) in &self.children {
|
||||
let mut child_region = UiRegion::full();
|
||||
let mut axis = child_region.axis_mut(self.dir.axis);
|
||||
axis.top_left.set(start);
|
||||
match *length {
|
||||
SpanLen::Fixed(offset) => {
|
||||
start.offset += offset;
|
||||
*axis.bot_right.offset = start.offset;
|
||||
*axis.bot_right.anchor = *axis.top_left.anchor;
|
||||
start.abs += offset;
|
||||
}
|
||||
SpanLen::Ratio(ratio) => {
|
||||
let offset = UIScalar::new(total.relative, total.fixed);
|
||||
let rel_end = UIScalar::from_anchor(ratio / total.ratio);
|
||||
start = rel_end.within(start, (UIScalar::max() + start) - offset);
|
||||
axis.bot_right.set(start);
|
||||
let offset = UiScalar::new(total.rel, total.abs);
|
||||
let rel_end = UiScalar::from_anchor(ratio / total.ratio);
|
||||
start = rel_end.within(start, (UiScalar::rel_max() + start) - offset);
|
||||
}
|
||||
SpanLen::Relative(rel) => {
|
||||
start.anchor += rel;
|
||||
axis.bot_right.set(start);
|
||||
start.rel += rel;
|
||||
}
|
||||
SpanLen::Sized(size) => {
|
||||
let offset = size.axis(self.dir.axis);
|
||||
start.offset += offset;
|
||||
*axis.bot_right.offset = start.offset;
|
||||
*axis.bot_right.anchor = *axis.top_left.anchor;
|
||||
let size_axis = size.axis(self.dir.axis);
|
||||
start.abs += size_axis.abs;
|
||||
start.rel += size_axis.rel;
|
||||
}
|
||||
}
|
||||
axis.bot_right.set(start);
|
||||
if self.dir.sign == Sign::Neg {
|
||||
child_region.flip();
|
||||
}
|
||||
@@ -43,24 +39,28 @@ impl Widget for Span {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_size(&mut self, ctx: &mut SizeCtx) -> Vec2 {
|
||||
fn desired_size(&mut self, ctx: &mut SizeCtx) -> UiVec2 {
|
||||
let total = self.setup(ctx);
|
||||
let axis = self.dir.axis;
|
||||
let dir_len = if total.ratio != 0.0 {
|
||||
ctx.size.axis(axis)
|
||||
UiScalar::rel_max()
|
||||
} else {
|
||||
total.fixed + total.relative * ctx.size.axis(axis)
|
||||
UiScalar::new(total.rel, total.abs)
|
||||
};
|
||||
Vec2::from_axis(axis, dir_len, total.max_sized)
|
||||
let mut max_ortho = UiScalar::default();
|
||||
for (child, _) in &self.children {
|
||||
let size = ctx.size(child);
|
||||
max_ortho = max_ortho.max(size.axis(!self.dir.axis));
|
||||
}
|
||||
UiVec2::from_axis(axis, dir_len, max_ortho)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SpanLenSums {
|
||||
pub fixed: f32,
|
||||
pub abs: f32,
|
||||
pub ratio: f32,
|
||||
pub relative: f32,
|
||||
pub max_sized: f32,
|
||||
pub rel: f32,
|
||||
}
|
||||
|
||||
impl Span {
|
||||
@@ -76,15 +76,15 @@ impl Span {
|
||||
.iter_mut()
|
||||
.fold(SpanLenSums::default(), |mut s, (id, l)| {
|
||||
match l {
|
||||
SpanLen::Fixed(v) => s.fixed += *v,
|
||||
SpanLen::Fixed(v) => s.abs += *v,
|
||||
SpanLen::Ratio(v) => s.ratio += *v,
|
||||
SpanLen::Relative(v) => s.relative += *v,
|
||||
SpanLen::Relative(v) => s.rel += *v,
|
||||
SpanLen::Sized(v) => {
|
||||
let size = ctx.size(id);
|
||||
let len = size.axis(self.dir.axis);
|
||||
s.max_sized = s.max_sized.max(size.axis(!self.dir.axis));
|
||||
*v = size;
|
||||
s.fixed += len;
|
||||
s.abs += len.abs;
|
||||
s.rel += len.rel;
|
||||
}
|
||||
}
|
||||
s
|
||||
@@ -105,7 +105,7 @@ pub enum SpanLen {
|
||||
/// size determined by the child widget itself
|
||||
/// the value is not used externally, I just don't wanna make a duplicate enum
|
||||
/// there are util functions instead so
|
||||
Sized(Vec2),
|
||||
Sized(UiVec2),
|
||||
}
|
||||
|
||||
pub fn fixed<N: UiNum>(x: N) -> SpanLen {
|
||||
@@ -121,7 +121,7 @@ pub fn relative<N: UiNum>(x: N) -> SpanLen {
|
||||
}
|
||||
|
||||
pub fn sized() -> SpanLen {
|
||||
SpanLen::Sized(Vec2::ZERO)
|
||||
SpanLen::Sized(UiVec2::default())
|
||||
}
|
||||
|
||||
impl<N: UiNum> From<N> for SpanLen {
|
||||
|
||||
+4
-4
@@ -66,15 +66,15 @@ impl Widget for Text {
|
||||
let dims = handle.size();
|
||||
self.size = offset.size(&handle);
|
||||
let mut region = self.region();
|
||||
region.top_left.offset += offset.top_left;
|
||||
region.bot_right.offset = region.top_left.offset + dims;
|
||||
region.top_left.abs += offset.top_left;
|
||||
region.bot_right.abs = region.top_left.abs + dims;
|
||||
painter.texture_within(&handle, region);
|
||||
}
|
||||
|
||||
fn get_size(&mut self, ctx: &mut SizeCtx) -> Vec2 {
|
||||
fn desired_size(&mut self, ctx: &mut SizeCtx) -> UiVec2 {
|
||||
self.update_buf(&mut ctx.text.font_system);
|
||||
let (handle, offset) = ctx.draw_text(&mut self.buf, &self.attrs);
|
||||
offset.size(&handle)
|
||||
UiVec2::abs(offset.size(&handle))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-5
@@ -24,16 +24,17 @@ impl TextEdit {
|
||||
impl Widget for TextEdit {
|
||||
fn draw(&mut self, painter: &mut Painter) {
|
||||
let font_system = &mut painter.text_data().font_system;
|
||||
self.buf.shape_until_scroll(font_system, false);
|
||||
self.attrs.apply(font_system, &mut self.buf);
|
||||
self.buf.shape_until_scroll(font_system, false);
|
||||
let (handle, tex_offset) = painter.render_text(&mut self.buf, &self.attrs);
|
||||
let dims = handle.size();
|
||||
self.size = tex_offset.size(&handle);
|
||||
let region = self.region();
|
||||
let mut tex_region = region;
|
||||
tex_region.top_left.offset += tex_offset.top_left;
|
||||
tex_region.bot_right.offset = tex_region.top_left.offset + dims;
|
||||
tex_region.top_left.abs += tex_offset.top_left;
|
||||
tex_region.bot_right.abs = tex_region.top_left.abs + dims;
|
||||
painter.texture_within(&handle, tex_region);
|
||||
|
||||
if let Some(cursor) = &self.cursor
|
||||
&& let Some(pos) = cursor_pos(cursor, &self.buf)
|
||||
{
|
||||
@@ -45,12 +46,15 @@ impl Widget for TextEdit {
|
||||
.shifted(offset)
|
||||
.within(®ion),
|
||||
);
|
||||
} else {
|
||||
// keep number of primitives constant so shifting isn't needed
|
||||
painter.primitive(RectPrimitive::color(Color::NONE));
|
||||
}
|
||||
}
|
||||
|
||||
fn get_size(&mut self, ctx: &mut SizeCtx) -> Vec2 {
|
||||
fn desired_size(&mut self, ctx: &mut SizeCtx) -> UiVec2 {
|
||||
let (handle, offset) = ctx.draw_text(&mut self.buf, &self.attrs);
|
||||
offset.size(&handle)
|
||||
UiVec2::abs(offset.size(&handle))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +109,10 @@ impl TextEditBuilder {
|
||||
self.attrs.line_height = height;
|
||||
self
|
||||
}
|
||||
pub fn text_align(mut self, align: Align) -> Self {
|
||||
self.align = align;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TextEditCtx<'a> {
|
||||
@@ -113,6 +121,21 @@ pub struct TextEditCtx<'a> {
|
||||
}
|
||||
|
||||
impl<'a> TextEditCtx<'a> {
|
||||
pub fn take(&mut self) -> String {
|
||||
let text = self
|
||||
.text
|
||||
.buf
|
||||
.lines
|
||||
.drain(..)
|
||||
.map(|l| l.into_text())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
self.text
|
||||
.buf
|
||||
.set_text(self.font_system, "", &Attrs::new(), Shaping::Advanced);
|
||||
text
|
||||
}
|
||||
|
||||
pub fn motion(&mut self, motion: Motion) {
|
||||
if let Some(cursor) = self.text.cursor
|
||||
&& let Some((cursor, _)) =
|
||||
|
||||
Reference in new issue
Block a user