Skip to content
This repository has been archived by the owner on Jul 25, 2024. It is now read-only.

feat!: remove title from Popup::new #31

Merged
merged 1 commit into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ fn main() -> Result<()> {
fn render(frame: &mut Frame) {
let area = frame.size();
let background = background(area);
let popup =
Popup::new("tui-popup demo", "Press any key to exit").style(Style::new().white().on_blue());
let popup = Popup::new("Press any key to exit")
.title("tui-popup demo")
.style(Style::new().white().on_blue());
frame.render_widget(background, area);
frame.render_widget(&popup, area);
}
Expand Down
5 changes: 3 additions & 2 deletions examples/paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ impl App {
let background = background(area);

let paragraph = paragraph(self.scroll);
let popup =
Popup::new("scroll: ↑/↓ quit: Esc", paragraph).style(Style::new().white().on_blue());
let popup = Popup::new(paragraph)
.title("scroll: ↑/↓ quit: Esc")
.style(Style::new().white().on_blue());

frame.render_widget(background, area);
frame.render_widget(&popup, area);
Expand Down
20 changes: 9 additions & 11 deletions examples/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,15 @@ impl App {
}

fn popup_widget() -> Popup<'static, Text<'static>> {
Popup::new(
"Popup",
Text::from_iter([
"q: exit",
"r: reset",
"j: move down",
"k: move up",
"h: move left",
"l: move right",
]),
)
Popup::new(Text::from_iter([
"q: exit",
"r: reset",
"j: move down",
"k: move up",
"h: move left",
"l: move right",
]))
.title("Popup")
.style(Style::new().white().on_blue())
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
//! use tui_popup::Popup;
//!
//! fn render_popup(frame: &mut Frame) {
//! let popup = Popup::new("tui-popup demo", "Press any key to exit")
//! let popup = Popup::new("Press any key to exit")
//! .title("tui-popup demo")
//! .style(Style::new().white().on_blue());
//! frame.render_widget(&popup, frame.size());
//! }
Expand All @@ -23,7 +24,6 @@

mod popup;
mod state;
mod widget;

pub use popup::*;
pub use state::*;
85 changes: 73 additions & 12 deletions src/popup.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::fmt::Debug;

use crate::PopupState;
use derive_setters::Setters;
use ratatui::{
prelude::*,
widgets::{Borders, WidgetRef},
prelude::{Buffer, Line, Rect, Style, Text},
widgets::{Block, Borders, Clear, StatefulWidgetRef, Widget, WidgetRef},
};
use std::cmp::min;

/// Configuration for a popup.
///
Expand All @@ -18,7 +20,8 @@ use ratatui::{
/// use tui_popup::Popup;
///
/// fn render_popup(frame: &mut Frame) {
/// let popup = Popup::new("tui-popup demo", "Press any key to exit")
/// let popup = Popup::new("Press any key to exit")
/// .title("tui-popup demo")
/// .style(Style::new().white().on_blue());
/// frame.render_widget(&popup, frame.size());
/// }
Expand All @@ -28,6 +31,7 @@ use ratatui::{
#[non_exhaustive]
pub struct Popup<'content, W: SizedWidgetRef> {
/// The body of the popup.
#[setters(skip)]
pub body: W,
/// The title of the popup.
pub title: Line<'content>,
Expand All @@ -53,8 +57,6 @@ impl<'content, W: SizedWidgetRef> Popup<'content, W> {
///
/// # Parameters
///
/// - `title` - The title of the popup. This can be any type that can be converted into a
/// [`Line`].
/// - `body` - The body of the popup. This can be any type that can be converted into a
/// [`Text`].
///
Expand All @@ -63,17 +65,14 @@ impl<'content, W: SizedWidgetRef> Popup<'content, W> {
/// ```rust
/// use tui_popup::Popup;
///
/// let popup = Popup::new("tui-popup demo", "Press any key to exit");
/// let popup = Popup::new("Press any key to exit").title("tui-popup demo");
/// ```
pub fn new<L>(title: L, body: W) -> Self
where
L: Into<Line<'content>>,
{
pub fn new(body: W) -> Self {
Self {
body,
title: title.into(),
style: Style::default(),
borders: Borders::ALL,
title: Line::default(),
style: Style::default(),
}
}
}
Expand Down Expand Up @@ -120,3 +119,65 @@ impl<W: WidgetRef + Debug> SizedWidgetRef for SizedWrapper<W> {
self.height
}
}

impl<W: SizedWidgetRef> WidgetRef for Popup<'_, W> {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
let mut state = PopupState::default();
StatefulWidgetRef::render_ref(self, area, buf, &mut state);
}
}

impl<W: SizedWidgetRef> StatefulWidgetRef for Popup<'_, W> {
type State = PopupState;

fn render_ref(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let area = if let Some(next) = state.area.take() {
// ensure that the popup remains on screen
let width = min(next.width, area.width);
let height = min(next.height, area.height);
let x = next.x.clamp(buf.area.x, area.right() - width);
let y = next.y.clamp(buf.area.y, area.bottom() - height);

Rect::new(x, y, width, height)
} else {
let border_height = usize::from(self.borders.intersects(Borders::TOP))
+ usize::from(self.borders.intersects(Borders::BOTTOM));
let border_width = usize::from(self.borders.intersects(Borders::LEFT))
+ usize::from(self.borders.intersects(Borders::RIGHT));

let height = self
.body
.height()
.saturating_add(border_height)
.try_into()
.unwrap_or(area.height);
let width = self
.body
.width()
.saturating_add(border_width)
.try_into()
.unwrap_or(area.width);
centered_rect(width, height, area)
};

state.area.replace(area);

Clear.render(area, buf);
let block = Block::default()
.borders(self.borders)
.title(self.title.clone())
.style(self.style);
block.render_ref(area, buf);
self.body.render_ref(block.inner(area), buf);
}
}

/// Create a rectangle centered in the given area.
fn centered_rect(width: u16, height: u16, area: Rect) -> Rect {
Rect {
x: area.width.saturating_sub(width) / 2,
y: area.height.saturating_sub(height) / 2,
width: min(width, area.width),
height: min(height, area.height),
}
}
70 changes: 0 additions & 70 deletions src/widget.rs

This file was deleted.