First commit

This commit is contained in:
Alexandre Bury 2015-05-09 12:18:25 -07:00
commit 13c4e86779
7 changed files with 191 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
target
*.swp
Cargo.lock

11
Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "cursive"
version = "0.1.0"
authors = ["Alexandre Bury <alexandre.bury@gmail.com>"]
[lib]
name = "cursive"
[dependencies.ncurses]
git = "https://github.com/jeaye/ncurses-rs"

0
src/example.rs Normal file
View File

4
src/focus.rs Normal file
View File

@ -0,0 +1,4 @@
pub enum FocusChange {
KeptFocus,
LostFocus,
}

65
src/lib.rs Normal file
View File

@ -0,0 +1,65 @@
extern crate ncurses;
pub mod focus;
pub mod view;
pub use self::view::{View,TextView,Button,Dialog,BackgroundView};
use std::ops::DerefMut;
pub struct Cursive {
background: Box<View>,
layers: Vec<Box<View>>,
running: bool,
}
pub type Callback = Fn(&mut Cursive);
impl Cursive {
pub fn new() -> Self {
ncurses::initscr();
ncurses::keypad(ncurses::stdscr, true);
ncurses::noecho();
Cursive{
background: Box::new(BackgroundView),
layers: Vec::new(),
running: true,
}
}
pub fn new_layer<V: 'static + View>(&mut self, view: V) {
self.layers.push(Box::new(view));
}
pub fn run(&mut self) {
while self.running {
ncurses::refresh();
// Handle event
match ncurses::getch() {
10 => {
let cb = self.layers.last_mut().unwrap_or(&mut self.background).click();
cb.map(|cb| cb(self));
},
ncurses::KEY_LEFT => { self.layers.last_mut().unwrap_or(&mut self.background).focus_left(); },
ncurses::KEY_RIGHT => { self.layers.last_mut().unwrap_or(&mut self.background).focus_right(); },
ncurses::KEY_DOWN => { self.layers.last_mut().unwrap_or(&mut self.background).focus_bottom(); },
ncurses::KEY_UP => { self.layers.last_mut().unwrap_or(&mut self.background).focus_top(); },
a => println!("Key: {}", a),
}
}
}
pub fn quit(&mut self) {
self.running = false;
println!("Quitting now!");
}
}
impl Drop for Cursive {
fn drop(&mut self) {
ncurses::endwin();
}
}

13
src/main.rs Normal file
View File

@ -0,0 +1,13 @@
extern crate cursive;
use cursive::{Cursive,Dialog};
fn main() {
let mut siv = Cursive::new();
siv.new_layer(
Dialog::new("Hello World !")
.button("ok", |s| s.quit() ));
siv.run();
}

95
src/view.rs Normal file
View File

@ -0,0 +1,95 @@
use super::Cursive;
use super::Callback;
use std::rc::Rc;
use ncurses;
use focus::FocusChange;
pub trait ToView {
fn to_view(self) -> Box<View>;
}
impl<'a> ToView for &'a str {
fn to_view(self) -> Box<View> {
Box::new(TextView::new(self))
}
}
pub trait View {
fn focus_left(&mut self) -> FocusChange { FocusChange::LostFocus }
fn focus_right(&mut self) -> FocusChange { FocusChange::LostFocus }
fn focus_bottom(&mut self) -> FocusChange { FocusChange::LostFocus }
fn focus_top(&mut self) -> FocusChange { FocusChange::LostFocus }
fn click(&mut self) -> Option<Rc<Box<Callback>>> { None }
}
pub struct TextView {
content: String,
}
impl TextView {
pub fn new(content: &str) -> Self {
TextView {
content: content.to_string(),
}
}
}
impl View for TextView {
}
pub struct Button {
label: String,
callback: Rc<Box<Fn(&mut Cursive)>>,
}
impl Button {
pub fn new<F>(label: &str, callback: F) -> Self
where F: 'static + Fn(&mut Cursive) {
Button {
label: label.to_string(),
callback: Rc::new(Box::new(callback)),
}
}
}
pub struct Dialog<'a> {
view: Box<View>,
buttons: Vec<Button>,
focus: Option<&'a Button>,
}
impl<'a> Dialog<'a> {
pub fn new<V: 'static + ToView>(view: V) -> Self {
Dialog{
view: view.to_view(),
buttons: Vec::new(),
focus: None,
}
}
pub fn button<F>(mut self, label: &str, callback: F) -> Self
where F: 'static + Fn(&mut Cursive) {
self.buttons.push(Button::new(label, callback));
self
}
}
impl<'a> View for Dialog<'a> {
fn click(&mut self) -> Option<Rc<Box<Callback>>> {
match self.focus {
None => return None,
Some(btn) => return Some(self.buttons[0].callback.clone()),
}
}
}
pub struct BackgroundView;
impl View for BackgroundView {
}