Struct kas_core::layout::SolveCache
source · pub struct SolveCache { /* private fields */ }
Expand description
Size solver
This struct is used to solve widget layout, read size constraints and cache the results until the next solver run.
SolveCache::find_constraints
constructs an instance of this struct,
solving for size constraints.
SolveCache::apply_rect
accepts a Rect
, updates constraints as
necessary and sets widget positions within this rect
.
Implementations§
source§impl SolveCache
impl SolveCache
sourcepub fn min(&self, inner_margin: bool) -> Size
pub fn min(&self, inner_margin: bool) -> Size
Get the minimum size
If inner_margin
is true, margins are included in the result.
sourcepub fn ideal(&self, inner_margin: bool) -> Size
pub fn ideal(&self, inner_margin: bool) -> Size
Get the ideal size
If inner_margin
is true, margins are included in the result.
Examples found in repository?
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
fn resize_popup(&mut self, mgr: &mut ConfigMgr, index: usize) {
// Notation: p=point/coord, s=size, m=margin
// r=window/root rect, c=anchor rect
let r = self.core.rect;
let popup = &mut self.popups[index].1;
let c = find_rect(&self.w, popup.parent.clone()).unwrap();
let widget = self.w.find_widget_mut(&popup.id).unwrap();
let mut cache = layout::SolveCache::find_constraints(widget, mgr.size_mgr());
let ideal = cache.ideal(false);
let m = cache.margins();
let is_reversed = popup.direction.is_reversed();
let place_in = |rp, rs: i32, cp: i32, cs: i32, ideal, m: (u16, u16)| -> (i32, i32) {
let m: (i32, i32) = (m.0.into(), m.1.into());
let before: i32 = cp - (rp + m.1);
let before = before.max(0);
let after = (rs - (cs + before + m.0)).max(0);
if after >= ideal {
if is_reversed && before >= ideal {
(cp - ideal - m.1, ideal)
} else {
(cp + cs + m.0, ideal)
}
} else if before >= ideal {
(cp - ideal - m.1, ideal)
} else if before > after {
(rp, before)
} else {
(cp + cs + m.0, after)
}
};
#[allow(clippy::manual_clamp)]
let place_out = |rp, rs, cp: i32, cs, ideal: i32| -> (i32, i32) {
let pos = cp.min(rp + rs - ideal).max(rp);
let size = ideal.max(cs).min(rs);
(pos, size)
};
let rect = if popup.direction.is_horizontal() {
let (x, w) = place_in(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0, m.horiz);
let (y, h) = place_out(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1);
Rect::new(Coord(x, y), Size::new(w, h))
} else {
let (x, w) = place_out(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0);
let (y, h) = place_in(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1, m.vert);
Rect::new(Coord(x, y), Size::new(w, h))
};
cache.apply_rect(widget, mgr, rect, false, true);
}
sourcepub fn margins(&self) -> Margins
pub fn margins(&self) -> Margins
Get the margins
Examples found in repository?
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
fn resize_popup(&mut self, mgr: &mut ConfigMgr, index: usize) {
// Notation: p=point/coord, s=size, m=margin
// r=window/root rect, c=anchor rect
let r = self.core.rect;
let popup = &mut self.popups[index].1;
let c = find_rect(&self.w, popup.parent.clone()).unwrap();
let widget = self.w.find_widget_mut(&popup.id).unwrap();
let mut cache = layout::SolveCache::find_constraints(widget, mgr.size_mgr());
let ideal = cache.ideal(false);
let m = cache.margins();
let is_reversed = popup.direction.is_reversed();
let place_in = |rp, rs: i32, cp: i32, cs: i32, ideal, m: (u16, u16)| -> (i32, i32) {
let m: (i32, i32) = (m.0.into(), m.1.into());
let before: i32 = cp - (rp + m.1);
let before = before.max(0);
let after = (rs - (cs + before + m.0)).max(0);
if after >= ideal {
if is_reversed && before >= ideal {
(cp - ideal - m.1, ideal)
} else {
(cp + cs + m.0, ideal)
}
} else if before >= ideal {
(cp - ideal - m.1, ideal)
} else if before > after {
(rp, before)
} else {
(cp + cs + m.0, after)
}
};
#[allow(clippy::manual_clamp)]
let place_out = |rp, rs, cp: i32, cs, ideal: i32| -> (i32, i32) {
let pos = cp.min(rp + rs - ideal).max(rp);
let size = ideal.max(cs).min(rs);
(pos, size)
};
let rect = if popup.direction.is_horizontal() {
let (x, w) = place_in(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0, m.horiz);
let (y, h) = place_out(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1);
Rect::new(Coord(x, y), Size::new(w, h))
} else {
let (x, w) = place_out(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0);
let (y, h) = place_in(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1, m.vert);
Rect::new(Coord(x, y), Size::new(w, h))
};
cache.apply_rect(widget, mgr, rect, false, true);
}
sourcepub fn find_constraints(widget: &mut dyn Widget, size_mgr: SizeMgr<'_>) -> Self
pub fn find_constraints(widget: &mut dyn Widget, size_mgr: SizeMgr<'_>) -> Self
Calculate required size of widget
Assumes no explicit alignment.
Examples found in repository?
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
fn resize_popup(&mut self, mgr: &mut ConfigMgr, index: usize) {
// Notation: p=point/coord, s=size, m=margin
// r=window/root rect, c=anchor rect
let r = self.core.rect;
let popup = &mut self.popups[index].1;
let c = find_rect(&self.w, popup.parent.clone()).unwrap();
let widget = self.w.find_widget_mut(&popup.id).unwrap();
let mut cache = layout::SolveCache::find_constraints(widget, mgr.size_mgr());
let ideal = cache.ideal(false);
let m = cache.margins();
let is_reversed = popup.direction.is_reversed();
let place_in = |rp, rs: i32, cp: i32, cs: i32, ideal, m: (u16, u16)| -> (i32, i32) {
let m: (i32, i32) = (m.0.into(), m.1.into());
let before: i32 = cp - (rp + m.1);
let before = before.max(0);
let after = (rs - (cs + before + m.0)).max(0);
if after >= ideal {
if is_reversed && before >= ideal {
(cp - ideal - m.1, ideal)
} else {
(cp + cs + m.0, ideal)
}
} else if before >= ideal {
(cp - ideal - m.1, ideal)
} else if before > after {
(rp, before)
} else {
(cp + cs + m.0, after)
}
};
#[allow(clippy::manual_clamp)]
let place_out = |rp, rs, cp: i32, cs, ideal: i32| -> (i32, i32) {
let pos = cp.min(rp + rs - ideal).max(rp);
let size = ideal.max(cs).min(rs);
(pos, size)
};
let rect = if popup.direction.is_horizontal() {
let (x, w) = place_in(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0, m.horiz);
let (y, h) = place_out(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1);
Rect::new(Coord(x, y), Size::new(w, h))
} else {
let (x, w) = place_out(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0);
let (y, h) = place_in(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1, m.vert);
Rect::new(Coord(x, y), Size::new(w, h))
};
cache.apply_rect(widget, mgr, rect, false, true);
}
sourcepub fn invalidate_rule_cache(&mut self)
pub fn invalidate_rule_cache(&mut self)
Force updating of size rules
This should be called whenever widget size rules have been changed. It
forces SolveCache::apply_rect
to recompute these rules when next
called.
sourcepub fn apply_rect(
&mut self,
widget: &mut dyn Widget,
mgr: &mut ConfigMgr<'_>,
rect: Rect,
inner_margin: bool,
print_heirarchy: bool
)
pub fn apply_rect(
&mut self,
widget: &mut dyn Widget,
mgr: &mut ConfigMgr<'_>,
rect: Rect,
inner_margin: bool,
print_heirarchy: bool
)
Apply layout solution to a widget
The widget’s layout is solved for the given rect
and assigned.
If inner_margin
is true, margins are internal to this rect
; if not,
the caller is responsible for handling margins.
If SolveCache::invalidate_rule_cache
was called since rules were
last calculated then this method will recalculate all rules; otherwise
it will only do so if necessary (when dimensions do not match those
last used).
Examples found in repository?
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
fn resize_popup(&mut self, mgr: &mut ConfigMgr, index: usize) {
// Notation: p=point/coord, s=size, m=margin
// r=window/root rect, c=anchor rect
let r = self.core.rect;
let popup = &mut self.popups[index].1;
let c = find_rect(&self.w, popup.parent.clone()).unwrap();
let widget = self.w.find_widget_mut(&popup.id).unwrap();
let mut cache = layout::SolveCache::find_constraints(widget, mgr.size_mgr());
let ideal = cache.ideal(false);
let m = cache.margins();
let is_reversed = popup.direction.is_reversed();
let place_in = |rp, rs: i32, cp: i32, cs: i32, ideal, m: (u16, u16)| -> (i32, i32) {
let m: (i32, i32) = (m.0.into(), m.1.into());
let before: i32 = cp - (rp + m.1);
let before = before.max(0);
let after = (rs - (cs + before + m.0)).max(0);
if after >= ideal {
if is_reversed && before >= ideal {
(cp - ideal - m.1, ideal)
} else {
(cp + cs + m.0, ideal)
}
} else if before >= ideal {
(cp - ideal - m.1, ideal)
} else if before > after {
(rp, before)
} else {
(cp + cs + m.0, after)
}
};
#[allow(clippy::manual_clamp)]
let place_out = |rp, rs, cp: i32, cs, ideal: i32| -> (i32, i32) {
let pos = cp.min(rp + rs - ideal).max(rp);
let size = ideal.max(cs).min(rs);
(pos, size)
};
let rect = if popup.direction.is_horizontal() {
let (x, w) = place_in(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0, m.horiz);
let (y, h) = place_out(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1);
Rect::new(Coord(x, y), Size::new(w, h))
} else {
let (x, w) = place_out(r.pos.0, r.size.0, c.pos.0, c.size.0, ideal.0);
let (y, h) = place_in(r.pos.1, r.size.1, c.pos.1, c.size.1, ideal.1, m.vert);
Rect::new(Coord(x, y), Size::new(w, h))
};
cache.apply_rect(widget, mgr, rect, false, true);
}