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}