Skip to content
Open
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
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ indoc = "2.0.5"
lipsum = "0.9.1"
pretty_assertions = "1.4.1"
ratatui = { version = "0.30.0-alpha.0", default-features = false }
ratatui-core = { version = "0.1.0-alpha.0" }
ratatui-core = "0.1.0-alpha.0"
ratatui-macros = "0.7.0-alpha.0"
ratatui-widgets = { version = "0.3.0-alpha.0" }
ratatui-widgets = "0.3.0-alpha.0"
rstest = "0.23.0"
strum = { version = "0.26.3", features = ["derive"] }
tokio = { version = "1.41.0" }
Expand Down
4 changes: 3 additions & 1 deletion tui-popup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ crossterm = ["ratatui/crossterm"]
document-features.workspace = true
derive-getters.workspace = true
derive_setters.workspace = true
ratatui = { workspace = true, features = ["unstable-widget-ref"] }
ratatui = { workspace = true, features = ["unstable-widget-ref"], optional = true }
ratatui-core.workspace = true
ratatui-widgets.workspace = true

[dev-dependencies]
pretty_assertions.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion tui-popup/src/known_size.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ratatui::text::Text;
use ratatui_core::text::Text;

/// A trait for widgets that have a fixed size.
///
Expand Down
20 changes: 10 additions & 10 deletions tui-popup/src/known_size_wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
use std::fmt::Debug;

use derive_setters::Setters;
use ratatui::{buffer::Buffer, layout::Rect, widgets::WidgetRef};
use ratatui_core::{buffer::Buffer, layout::Rect, widgets::Widget};

use crate::KnownSize;

/// The `KnownSizeWrapper` struct wraps a widget and provides a fixed size for it.
///
/// This struct is used to wrap a widget and provide a fixed size for it. This is useful when you
/// want to use a widget that does not implement `SizedWidgetRef` as the body of a popup.
#[derive(Debug, Setters)]
#[derive(Debug, Setters, Clone)]
pub struct KnownSizeWrapper<W> {
#[setters(skip)]
pub inner: W,
pub width: usize,
pub height: usize,
}

