mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Stop using ncurses::WINDOW
Overlap is a mess. Let's do it ourselve.
This commit is contained in:
parent
d9b56574d2
commit
7e823435cd
@ -6,11 +6,14 @@ use cursive::view::{IdView,TextView,Dialog,Selector};
|
||||
fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
|
||||
siv.add_layer(IdView::new("text", TextView::new("Aaahh\nAaaah\nAaaah\nAaaaah\nAaaaah\nAaaaah\nAaaaah")));
|
||||
siv.add_global_callback('q' as i32, |s,_| s.quit());
|
||||
|
||||
siv.add_layer(IdView::new("text", TextView::new("Aaahh\nAaaah\nAaaah\nAaaaah\nAaaaah\nAaaaah\nAaaaah\nAaaaaah\nAaaaah")));
|
||||
|
||||
siv.add_layer(Dialog::new(TextView::new("Tak!"))
|
||||
.button("Change", |s,_| s.find::<TextView>(&Selector::Id("text")).unwrap()
|
||||
.set_content("Bleeeeh") ));
|
||||
.set_content("Bleeeeh\nBleeeeeeeeeeh\nBleeeh") )
|
||||
.dismiss_button("Ok"));
|
||||
|
||||
siv.run();
|
||||
}
|
||||
|
@ -188,11 +188,11 @@ impl Cursive {
|
||||
|
||||
fn draw(&mut self) {
|
||||
let printer = Printer {
|
||||
win: ncurses::stdscr,
|
||||
offset: Vec2::new(0,0),
|
||||
size: self.screen_size(),
|
||||
};
|
||||
self.screen_mut().draw(&printer, true);
|
||||
ncurses::refresh();
|
||||
}
|
||||
|
||||
/// Runs the event loop.
|
||||
|
@ -5,50 +5,18 @@ use ncurses;
|
||||
use color;
|
||||
use vec::{Vec2,ToVec2};
|
||||
|
||||
/// Wrapper around a subset of a ncurses window.
|
||||
/// Convenient interface to draw on a subset of the screen.
|
||||
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,
|
||||
}
|
||||
|
||||
/// Wrapper around a parent printer that applies a style to prints.
|
||||
pub struct StyledPrinter<'a> {
|
||||
parent: &'a Printer,
|
||||
style: color::ThemeColor,
|
||||
}
|
||||
|
||||
impl <'a> StyledPrinter<'a> {
|
||||
/// Wrapper around the parent's `print` method with `self.style` applied.
|
||||
pub fn print<S: ToVec2>(&self, pos: S, text: &str) {
|
||||
ncurses::wattron(self.parent.win, ncurses::COLOR_PAIR(self.style) as i32);
|
||||
self.parent.print(pos, text);
|
||||
ncurses::wattroff(self.parent.win, ncurses::COLOR_PAIR(self.style) as i32);
|
||||
}
|
||||
|
||||
/// Wrapper around the parent's `print_vline` method with `self.style` applied.
|
||||
pub fn print_vline<T: ToVec2>(&self, start: T, len: u32, c: u64) {
|
||||
ncurses::wattron(self.parent.win, ncurses::COLOR_PAIR(self.style) as i32);
|
||||
self.parent.print_vline(start, len, c);
|
||||
ncurses::wattroff(self.parent.win, ncurses::COLOR_PAIR(self.style) as i32);
|
||||
}
|
||||
|
||||
/// Wrapper around the parent's `print_hline` method with `self.style` applied.
|
||||
pub fn print_hline<T: ToVec2>(&self, start: T, len: u32, c: u64) {
|
||||
ncurses::wattron(self.parent.win, ncurses::COLOR_PAIR(self.style) as i32);
|
||||
self.parent.print_hline(start, len, c);
|
||||
ncurses::wattroff(self.parent.win, ncurses::COLOR_PAIR(self.style) as i32);
|
||||
}
|
||||
}
|
||||
|
||||
impl Printer {
|
||||
/// Creates a new printer on the given window.
|
||||
pub fn new<T: ToVec2>(win: ncurses::WINDOW, size: T) -> Self {
|
||||
pub fn new<T: ToVec2>(size: T) -> Self {
|
||||
Printer {
|
||||
win: win,
|
||||
offset: Vec2::zero(),
|
||||
size: size.to_vec2(),
|
||||
}
|
||||
@ -57,28 +25,30 @@ 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() + self.offset;
|
||||
ncurses::mvwprintw(self.win, p.y as i32, p.x as i32, text);
|
||||
ncurses::mvprintw(p.y as i32, p.x as i32, text);
|
||||
}
|
||||
|
||||
/// Prints a vertical line using the given character.
|
||||
pub fn print_vline<T: ToVec2>(&self, start: T, len: u32, c: u64) {
|
||||
let p = start.to_vec2() + self.offset;
|
||||
ncurses::mvwvline(self.win, p.y as i32, p.x as i32, c, len as i32);
|
||||
ncurses::mvvline(p.y as i32, p.x as i32, c, len as i32);
|
||||
}
|
||||
|
||||
/// Prints a horizontal line using the given character.
|
||||
pub fn print_hline<T: ToVec2>(&self, start: T, len: u32, c: u64) {
|
||||
let p = start.to_vec2() + self.offset;
|
||||
ncurses::mvwhline(self.win, p.y as i32, p.x as i32, c, len as i32);
|
||||
ncurses::mvhline(p.y as i32, p.x as i32, c, len as i32);
|
||||
}
|
||||
|
||||
/// Returns a wrapper around this printer,
|
||||
/// that will apply the given style on prints.
|
||||
pub fn style<'a>(&'a self, style: color::ThemeColor) -> StyledPrinter<'a> {
|
||||
StyledPrinter {
|
||||
parent: self,
|
||||
style: style,
|
||||
}
|
||||
pub fn with_style<'a, F>(&'a self, style: color::ThemeColor, f: F)
|
||||
where F: Fn(&Printer)
|
||||
{
|
||||
ncurses::attron(ncurses::COLOR_PAIR(style));
|
||||
f(self);
|
||||
ncurses::attroff(ncurses::COLOR_PAIR(style));
|
||||
ncurses::attron(ncurses::COLOR_PAIR(color::PRIMARY));
|
||||
}
|
||||
|
||||
/// Prints a rectangular box.
|
||||
@ -92,8 +62,6 @@ impl Printer {
|
||||
let start_v = start.to_vec2();
|
||||
let size_v = size.to_vec2() - (1,1);
|
||||
|
||||
|
||||
|
||||
self.print(start_v, "┌");
|
||||
self.print(start_v + size_v.keep_x(), "┐");
|
||||
self.print(start_v + size_v.keep_y(), "└");
|
||||
@ -109,7 +77,6 @@ impl Printer {
|
||||
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()),
|
||||
|
@ -32,10 +32,11 @@ impl View for Button {
|
||||
let style = if !focused { color::PRIMARY } else { color::HIGHLIGHT };
|
||||
let x = printer.size.x - 1;
|
||||
|
||||
let printer = printer.style(style);
|
||||
printer.print((1u32,0u32), &self.label);
|
||||
printer.print((0u32,0u32), "<");
|
||||
printer.print((x,0), ">");
|
||||
printer.with_style(style, |printer| {
|
||||
printer.print((1u32,0u32), &self.label);
|
||||
printer.print((0u32,0u32), "<");
|
||||
printer.print((x,0), ">");
|
||||
});
|
||||
}
|
||||
|
||||
fn get_min_size(&self, _: SizeRequest) -> Vec2 {
|
||||
|
@ -106,7 +106,7 @@ impl View for Dialog {
|
||||
printer.print((x-2,0), "┤ ");
|
||||
printer.print((x+self.title.len() as u32,0), " ├");
|
||||
|
||||
printer.style(color::TITLE_PRIMARY).print((x,0), &self.title);
|
||||
printer.with_style(color::TITLE_PRIMARY, |p| p.print((x,0), &self.title));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ mod button;
|
||||
mod sized_view;
|
||||
mod full_view;
|
||||
mod id_view;
|
||||
mod shadow_view;
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
@ -25,6 +26,7 @@ pub use self::sized_view::SizedView;
|
||||
pub use self::view_wrapper::ViewWrapper;
|
||||
pub use self::full_view::FullView;
|
||||
pub use self::id_view::IdView;
|
||||
pub use self::shadow_view::ShadowView;
|
||||
|
||||
use event::EventResult;
|
||||
use vec::{Vec2,ToVec2};
|
||||
|
53
src/view/shadow_view.rs
Normal file
53
src/view/shadow_view.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use view::{View,ViewWrapper,SizeRequest};
|
||||
use printer::Printer;
|
||||
use vec::Vec2;
|
||||
use color;
|
||||
|
||||
pub struct ShadowView<T: View> {
|
||||
pub view: T,
|
||||
}
|
||||
|
||||
impl <T: View> ShadowView<T> {
|
||||
pub fn new(view: T) -> Self {
|
||||
ShadowView {
|
||||
view: view,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <T: View> ViewWrapper for ShadowView<T> {
|
||||
|
||||
wrap_impl!(&self.view);
|
||||
|
||||
fn wrap_get_min_size(&self, req: SizeRequest) -> Vec2 {
|
||||
self.view.get_min_size(req.reduced((2,2))) + (2,2)
|
||||
}
|
||||
|
||||
fn wrap_layout(&mut self, size: Vec2) {
|
||||
self.view.layout(size - (2,2));
|
||||
}
|
||||
|
||||
fn wrap_draw(&mut self, printer: &Printer, focused: bool) {
|
||||
|
||||
{
|
||||
printer.with_style(color::PRIMARY, |printer| {
|
||||
// Draw the view background
|
||||
for y in 1..printer.size.y-1 {
|
||||
printer.print_hline((1,y), printer.size.x-2, ' ' as u64);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
self.view.draw(&printer.sub_printer(Vec2::new(1,1), printer.size - (2,2)), focused);
|
||||
|
||||
|
||||
let h = printer.size.y-1;
|
||||
let w = printer.size.x-1;
|
||||
|
||||
printer.with_style(color::SHADOW, |printer| {
|
||||
printer.print_hline((2,h), w-1, ' ' as u64);
|
||||
printer.print_vline((w,2), h-1, ' ' as u64);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
use std::cmp::max;
|
||||
use std::any::Any;
|
||||
|
||||
use ncurses;
|
||||
|
||||
use color;
|
||||
use vec::Vec2;
|
||||
use view::{View,SizeRequest,DimensionRequest,Selector};
|
||||
use view::{View,SizeRequest,DimensionRequest,Selector,ShadowView};
|
||||
use event::EventResult;
|
||||
use printer::Printer;
|
||||
|
||||
@ -18,7 +16,6 @@ pub struct StackView {
|
||||
struct Layer {
|
||||
view: Box<View>,
|
||||
size: Vec2,
|
||||
win: Option<ncurses::WINDOW>,
|
||||
}
|
||||
|
||||
impl StackView {
|
||||
@ -32,9 +29,8 @@ impl StackView {
|
||||
/// Add new view on top of the stack.
|
||||
pub fn add_layer<T: 'static + View>(&mut self, view: T) {
|
||||
self.layers.push(Layer {
|
||||
view: Box::new(view),
|
||||
view: Box::new(ShadowView::new(view)),
|
||||
size: Vec2::new(0,0),
|
||||
win: None,
|
||||
});
|
||||
}
|
||||
|
||||
@ -44,26 +40,17 @@ impl StackView {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl View for StackView {
|
||||
fn draw(&mut self, printer: &Printer, focused: bool) {
|
||||
ncurses::wrefresh(printer.win);
|
||||
for v in self.layers.iter_mut() {
|
||||
// Center the view
|
||||
v.view.draw(&Printer::new(v.win.unwrap(), v.size), focused);
|
||||
|
||||
let h = v.size.y;
|
||||
let w = v.size.x;
|
||||
let x = (printer.size.x - w) / 2;
|
||||
let y = (printer.size.y - h) / 2;
|
||||
let size = v.size;
|
||||
let offset = (printer.size - size) / 2;
|
||||
v.view.draw(&printer.sub_printer(offset, size), focused);
|
||||
|
||||
|
||||
let printer = printer.style(color::HIGHLIGHT);
|
||||
printer.print_hline((x+1,y+h), w, ' ' as u64);
|
||||
printer.print_vline((x+w,y+1), h, ' ' as u64);
|
||||
|
||||
// v.view.draw(&printer.sub_printer(offset, v.size), focused);
|
||||
ncurses::wrefresh(v.win.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,14 +74,6 @@ impl View for StackView {
|
||||
let w = layer.size.x as i32;
|
||||
let x = (size.x as i32 - w) / 2;
|
||||
let y = (size.y as i32 - h) / 2;
|
||||
let win = ncurses::newwin(h, w, y, x);
|
||||
ncurses::wbkgd(win, ncurses::COLOR_PAIR(color::PRIMARY));
|
||||
|
||||
match layer.win {
|
||||
None => (),
|
||||
Some(w) => { ncurses::delwin(w); },
|
||||
}
|
||||
layer.win = Some(win);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user