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