rat_popup/
lib.rs

1#![doc = include_str!("../readme.md")]
2//
3#![allow(clippy::collapsible_else_if)]
4
5use ratatui::layout::{Alignment, Rect};
6
7mod popup;
8
9pub use popup::*;
10
11pub mod event {
12    use rat_event::*;
13
14    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15    pub enum PopupOutcome {
16        /// The given event has not been used at all.
17        Continue,
18        /// The event has been recognized, but nothing noticeable has changed.
19        /// Further processing for this event may stop.
20        /// Rendering the ui is not necessary.
21        Unchanged,
22        /// The event has been recognized and there is some change due to it.
23        /// Further processing for this event may stop.
24        /// Rendering the ui is advised.
25        Changed,
26        /// Popup should be hidden.
27        Hide,
28    }
29
30    impl ConsumedEvent for PopupOutcome {
31        fn is_consumed(&self) -> bool {
32            *self != PopupOutcome::Continue
33        }
34    }
35
36    impl From<PopupOutcome> for Outcome {
37        fn from(value: PopupOutcome) -> Self {
38            match value {
39                PopupOutcome::Continue => Outcome::Continue,
40                PopupOutcome::Unchanged => Outcome::Unchanged,
41                PopupOutcome::Changed => Outcome::Changed,
42                PopupOutcome::Hide => Outcome::Changed,
43            }
44        }
45    }
46}
47
48/// Placement of the popup.
49///
50/// This enum is for use in a widget that then uses PopupCore
51/// internally. Expose Placement to the users of your widget
52/// to let them define a popup placement. Convert the Placement
53/// to a PopupConstraint internally when forwarding this
54/// to PopupCore.
55#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
56#[non_exhaustive]
57pub enum Placement {
58    /// Use the render-area for the popup as is.
59    #[default]
60    None,
61    /// Place above the given area.
62    Above,
63    /// Place below the given area:
64    Below,
65    /// Place left of the given area.
66    Left,
67    /// Place right of the given area.
68    Right,
69    /// Above or below dependent on available space. Aligned left.
70    AboveOrBelow,
71    /// Below or above dependent on available space. Aligned left.
72    BelowOrAbove,
73    /// Use the render-area for the popup, but place it at position (x,y).
74    Position(u16, u16),
75}
76
77impl Placement {
78    pub fn into_constraint(self, alignment: Alignment, rel_area: Rect) -> PopupConstraint {
79        match self {
80            Placement::None => PopupConstraint::None,
81            Placement::Above => PopupConstraint::Above(alignment, rel_area),
82            Placement::Below => PopupConstraint::Below(alignment, rel_area),
83            Placement::Left => PopupConstraint::Left(alignment, rel_area),
84            Placement::Right => PopupConstraint::Right(alignment, rel_area),
85            Placement::AboveOrBelow => PopupConstraint::AboveOrBelow(alignment, rel_area),
86            Placement::BelowOrAbove => PopupConstraint::BelowOrAbove(alignment, rel_area),
87            Placement::Position(x, y) => PopupConstraint::Position(x, y),
88        }
89    }
90}
91
92/// Placement relative to the widget area + the widget area.
93///
94/// The render() call for PopupCore will only use the size of
95/// the area given to the render call as the size of the popup.
96/// It will calculate the position of the popup given one of
97/// these constraints.
98///
99/// If you build a widget that uses a PopupCore internally you
100/// will rather use Placement as a parameter
101///
102#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
103#[non_exhaustive]
104pub enum PopupConstraint {
105    /// Use the render-area for the popup as is.
106    #[default]
107    None,
108    /// Synonym for AboveLeft
109    Above(Alignment, Rect),
110    /// Synonym for BelowLeft
111    Below(Alignment, Rect),
112    /// Synonym for LeftTop
113    Left(Alignment, Rect),
114    /// Synonym for RightTop
115    Right(Alignment, Rect),
116    /// Above or below dependent on available space. Aligned left.
117    AboveOrBelow(Alignment, Rect),
118    /// Below or above dependent on available space. Aligned left.
119    BelowOrAbove(Alignment, Rect),
120    /// Use the render-area for the popup, but place it at position (x,y).
121    Position(u16, u16),
122}
123
124mod _private {
125    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
126    pub struct NonExhaustive;
127}