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/// Use this enum for your widgets API.
51///
52/// Then convert the Placement to a [PopupConstraint] and
53/// set the constraint with the PopupCore.
54#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
55#[non_exhaustive]
56pub enum Placement {
57    /// Use the render-area for the popup as is.
58    #[default]
59    None,
60    /// Place above the main widget area.
61    Above,
62    /// Place below the main widget area.
63    Below,
64    /// Place left of the main widget area.
65    Left,
66    /// Place right of the main widget area.
67    Right,
68    /// Above or below the main widget dependent on available space.
69    AboveOrBelow,
70    /// Below or above the main widget dependent on available space.
71    BelowOrAbove,
72    /// Place the popup at this position.
73    Position(u16, u16),
74}
75
76impl Placement {
77    /// Convert the placement to a PopupConstraint.
78    /// Needs an extra alignment and the area of the main widget.
79    ///
80    pub fn into_constraint(self, alignment: Alignment, relative_to_area: Rect) -> PopupConstraint {
81        match self {
82            Placement::None => PopupConstraint::None,
83            Placement::Above => PopupConstraint::Above(alignment, relative_to_area),
84            Placement::Below => PopupConstraint::Below(alignment, relative_to_area),
85            Placement::Left => PopupConstraint::Left(alignment, relative_to_area),
86            Placement::Right => PopupConstraint::Right(alignment, relative_to_area),
87            Placement::AboveOrBelow => PopupConstraint::AboveOrBelow(alignment, relative_to_area),
88            Placement::BelowOrAbove => PopupConstraint::BelowOrAbove(alignment, relative_to_area),
89            Placement::Position(x, y) => PopupConstraint::Position(x, y),
90        }
91    }
92}
93
94/// Placement constraint for PopupCore.
95///
96/// This defines a position relative to the main widget,
97/// plus an alignment and the main widget area.
98#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
99#[non_exhaustive]
100pub enum PopupConstraint {
101    /// Use the render-area for the popup as is.
102    #[default]
103    None,
104    /// Place above the main widget area.
105    Above(Alignment, Rect),
106    /// Place below the main widget area.
107    Below(Alignment, Rect),
108    /// Place left of the main widget area.
109    /// Alignment::Left == Top, Alignment::Center == Middle, Alignment::Right == Bottom
110    Left(Alignment, Rect),
111    /// Place right of the main widget area.
112    /// Alignment::Left == Top, Alignment::Center == Middle, Alignment::Right == Bottom
113    Right(Alignment, Rect),
114    /// Above or below the main widget dependent on available space.
115    AboveOrBelow(Alignment, Rect),
116    /// Below or above the main widget dependent on available space.
117    BelowOrAbove(Alignment, Rect),
118    /// Place the popup at this position.
119    Position(u16, u16),
120}
121
122mod _private {
123    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
124    pub struct NonExhaustive;
125}