Skip to content

Commit

Permalink
Support replacing angle brackets in SelectView popup button
Browse files Browse the repository at this point in the history
Allow a SelectView to be configured with custom decorators instead of the
angle brackets around the current item label.
  • Loading branch information
bgilbert committed Jun 18, 2024
1 parent 51f9cb3 commit 596e4d7
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions cursive-core/src/views/select_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub struct SelectView<T = String> {

// `true` if we show a one-line view, with popup on selection.
popup: bool,
// Decorators to draw around the popup button.
decorators: [String; 2],

// We need the last offset to place the popup window
// We "cache" it during the draw, so we need interior mutability.
Expand Down Expand Up @@ -102,6 +104,7 @@ impl<T: 'static + Send + Sync> SelectView<T> {
on_submit: None,
align: Align::top_left(),
popup: false,
decorators: ["<".to_string(), ">".to_string()],
autojump: false,
last_offset: Mutex::new(Vec2::zero()),
last_size: Vec2::zero(),
Expand Down Expand Up @@ -167,6 +170,19 @@ impl<T: 'static + Send + Sync> SelectView<T> {
self.last_required_size = None;
}

/// Use custom decorators around the popup button instead of "<" and ">".
///
/// Chainable variant.
#[must_use]
pub fn decorators<S: Into<String>>(self, start: S, end: S) -> Self {
self.with(|s| s.set_decorators(start, end))
}

/// Use custom decorators around the popup button instead of "<" and ">".
pub fn set_decorators<S: Into<String>>(&mut self, start: S, end: S) {
self.decorators = [start.into(), end.into()];
}

/// Sets a callback to be used when an item is selected.
#[crate::callback_helpers]
pub fn set_on_select<F>(&mut self, cb: F)
Expand Down Expand Up @@ -965,13 +981,16 @@ impl<T: 'static + Send + Sync> View for SelectView<T> {
printer.with_style(style, |printer| {
// Prepare the entire background
printer.print_hline((1, 0), x, " ");
// Draw the borders
printer.print((0, 0), "<");
printer.print((x, 0), ">");
// Draw the decorators
printer.print((0, 0), &self.decorators[0]);
printer.print((x + 1 - self.decorators[1].len(), 0), &self.decorators[1]);

if let Some(label) = self.items.get(focus).map(|item| &item.label) {
// And center the text?
let offset = HAlign::Center.get_offset(label.width(), x + 1);
let offset = HAlign::Center.get_offset(
label.width(),
x + 1 - self.decorators.iter().map(|d| d.len()).sum::<usize>(),
) + self.decorators[0].len();

printer.print_styled((offset, 0), label);
}
Expand Down Expand Up @@ -1027,7 +1046,10 @@ impl<T: 'static + Send + Sync> View for SelectView<T> {
.max()
.unwrap_or(1);
let size = if self.popup {
Vec2::new(w + 2, 1)
Vec2::new(
w + self.decorators.iter().map(|d| d.len()).sum::<usize>(),
1,
)
} else {
let h = self.items.len();

Expand Down

0 comments on commit 596e4d7

Please sign in to comment.