mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-09 10:50:40 +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 super::{Size,ToSize};
|
||||
use vec2::{Vec2,ToVec2};
|
||||
use view::{View,SizeRequest};
|
||||
use printer::Printer;
|
||||
|
||||
/// BoxView is a wrapper around an other view, with a given minimum size.
|
||||
pub struct BoxView {
|
||||
size: Size,
|
||||
size: Vec2,
|
||||
|
||||
content: Box<View>,
|
||||
}
|
||||
@ -19,9 +19,9 @@ impl BoxView {
|
||||
/// // Creates a 20x4 BoxView with a TextView content.
|
||||
/// 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 {
|
||||
size: size.to_size(),
|
||||
size: size.to_vec2(),
|
||||
content: Box::new(view),
|
||||
}
|
||||
}
|
||||
@ -32,15 +32,15 @@ impl View for BoxView {
|
||||
self.content.on_key_event(ch)
|
||||
}
|
||||
|
||||
fn draw(&self, win: ncurses::WINDOW, size: Size) {
|
||||
self.content.draw(win, size)
|
||||
fn draw(&self, printer: &Printer) {
|
||||
self.content.draw(printer)
|
||||
}
|
||||
|
||||
fn get_min_size(&self, _: SizeRequest) -> Size {
|
||||
fn get_min_size(&self, _: SizeRequest) -> Vec2 {
|
||||
self.size
|
||||
}
|
||||
|
||||
fn layout(&mut self, size: Size) {
|
||||
fn layout(&mut self, size: Vec2) {
|
||||
self.content.layout(size);
|
||||
}
|
||||
}
|
||||
|
41
src/lib.rs
41
src/lib.rs
@ -1,9 +1,13 @@
|
||||
extern crate ncurses;
|
||||
|
||||
/// Module for user-input events and their effects.
|
||||
/// User-input events and their effects.
|
||||
pub mod event;
|
||||
/// Define various views to use when creating the layout.
|
||||
/// Defines various views to use when creating the layout.
|
||||
pub mod view;
|
||||
/// Makes drawing on ncurses windows easier.
|
||||
pub mod printer;
|
||||
/// 2D points.
|
||||
pub mod vec2;
|
||||
mod box_view;
|
||||
mod stack_view;
|
||||
mod text_view;
|
||||
@ -18,6 +22,7 @@ use stack_view::StackView;
|
||||
|
||||
use event::{EventResult,Callback};
|
||||
|
||||
/// Identifies a screen in the cursive ROOT.
|
||||
pub type ScreenId = usize;
|
||||
|
||||
/// 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 ncurses;
|
||||
|
||||
use super::Size;
|
||||
use vec2::Vec2;
|
||||
use view::{View,SizeRequest};
|
||||
use event::EventResult;
|
||||
use printer::Printer;
|
||||
|
||||
/// Simple stack of views.
|
||||
/// Only the top-most view is active and can receive input.
|
||||
@ -33,10 +32,10 @@ impl StackView {
|
||||
|
||||
|
||||
impl View for StackView {
|
||||
fn draw(&self, win: ncurses::WINDOW, size: Size) {
|
||||
fn draw(&self, printer: &Printer) {
|
||||
match self.layers.last() {
|
||||
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
|
||||
let mut s = Size::new(1,1);
|
||||
let mut s = Vec2::new(1,1);
|
||||
|
||||
for view in self.layers.iter() {
|
||||
let vs = view.get_min_size(size);
|
||||
s.w = max(s.w, vs.w);
|
||||
s.h = max(s.h, vs.h);
|
||||
s.x = max(s.x, vs.x);
|
||||
s.y = max(s.y, vs.y);
|
||||
}
|
||||
|
||||
s
|
||||
|
@ -1,8 +1,7 @@
|
||||
use ncurses;
|
||||
|
||||
use super::Size;
|
||||
use vec2::Vec2;
|
||||
use view::{View,DimensionRequest,SizeRequest};
|
||||
use div::*;
|
||||
use printer::Printer;
|
||||
|
||||
/// A simple view showing a fixed text
|
||||
pub struct TextView {
|
||||
@ -48,19 +47,20 @@ impl 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) {
|
||||
(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),_) => {
|
||||
let h = self.get_num_lines(w as usize) as u32;
|
||||
Size::new(w, h)
|
||||
Vec2::new(w, h)
|
||||
},
|
||||
(_,DimensionRequest::Fixed(h)) => {
|
||||
let w = self.get_num_cols(h as usize) as u32;
|
||||
Size::new(w, h)
|
||||
Vec2::new(w, h)
|
||||
},
|
||||
(DimensionRequest::AtMost(_),DimensionRequest::AtMost(_)) => 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;
|
||||
|
||||
pub use box_view::BoxView;
|
||||
pub use stack_view::StackView;
|
||||
pub use text_view::TextView;
|
||||
|
||||
use super::Size;
|
||||
use vec2::Vec2;
|
||||
use printer::Printer;
|
||||
|
||||
/// Describe constraints on a view layout in one dimension.
|
||||
#[derive(PartialEq,Clone,Copy)]
|
||||
@ -34,12 +33,12 @@ pub trait View {
|
||||
fn on_key_event(&mut self, i32) -> EventResult { EventResult::Ignored }
|
||||
|
||||
/// 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
|
||||
/// propagate the information to its children.
|
||||
fn layout(&mut self, Size) { }
|
||||
fn layout(&mut self, Vec2) { }
|
||||
|
||||
/// 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