use crate::app::Application;
use crate::core::geometry::Rect;
use crate::core::command::{CommandId, CM_YES, CM_NO, CM_OK, CM_CANCEL};
use crate::views::dialog::Dialog;
use crate::views::button::Button;
use crate::views::static_text::StaticText;
use crate::views::input_line::InputLine;
use crate::views::View;
use std::rc::Rc;
use std::cell::RefCell;
pub const MF_WARNING: u16 = 0x0000;
pub const MF_ERROR: u16 = 0x0001;
pub const MF_INFORMATION: u16 = 0x0002;
pub const MF_CONFIRMATION: u16 = 0x0003;
pub const MF_YES_BUTTON: u16 = 0x0100;
pub const MF_NO_BUTTON: u16 = 0x0200;
pub const MF_OK_BUTTON: u16 = 0x0400;
pub const MF_CANCEL_BUTTON: u16 = 0x0800;
pub const MF_YES_NO_CANCEL: u16 = MF_YES_BUTTON | MF_NO_BUTTON | MF_CANCEL_BUTTON;
pub const MF_OK_CANCEL: u16 = MF_OK_BUTTON | MF_CANCEL_BUTTON;
pub fn message_box(app: &mut Application, msg: &str, options: u16) -> CommandId {
let (width, height) = app.terminal.size();
let dialog_width = 40i16;
let dialog_height = 9i16;
let dialog_x = (width as i16 - dialog_width) / 2;
let dialog_y = (height as i16 - dialog_height - 2) / 2;
let bounds = Rect::new(dialog_x, dialog_y, dialog_x + dialog_width, dialog_y + dialog_height);
message_box_rect(app, bounds, msg, options)
}
pub fn message_box_rect(app: &mut Application, bounds: Rect, msg: &str, options: u16) -> CommandId {
let title = match options & 0x03 {
MF_WARNING => "Warning",
MF_ERROR => "Error",
MF_INFORMATION => "Information",
MF_CONFIRMATION => "Confirm",
_ => "Message",
};
let mut dialog = Dialog::new(bounds, title);
let text_bounds = Rect::new(3, 2, bounds.width() - 2, bounds.height() - 3);
dialog.add(Box::new(StaticText::new(text_bounds, msg)));
let button_specs = [
(MF_YES_BUTTON, "~Y~es", CM_YES),
(MF_NO_BUTTON, "~N~o", CM_NO),
(MF_OK_BUTTON, "O~K~", CM_OK),
(MF_CANCEL_BUTTON, "Cancel", CM_CANCEL),
];
let mut buttons = Vec::new();
let mut total_width = -2i16;
for (flag, label, command) in button_specs.iter() {
if (options & flag) != 0 {
let button = Button::new(Rect::new(0, 0, 10, 2), label, *command, buttons.is_empty());
total_width += 10 + 2; buttons.push((button, *command));
}
}
let mut x = (bounds.width() - total_width) / 2;
let y = bounds.height() - 3;
for (mut button, _cmd) in buttons {
let button_bounds = Rect::new(x, y, x + 10, y + 2);
button.set_bounds(button_bounds);
dialog.add(Box::new(button));
x += 12; }
dialog.set_initial_focus();
dialog.execute(app)
}
pub fn input_box(app: &mut Application, title: &str, label: &str, default: &str, limit: usize) -> (CommandId, String) {
let (width, height) = app.terminal.size();
let dialog_width = 60i16;
let dialog_height = 8i16;
let dialog_x = (width as i16 - dialog_width) / 2;
let dialog_y = (height as i16 - dialog_height - 2) / 2;
let bounds = Rect::new(dialog_x, dialog_y, dialog_x + dialog_width, dialog_y + dialog_height);
input_box_rect(app, bounds, title, label, default, limit)
}
pub fn input_box_rect(app: &mut Application, bounds: Rect, title: &str, label: &str, default: &str, limit: usize) -> (CommandId, String) {
let mut dialog = Dialog::new(bounds, title);
let input_data = Rc::new(RefCell::new(default.to_string()));
if !label.is_empty() {
let label_bounds = Rect::new(2, 2, 2 + label.len() as i16 + 1, 3);
dialog.add(Box::new(StaticText::new(label_bounds, label)));
}
let input_x = if !label.is_empty() { 4 + label.len() as i16 } else { 3 };
let input_bounds = Rect::new(input_x, 2, bounds.width() - 3, 3);
let input = InputLine::new(input_bounds, limit, Rc::clone(&input_data));
dialog.add(Box::new(input));
let ok_button = Button::new(
Rect::new(bounds.width() / 2 - 12, bounds.height() - 3, bounds.width() / 2 - 2, bounds.height() - 1),
"O~K~",
CM_OK,
true );
dialog.add(Box::new(ok_button));
let cancel_button = Button::new(
Rect::new(bounds.width() / 2 + 2, bounds.height() - 3, bounds.width() / 2 + 12, bounds.height() - 1),
"Cancel",
CM_CANCEL,
false
);
dialog.add(Box::new(cancel_button));
dialog.set_initial_focus();
let result = dialog.execute(app);
let text = input_data.borrow().clone();
(result, text)
}