Merge pull request #4 from selimaj-dev/patches-and-centering

Patches and centering
This commit is contained in:
2026-07-15 08:58:38 +02:00
committed by GitHub
6 changed files with 70 additions and 20 deletions
+7 -2
View File
@@ -7,6 +7,7 @@ pub enum LayoutItem {
Frame { padding: u16, item: Box<LayoutItem> },
Widget(Size),
Spacing(Size),
}
#[derive(Debug, Clone)]
@@ -28,7 +29,7 @@ impl LayoutItem {
let remaining = allocation
- items
.iter()
.map(|item| item.get_size().get_fixed(alloc.height))
.map(|item| item.get_size().get_fixed(allocation))
.sum::<u16>();
let total_weight = items
@@ -82,6 +83,10 @@ impl LayoutItem {
Self::Widget(_) => {
full_alloc.widgets.push(*alloc);
}
Self::Spacing(_) => {
full_alloc.frame.push(*alloc);
}
}
}
@@ -89,7 +94,7 @@ impl LayoutItem {
match self {
Self::Rows { unit, .. } => unit,
Self::Columns { unit, .. } => unit,
Self::Widget(unit) => unit,
Self::Widget(unit) | Self::Spacing(unit) => unit,
Self::Frame { item, .. } => item.get_size(),
}
}
+7 -5
View File
@@ -1,4 +1,4 @@
use std::any::Any;
use std::{any::Any, time::Duration};
use tokio::sync::mpsc;
@@ -38,10 +38,12 @@ pub async fn run<A: App>(create_app: impl FnOnce(&state::Context) -> A) {
crossterm::terminal::enable_raw_mode().unwrap();
tokio::spawn(async move {
loop {
tx.send(Box::new(crossterm::event::read().unwrap()))
.await
.unwrap();
while !tx.is_closed() {
if crossterm::event::poll(Duration::from_millis(100)).unwrap() {
tx.send(Box::new(crossterm::event::read().unwrap()))
.await
.unwrap();
}
}
});
+20
View File
@@ -0,0 +1,20 @@
use crate::widget::Widget;
pub struct Center(pub String);
impl Widget for Center {
fn render(&self, scope: &mut crate::render::RenderScope) {
let mut width = 0;
let mut height = 0;
for line in self.0.lines() {
height += 1;
width = width.max(line.len() as u16);
}
let x = (scope.rect.width - width) / 2;
let y = (scope.rect.height - height) / 2;
scope.draw_text((x, y), &self.0);
}
}
+1
View File
@@ -1,3 +1,4 @@
pub mod center;
pub mod outline;
pub mod spaced;
+25 -6
View File
@@ -4,16 +4,26 @@ pub struct SpacedRows(pub Vec<(LayoutItem, Box<dyn Widget>)>);
impl Widget for SpacedRows {
fn render(&self, scope: &mut crate::render::RenderScope) {
let alloc = scope.rect.allocate(&crate::layout::LayoutItem::Rows {
let mut items = Vec::new();
for (i, (item, _)) in self.0.iter().enumerate() {
if i > 0 {
items.push(LayoutItem::Spacing(crate::unit::Size::Fixed(1)))
}
items.push(item.clone());
}
let mut alloc = scope.rect.allocate(&crate::layout::LayoutItem::Rows {
unit: Percent(100),
items: self.0.iter().map(|v| v.0.clone()).collect(),
items,
});
for i in 0..alloc.widgets.len() {
let item = &self.0[i];
if i > 0 {
let rect = &alloc.widgets[i];
let rect = &mut alloc.widgets[i];
scope.draw_text((0, rect.y - 2), "─".repeat(rect.width as usize));
}
@@ -27,9 +37,19 @@ pub struct SpacedColumns(pub Vec<(LayoutItem, Box<dyn Widget>)>);
impl Widget for SpacedColumns {
fn render(&self, scope: &mut crate::render::RenderScope) {
let mut items = Vec::new();
for (i, (item, _)) in self.0.iter().enumerate() {
if i > 0 {
items.push(LayoutItem::Spacing(crate::unit::Size::Fixed(1)))
}
items.push(item.clone());
}
let mut alloc = scope.rect.allocate(&crate::layout::LayoutItem::Columns {
unit: Percent(100),
items: self.0.iter().map(|v| v.0.clone()).collect(),
items,
});
for i in 0..alloc.widgets.len() {
@@ -39,9 +59,8 @@ impl Widget for SpacedColumns {
let rect = &mut alloc.widgets[i];
for i in 0..rect.height {
scope.draw_text((rect.x - 1, i), "│");
scope.draw_text((rect.x - 2, i), "│");
}
rect.x += 1;
}
alloc.draw(i, &*item.1);
+10 -7
View File
@@ -1,11 +1,7 @@
use std::any::Any;
use pulse_ui::{
App,
layout::{LayoutItem, layout},
state::{Refresh, State},
unit::Size,
widget::{outline::Outline, spaced::SpacedRows},
App, layout::{LayoutItem, layout}, state::{Refresh, State}, unit::Size, widget::{outline::Outline, spaced::{SpacedColumns, SpacedRows}},
};
pub struct PulseTradeApp {
@@ -21,6 +17,10 @@ impl App for PulseTradeApp {
}
*self.count.lock().await += 1;
if *self.count.lock().await > 10 {
ctx.close().await;
}
}
async fn layout(&self) -> pulse_ui::layout::LayoutItem {
@@ -35,11 +35,14 @@ impl App for PulseTradeApp {
layout.draw(
0,
SpacedRows(vec![
SpacedColumns(vec![
(LayoutItem::Widget(Size::Flex(1)), Box::new("one")),
(LayoutItem::Widget(Size::Flex(1)), Box::new("two")),
(LayoutItem::Widget(Size::Flex(1)), Box::new("three")),
(LayoutItem::Widget(Size::Flex(1)), Box::new(self.count.display().await)),
(
LayoutItem::Widget(Size::Flex(1)),
Box::new(self.count.display().await),
),
]),
);
}