mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Fix clippy warnings
This commit is contained in:
parent
80b219f34a
commit
d02c30ae9f
@ -37,8 +37,8 @@ impl View for KeyCodeView {
|
|||||||
|
|
||||||
fn on_event(&mut self, event: Event) -> EventResult {
|
fn on_event(&mut self, event: Event) -> EventResult {
|
||||||
let line = match event {
|
let line = match event {
|
||||||
Event::CharEvent(c) => format!("Char: {}", c),
|
Event::Char(c) => format!("Char: {}", c),
|
||||||
Event::KeyEvent(key) => format!("Key: {}", key),
|
Event::Key(key) => format!("Key: {}", key),
|
||||||
};
|
};
|
||||||
self.history.push(line);
|
self.history.push(line);
|
||||||
|
|
||||||
|
10
src/event.rs
10
src/event.rs
@ -245,7 +245,7 @@ impl Key {
|
|||||||
// TODO: shift and ctrl Fn keys
|
// TODO: shift and ctrl Fn keys
|
||||||
// Avoids 8-10 (H,I,J), they are used by other commands.
|
// Avoids 8-10 (H,I,J), they are used by other commands.
|
||||||
c @ 1...7 | c @ 11...25 => {
|
c @ 1...7 | c @ 11...25 => {
|
||||||
Key::CtrlChar(('a' as u8 + (c - 1) as u8) as char)
|
Key::CtrlChar((b'a' + (c - 1) as u8) as char)
|
||||||
}
|
}
|
||||||
_ => Key::Unknown(ch),
|
_ => Key::Unknown(ch),
|
||||||
}
|
}
|
||||||
@ -362,9 +362,9 @@ impl fmt::Display for Key {
|
|||||||
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
|
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
/// A text character was entered.
|
/// A text character was entered.
|
||||||
CharEvent(char),
|
Char(char),
|
||||||
/// A key was pressed.
|
/// A key was pressed.
|
||||||
KeyEvent(Key),
|
Key(Key),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic trait to convert a value to an event.
|
/// Generic trait to convert a value to an event.
|
||||||
@ -374,13 +374,13 @@ pub trait ToEvent {
|
|||||||
|
|
||||||
impl ToEvent for char {
|
impl ToEvent for char {
|
||||||
fn to_event(self) -> Event {
|
fn to_event(self) -> Event {
|
||||||
Event::CharEvent(self)
|
Event::Char(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToEvent for Key {
|
impl ToEvent for Key {
|
||||||
fn to_event(self) -> Event {
|
fn to_event(self) -> Event {
|
||||||
Event::KeyEvent(self)
|
Event::Key(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -72,6 +72,12 @@ pub struct Cursive {
|
|||||||
running: bool,
|
running: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Cursive {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Cursive {
|
impl Cursive {
|
||||||
/// Creates a new Cursive root, and initialize ncurses.
|
/// Creates a new Cursive root, and initialize ncurses.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -275,11 +281,11 @@ impl Cursive {
|
|||||||
|
|
||||||
// Is it a UTF-8 starting point?
|
// Is it a UTF-8 starting point?
|
||||||
if 32 <= ch && ch < 0x100 && ch != 127 {
|
if 32 <= ch && ch < 0x100 && ch != 127 {
|
||||||
Event::CharEvent(utf8::read_char(ch as u8,
|
Event::Char(utf8::read_char(ch as u8,
|
||||||
|| ncurses::getch() as u8)
|
|| ncurses::getch() as u8)
|
||||||
.unwrap())
|
.unwrap())
|
||||||
} else {
|
} else {
|
||||||
Event::KeyEvent(Key::from_ncurses(ch))
|
Event::Key(Key::from_ncurses(ch))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +50,8 @@ impl MenuTree {
|
|||||||
|
|
||||||
pub fn new_subtree(&mut self, title: &str) -> &mut Box<MenuTree> {
|
pub fn new_subtree(&mut self, title: &str) -> &mut Box<MenuTree> {
|
||||||
self.add_subtree(title, MenuTree::new());
|
self.add_subtree(title, MenuTree::new());
|
||||||
match self.children.last_mut().unwrap() {
|
match *self.children.last_mut().unwrap() {
|
||||||
&mut MenuItem::Subtree(_, ref mut tree) => tree,
|
MenuItem::Subtree(_, ref mut tree) => tree,
|
||||||
_ => panic!("??"),
|
_ => panic!("??"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ impl Menubar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_event(&mut self, event: Event) -> Option<Rc<Callback>> {
|
pub fn on_event(&mut self, event: Event) -> Option<Rc<Callback>> {
|
||||||
|
let _ = &event;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,10 @@ impl Orientation {
|
|||||||
pub fn stack<'a, T: Iterator<Item = &'a Vec2>>(&self, iter: T) -> Vec2 {
|
pub fn stack<'a, T: Iterator<Item = &'a Vec2>>(&self, iter: T) -> Vec2 {
|
||||||
match *self {
|
match *self {
|
||||||
Orientation::Horizontal => {
|
Orientation::Horizontal => {
|
||||||
iter.fold(Vec2::zero(), |a, b| a.stack_horizontal(&b))
|
iter.fold(Vec2::zero(), |a, b| a.stack_horizontal(b))
|
||||||
}
|
}
|
||||||
Orientation::Vertical => {
|
Orientation::Vertical => {
|
||||||
iter.fold(Vec2::zero(), |a, b| a.stack_vertical(&b))
|
iter.fold(Vec2::zero(), |a, b| a.stack_vertical(b))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ impl Printer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let p = p + self.offset;
|
let p = p + self.offset;
|
||||||
if text.contains("%") {
|
if text.contains('%') {
|
||||||
ncurses::mvprintw(p.y as i32,
|
ncurses::mvprintw(p.y as i32,
|
||||||
p.x as i32,
|
p.x as i32,
|
||||||
&text.replace("%", "%%"));
|
&text.replace("%", "%%"));
|
||||||
@ -98,7 +98,7 @@ impl Printer {
|
|||||||
/// printer.print((0,0), "This text is highlighted!");
|
/// printer.print((0,0), "This text is highlighted!");
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub fn with_color<'a, F>(&'a self, c: ColorPair, f: F)
|
pub fn with_color<F>(&self, c: ColorPair, f: F)
|
||||||
where F: Fn(&Printer)
|
where F: Fn(&Printer)
|
||||||
{
|
{
|
||||||
self.with_style(ncurses::COLOR_PAIR(c.ncurses_id()), f);
|
self.with_style(ncurses::COLOR_PAIR(c.ncurses_id()), f);
|
||||||
@ -109,7 +109,7 @@ impl Printer {
|
|||||||
/// like `ncurses::A_BOLD()` or `ncurses::A_REVERSE()`.
|
/// like `ncurses::A_BOLD()` or `ncurses::A_REVERSE()`.
|
||||||
///
|
///
|
||||||
/// Will probably use a cursive enum some day.
|
/// Will probably use a cursive enum some day.
|
||||||
pub fn with_style<'a, F>(&'a self, style: ncurses::attr_t, f: F)
|
pub fn with_style<F>(&self, style: ncurses::attr_t, f: F)
|
||||||
where F: Fn(&Printer)
|
where F: Fn(&Printer)
|
||||||
{
|
{
|
||||||
ncurses::attron(style);
|
ncurses::attron(style);
|
||||||
|
35
src/theme.rs
35
src/theme.rs
@ -80,24 +80,18 @@ impl Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load(&mut self, table: &toml::Table) {
|
fn load(&mut self, table: &toml::Table) {
|
||||||
match table.get("shadow") {
|
if let Some(&toml::Value::Boolean(shadow)) = table.get("shadow") {
|
||||||
Some(&toml::Value::Boolean(shadow)) => self.shadow = shadow,
|
self.shadow = shadow;
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match table.get("borders") {
|
if let Some(&toml::Value::String(ref borders)) = table.get("borders") {
|
||||||
Some(&toml::Value::String(ref borders)) => {
|
if let Some(borders) = BorderStyle::from(borders) {
|
||||||
match BorderStyle::from(borders) {
|
self.borders = borders;
|
||||||
Some(borders) => self.borders = borders,
|
|
||||||
None => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
match table.get("colors") {
|
if let Some(&toml::Value::Table(ref table)) = table.get("colors") {
|
||||||
Some(&toml::Value::Table(ref table)) => self.colors.load(table),
|
self.colors.load(table);
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,14 +219,14 @@ impl Color {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// An error occured when reading the file.
|
/// An error occured when reading the file.
|
||||||
IoError(io::Error),
|
Io(io::Error),
|
||||||
/// An error occured when parsing the toml content.
|
/// An error occured when parsing the toml content.
|
||||||
ParseError,
|
Parse,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
impl From<io::Error> for Error {
|
||||||
fn from(err: io::Error) -> Self {
|
fn from(err: io::Error) -> Self {
|
||||||
Error::IoError(err)
|
Error::Io(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,14 +263,11 @@ impl Color {
|
|||||||
}
|
}
|
||||||
Some(&toml::Value::Array(ref array)) => {
|
Some(&toml::Value::Array(ref array)) => {
|
||||||
for color in array.iter() {
|
for color in array.iter() {
|
||||||
match color {
|
if let toml::Value::String(ref color) = *color {
|
||||||
&toml::Value::String(ref color) => {
|
|
||||||
if self.load_value(color, new_id) {
|
if self.load_value(color, new_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -297,7 +288,7 @@ impl Color {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !value.starts_with("#") {
|
if !value.starts_with('#') {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +389,7 @@ pub fn load_theme<P: AsRef<Path>>(filename: P) -> Result<Theme, Error> {
|
|||||||
let mut parser = toml::Parser::new(&content);
|
let mut parser = toml::Parser::new(&content);
|
||||||
let table = match parser.parse() {
|
let table = match parser.parse() {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => return Err(Error::ParseError),
|
None => return Err(Error::Parse),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut theme = Theme::default();
|
let mut theme = Theme::default();
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
use vec::{ToVec2, Vec2};
|
use vec::{ToVec2, Vec2};
|
||||||
use super::{DimensionRequest, SizeRequest, View, ViewWrapper};
|
use super::{DimensionRequest, SizeRequest, View, ViewWrapper};
|
||||||
|
|
||||||
/// BoxView is a wrapper around an other view, with a given minimum size.
|
/// `BoxView` is a wrapper around an other view, with a given minimum size.
|
||||||
pub struct BoxView<T: View> {
|
pub struct BoxView<T: View> {
|
||||||
size: Vec2,
|
size: Vec2,
|
||||||
view: T,
|
view: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> BoxView<T> {
|
impl<T: View> BoxView<T> {
|
||||||
/// Creates a new BoxView with the given minimum size and content
|
/// Creates a new `BoxView` with the given minimum size and content
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -50,7 +50,7 @@ impl View for Button {
|
|||||||
fn on_event(&mut self, event: Event) -> EventResult {
|
fn on_event(&mut self, event: Event) -> EventResult {
|
||||||
match event {
|
match event {
|
||||||
// 10 is the ascii code for '\n', that is the return key
|
// 10 is the ascii code for '\n', that is the return key
|
||||||
Event::KeyEvent(Key::Enter) => {
|
Event::Key(Key::Enter) => {
|
||||||
EventResult::Consumed(Some(self.callback.clone()))
|
EventResult::Consumed(Some(self.callback.clone()))
|
||||||
}
|
}
|
||||||
_ => EventResult::Ignored,
|
_ => EventResult::Ignored,
|
||||||
|
@ -59,7 +59,7 @@ impl Dialog {
|
|||||||
/// Adds a button to the dialog with the given label and callback.
|
/// Adds a button to the dialog with the given label and callback.
|
||||||
///
|
///
|
||||||
/// Consumes and returns self for easy chaining.
|
/// Consumes and returns self for easy chaining.
|
||||||
pub fn button<'a, F>(mut self, label: &'a str, cb: F) -> Self
|
pub fn button<F>(mut self, label: &str, cb: F) -> Self
|
||||||
where F: Fn(&mut Cursive) + 'static
|
where F: Fn(&mut Cursive) + 'static
|
||||||
{
|
{
|
||||||
self.buttons.push(SizedView::new(Button::new(label, cb)));
|
self.buttons.push(SizedView::new(Button::new(label, cb)));
|
||||||
@ -84,7 +84,7 @@ impl Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Shortcut method to add a button that will dismiss the dialog.
|
/// Shortcut method to add a button that will dismiss the dialog.
|
||||||
pub fn dismiss_button<'a>(self, label: &'a str) -> Self {
|
pub fn dismiss_button(self, label: &str) -> Self {
|
||||||
self.button(label, |s| s.screen_mut().pop_layer())
|
self.button(label, |s| s.screen_mut().pop_layer())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ impl View for Dialog {
|
|||||||
|
|
||||||
printer.print_box(Vec2::new(0, 0), printer.size);
|
printer.print_box(Vec2::new(0, 0), printer.size);
|
||||||
|
|
||||||
if self.title.len() > 0 {
|
if !self.title.is_empty() {
|
||||||
let len = self.title.chars().count();
|
let len = self.title.chars().count();
|
||||||
let x = (printer.size.x - len) / 2;
|
let x = (printer.size.x - len) / 2;
|
||||||
printer.print((x - 2, 0), "┤ ");
|
printer.print((x - 2, 0), "┤ ");
|
||||||
@ -172,7 +172,7 @@ impl View for Dialog {
|
|||||||
if !self.buttons.is_empty() {
|
if !self.buttons.is_empty() {
|
||||||
buttons_size.x += self.buttons.len() - 1;
|
buttons_size.x += self.buttons.len() - 1;
|
||||||
}
|
}
|
||||||
for button in self.buttons.iter() {
|
for button in &self.buttons {
|
||||||
let s = button.view.get_min_size(req);
|
let s = button.view.get_min_size(req);
|
||||||
buttons_size.x += s.x;
|
buttons_size.x += s.x;
|
||||||
buttons_size.y = max(buttons_size.y, s.y + 1);
|
buttons_size.y = max(buttons_size.y, s.y + 1);
|
||||||
@ -185,7 +185,7 @@ impl View for Dialog {
|
|||||||
self.padding.combined() +
|
self.padding.combined() +
|
||||||
self.borders.combined();
|
self.borders.combined();
|
||||||
|
|
||||||
if self.title.len() > 0 {
|
if !self.title.is_empty() {
|
||||||
// If we have a title, we have to fit it too!
|
// If we have a title, we have to fit it too!
|
||||||
inner_size.x = max(inner_size.x, self.title.chars().count() + 6);
|
inner_size.x = max(inner_size.x, self.title.chars().count() + 6);
|
||||||
}
|
}
|
||||||
@ -220,16 +220,13 @@ impl View for Dialog {
|
|||||||
match self.content.on_event(event) {
|
match self.content.on_event(event) {
|
||||||
EventResult::Ignored if !self.buttons.is_empty() => {
|
EventResult::Ignored if !self.buttons.is_empty() => {
|
||||||
match event {
|
match event {
|
||||||
Event::KeyEvent(Key::Down) => {
|
Event::Key(Key::Down) |
|
||||||
|
Event::Key(Key::Tab) |
|
||||||
|
Event::Key(Key::ShiftTab) => {
|
||||||
// Default to leftmost button when going down.
|
// Default to leftmost button when going down.
|
||||||
self.focus = Focus::Button(0);
|
self.focus = Focus::Button(0);
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Tab) |
|
|
||||||
Event::KeyEvent(Key::ShiftTab) => {
|
|
||||||
self.focus = Focus::Button(0);
|
|
||||||
EventResult::Consumed(None)
|
|
||||||
}
|
|
||||||
_ => EventResult::Ignored,
|
_ => EventResult::Ignored,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,16 +239,9 @@ impl View for Dialog {
|
|||||||
EventResult::Ignored => {
|
EventResult::Ignored => {
|
||||||
match event {
|
match event {
|
||||||
// Up goes back to the content
|
// Up goes back to the content
|
||||||
Event::KeyEvent(Key::Up) => {
|
Event::Key(Key::Up) |
|
||||||
if self.content.take_focus() {
|
Event::Key(Key::Tab) |
|
||||||
self.focus = Focus::Content;
|
Event::Key(Key::ShiftTab) => {
|
||||||
EventResult::Consumed(None)
|
|
||||||
} else {
|
|
||||||
EventResult::Ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Event::KeyEvent(Key::Tab) |
|
|
||||||
Event::KeyEvent(Key::ShiftTab) => {
|
|
||||||
if self.content.take_focus() {
|
if self.content.take_focus() {
|
||||||
self.focus = Focus::Content;
|
self.focus = Focus::Content;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
@ -260,13 +250,13 @@ impl View for Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Left and Right move to other buttons
|
// Left and Right move to other buttons
|
||||||
Event::KeyEvent(Key::Right) if i + 1 <
|
Event::Key(Key::Right) if i + 1 <
|
||||||
self.buttons
|
self.buttons
|
||||||
.len() => {
|
.len() => {
|
||||||
self.focus = Focus::Button(i + 1);
|
self.focus = Focus::Button(i + 1);
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Left) if i > 0 => {
|
Event::Key(Key::Left) if i > 0 => {
|
||||||
self.focus = Focus::Button(i - 1);
|
self.focus = Focus::Button(i - 1);
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,12 @@ pub struct EditView {
|
|||||||
* TODO: add a max text length? */
|
* TODO: add a max text length? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for EditView {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EditView {
|
impl EditView {
|
||||||
/// Creates a new, empty edit view.
|
/// Creates a new, empty edit view.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -38,7 +44,7 @@ impl EditView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Replace the entire content of the view with the given one.
|
/// Replace the entire content of the view with the given one.
|
||||||
pub fn set_content<'a>(&mut self, content: &'a str) {
|
pub fn set_content(&mut self, content: &str) {
|
||||||
self.offset = 0;
|
self.offset = 0;
|
||||||
self.content = content.to_string();
|
self.content = content.to_string();
|
||||||
}
|
}
|
||||||
@ -49,7 +55,7 @@ impl EditView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current content to the given value. Convenient chainable method.
|
/// Sets the current content to the given value. Convenient chainable method.
|
||||||
pub fn content<'a>(mut self, content: &'a str) -> Self {
|
pub fn content(mut self, content: &str) -> Self {
|
||||||
self.set_content(content);
|
self.set_content(content);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -130,7 +136,7 @@ impl View for EditView {
|
|||||||
fn on_event(&mut self, event: Event) -> EventResult {
|
fn on_event(&mut self, event: Event) -> EventResult {
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::CharEvent(ch) => {
|
Event::Char(ch) => {
|
||||||
// Find the byte index of the char at self.cursor
|
// Find the byte index of the char at self.cursor
|
||||||
|
|
||||||
match self.content.char_indices().nth(self.cursor) {
|
match self.content.char_indices().nth(self.cursor) {
|
||||||
@ -140,7 +146,7 @@ impl View for EditView {
|
|||||||
// TODO: handle wide (CJK) chars
|
// TODO: handle wide (CJK) chars
|
||||||
self.cursor += 1;
|
self.cursor += 1;
|
||||||
}
|
}
|
||||||
Event::KeyEvent(key) => {
|
Event::Key(key) => {
|
||||||
match key {
|
match key {
|
||||||
Key::Home => self.cursor = 0,
|
Key::Home => self.cursor = 0,
|
||||||
Key::End => self.cursor = self.content.chars().count(),
|
Key::End => self.cursor = self.content.chars().count(),
|
||||||
|
@ -18,12 +18,12 @@ impl<T: View> ViewWrapper for FullView<T> {
|
|||||||
|
|
||||||
fn wrap_get_min_size(&self, req: SizeRequest) -> Vec2 {
|
fn wrap_get_min_size(&self, req: SizeRequest) -> Vec2 {
|
||||||
let w = match req.w {
|
let w = match req.w {
|
||||||
DimensionRequest::Fixed(w) => w,
|
DimensionRequest::Fixed(w) |
|
||||||
DimensionRequest::AtMost(w) => w,
|
DimensionRequest::AtMost(w) => w,
|
||||||
DimensionRequest::Unknown => self.view.get_min_size(req).x,
|
DimensionRequest::Unknown => self.view.get_min_size(req).x,
|
||||||
};
|
};
|
||||||
let h = match req.h {
|
let h = match req.h {
|
||||||
DimensionRequest::Fixed(h) => h,
|
DimensionRequest::Fixed(h) |
|
||||||
DimensionRequest::AtMost(h) => h,
|
DimensionRequest::AtMost(h) => h,
|
||||||
DimensionRequest::Unknown => self.view.get_min_size(req).y,
|
DimensionRequest::Unknown => self.view.get_min_size(req).y,
|
||||||
};
|
};
|
||||||
|
@ -60,7 +60,7 @@ impl LinearLayout {
|
|||||||
|
|
||||||
/// Returns the index of the maximum element.
|
/// Returns the index of the maximum element.
|
||||||
/// WTF isn't it part of standard library??
|
/// WTF isn't it part of standard library??
|
||||||
fn find_max(list: &Vec<usize>) -> usize {
|
fn find_max(list: &[usize]) -> usize {
|
||||||
let mut max_value = 0;
|
let mut max_value = 0;
|
||||||
let mut max = 0;
|
let mut max = 0;
|
||||||
for (i, &x) in list.iter().enumerate() {
|
for (i, &x) in list.iter().enumerate() {
|
||||||
@ -78,7 +78,7 @@ fn find_max(list: &Vec<usize>) -> usize {
|
|||||||
fn share(total: usize, weights: Vec<usize>) -> Vec<usize> {
|
fn share(total: usize, weights: Vec<usize>) -> Vec<usize> {
|
||||||
// It first give a base value to everyone, which is their truncated share.
|
// It first give a base value to everyone, which is their truncated share.
|
||||||
// Then, it gives the rest to the most deserving.
|
// Then, it gives the rest to the most deserving.
|
||||||
if weights.len() == 0 {
|
if weights.is_empty() {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ fn share(total: usize, weights: Vec<usize>) -> Vec<usize> {
|
|||||||
let mut rest = Vec::with_capacity(weights.len());
|
let mut rest = Vec::with_capacity(weights.len());
|
||||||
let mut extra = total;
|
let mut extra = total;
|
||||||
|
|
||||||
for weight in weights.iter() {
|
for weight in &weights {
|
||||||
let b = total * weight / sum_weight;
|
let b = total * weight / sum_weight;
|
||||||
extra -= b;
|
extra -= b;
|
||||||
base.push(b);
|
base.push(b);
|
||||||
@ -190,35 +190,35 @@ impl View for LinearLayout {
|
|||||||
match self.children[self.focus].view.on_event(event) {
|
match self.children[self.focus].view.on_event(event) {
|
||||||
EventResult::Ignored => {
|
EventResult::Ignored => {
|
||||||
match event {
|
match event {
|
||||||
Event::KeyEvent(Key::Tab) if self.focus > 0 => {
|
Event::Key(Key::Tab) if self.focus > 0 => {
|
||||||
self.focus -= 1;
|
self.focus -= 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::ShiftTab) if self.focus + 1 <
|
Event::Key(Key::ShiftTab) if self.focus + 1 <
|
||||||
self.children.len() => {
|
self.children.len() => {
|
||||||
self.focus += 1;
|
self.focus += 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Left) if self.orientation ==
|
Event::Key(Key::Left) if self.orientation ==
|
||||||
Orientation::Horizontal &&
|
Orientation::Horizontal &&
|
||||||
self.focus > 0 => {
|
self.focus > 0 => {
|
||||||
self.focus -= 1;
|
self.focus -= 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Up) if self.orientation ==
|
Event::Key(Key::Up) if self.orientation ==
|
||||||
Orientation::Vertical &&
|
Orientation::Vertical &&
|
||||||
self.focus > 0 => {
|
self.focus > 0 => {
|
||||||
self.focus -= 1;
|
self.focus -= 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Right) if self.orientation ==
|
Event::Key(Key::Right) if self.orientation ==
|
||||||
Orientation::Horizontal &&
|
Orientation::Horizontal &&
|
||||||
self.focus + 1 <
|
self.focus + 1 <
|
||||||
self.children.len() => {
|
self.children.len() => {
|
||||||
self.focus += 1;
|
self.focus += 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Down) if self.orientation ==
|
Event::Key(Key::Down) if self.orientation ==
|
||||||
Orientation::Vertical &&
|
Orientation::Vertical &&
|
||||||
self.focus + 1 <
|
self.focus + 1 <
|
||||||
self.children.len() => {
|
self.children.len() => {
|
||||||
|
@ -5,6 +5,7 @@ use vec::Vec2;
|
|||||||
use printer::Printer;
|
use printer::Printer;
|
||||||
|
|
||||||
/// Provide scrolling functionalities to a view.
|
/// Provide scrolling functionalities to a view.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct ScrollBase {
|
pub struct ScrollBase {
|
||||||
pub start_line: usize,
|
pub start_line: usize,
|
||||||
pub content_height: usize,
|
pub content_height: usize,
|
||||||
|
@ -180,23 +180,23 @@ impl<T: 'static> View for SelectView<T> {
|
|||||||
|
|
||||||
fn on_event(&mut self, event: Event) -> EventResult {
|
fn on_event(&mut self, event: Event) -> EventResult {
|
||||||
match event {
|
match event {
|
||||||
Event::KeyEvent(Key::Up) if self.focus > 0 => self.focus -= 1,
|
Event::Key(Key::Up) if self.focus > 0 => self.focus -= 1,
|
||||||
Event::KeyEvent(Key::Down) if self.focus + 1 <
|
Event::Key(Key::Down) if self.focus + 1 <
|
||||||
self.items.len() => self.focus += 1,
|
self.items.len() => self.focus += 1,
|
||||||
Event::KeyEvent(Key::PageUp) => self.focus -= min(self.focus, 10),
|
Event::Key(Key::PageUp) => self.focus -= min(self.focus, 10),
|
||||||
Event::KeyEvent(Key::PageDown) => {
|
Event::Key(Key::PageDown) => {
|
||||||
self.focus = min(self.focus + 10, self.items.len() - 1)
|
self.focus = min(self.focus + 10, self.items.len() - 1)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Home) => self.focus = 0,
|
Event::Key(Key::Home) => self.focus = 0,
|
||||||
Event::KeyEvent(Key::End) => self.focus = self.items.len() - 1,
|
Event::Key(Key::End) => self.focus = self.items.len() - 1,
|
||||||
Event::KeyEvent(Key::Enter) if self.select_cb.is_some() => {
|
Event::Key(Key::Enter) if self.select_cb.is_some() => {
|
||||||
let cb = self.select_cb.as_ref().unwrap().clone();
|
let cb = self.select_cb.as_ref().unwrap().clone();
|
||||||
let v = self.selection();
|
let v = self.selection();
|
||||||
// We return a Rc<Box<Callback>>
|
// We return a Rc<Box<Callback>>
|
||||||
// With callback being |s| cb(s, &*v)
|
// With callback being |s| cb(s, &*v)
|
||||||
return EventResult::Consumed(Some(Rc::new(Box::new(move |s| cb(s, &*v)))));
|
return EventResult::Consumed(Some(Rc::new(Box::new(move |s| cb(s, &*v)))));
|
||||||
}
|
}
|
||||||
Event::CharEvent(c) => {
|
Event::Char(c) => {
|
||||||
// Starting from the current focus,
|
// Starting from the current focus,
|
||||||
// find the first item that match the char.
|
// find the first item that match the char.
|
||||||
// Cycle back to the beginning of
|
// Cycle back to the beginning of
|
||||||
|
@ -18,6 +18,12 @@ struct Layer {
|
|||||||
virgin: bool,
|
virgin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for StackView {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl StackView {
|
impl StackView {
|
||||||
/// Creates a new empty StackView
|
/// Creates a new empty StackView
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -63,7 +69,7 @@ impl View for StackView {
|
|||||||
w: DimensionRequest::AtMost(size.x),
|
w: DimensionRequest::AtMost(size.x),
|
||||||
h: DimensionRequest::AtMost(size.y),
|
h: DimensionRequest::AtMost(size.y),
|
||||||
};
|
};
|
||||||
for layer in self.layers.iter_mut() {
|
for layer in &mut self.layers {
|
||||||
layer.size = Vec2::min(size, layer.view.get_min_size(req));
|
layer.size = Vec2::min(size, layer.view.get_min_size(req));
|
||||||
layer.view.layout(layer.size);
|
layer.view.layout(layer.size);
|
||||||
// We do it here instead of when adding a new layer because...?
|
// We do it here instead of when adding a new layer because...?
|
||||||
@ -78,7 +84,7 @@ impl View for StackView {
|
|||||||
// The min size is the max of all children's
|
// The min size is the max of all children's
|
||||||
let mut s = Vec2::new(1, 1);
|
let mut s = Vec2::new(1, 1);
|
||||||
|
|
||||||
for layer in self.layers.iter() {
|
for layer in &self.layers {
|
||||||
let vs = layer.view.get_min_size(size);
|
let vs = layer.view.get_min_size(size);
|
||||||
s = Vec2::max(s, vs);
|
s = Vec2::max(s, vs);
|
||||||
}
|
}
|
||||||
@ -94,7 +100,7 @@ impl View for StackView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn find(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn find(&mut self, selector: &Selector) -> Option<&mut Any> {
|
||||||
for layer in self.layers.iter_mut() {
|
for layer in &mut self.layers {
|
||||||
if let Some(any) = layer.view.find(selector) {
|
if let Some(any) = layer.view.find(selector) {
|
||||||
return Some(any);
|
return Some(any);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ fn get_line_span(line: &str, max_width: usize) -> usize {
|
|||||||
// (Or use a common function? Better!)
|
// (Or use a common function? Better!)
|
||||||
let mut lines = 1;
|
let mut lines = 1;
|
||||||
let mut length = 0;
|
let mut length = 0;
|
||||||
for l in line.split(" ").map(|word| word.chars().count()) {
|
for l in line.split(' ').map(|word| word.chars().count()) {
|
||||||
length += l;
|
length += l;
|
||||||
if length > max_width {
|
if length > max_width {
|
||||||
length = l;
|
length = l;
|
||||||
@ -100,7 +100,7 @@ impl TextView {
|
|||||||
/// with the given width.
|
/// with the given width.
|
||||||
fn get_num_lines(&self, max_width: usize) -> usize {
|
fn get_num_lines(&self, max_width: usize) -> usize {
|
||||||
self.content
|
self.content
|
||||||
.split("\n")
|
.split('\n')
|
||||||
.map(|line| get_line_span(line, max_width))
|
.map(|line| get_line_span(line, max_width))
|
||||||
.fold(0, |sum, x| sum + x)
|
.fold(0, |sum, x| sum + x)
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ impl TextView {
|
|||||||
let mut max_width = 0;
|
let mut max_width = 0;
|
||||||
let mut height = 0;
|
let mut height = 0;
|
||||||
|
|
||||||
for line in self.content.split("\n") {
|
for line in self.content.split('\n') {
|
||||||
height += 1;
|
height += 1;
|
||||||
max_width = max(max_width, line.chars().count());
|
max_width = max(max_width, line.chars().count());
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ impl<'a> Iterator for LinesIterator<'a> {
|
|||||||
let start = self.start;
|
let start = self.start;
|
||||||
let content = &self.content[self.start..];
|
let content = &self.content[self.start..];
|
||||||
|
|
||||||
if let Some(next) = content.find("\n") {
|
if let Some(next) = content.find('\n') {
|
||||||
if content[..next].chars().count() <= self.width {
|
if content[..next].chars().count() <= self.width {
|
||||||
// We found a newline before the allowed limit.
|
// We found a newline before the allowed limit.
|
||||||
// Break early.
|
// Break early.
|
||||||
@ -189,7 +189,7 @@ impl<'a> Iterator for LinesIterator<'a> {
|
|||||||
content.char_indices().nth(self.width + 1).unwrap().0
|
content.char_indices().nth(self.width + 1).unwrap().0
|
||||||
};
|
};
|
||||||
let substr = &content[..i];
|
let substr = &content[..i];
|
||||||
if let Some(i) = substr.rfind(" ") {
|
if let Some(i) = substr.rfind(' ') {
|
||||||
// If we have to break, try to find a whitespace for that.
|
// If we have to break, try to find a whitespace for that.
|
||||||
self.start += i + 1;
|
self.start += i + 1;
|
||||||
return Some(Row {
|
return Some(Row {
|
||||||
@ -201,10 +201,11 @@ impl<'a> Iterator for LinesIterator<'a> {
|
|||||||
// Meh, no whitespace, so just cut in this mess.
|
// Meh, no whitespace, so just cut in this mess.
|
||||||
// TODO: look for ponctuation instead?
|
// TODO: look for ponctuation instead?
|
||||||
self.start += self.width;
|
self.start += self.width;
|
||||||
return Some(Row {
|
|
||||||
|
Some(Row {
|
||||||
start: start,
|
start: start,
|
||||||
end: start + self.width,
|
end: start + self.width,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,21 +233,21 @@ impl View for TextView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::KeyEvent(Key::Home) => self.scrollbase.scroll_top(),
|
Event::Key(Key::Home) => self.scrollbase.scroll_top(),
|
||||||
Event::KeyEvent(Key::End) => self.scrollbase.scroll_bottom(),
|
Event::Key(Key::End) => self.scrollbase.scroll_bottom(),
|
||||||
Event::KeyEvent(Key::Up) if self.scrollbase.can_scroll_up() => {
|
Event::Key(Key::Up) if self.scrollbase.can_scroll_up() => {
|
||||||
self.scrollbase.scroll_up(1)
|
self.scrollbase.scroll_up(1)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::Down) if self.scrollbase
|
Event::Key(Key::Down) if self.scrollbase
|
||||||
.can_scroll_down() => {
|
.can_scroll_down() => {
|
||||||
self.scrollbase.scroll_down(1)
|
self.scrollbase.scroll_down(1)
|
||||||
}
|
}
|
||||||
Event::KeyEvent(Key::PageDown) => self.scrollbase.scroll_down(10),
|
Event::Key(Key::PageDown) => self.scrollbase.scroll_down(10),
|
||||||
Event::KeyEvent(Key::PageUp) => self.scrollbase.scroll_up(10),
|
Event::Key(Key::PageUp) => self.scrollbase.scroll_up(10),
|
||||||
_ => return EventResult::Ignored,
|
_ => return EventResult::Ignored,
|
||||||
}
|
}
|
||||||
|
|
||||||
return EventResult::Consumed(None);
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_min_size(&self, size: SizeRequest) -> Vec2 {
|
fn get_min_size(&self, size: SizeRequest) -> Vec2 {
|
||||||
|
@ -5,6 +5,12 @@ pub struct ViewPath {
|
|||||||
pub path: Vec<usize>,
|
pub path: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ViewPath {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ViewPath {
|
impl ViewPath {
|
||||||
/// Creates a new empty path.
|
/// Creates a new empty path.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -17,7 +23,7 @@ impl ViewPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic trait for elements that can be converted into a ViewPath.
|
/// Generic trait for elements that can be converted into a `ViewPath`.
|
||||||
pub trait ToPath {
|
pub trait ToPath {
|
||||||
/// Creates a path from the element.
|
/// Creates a path from the element.
|
||||||
fn to_path(self) -> ViewPath;
|
fn to_path(self) -> ViewPath;
|
||||||
|
Loading…
Reference in New Issue
Block a user