mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 11:16:03 +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`.
|
/// Returns a new `Vec2` with the axis `o` set to `value`.
|
||||||
pub fn with(&self, o: Orientation, value: usize) -> Self {
|
pub fn with(&self, o: Orientation, value: usize) -> Self {
|
||||||
let mut other = self.clone();
|
let mut other = *self;
|
||||||
*o.get_ref(&mut other) = value;
|
*o.get_ref(&mut other) = value;
|
||||||
other
|
other
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,6 @@ impl<T: View> ViewWrapper for BoxView<T> {
|
|||||||
|
|
||||||
Vec2::new(self.size.x.unwrap_or(child_size.x),
|
Vec2::new(self.size.x.unwrap_or(child_size.x),
|
||||||
self.size.y.unwrap_or(child_size.y))
|
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 {
|
impl View for LinearLayout {
|
||||||
fn draw(&mut self, printer: &Printer) {
|
fn draw(&mut self, printer: &Printer) {
|
||||||
// Use pre-computed sizes
|
// Use pre-computed sizes
|
||||||
@ -184,50 +134,8 @@ impl View for LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for child in &mut self.children {
|
for child in &mut self.children {
|
||||||
// println_stderr!("Child size: {:?}", child.size);
|
|
||||||
child.view.layout(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 {
|
fn get_min_size(&mut self, req: Vec2) -> Vec2 {
|
||||||
|
@ -1,4 +1,38 @@
|
|||||||
//! Defines various views to use when creating the layout.
|
//! 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]
|
#[macro_use]
|
||||||
mod view_wrapper;
|
mod view_wrapper;
|
||||||
|
Loading…
Reference in New Issue
Block a user