mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add printer abstraction on ncurses::WINDOW
Also rename Size -> Vec2
This commit is contained in:
parent
4ebb422611
commit
e5c623bb07
@ -1,11 +1,11 @@
|
|||||||
use ncurses;
|
|
||||||
use event::EventResult;
|
use event::EventResult;
|
||||||
use super::{Size,ToSize};
|
use vec2::{Vec2,ToVec2};
|
||||||
use view::{View,SizeRequest};
|
use view::{View,SizeRequest};
|
||||||
|
use printer::Printer;
|
||||||
|
|
||||||
/// 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 {
|
pub struct BoxView {
|
||||||
size: Size,
|
size: Vec2,
|
||||||
|
|
||||||
content: Box<View>,
|
content: Box<View>,
|
||||||
}
|
}
|
||||||
@ -19,9 +19,9 @@ impl BoxView {
|
|||||||
/// // Creates a 20x4 BoxView with a TextView content.
|
/// // Creates a 20x4 BoxView with a TextView content.
|
||||||
/// let box = BoxView::new((20,4), TextView::new("Hello!"))
|
/// let box = BoxView::new((20,4), TextView::new("Hello!"))
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new<S: ToSize, V: View + 'static>(size: S, view: V) -> Self {
|
pub fn new<S: ToVec2, V: View + 'static>(size: S, view: V) -> Self {
|
||||||
BoxView {
|
BoxView {
|
||||||
size: size.to_size(),
|
size: size.to_vec2(),
|
||||||
content: Box::new(view),
|
content: Box::new(view),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,15 +32,15 @@ impl View for BoxView {
|
|||||||
self.content.on_key_event(ch)
|
self.content.on_key_event(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, win: ncurses::WINDOW, size: Size) {
|
fn draw(&self, printer: &Printer) {
|
||||||
self.content.draw(win, size)
|
self.content.draw(printer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_min_size(&self, _: SizeRequest) -> Size {
|
fn get_min_size(&self, _: SizeRequest) -> Vec2 {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(&mut self, size: Size) {
|
fn layout(&mut self, size: Vec2) {
|
||||||
self.content.layout(size);
|
self.content.layout(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
src/lib.rs
41
src/lib.rs
@ -1,9 +1,13 @@
|
|||||||
extern crate ncurses;
|
extern crate ncurses;
|
||||||
|
|
||||||
/// Module for user-input events and their effects.
|
/// User-input events and their effects.
|
||||||
pub mod event;
|
pub mod event;
|
||||||
/// Define various views to use when creating the layout.
|
/// Defines various views to use when creating the layout.
|
||||||
pub mod view;
|
pub mod view;
|
||||||
|
/// Makes drawing on ncurses windows easier.
|
||||||
|
pub mod printer;
|
||||||
|
/// 2D points.
|
||||||
|
pub mod vec2;
|
||||||
mod box_view;
|
mod box_view;
|
||||||
mod stack_view;
|
mod stack_view;
|
||||||
mod text_view;
|
mod text_view;
|
||||||
@ -18,6 +22,7 @@ use stack_view::StackView;
|
|||||||
|
|
||||||
use event::{EventResult,Callback};
|
use event::{EventResult,Callback};
|
||||||
|
|
||||||
|
/// Identifies a screen in the cursive ROOT.
|
||||||
pub type ScreenId = usize;
|
pub type ScreenId = usize;
|
||||||
|
|
||||||
/// Central part of the cursive library.
|
/// Central part of the cursive library.
|
||||||
@ -134,35 +139,3 @@ impl Drop for Cursive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simple 2D size, in characters.
|
|
||||||
#[derive(Clone,Copy)]
|
|
||||||
pub struct Size {
|
|
||||||
pub w: u32,
|
|
||||||
pub h: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Size {
|
|
||||||
pub fn new(w: u32, h: u32) -> Self {
|
|
||||||
Size {
|
|
||||||
w: w,
|
|
||||||
h: h,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A generic trait for converting a value into a 2D size
|
|
||||||
pub trait ToSize {
|
|
||||||
fn to_size(self) -> Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToSize for Size {
|
|
||||||
fn to_size(self) -> Size {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToSize for (u32,u32) {
|
|
||||||
fn to_size(self) -> Size {
|
|
||||||
Size::new(self.0, self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
31
src/printer.rs
Normal file
31
src/printer.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use ncurses;
|
||||||
|
use vec2::{Vec2,ToVec2};
|
||||||
|
|
||||||
|
/// Wrapper around a subset of a ncurses window.
|
||||||
|
pub struct Printer {
|
||||||
|
/// ncurses window this printer will use. You can use it directly if you want.
|
||||||
|
pub win: ncurses::WINDOW,
|
||||||
|
/// Offset into the window this printer should start drawing at.
|
||||||
|
pub offset: Vec2,
|
||||||
|
/// Size of the area we are allowed to draw on.
|
||||||
|
pub size: Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Printer {
|
||||||
|
/// 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();
|
||||||
|
ncurses::mvwprintw(self.win, (p.y + self.offset.y) as i32, (p.x + self.offset.x) as i32, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a printer on a subset of this one's area.
|
||||||
|
pub fn sub_printer<S: ToVec2>(&self, offset: S, size: S) -> Printer {
|
||||||
|
let offset_v = offset.to_vec2();
|
||||||
|
Printer {
|
||||||
|
win: self.win,
|
||||||
|
offset: self.offset + offset_v,
|
||||||
|
// We can't be larger than what remains
|
||||||
|
size: Vec2::min(self.size - offset_v, size.to_vec2()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,9 @@
|
|||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
|
||||||
use ncurses;
|
use vec2::Vec2;
|
||||||
|
|
||||||
use super::Size;
|
|
||||||
use view::{View,SizeRequest};
|
use view::{View,SizeRequest};
|
||||||
use event::EventResult;
|
use event::EventResult;
|
||||||
|
use printer::Printer;
|
||||||
|
|
||||||
/// Simple stack of views.
|
/// Simple stack of views.
|
||||||
/// Only the top-most view is active and can receive input.
|
/// Only the top-most view is active and can receive input.
|
||||||
@ -33,10 +32,10 @@ impl StackView {
|
|||||||
|
|
||||||
|
|
||||||
impl View for StackView {
|
impl View for StackView {
|
||||||
fn draw(&self, win: ncurses::WINDOW, size: Size) {
|
fn draw(&self, printer: &Printer) {
|
||||||
match self.layers.last() {
|
match self.layers.last() {
|
||||||
None => (),
|
None => (),
|
||||||
Some(v) => v.draw(win, size),
|
Some(v) => v.draw(printer),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,14 +46,14 @@ impl View for StackView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_min_size(&self, size: SizeRequest) -> Size {
|
fn get_min_size(&self, size: SizeRequest) -> Vec2 {
|
||||||
// The min size is the max of all children's
|
// The min size is the max of all children's
|
||||||
let mut s = Size::new(1,1);
|
let mut s = Vec2::new(1,1);
|
||||||
|
|
||||||
for view in self.layers.iter() {
|
for view in self.layers.iter() {
|
||||||
let vs = view.get_min_size(size);
|
let vs = view.get_min_size(size);
|
||||||
s.w = max(s.w, vs.w);
|
s.x = max(s.x, vs.x);
|
||||||
s.h = max(s.h, vs.h);
|
s.y = max(s.y, vs.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
s
|
s
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use ncurses;
|
use vec2::Vec2;
|
||||||
|
|
||||||
use super::Size;
|
|
||||||
use view::{View,DimensionRequest,SizeRequest};
|
use view::{View,DimensionRequest,SizeRequest};
|
||||||
use div::*;
|
use div::*;
|
||||||
|
use printer::Printer;
|
||||||
|
|
||||||
/// A simple view showing a fixed text
|
/// A simple view showing a fixed text
|
||||||
pub struct TextView {
|
pub struct TextView {
|
||||||
@ -48,19 +47,20 @@ impl TextView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl View for TextView {
|
impl View for TextView {
|
||||||
fn draw(&self, win: ncurses::WINDOW, size: Size) {
|
fn draw(&self, printer: &Printer) {
|
||||||
|
printer.print((0,0), &self.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_min_size(&self, size: SizeRequest) -> Size {
|
fn get_min_size(&self, size: SizeRequest) -> Vec2 {
|
||||||
match (size.w,size.h) {
|
match (size.w,size.h) {
|
||||||
(DimensionRequest::Unknown, DimensionRequest::Unknown) => Size::new(self.content.len() as u32, 1),
|
(DimensionRequest::Unknown, DimensionRequest::Unknown) => Vec2::new(self.content.len() as u32, 1),
|
||||||
(DimensionRequest::Fixed(w),_) => {
|
(DimensionRequest::Fixed(w),_) => {
|
||||||
let h = self.get_num_lines(w as usize) as u32;
|
let h = self.get_num_lines(w as usize) as u32;
|
||||||
Size::new(w, h)
|
Vec2::new(w, h)
|
||||||
},
|
},
|
||||||
(_,DimensionRequest::Fixed(h)) => {
|
(_,DimensionRequest::Fixed(h)) => {
|
||||||
let w = self.get_num_cols(h as usize) as u32;
|
let w = self.get_num_cols(h as usize) as u32;
|
||||||
Size::new(w, h)
|
Vec2::new(w, h)
|
||||||
},
|
},
|
||||||
(DimensionRequest::AtMost(_),DimensionRequest::AtMost(_)) => unreachable!(),
|
(DimensionRequest::AtMost(_),DimensionRequest::AtMost(_)) => unreachable!(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
68
src/vec2.rs
Normal file
68
src/vec2.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use std::ops::{Add, Sub};
|
||||||
|
use std::cmp::min;
|
||||||
|
|
||||||
|
/// Simple 2D size, in characters.
|
||||||
|
#[derive(Clone,Copy)]
|
||||||
|
pub struct Vec2 {
|
||||||
|
/// X coordinate (column), from left to right.
|
||||||
|
pub x: u32,
|
||||||
|
/// Y coordinate (row), from top to bottom.
|
||||||
|
pub y: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vec2 {
|
||||||
|
/// Creates a new Vec2 from coordinates.
|
||||||
|
pub fn new(x: u32, y: u32) -> Self {
|
||||||
|
Vec2 {
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new Vec2 that is no larger than any input in both dimensions.
|
||||||
|
pub fn min(a: Vec2, b: Vec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: min(a.x, b.x),
|
||||||
|
y: min(a.y, b.y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A generic trait for converting a value into a 2D vector.
|
||||||
|
pub trait ToVec2 {
|
||||||
|
fn to_vec2(self) -> Vec2;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToVec2 for Vec2 {
|
||||||
|
fn to_vec2(self) -> Vec2 {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToVec2 for (u32,u32) {
|
||||||
|
fn to_vec2(self) -> Vec2 {
|
||||||
|
Vec2::new(self.0, self.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Vec2 {
|
||||||
|
type Output = Vec2;
|
||||||
|
|
||||||
|
fn add(self, other: Vec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self.x + other.x,
|
||||||
|
y: self.y + other.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub for Vec2 {
|
||||||
|
type Output = Vec2;
|
||||||
|
|
||||||
|
fn sub(self, other: Vec2) -> Vec2 {
|
||||||
|
Vec2 {
|
||||||
|
x: self.x - other.x,
|
||||||
|
y: self.y - other.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/view.rs
11
src/view.rs
@ -1,12 +1,11 @@
|
|||||||
use ncurses;
|
|
||||||
|
|
||||||
use event::EventResult;
|
use event::EventResult;
|
||||||
|
|
||||||
pub use box_view::BoxView;
|
pub use box_view::BoxView;
|
||||||
pub use stack_view::StackView;
|
pub use stack_view::StackView;
|
||||||
pub use text_view::TextView;
|
pub use text_view::TextView;
|
||||||
|
|
||||||
use super::Size;
|
use vec2::Vec2;
|
||||||
|
use printer::Printer;
|
||||||
|
|
||||||
/// Describe constraints on a view layout in one dimension.
|
/// Describe constraints on a view layout in one dimension.
|
||||||
#[derive(PartialEq,Clone,Copy)]
|
#[derive(PartialEq,Clone,Copy)]
|
||||||
@ -34,12 +33,12 @@ pub trait View {
|
|||||||
fn on_key_event(&mut self, i32) -> EventResult { EventResult::Ignored }
|
fn on_key_event(&mut self, i32) -> EventResult { EventResult::Ignored }
|
||||||
|
|
||||||
/// Returns the minimum size the view requires under the given restrictions.
|
/// Returns the minimum size the view requires under the given restrictions.
|
||||||
fn get_min_size(&self, SizeRequest) -> Size { Size::new(1,1) }
|
fn get_min_size(&self, SizeRequest) -> Vec2 { Vec2::new(1,1) }
|
||||||
|
|
||||||
/// Called once the size for this view has been decided, so it can
|
/// Called once the size for this view has been decided, so it can
|
||||||
/// propagate the information to its children.
|
/// propagate the information to its children.
|
||||||
fn layout(&mut self, Size) { }
|
fn layout(&mut self, Vec2) { }
|
||||||
|
|
||||||
/// Draws the view within the given bounds.
|
/// Draws the view within the given bounds.
|
||||||
fn draw(&self, ncurses::WINDOW, Size);
|
fn draw(&self, &Printer);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user