All components must have focus

This commit is contained in:
veeso
2021-03-07 17:40:45 +01:00
parent 5a2d0b7b0b
commit 43c177e04d
3 changed files with 105 additions and 27 deletions

View File

@@ -31,12 +31,23 @@ use tui::{
widgets::{Block, Borders, Gauge}, widgets::{Block, Borders, Gauge},
}; };
// NOTE: this component doesn't handle any state // -- state
struct OwnStates {
focus: bool,
}
impl Default for OwnStates {
fn default() -> Self {
OwnStates { focus: false }
}
}
// -- component // -- component
pub struct ProgressBar { pub struct ProgressBar {
props: Props, props: Props,
states: OwnStates,
} }
impl ProgressBar { impl ProgressBar {
@@ -44,7 +55,10 @@ impl ProgressBar {
/// ///
/// Instantiate a new Progress Bar /// Instantiate a new Progress Bar
pub fn new(props: Props) -> Self { pub fn new(props: Props) -> Self {
ProgressBar { props } ProgressBar {
props,
states: OwnStates::default(),
}
} }
} }
@@ -121,8 +135,13 @@ impl Component for ProgressBar {
/// Handle input event and update internal states. /// Handle input event and update internal states.
/// Returns a Msg to the view. /// Returns a Msg to the view.
/// Returns always None, since cannot have any focus /// Returns always None, since cannot have any focus
fn on(&mut self, _ev: InputEvent) -> Msg { fn on(&mut self, ev: InputEvent) -> Msg {
Msg::None // Return key
if let InputEvent::Key(key) = ev {
Msg::OnKey(key)
} else {
Msg::None
}
} }
/// ### get_value /// ### get_value
@@ -146,13 +165,17 @@ impl Component for ProgressBar {
/// ### blur /// ### blur
/// ///
/// Blur component; does nothing on this component /// Blur component
fn blur(&mut self) {} fn blur(&mut self) {
self.states.focus = false;
}
/// ### active /// ### active
/// ///
/// Active component; does nothing on this component /// Active component
fn active(&mut self) {} fn active(&mut self) {
self.states.focus = true;
}
} }
#[cfg(test)] #[cfg(test)]
@@ -174,8 +197,11 @@ mod tests {
.build(), .build(),
); );
// Focus // Focus
assert_eq!(component.states.focus, false);
component.active(); component.active();
assert_eq!(component.states.focus, true);
component.blur(); component.blur();
assert_eq!(component.states.focus, false);
// Should umount // Should umount
assert_eq!(component.should_umount(), false); assert_eq!(component.should_umount(), false);
// Get value // Get value
@@ -185,7 +211,7 @@ mod tests {
// Event // Event
assert_eq!( assert_eq!(
component.on(InputEvent::Key(KeyEvent::from(KeyCode::Delete))), component.on(InputEvent::Key(KeyEvent::from(KeyCode::Delete))),
Msg::None Msg::OnKey(KeyEvent::from(KeyCode::Delete))
); );
} }
} }

View File

