add offset / scrolling + clipboard support

This commit is contained in:
2025-09-27 21:13:00 -04:00
parent 95f049acb4
commit 5445008528
16 changed files with 386 additions and 99 deletions

View File

@@ -85,7 +85,7 @@ pub enum Align {
}
impl Align {
pub const fn anchor(&self) -> Vec2 {
pub const fn rel(&self) -> Vec2 {
match self {
Self::TopLeft => vec2(0.0, 0.0),
Self::Top => vec2(0.5, 0.0),

View File

@@ -131,7 +131,9 @@ impl<'a> PainterCtx<'a> {
if active.region == region {
return;
} else if active.region.size() == region.size() {
self.mov(id, region);
// TODO: epsilon?
let from = active.region;
self.mov(id, from, region);
return;
}
let active = self.remove(id).unwrap();
@@ -185,22 +187,21 @@ impl<'a> PainterCtx<'a> {
self.active.insert(id, instance);
}
fn mov(&mut self, id: Id, to: UiRegion) {
fn mov(&mut self, id: Id, from: UiRegion, to: UiRegion) {
let active = self.active.get_mut(&id).unwrap();
// children will not be changed, so this technically should not be needed
// probably need unsafe
let from = active.region;
for h in &active.primitives {
let region = self.layers[h.layer].primitives.region_mut(h);
*region = region.outside(&from).within(&to);
}
active.region = to;
active.region = active.region.outside(&from).within(&to);
for m in self.modules.iter_mut() {
m.on_move(active);
}
let children = active.children.clone();
for child in children {
self.mov(child, to);
self.mov(child, from, to);
}
}

View File

@@ -11,23 +11,20 @@ pub struct UiVec2 {
}
impl UiVec2 {
pub const ZERO: Self = Self {
rel: Vec2::ZERO,
abs: Vec2::ZERO,
};
/// expands this position into a sized region centered at self
pub fn expand(&self, size: impl Into<Vec2>) -> UiRegion {
let size = size.into();
UiRegion {
top_left: self.shifted(-size / 2.0),
bot_right: self.shifted(size / 2.0),
top_left: self.offset(-size / 2.0),
bot_right: self.offset(size / 2.0),
}
}
pub const fn anchor(anchor: Vec2) -> Self {
Self::rel(anchor)
}
pub const fn offset(offset: Vec2) -> Self {
Self::abs(offset)
}
pub const fn abs(abs: Vec2) -> Self {
Self {
rel: Vec2::ZERO,
@@ -42,11 +39,12 @@ impl UiVec2 {
}
}
pub const fn shift(&mut self, offset: impl const Into<Vec2>) {
self.abs += offset.into();
pub const fn shift(&mut self, offset: impl const Into<UiVec2>) {
let offset = offset.into();
*self += offset;
}
pub const fn shifted(mut self, offset: Vec2) -> Self {
pub const fn offset(mut self, offset: impl const Into<UiVec2>) -> Self {
self.shift(offset);
self
}
@@ -118,7 +116,7 @@ impl_op!(UiVec2 Sub sub; rel abs);
impl const From<Align> for UiVec2 {
fn from(align: Align) -> Self {
Self::anchor(align.anchor())
Self::rel(align.rel())
}
}
@@ -128,6 +126,12 @@ impl Align {
}
}
impl const From<Vec2> for UiVec2 {
fn from(abs: Vec2) -> Self {
Self::abs(abs)
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct UiScalar {
pub rel: f32,
@@ -198,10 +202,10 @@ impl UiRegion {
bot_right: Align::BotRight.into(),
}
}
pub fn anchor(anchor: Vec2) -> Self {
pub fn rel(anchor: Vec2) -> Self {
Self {
top_left: UiVec2::anchor(anchor),
bot_right: UiVec2::anchor(anchor),
top_left: UiVec2::rel(anchor),
bot_right: UiVec2::rel(anchor),
}
}
pub fn within(&self, parent: &Self) -> Self {
@@ -229,13 +233,13 @@ impl UiRegion {
std::mem::swap(&mut self.top_left, &mut self.bot_right);
}
pub fn shift(&mut self, offset: impl Into<Vec2>) {
pub fn shift(&mut self, offset: impl Into<UiVec2>) {
let offset = offset.into();
self.top_left.shift(offset);
self.bot_right.shift(offset);
}
pub fn shifted(mut self, offset: impl Into<Vec2>) -> Self {
pub fn offset(mut self, offset: impl Into<UiVec2>) -> Self {
self.shift(offset);
self
}
@@ -265,9 +269,9 @@ impl UiRegion {
pub fn from_size_align(size: Vec2, align: Align) -> Self {
let mut top_left = UiVec2::from(align);
top_left.abs -= size * align.anchor();
top_left.abs -= size * align.rel();
let mut bot_right = UiVec2::from(align);
bot_right.abs += size * (Vec2::ONE - align.anchor());
bot_right.abs += size * (Vec2::ONE - align.rel());
Self {
top_left,
bot_right,
@@ -276,11 +280,11 @@ impl UiRegion {
pub fn from_ui_size_align(size: UiVec2, align: Align) -> Self {
let mut top_left = UiVec2::from(align);
top_left.abs -= size.abs * align.anchor();
top_left.rel -= size.rel * align.anchor();
top_left.abs -= size.abs * align.rel();
top_left.rel -= size.rel * align.rel();
let mut bot_right = UiVec2::from(align);
bot_right.abs += size.abs * (Vec2::ONE - align.anchor());
bot_right.rel += size.rel * (Vec2::ONE - align.anchor());
bot_right.abs += size.abs * (Vec2::ONE - align.rel());
bot_right.rel += size.rel * (Vec2::ONE - align.rel());
Self {
top_left,
bot_right,