use super::types::{PixelRect, UiDirection, UiLayout, UiSizing};
#[derive(Clone, Debug)]
pub(super) struct PanelScope {
pub(super) outer: PixelRect,
pub(super) inner: PixelRect,
pub(super) layout: UiLayout,
pub(super) cursor: [i32; 2],
pub(super) row_width: u32,
pub(super) clip_override: Option<PixelRect>,
pub(super) scroll_viewport: Option<PixelRect>,
pub(super) scroll_offset_y: i32,
}
impl PanelScope {
pub(super) fn new(rect: PixelRect, layout: UiLayout) -> Self {
let pad = &layout.padding;
let ix = rect.x + pad.left as i32;
let iy = rect.y + pad.top as i32;
let iw = (rect.w as f32 - pad.left - pad.right).max(0.0) as u32;
let ih = (rect.h as f32 - pad.top - pad.bottom).max(0.0) as u32;
let inner = PixelRect {
x: ix,
y: iy,
w: iw,
h: ih,
};
Self {
outer: rect,
inner,
cursor: [ix, iy],
layout,
row_width: 0,
clip_override: None,
scroll_viewport: None,
scroll_offset_y: 0,
}
}
pub(super) fn allocate(&mut self, w: u32, h: u32) -> PixelRect {
let rect = PixelRect {
x: self.cursor[0],
y: self.cursor[1],
w,
h,
};
match self.layout.direction {
UiDirection::Column => {
self.cursor[1] += h as i32 + self.layout.gap as i32;
}
UiDirection::Row => {
self.cursor[0] += w as i32 + self.layout.gap as i32;
if h > self.row_width {
self.row_width = h;
}
}
}
rect
}
pub(super) fn content_width(&self) -> u32 {
self.inner.w
}
pub(super) fn clip(&self) -> PixelRect {
self.clip_override.unwrap_or(self.outer).clip(&self.inner)
}
}
#[derive(Default)]
pub(super) struct LayoutStack {
pub(super) panels: Vec<PanelScope>,
}
impl LayoutStack {
pub(super) fn push(&mut self, scope: PanelScope) {
self.panels.push(scope);
}
pub(super) fn pop(&mut self) {
self.panels.pop();
}
pub(super) fn top(&self) -> Option<&PanelScope> {
self.panels.last()
}
pub(super) fn top_mut(&mut self) -> Option<&mut PanelScope> {
self.panels.last_mut()
}
}
pub(super) fn resolve_width(sizing: &UiSizing, parent_content_width: u32) -> u32 {
match sizing {
UiSizing::Fill => parent_content_width,
UiSizing::Fixed(px) => *px as u32,
UiSizing::Hug => 0, }
}
pub(super) fn default_item_height(padding: f32) -> u32 {
(padding * 4.0 + 14.0) as u32
}
pub(super) fn separator_rect(scope: &PanelScope) -> PixelRect {
match scope.layout.direction {
UiDirection::Column => PixelRect {
x: scope.inner.x,
y: scope.cursor[1],
w: scope.inner.w,
h: 1,
},
UiDirection::Row => PixelRect {
x: scope.cursor[0],
y: scope.inner.y,
w: 1,
h: scope.inner.h,
},
}
}