mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-04-08 17:05:59 +02:00
Shortcut with generic
This commit is contained in:
parent
68d2e9ae5b
commit
f56d70b9ee
@ -29,7 +29,7 @@ use frozen_state::FrozenState;
|
|||||||
use crate::{
|
use crate::{
|
||||||
canvas::Painter,
|
canvas::Painter,
|
||||||
constants,
|
constants,
|
||||||
tuine::{Application, Element, Flex, Shortcut, ViewContext},
|
tuine::{Application, Element, Flex, ViewContext},
|
||||||
units::data_units::DataUnit,
|
units::data_units::DataUnit,
|
||||||
Pid,
|
Pid,
|
||||||
};
|
};
|
||||||
@ -236,15 +236,13 @@ impl Application for AppState {
|
|||||||
|
|
||||||
fn view<'b>(&mut self, ctx: &mut ViewContext<'_>) -> Element<'static, Self::Message> {
|
fn view<'b>(&mut self, ctx: &mut ViewContext<'_>) -> Element<'static, Self::Message> {
|
||||||
use crate::tuine::FlexElement;
|
use crate::tuine::FlexElement;
|
||||||
|
use crate::tuine::TempTable;
|
||||||
use crate::tuine::TextTable;
|
use crate::tuine::TextTable;
|
||||||
|
|
||||||
Flex::column()
|
Flex::column()
|
||||||
.with_flex_child(
|
.with_flex_child(
|
||||||
Flex::row_with_children(vec![
|
Flex::row_with_children(vec![
|
||||||
FlexElement::new(Shortcut::with_child(TextTable::new(
|
FlexElement::new(TempTable::new(ctx)),
|
||||||
ctx,
|
|
||||||
vec!["A", "B", "C"],
|
|
||||||
))),
|
|
||||||
FlexElement::new(TextTable::new(ctx, vec!["D", "E", "F"])),
|
FlexElement::new(TextTable::new(ctx, vec!["D", "E", "F"])),
|
||||||
]),
|
]),
|
||||||
1,
|
1,
|
||||||
|
@ -2,20 +2,23 @@ use rustc_hash::FxHashMap;
|
|||||||
use tui::{backend::Backend, layout::Rect, Frame};
|
use tui::{backend::Backend, layout::Rect, Frame};
|
||||||
|
|
||||||
use crate::tuine::{
|
use crate::tuine::{
|
||||||
Bounds, DrawContext, Element, Event, LayoutNode, Size, StateContext, Status, TmpComponent,
|
Bounds, DrawContext, Event, LayoutNode, Size, StateContext, Status, TmpComponent,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A [`Component`] to handle keyboard shortcuts and assign actions to them.
|
/// A [`Component`] to handle keyboard shortcuts and assign actions to them.
|
||||||
///
|
///
|
||||||
/// Inspired by [Flutter's approach](https://docs.flutter.dev/development/ui/advanced/actions_and_shortcuts).
|
/// Inspired by [Flutter's approach](https://docs.flutter.dev/development/ui/advanced/actions_and_shortcuts).
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Shortcut<'a, Message> {
|
pub struct Shortcut<Message, Child>
|
||||||
child: Option<Box<Element<'a, Message>>>,
|
where
|
||||||
|
Child: TmpComponent<Message>,
|
||||||
|
{
|
||||||
|
child: Option<Child>,
|
||||||
shortcuts: FxHashMap<
|
shortcuts: FxHashMap<
|
||||||
Event,
|
Event,
|
||||||
Box<
|
Box<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&mut Element<'a, Message>,
|
&mut Child,
|
||||||
&mut StateContext<'_>,
|
&mut StateContext<'_>,
|
||||||
&DrawContext<'_>,
|
&DrawContext<'_>,
|
||||||
Event,
|
Event,
|
||||||
@ -25,22 +28,19 @@ pub struct Shortcut<'a, Message> {
|
|||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message> Shortcut<'a, Message> {
|
impl<Message, Child> Shortcut<Message, Child>
|
||||||
pub fn with_child<C>(child: C) -> Self
|
|
||||||
where
|
where
|
||||||
C: Into<Element<'a, Message>>,
|
Child: TmpComponent<Message>,
|
||||||
{
|
{
|
||||||
|
pub fn with_child(child: Child) -> Self {
|
||||||
Self {
|
Self {
|
||||||
child: Some(Box::new(child.into())),
|
child: Some(child),
|
||||||
shortcuts: Default::default(),
|
shortcuts: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn child<C>(mut self, child: Option<C>) -> Self
|
pub fn child(mut self, child: Option<Child>) -> Self {
|
||||||
where
|
self.child = child;
|
||||||
C: Into<Element<'a, Message>>,
|
|
||||||
{
|
|
||||||
self.child = child.map(|c| Box::new(c.into()));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ impl<'a, Message> Shortcut<'a, Message> {
|
|||||||
mut self, event: Event,
|
mut self, event: Event,
|
||||||
f: Box<
|
f: Box<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&mut Element<'a, Message>,
|
&mut Child,
|
||||||
&mut StateContext<'_>,
|
&mut StateContext<'_>,
|
||||||
&DrawContext<'_>,
|
&DrawContext<'_>,
|
||||||
Event,
|
Event,
|
||||||
@ -66,7 +66,10 @@ impl<'a, Message> Shortcut<'a, Message> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message> TmpComponent<Message> for Shortcut<'a, Message> {
|
impl<'a, Message, Child> TmpComponent<Message> for Shortcut<Message, Child>
|
||||||
|
where
|
||||||
|
Child: TmpComponent<Message>,
|
||||||
|
{
|
||||||
fn draw<B>(
|
fn draw<B>(
|
||||||
&mut self, state_ctx: &mut StateContext<'_>, draw_ctx: &DrawContext<'_>,
|
&mut self, state_ctx: &mut StateContext<'_>, draw_ctx: &DrawContext<'_>,
|
||||||
frame: &mut Frame<'_, B>,
|
frame: &mut Frame<'_, B>,
|
||||||
|
@ -246,7 +246,7 @@ impl<'a, Message> TmpComponent<Message> for TextTable<'a, Message> {
|
|||||||
let y = mouse_event.row - rect.top();
|
let y = mouse_event.row - rect.top();
|
||||||
|
|
||||||
if self.sortable && y == 0 {
|
if self.sortable && y == 0 {
|
||||||
todo!()
|
todo!() // Sort by the clicked column!
|
||||||
} else if y > self.table_gap {
|
} else if y > self.table_gap {
|
||||||
let visual_index = usize::from(y - self.table_gap);
|
let visual_index = usize::from(y - self.table_gap);
|
||||||
state.set_visual_index(visual_index)
|
state.set_visual_index(visual_index)
|
@ -1 +1,2 @@
|
|||||||
|
pub mod temp_table;
|
||||||
|
pub use temp_table::*;
|
||||||
|
40
src/tuine/component/widget/temp_table.rs
Normal file
40
src/tuine/component/widget/temp_table.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use crate::tuine::{Shortcut, TextTable, TmpComponent, ViewContext};
|
||||||
|
|
||||||
|
/// A [`TempTable`] is a text table that is meant to display temperature data.
|
||||||
|
pub struct TempTable<'a, Message> {
|
||||||
|
inner: Shortcut<Message, TextTable<'a, Message>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message> TempTable<'a, Message> {
|
||||||
|
#[track_caller]
|
||||||
|
pub fn new(ctx: &mut ViewContext<'_>) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Shortcut::with_child(TextTable::new(ctx, vec!["Sensor", "Temp"])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message> TmpComponent<Message> for TempTable<'a, Message> {
|
||||||
|
fn draw<Backend>(
|
||||||
|
&mut self, state_ctx: &mut crate::tuine::StateContext<'_>,
|
||||||
|
draw_ctx: &crate::tuine::DrawContext<'_>, frame: &mut tui::Frame<'_, Backend>,
|
||||||
|
) where
|
||||||
|
Backend: tui::backend::Backend,
|
||||||
|
{
|
||||||
|
self.inner.draw(state_ctx, draw_ctx, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(
|
||||||
|
&mut self, state_ctx: &mut crate::tuine::StateContext<'_>,
|
||||||
|
draw_ctx: &crate::tuine::DrawContext<'_>, event: crate::tuine::Event,
|
||||||
|
messages: &mut Vec<Message>,
|
||||||
|
) -> crate::tuine::Status {
|
||||||
|
self.inner.on_event(state_ctx, draw_ctx, event, messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&self, bounds: crate::tuine::Bounds, node: &mut crate::tuine::LayoutNode,
|
||||||
|
) -> crate::tuine::Size {
|
||||||
|
self.inner.layout(bounds, node)
|
||||||
|
}
|
||||||
|
}
|
@ -3,17 +3,21 @@ use tui::Frame;
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Block, Bounds, Carousel, Container, DrawContext, Empty, Event, Flex, LayoutNode, Shortcut,
|
Block, Bounds, Carousel, Container, DrawContext, Empty, Event, Flex, LayoutNode, Shortcut,
|
||||||
Size, StateContext, Status, TextTable, TmpComponent,
|
Size, StateContext, Status, TempTable, TextTable, TmpComponent,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An [`Element`] is an instantiated [`Component`].
|
/// An [`Element`] is an instantiated [`Component`].
|
||||||
#[enum_dispatch(TmpComponent<Message>)]
|
#[enum_dispatch(TmpComponent<Message>)]
|
||||||
pub enum Element<'a, Message> {
|
pub enum Element<'a, Message, C = Empty>
|
||||||
|
where
|
||||||
|
C: TmpComponent<Message>,
|
||||||
|
{
|
||||||
Block,
|
Block,
|
||||||
Carousel,
|
Carousel,
|
||||||
Container(Container<'a, Message>),
|
Container(Container<'a, Message>),
|
||||||
Flex(Flex<'a, Message>),
|
Flex(Flex<'a, Message>),
|
||||||
Shortcut(Shortcut<'a, Message>),
|
Shortcut(Shortcut<Message, C>),
|
||||||
TextTable(TextTable<'a, Message>),
|
TextTable(TextTable<'a, Message>),
|
||||||
Empty,
|
Empty,
|
||||||
|
TempTable(TempTable<'a, Message>),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user