From 13c4e86779d0a9fd60eafbe6aaed2490446fd9e0 Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Sat, 9 May 2015 12:18:25 -0700 Subject: [PATCH] First commit --- .gitignore | 3 ++ Cargo.toml | 11 ++++++ src/example.rs | 0 src/focus.rs | 4 +++ src/lib.rs | 65 ++++++++++++++++++++++++++++++++++ src/main.rs | 13 +++++++ src/view.rs | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/example.rs create mode 100644 src/focus.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs create mode 100644 src/view.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..478a37b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target +*.swp +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e89610f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "cursive" +version = "0.1.0" +authors = ["Alexandre Bury "] + +[lib] +name = "cursive" + +[dependencies.ncurses] +git = "https://github.com/jeaye/ncurses-rs" + diff --git a/src/example.rs b/src/example.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/focus.rs b/src/focus.rs new file mode 100644 index 0000000..485b665 --- /dev/null +++ b/src/focus.rs @@ -0,0 +1,4 @@ +pub enum FocusChange { + KeptFocus, + LostFocus, +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..27ac02c --- /dev/null +++ b/src/lib.rs @@ -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, + layers: Vec>, + + 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(&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(); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..93eb4e4 --- /dev/null +++ b/src/main.rs @@ -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(); +} diff --git a/src/view.rs b/src/view.rs new file mode 100644 index 0000000..45a00c4 --- /dev/null +++ b/src/view.rs @@ -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; +} + +impl<'a> ToView for &'a str { + fn to_view(self) -> Box { + 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>> { 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>, +} + +impl Button { + pub fn new(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, + buttons: Vec