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}