mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-10 03:10:41 +00:00
Split width
and height
in BoxView
They are now both optional
This commit is contained in:
parent
c07e8b6aee
commit
b7a270f258
@ -9,7 +9,7 @@ use cursive::event::{EventResult, Event};
|
||||
fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
|
||||
siv.add_layer(BoxView::new((30, 10), KeyCodeView::new(10)));
|
||||
siv.add_layer(BoxView::fixed_size((30, 10), KeyCodeView::new(10)));
|
||||
|
||||
siv.run();
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ fn main() {
|
||||
.child(TextView::new("Title").h_align(HAlign::Center))
|
||||
// Box the textview, so it doesn't get too wide.
|
||||
// A 0 height value means it will be unconstrained.
|
||||
.child(BoxView::new((30,0), TextView::new(text))))
|
||||
.child(BoxView::fixed_width(30, TextView::new(text))))
|
||||
.button("Quit", |s| s.quit())
|
||||
.h_align(HAlign::Center));
|
||||
|
||||
|
@ -24,7 +24,7 @@ fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
|
||||
// Let's add a BoxView to keep the list at a reasonable size - it can scroll anyway.
|
||||
siv.add_layer(Dialog::new(BoxView::new((20, 10), select))
|
||||
siv.add_layer(Dialog::new(BoxView::fixed_size((20, 10), select))
|
||||
.title("Where are you from?"));
|
||||
|
||||
siv.run();
|
||||
|
@ -7,7 +7,7 @@ use backend::Backend;
|
||||
use B;
|
||||
|
||||
use theme::{ColorStyle, Effect, Theme};
|
||||
use vec::{ToVec2, Vec2};
|
||||
use vec::Vec2;
|
||||
|
||||
/// Convenient interface to draw on a subset of the screen.
|
||||
#[derive(Clone)]
|
||||
@ -24,10 +24,10 @@ pub struct Printer {
|
||||
|
||||
impl Printer {
|
||||
/// Creates a new printer on the given window.
|
||||
pub fn new<T: ToVec2>(size: T, theme: Theme) -> Self {
|
||||
pub fn new<T: Into<Vec2>>(size: T, theme: Theme) -> Self {
|
||||
Printer {
|
||||
offset: Vec2::zero(),
|
||||
size: size.to_vec2(),
|
||||
size: size.into(),
|
||||
focused: true,
|
||||
theme: theme,
|
||||
}
|
||||
@ -36,8 +36,8 @@ impl Printer {
|
||||
// TODO: use &mut self? We don't *need* it, but it may make sense.
|
||||
// We don't want people to start calling prints in parallel?
|
||||
/// Prints some text at the given position relative to the window.
|
||||
pub fn print<S: ToVec2>(&self, pos: S, text: &str) {
|
||||
let p = pos.to_vec2();
|
||||
pub fn print<S: Into<Vec2>>(&self, pos: S, text: &str) {
|
||||
let p = pos.into();
|
||||
if p.y >= self.size.y || p.x >= self.size.x {
|
||||
return;
|
||||
}
|
||||
@ -59,8 +59,8 @@ impl Printer {
|
||||
}
|
||||
|
||||
/// Prints a vertical line using the given character.
|
||||
pub fn print_vline<T: ToVec2>(&self, start: T, len: usize, c: &str) {
|
||||
let p = start.to_vec2();
|
||||
pub fn print_vline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) {
|
||||
let p = start.into();
|
||||
if p.y > self.size.y || p.x > self.size.x {
|
||||
return;
|
||||
}
|
||||
@ -73,8 +73,8 @@ impl Printer {
|
||||
}
|
||||
|
||||
/// Prints a horizontal line using the given character.
|
||||
pub fn print_hline<T: ToVec2>(&self, start: T, len: usize, c: &str) {
|
||||
let p = start.to_vec2();
|
||||
pub fn print_hline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) {
|
||||
let p = start.into();
|
||||
if p.y > self.size.y || p.x > self.size.x {
|
||||
return;
|
||||
}
|
||||
@ -125,9 +125,9 @@ impl Printer {
|
||||
/// # let printer = Printer::new((6,4), theme::load_default());
|
||||
/// printer.print_box((0,0), (6,4));
|
||||
/// ```
|
||||
pub fn print_box<T: ToVec2>(&self, start: T, size: T) {
|
||||
let start_v = start.to_vec2();
|
||||
let size_v = size.to_vec2() - (1, 1);
|
||||
pub fn print_box<T: Into<Vec2>>(&self, start: T, size: T) {
|
||||
let start_v = start.into();
|
||||
let size_v = size.into() - (1, 1);
|
||||
|
||||
self.print(start_v, "┌");
|
||||
self.print(start_v + size_v.keep_x(), "┐");
|
||||
@ -157,21 +157,21 @@ impl Printer {
|
||||
f);
|
||||
}
|
||||
|
||||
pub fn print_hdelim<T: ToVec2>(&self, start: T, len: usize) {
|
||||
let start = start.to_vec2();
|
||||
pub fn print_hdelim<T: Into<Vec2>>(&self, start: T, len: usize) {
|
||||
let start = start.into();
|
||||
self.print(start, "├");
|
||||
self.print_hline(start + (1, 0), len - 2, "─");
|
||||
self.print(start + (len - 1, 0), "┤");
|
||||
}
|
||||
|
||||
/// Returns a printer on a subset of this one's area.
|
||||
pub fn sub_printer<S: ToVec2>(&self, offset: S, size: S, focused: bool)
|
||||
-> Printer {
|
||||
let offset_v = offset.to_vec2();
|
||||
pub fn sub_printer<S: Into<Vec2>>(&self, offset: S, size: S, focused: bool)
|
||||
-> Printer {
|
||||
let offset_v = offset.into();
|
||||
Printer {
|
||||
offset: self.offset + offset_v,
|
||||
// We can't be larger than what remains
|
||||
size: Vec2::min(self.size - offset_v, size.to_vec2()),
|
||||
size: Vec2::min(self.size - offset_v, size.into()),
|
||||
focused: self.focused && focused,
|
||||
theme: self.theme.clone(),
|
||||
}
|
||||
|
72
src/vec.rs
72
src/vec.rs
@ -68,41 +68,30 @@ impl Vec2 {
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic trait for converting a value into a 2D vector.
|
||||
pub trait ToVec2 {
|
||||
/// Converts self into a Vec2.
|
||||
fn to_vec2(self) -> Vec2;
|
||||
}
|
||||
|
||||
impl ToVec2 for Vec2 {
|
||||
fn to_vec2(self) -> Vec2 {
|
||||
self
|
||||
impl From<(usize, usize)> for Vec2 {
|
||||
fn from((x, y): (usize, usize)) -> Self {
|
||||
Vec2::new(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToVec2 for (i32, i32) {
|
||||
fn to_vec2(self) -> Vec2 {
|
||||
(self.0 as usize, self.1 as usize).to_vec2()
|
||||
impl From<(i32, i32)> for Vec2 {
|
||||
fn from((x, y): (i32, i32)) -> Self {
|
||||
(x as usize, y as usize).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToVec2 for (usize, usize) {
|
||||
fn to_vec2(self) -> Vec2 {
|
||||
Vec2::new(self.0, self.1)
|
||||
impl From<(u32, u32)> for Vec2 {
|
||||
fn from((x, y): (u32, u32)) -> Self {
|
||||
(x as usize, y as usize).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToVec2 for (u32, u32) {
|
||||
fn to_vec2(self) -> Vec2 {
|
||||
Vec2::new(self.0 as usize, self.1 as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToVec2> Add<T> for Vec2 {
|
||||
impl<T: Into<Vec2>> Add<T> for Vec2 {
|
||||
type Output = Vec2;
|
||||
|
||||
fn add(self, other: T) -> Vec2 {
|
||||
let ov = other.to_vec2();
|
||||
let ov = other.into();
|
||||
Vec2 {
|
||||
x: self.x + ov.x,
|
||||
y: self.y + ov.y,
|
||||
@ -110,11 +99,11 @@ impl<T: ToVec2> Add<T> for Vec2 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToVec2> Sub<T> for Vec2 {
|
||||
impl<T: Into<Vec2>> Sub<T> for Vec2 {
|
||||
type Output = Vec2;
|
||||
|
||||
fn sub(self, other: T) -> Vec2 {
|
||||
let ov = other.to_vec2();
|
||||
let ov = other.into();
|
||||
Vec2 {
|
||||
x: self.x - ov.x,
|
||||
y: self.y - ov.y,
|
||||
@ -194,38 +183,23 @@ impl Vec4 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Generic trait for converting a value into a Vec4.
|
||||
pub trait ToVec4 {
|
||||
/// Converts self to a Vec4.
|
||||
fn to_vec4(self) -> Vec4;
|
||||
}
|
||||
|
||||
impl ToVec4 for Vec4 {
|
||||
fn to_vec4(self) -> Vec4 {
|
||||
self
|
||||
impl From<(usize, usize, usize, usize)> for Vec4 {
|
||||
fn from((left, right, top, bottom): (usize, usize, usize, usize)) -> Vec4 {
|
||||
Vec4::new(left, right, top, bottom)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToVec4 for (usize, usize, usize, usize) {
|
||||
fn to_vec4(self) -> Vec4 {
|
||||
Vec4::new(self.0, self.1, self.2, self.3)
|
||||
impl From<(i32, i32, i32, i32)> for Vec4 {
|
||||
fn from((left, right, top, bottom): (i32, i32, i32, i32)) -> Vec4 {
|
||||
(left as usize, right as usize, top as usize, bottom as usize).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToVec4 for (i32, i32, i32, i32) {
|
||||
fn to_vec4(self) -> Vec4 {
|
||||
Vec4::new(self.0 as usize,
|
||||
self.1 as usize,
|
||||
self.2 as usize,
|
||||
self.3 as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToVec4> Add<T> for Vec4 {
|
||||
impl<T: Into<Vec4>> Add<T> for Vec4 {
|
||||
type Output = Vec4;
|
||||
|
||||
fn add(self, other: T) -> Vec4 {
|
||||
let ov = other.to_vec4();
|
||||
let ov = other.into();
|
||||
|
||||
Vec4 {
|
||||
left: self.left + ov.left,
|
||||
@ -236,11 +210,11 @@ impl<T: ToVec4> Add<T> for Vec4 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToVec4> Sub<T> for Vec4 {
|
||||
impl<T: Into<Vec4>> Sub<T> for Vec4 {
|
||||
type Output = Vec4;
|
||||
|
||||
fn sub(self, other: T) -> Vec4 {
|
||||
let ov = other.to_vec4();
|
||||
let ov = other.into();
|
||||
|
||||
Vec4 {
|
||||
left: self.left - ov.left,
|
||||
|
@ -1,11 +1,12 @@
|
||||
use std::cmp;
|
||||
|
||||
use vec::{ToVec2, Vec2};
|
||||
use vec::Vec2;
|
||||
use super::{View, ViewWrapper};
|
||||
|
||||
/// `BoxView` is a wrapper around an other view, with a given minimum size.
|
||||
pub struct BoxView<T: View> {
|
||||
size: Vec2,
|
||||
width: Option<usize>,
|
||||
height: Option<usize>,
|
||||
view: T,
|
||||
}
|
||||
|
||||
@ -17,38 +18,48 @@ impl<T: View> BoxView<T> {
|
||||
/// ```
|
||||
/// # use cursive::view::{BoxView,TextView};
|
||||
/// // Creates a 20x4 BoxView with a TextView content.
|
||||
/// let view = BoxView::new((20,4), TextView::new("Hello!"));
|
||||
/// let view = BoxView::fixed_size((20,4), TextView::new("Hello!"));
|
||||
/// ```
|
||||
pub fn new<S: ToVec2>(size: S, view: T) -> Self {
|
||||
pub fn fixed_size<S: Into<Vec2>>(size: S, view: T) -> Self {
|
||||
let size = size.into();
|
||||
|
||||
BoxView::new(Some(size.x), Some(size.y), view)
|
||||
}
|
||||
|
||||
pub fn new(width: Option<usize>, height: Option<usize>, view: T) -> Self {
|
||||
BoxView {
|
||||
size: size.to_vec2(),
|
||||
width: width,
|
||||
height: height,
|
||||
view: view,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fixed_width(width: usize, view: T) -> Self {
|
||||
BoxView::new(Some(width), None, view)
|
||||
}
|
||||
}
|
||||
|
||||
fn min<T: Ord>(a: T, b: Option<T>) -> T {
|
||||
match b {
|
||||
Some(b) => cmp::min(a, b),
|
||||
None => a,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: View> ViewWrapper for BoxView<T> {
|
||||
wrap_impl!(&self.view);
|
||||
|
||||
fn wrap_get_min_size(&mut self, mut req: Vec2) -> Vec2 {
|
||||
if self.size.x > 0 {
|
||||
req.x = cmp::min(self.size.x, req.x);
|
||||
}
|
||||
if self.size.y > 0 {
|
||||
req.y = cmp::min(self.size.y, req.y);
|
||||
}
|
||||
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
||||
|
||||
let mut size = self.view.get_min_size(req);
|
||||
if let (Some(w), Some(h)) = (self.width, self.height) {
|
||||
Vec2::new(w, h)
|
||||
} else {
|
||||
let req = Vec2::new(min(req.x, self.width),
|
||||
min(req.y, self.height));
|
||||
let child_size = self.view.get_min_size(req);
|
||||
|
||||
// Did he think he got to decide?
|
||||
// Of course we have the last word here.
|
||||
if self.size.x > 0 {
|
||||
size.x = self.size.x;
|
||||
Vec2::new(self.width.unwrap_or(child_size.x),
|
||||
self.height.unwrap_or(child_size.y))
|
||||
}
|
||||
if self.size.y > 0 {
|
||||
size.y = self.size.y;
|
||||
}
|
||||
|
||||
size
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use event::*;
|
||||
use theme::ColorStyle;
|
||||
use view::{Selector, TextView, View};
|
||||
use view::{Button, SizedView};
|
||||
use vec::{ToVec4, Vec2, Vec4};
|
||||
use vec::{Vec2, Vec4};
|
||||
use printer::Printer;
|
||||
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
@ -99,8 +99,8 @@ impl Dialog {
|
||||
}
|
||||
|
||||
/// Sets the padding in the dialog (around content and buttons).
|
||||
pub fn padding<T: ToVec4>(mut self, padding: T) -> Self {
|
||||
self.padding = padding.to_vec4();
|
||||
pub fn padding<T: Into<Vec4>>(mut self, padding: T) -> Self {
|
||||
self.padding = padding.into();
|
||||
|
||||
self
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::cmp::min;
|
||||
use vec::{ToVec2, Vec2};
|
||||
use vec::Vec2;
|
||||
|
||||
/// Location of the view on screen
|
||||
#[derive(PartialEq,Debug,Clone)]
|
||||
@ -17,13 +17,13 @@ impl Position {
|
||||
Position::new(Offset::Center, Offset::Center)
|
||||
}
|
||||
|
||||
pub fn absolute<T: ToVec2>(offset: T) -> Self {
|
||||
let offset = offset.to_vec2();
|
||||
pub fn absolute<T: Into<Vec2>>(offset: T) -> Self {
|
||||
let offset = offset.into();
|
||||
Position::new(Offset::Absolute(offset.x), Offset::Absolute(offset.y))
|
||||
}
|
||||
|
||||
pub fn parent<T: ToVec2>(offset: T) -> Self {
|
||||
let offset = offset.to_vec2();
|
||||
pub fn parent<T: Into<Vec2>>(offset: T) -> Self {
|
||||
let offset = offset.into();
|
||||
Position::new(Offset::Parent(offset.x), Offset::Parent(offset.y))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user