Add EditView

TODO: proper visualization:
* Display cursor when focused (instead of color change)
* Do not use HIGHLIGHT, but something like INVERTED
This commit is contained in:
Alexandre Bury 2015-05-26 15:46:05 -07:00
parent 0dc079233a
commit e8fcaabd6c
7 changed files with 118 additions and 1 deletions

View File

@ -36,3 +36,7 @@ path = "examples/logs.rs"
[[example]] [[example]]
name = "mutation" name = "mutation"
path = "examples/mutation.rs" path = "examples/mutation.rs"
[[example]]
name = "edit"
path = "examples/edit.rs"

22
examples/edit.rs Normal file
View File

@ -0,0 +1,22 @@
extern crate cursive;
use cursive::{Cursive};
use cursive::view::{Dialog,IdView,EditView,Selector,TextView};
fn main() {
let mut siv = Cursive::new();
siv.add_layer(Dialog::new(IdView::new("edit", EditView::new()))
.title("Enter your name")
.button("Ok", |s| {
let content = {
let name = s.find::<EditView>(&Selector::Id("edit")).unwrap().get_content();
format!("Hello {}", name)
};
s.pop_layer();
s.add_layer(Dialog::new(TextView::new(&content))
.button("Quit", |s| s.quit()));
}));
siv.run();
}

View File

@ -156,6 +156,10 @@ impl Cursive {
self.screen_mut().add_layer(view); self.screen_mut().add_layer(view);
} }
pub fn pop_layer(&mut self) {
self.screen_mut().pop_layer();
}
// Handles a key event when it was ignored by the current view // Handles a key event when it was ignored by the current view
fn on_key_event(&mut self, ch: i32) { fn on_key_event(&mut self, ch: i32) {
let cb = match self.global_callbacks.get(&ch) { let cb = match self.global_callbacks.get(&ch) {

View File

@ -1,11 +1,12 @@
use std::cmp::max; use std::cmp::max;
use std::any::Any;
use ncurses; use ncurses;
use color; use color;
use ::{Cursive}; use ::{Cursive};
use event::EventResult; use event::EventResult;
use view::{View,SizeRequest,DimensionRequest}; use view::{View,SizeRequest,DimensionRequest,Selector};
use view::{Button,SizedView}; use view::{Button,SizedView};
use vec::{Vec2,Vec4,ToVec4}; use vec::{Vec2,Vec4,ToVec4};
use printer::Printer; use printer::Printer;
@ -215,4 +216,8 @@ impl View for Dialog {
self.content.take_focus() self.content.take_focus()
} }
} }
fn find(&mut self, selector: &Selector) -> Option<&mut Any> {
self.content.find(selector)
}
} }

79
src/view/edit_view.rs Normal file
View File

@ -0,0 +1,79 @@
use ncurses;
use color;
use view::{View};
use event::EventResult;
use printer::Printer;
/// Displays an editable text.
pub struct EditView {
content: String,
cursor: usize,
multiline: bool,
}
impl EditView {
pub fn new() -> Self {
EditView {
content: String::new(),
cursor: 0,
multiline: false,
}
}
pub fn set_content<'a>(&mut self, content: &'a str) {
self.content = content.to_string();
}
pub fn get_content(&self) -> &str {
&self.content
}
pub fn content<'a>(mut self, content: &'a str) -> Self {
self.set_content(content);
self
}
}
fn read_char(ch: i32) -> Option<char> {
// Printable ascii range: 32-126
if ch >= ' ' as i32 && ch <= '~' as i32 {
Some(ch as u8 as char)
} else {
None
}
}
impl View for EditView {
fn draw(&mut self, printer: &Printer, focused: bool) {
let style = if focused { color::HIGHLIGHT } else { color::HIGHLIGHT_INACTIVE };
printer.with_style(style, |printer| {
printer.print((0,0), &self.content);
});
}
fn take_focus(&mut self) -> bool {
true
}
fn on_key_event(&mut self, ch: i32) -> EventResult {
if let Some(ch) = read_char(ch) {
self.content.insert(self.cursor, ch);
self.cursor += 1;
return EventResult::Consumed(None);
}
match ch {
ncurses::KEY_HOME => self.cursor = 0,
ncurses::KEY_END => self.cursor = self.content.len(),
ncurses::KEY_LEFT if self.cursor > 0 => self.cursor -= 1,
ncurses::KEY_RIGHT if self.cursor < self.content.len() => self.cursor += 1,
127 if self.cursor > 0 => { self.cursor -= 1; self.content.remove(self.cursor); },
330 if self.cursor < self.content.len() => { self.content.remove(self.cursor); },
_ => return EventResult::Ignored,
}
EventResult::Consumed(None)
}
}

View File

@ -22,6 +22,7 @@ impl <T: View + Any> ViewWrapper for IdView<T> {
wrap_impl!(&self.view); wrap_impl!(&self.view);
fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> { fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> {
println!(" ID VIEWING ");
match selector { match selector {
&Selector::Id(id) if id == self.id => Some(&mut self.view), &Selector::Id(id) if id == self.id => Some(&mut self.view),
s => self.view.find(s), s => self.view.find(s),

View File

@ -12,6 +12,7 @@ mod sized_view;
mod full_view; mod full_view;
mod id_view; mod id_view;
mod shadow_view; mod shadow_view;
mod edit_view;
use std::any::Any; use std::any::Any;
@ -27,6 +28,7 @@ pub use self::view_wrapper::ViewWrapper;
pub use self::full_view::FullView; pub use self::full_view::FullView;
pub use self::id_view::IdView; pub use self::id_view::IdView;
pub use self::shadow_view::ShadowView; pub use self::shadow_view::ShadowView;
pub use self::edit_view::EditView;
use event::EventResult; use event::EventResult;
use vec::{Vec2,ToVec2}; use vec::{Vec2,ToVec2};