impl<W: WidgetRef> WidgetRef for KnownSizeWrapper<W> {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
self.inner.render_ref(area, buf);
impl<W: Widget> Widget for KnownSizeWrapper<W> {
fn render(self, area: Rect, buf: &mut Buffer) {
self.inner.render(area, buf);
}
}

Expand Down Expand Up @@ -55,15 +55,15 @@ impl<W> KnownSizeWrapper<W> {
}
#[cfg(test)]
mod tests {
use ratatui::{buffer::Buffer, layout::Rect};
use ratatui_core::{buffer::Buffer, layout::Rect};

use super::*;

struct TestWidget;

impl WidgetRef for TestWidget {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
"Hello".render_ref(area, buf);
impl Widget for TestWidget {
fn render(self, area: Rect, buf: &mut Buffer) {
"Hello".render(area, buf);
}
}

Expand All @@ -80,7 +80,7 @@ mod tests {
let widget = TestWidget;
let wrapper = KnownSizeWrapper::new(widget, 20, 5);
let mut buffer = Buffer::empty(Rect::new(0, 0, 20, 5));
wrapper.render_ref(buffer.area, &mut buffer);
wrapper.render(buffer.area, &mut buffer);
let expected = Buffer::with_lines([
"Hello ",
" ",
Expand Down
59 changes: 15 additions & 44 deletions tui-popup/src/popup.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::{cmp::min, fmt};
use std::cmp::min;

use derive_setters::Setters;
use ratatui::{
use ratatui_core::{
buffer::Buffer,
layout::Rect,
style::Style,
symbols::border::Set,
text::Line,
widgets::{Block, Borders, Clear, StatefulWidget, Widget, WidgetRef},
widgets::{StatefulWidget, Widget},
};
use ratatui_widgets::{block::Block, borders::Borders, clear::Clear};

use crate::{KnownSize, PopupState};

Expand Down Expand Up @@ -51,31 +52,6 @@ pub struct Popup<'content, W> {
pub border_style: Style,
}

impl<W> fmt::Debug for Popup<'_, W> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// body does not implement Debug, so we can't use #[derive(Debug)]
f.debug_struct("Popup")
.field("body", &"...")
.field("title", &self.title)
.field("style", &self.style)
.field("borders", &self.borders)
.field("border_set", &self.border_set)
.field("border_style", &self.border_style)
.finish()
}
}

impl<W: PartialEq> PartialEq for Popup<'_, W> {
fn eq(&self, other: &Self) -> bool {
self.body == other.body
&& self.title == other.title
&& self.style == other.style
&& self.borders == other.borders
&& self.border_set == other.border_set
&& self.border_style == other.border_style
}
}

impl<'content, W> Popup<'content, W> {
/// Create a new popup with the given title and body with all the borders.
///
Expand Down Expand Up @@ -103,29 +79,29 @@ impl<'content, W> Popup<'content, W> {
}
}

impl<W: KnownSize + WidgetRef> Widget for Popup<'_, W> {
impl<W: KnownSize + Widget + Clone> Widget for Popup<'_, W> {
fn render(self, area: Rect, buf: &mut Buffer) {
let mut state = PopupState::default();
StatefulWidget::render(&self, area, buf, &mut state);
}
}

impl<W: KnownSize + WidgetRef> Widget for &Popup<'_, W> {
impl<W: KnownSize + Widget + Clone> Widget for &Popup<'_, W> {
fn render(self, area: Rect, buf: &mut Buffer) {
let mut state = PopupState::default();
StatefulWidget::render(self, area, buf, &mut state);
}
}

impl<W: KnownSize + WidgetRef> StatefulWidget for Popup<'_, W> {
impl<W: KnownSize + Widget + Clone> StatefulWidget for Popup<'_, W> {
type State = PopupState;

fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
StatefulWidget::render(&self, area, buf, state);
}
}

impl<W: KnownSize + WidgetRef> StatefulWidget for &Popup<'_, W> {
impl<W: KnownSize + Widget + Clone> StatefulWidget for &Popup<'_, W> {
type State = PopupState;

fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
Expand All @@ -144,7 +120,7 @@ impl<W: KnownSize + WidgetRef> StatefulWidget for &Popup<'_, W> {
let inner_area = block.inner(popup_area);
block.render(popup_area, buf);

self.body.render_ref(inner_area, buf);
self.body.clone().render(inner_area, buf);
Comment on lines -147 to +123
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one line is the crux of this entire change. I can't get this to work with &Widget, the best I can do is Clone the inner body widget. I'm not sure if this would be better left using WidgetRef instead of requiring Clone

}
}

Expand Down Expand Up @@ -191,17 +167,12 @@ mod tests {
#[test]
fn new() {
let popup = Popup::new("Test Body");
assert_eq!(
popup,
Popup {
body: "Test Body", // &str is a widget
borders: Borders::ALL,
border_set: Set::default(),
border_style: Style::default(),
title: Line::default(),
style: Style::default(),
}
);
assert_eq!(popup.body, "Test Body");
assert_eq!(popup.title, Line::default());
assert_eq!(popup.style, Style::default());
assert_eq!(popup.borders, Borders::ALL);
assert_eq!(popup.border_set, Set::default());
assert_eq!(popup.border_style, Style::default());
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion tui-popup/src/popup_state.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use derive_getters::Getters;
#[cfg(feature = "crossterm")]
use ratatui::crossterm::event::{MouseButton, MouseEvent, MouseEventKind};
use ratatui::prelude::Rect;
use ratatui_core::layout::Rect;

#[derive(Clone, Debug, Default, Getters)]
pub struct PopupState {
Expand Down