mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add some documentation to view
module
This commit is contained in:
parent
03c400ad44
commit
e166869c51
@ -82,7 +82,7 @@ impl Vec2 {
|
||||
|
||||
/// Returns a new `Vec2` with the axis `o` set to `value`.
|
||||
pub fn with(&self, o: Orientation, value: usize) -> Self {
|
||||
let mut other = self.clone();
|
||||
let mut other = *self;
|
||||
*o.get_ref(&mut other) = value;
|
||||
other
|
||||
}
|
||||
|
@ -68,6 +68,6 @@ impl<T: View> ViewWrapper for BoxView<T> {
|
||||
|
||||
Vec2::new(self.size.x.unwrap_or(child_size.x),
|
||||
self.size.y.unwrap_or(child_size.y))
|
||||
}.or_min(req)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,56 +103,6 @@ impl LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the index of the maximum element.
|
||||
/// WTF isn't it part of standard library??
|
||||
fn find_max(list: &[usize]) -> usize {
|
||||
let mut max_value = 0;
|
||||
let mut max = 0;
|
||||
for (i, &x) in list.iter().enumerate() {
|
||||
if x > max_value {
|
||||
max_value = x;
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
max
|
||||
}
|
||||
|
||||
/// Given a total number of points and a list of weights,
|
||||
/// try to share the points according to the weight,
|
||||
/// rounding properly and conserving the sum of points.
|
||||
fn share(total: usize, weights: Vec<usize>) -> Vec<usize> {
|
||||
// It first give a base value to everyone, which is their truncated share.
|
||||
// Then, it gives the rest to the most deserving.
|
||||
if weights.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let sum_weight = weights.iter().fold(0, |a, b| a + b);
|
||||
if sum_weight == 0 {
|
||||
return (0..weights.len()).map(|_| 0).collect();
|
||||
}
|
||||
|
||||
let mut base = Vec::with_capacity(weights.len());
|
||||
let mut rest = Vec::with_capacity(weights.len());
|
||||
let mut extra = total;
|
||||
|
||||
for weight in &weights {
|
||||
let b = total * weight / sum_weight;
|
||||
extra -= b;
|
||||
base.push(b);
|
||||
rest.push(total * weight - b * sum_weight);
|
||||
}
|
||||
|
||||
// TODO: better to sort (base,rest) as one array and pick the extra first.
|
||||
for _ in 0..extra {
|
||||
let i = find_max(&rest);
|
||||
rest[i] = 0;
|
||||
base[i] += 1;
|
||||
}
|
||||
|
||||
base
|
||||
}
|
||||
|
||||
impl View for LinearLayout {
|
||||
fn draw(&mut self, printer: &Printer) {
|
||||
// Use pre-computed sizes
|
||||
@ -184,50 +134,8 @@ impl View for LinearLayout {
|
||||
}
|
||||
|
||||
for child in &mut self.children {
|
||||
// println_stderr!("Child size: {:?}", child.size);
|
||||
child.view.layout(child.size);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// Need to compute things again...
|
||||
self.get_min_size(size);
|
||||
|
||||
let min_sizes: Vec<Vec2> = self.children
|
||||
.iter_mut()
|
||||
.map(|child| Vec2::min(size, child.view.get_min_size(size)))
|
||||
.collect();
|
||||
let min_size = self.orientation.stack(min_sizes.iter());
|
||||
|
||||
// Emulate 'non-strict inequality' on integers
|
||||
// (default comparison on Vec2 is strict,
|
||||
// and (0,1).cmp((1,1)) is undefined)
|
||||
if !(min_size < size + (1, 1)) {
|
||||
// Error! Not enough space! Emergency procedures!
|
||||
return;
|
||||
}
|
||||
|
||||
// Now share this extra space among everyone
|
||||
|
||||
let extras = {
|
||||
let extra = size - min_size;
|
||||
let space = self.orientation.get(&extra);
|
||||
share(space,
|
||||
self.children.iter().map(|child| child.weight).collect())
|
||||
};
|
||||
|
||||
|
||||
for (child, (child_size, extra)) in self.children
|
||||
.iter_mut()
|
||||
.zip(min_sizes.iter().zip(extras.iter())) {
|
||||
let mut child_size = *child_size;
|
||||
*self.orientation.get_ref(&mut child_size) += *extra;
|
||||
*self.orientation.swap().get_ref(&mut child_size) =
|
||||
self.orientation.swap().get(&size);
|
||||
child.size = child_size;
|
||||
child.view.layout(child_size);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
fn get_min_size(&mut self, req: Vec2) -> Vec2 {
|
||||
|
@ -1,4 +1,38 @@
|
||||
//! Defines various views to use when creating the layout.
|
||||
//!
|
||||
//! Views are the main building blocks of your UI.
|
||||
//!
|
||||
//! A view can delegate part or all of its responsabilities to child views,
|
||||
//! forming a view tree. The root of this tree is a `StackView` handled
|
||||
//! directly by the `Cursive` element.
|
||||
//!
|
||||
//! # Layout
|
||||
//!
|
||||
//! The layout phase is when the size and location of each view is computed.
|
||||
//!
|
||||
//! Each view is given an area of the screen by the `View::layout()` method.
|
||||
//! With this, the view is free to plan its content, including calling
|
||||
//! `View::layout()` on its own children.
|
||||
//!
|
||||
//! In order to determine how much space should be given each child, parents
|
||||
//! can use `View::get_min_size()` on them.
|
||||
//!
|
||||
//!
|
||||
//! ### Contracts
|
||||
//!
|
||||
//! When building new Views, you should respect these contracts:
|
||||
//!
|
||||
//! * By default, `View::layout()` should be called before any call to
|
||||
//! `View::draw()` with the same available size. The only exceptions is
|
||||
//! when both following conditions are met:
|
||||
//! * The available size has not changed since the last call to `View::layout()`
|
||||
//! * `View::needs_relayout()` returns `false`
|
||||
//!
|
||||
//! In this case, it is safe to omit the call to `View::layout()`.
|
||||
//!
|
||||
//! * The value returned by `get_min_size` should be an actually viable size,
|
||||
//! no matter what the request is. This means calling `View::layout()` with
|
||||
//! a size returned by `get_min_size` is **never** an error.
|
||||
|
||||
#[macro_use]
|
||||
mod view_wrapper;
|
||||
|
Loading…
Reference in New Issue
Block a user