@@ -33,7 +33,17 @@ use tui::{
widgets::{Block, BorderType, Borders, List, ListItem}, widgets::{Block, BorderType, Borders, List, ListItem},
}; };
// NOTE: this component doesn't handle any state // -- state
struct OwnStates {
focus: bool,
}
impl Default for OwnStates {
fn default() -> Self {
OwnStates { focus: false }
}
}
// -- component // -- component
@@ -42,6 +52,7 @@ use tui::{
/// Table is a table component. List n rows with n text span columns /// Table is a table component. List n rows with n text span columns
pub struct Table { pub struct Table {
props: Props, props: Props,
states: OwnStates,
} }
impl Table { impl Table {
@@ -49,7 +60,10 @@ impl Table {
/// ///
/// Instantiate a new Table component /// Instantiate a new Table component
pub fn new(props: Props) -> Self { pub fn new(props: Props) -> Self {
Table { props } Table {
props,
states: OwnStates::default(),
}
} }
} }
@@ -134,8 +148,13 @@ impl Component for Table {
/// Handle input event and update internal states. /// Handle input event and update internal states.
/// Returns a Msg to the view. /// Returns a Msg to the view.
/// Returns always None, since cannot have any focus /// Returns always None, since cannot have any focus
fn on(&mut self, _ev: InputEvent) -> Msg { fn on(&mut self, ev: InputEvent) -> Msg {
Msg::None // Return key
if let InputEvent::Key(key) = ev {
Msg::OnKey(key)
} else {
Msg::None
}
} }
/// ### get_value /// ### get_value
@@ -159,13 +178,17 @@ impl Component for Table {
/// ### blur /// ### blur
/// ///
/// Blur component; does nothing on this component /// Blur component
fn blur(&mut self) {} fn blur(&mut self) {
self.states.focus = false;
}
/// ### active /// ### active
/// ///
/// Active component; does nothing on this component /// Active component
fn active(&mut self) {} fn active(&mut self) {
self.states.focus = true;
}
} }
#[cfg(test)] #[cfg(test)]
@@ -193,8 +216,11 @@ mod tests {
.build(), .build(),
); );
// Focus // Focus
assert_eq!(component.states.focus, false);
component.active(); component.active();
assert_eq!(component.states.focus, true);
component.blur(); component.blur();
assert_eq!(component.states.focus, false);
// Should umount // Should umount
assert_eq!(component.should_umount(), false); assert_eq!(component.should_umount(), false);
// Get value // Get value
@@ -204,7 +230,7 @@ mod tests {
// Event // Event
assert_eq!( assert_eq!(
component.on(InputEvent::Key(KeyEvent::from(KeyCode::Delete))), component.on(InputEvent::Key(KeyEvent::from(KeyCode::Delete))),
Msg::None Msg::OnKey(KeyEvent::from(KeyCode::Delete))
); );
} }
} }

View File

@@ -32,12 +32,23 @@ use tui::{
widgets::Paragraph, widgets::Paragraph,
}; };
// NOTE: this component doesn't handle any state // -- state
struct OwnStates {
focus: bool,
}
impl Default for OwnStates {
fn default() -> Self {
OwnStates { focus: false }
}
}
// -- component // -- component
pub struct Text { pub struct Text {
props: Props, props: Props,
states: OwnStates,
} }
impl Text { impl Text {
@@ -45,7 +56,10 @@ impl Text {
/// ///
/// Instantiate a new Text component /// Instantiate a new Text component
pub fn new(props: Props) -> Self { pub fn new(props: Props) -> Self {
Text { props } Text {
props,
states: OwnStates::default(),
}
} }
} }
@@ -117,8 +131,13 @@ impl Component for Text {
/// Handle input event and update internal states. /// Handle input event and update internal states.
/// Returns a Msg to the view. /// Returns a Msg to the view.
/// Returns always None, since cannot have any focus /// Returns always None, since cannot have any focus
fn on(&mut self, _ev: InputEvent) -> Msg { fn on(&mut self, ev: InputEvent) -> Msg {
Msg::None // Return key
if let InputEvent::Key(key) = ev {
Msg::OnKey(key)
} else {
Msg::None
}
} }
/// ### get_value /// ### get_value
@@ -142,13 +161,17 @@ impl Component for Text {
/// ### blur /// ### blur
/// ///
/// Blur component; does nothing on this component /// Blur component
fn blur(&mut self) {} fn blur(&mut self) {
self.states.focus = false;
}
/// ### active /// ### active
/// ///
/// Active component; does nothing on this component /// Active component
fn active(&mut self) {} fn active(&mut self) {
self.states.focus = true;
}
} }
#[cfg(test)] #[cfg(test)]
@@ -178,8 +201,11 @@ mod tests {
.build(), .build(),
); );
// Focus // Focus
assert_eq!(component.states.focus, false);
component.active(); component.active();
assert_eq!(component.states.focus, true);
component.blur(); component.blur();
assert_eq!(component.states.focus, false);
// Should umount // Should umount
assert_eq!(component.should_umount(), false); assert_eq!(component.should_umount(), false);
// Get value // Get value
@@ -189,7 +215,7 @@ mod tests {
// Event // Event
assert_eq!( assert_eq!(
component.on(InputEvent::Key(KeyEvent::from(KeyCode::Delete))), component.on(InputEvent::Key(KeyEvent::from(KeyCode::Delete))),
Msg::None Msg::OnKey(KeyEvent::from(KeyCode::Delete))
); );
} }
} }