use crate::*;
use fui_core::*;
use fui_drawing::Color;
use fui_macros::ui;
use futures_channel::oneshot;
use futures_channel::oneshot::Canceled;
use std::cell::RefCell;
use std::future::Future;
use std::rc::Rc;
use typemap::TypeMap;
pub struct DialogButtonViewModel {
pub text: Property<String>,
pub callback: Callback<()>,
}
impl DialogButtonViewModel {
pub fn new(text: String, callback: Callback<()>) -> Self {
Self {
text: Property::new(text),
callback,
}
}
}
impl ViewModel for DialogButtonViewModel {
fn create_view(self: &Rc<Self>) -> Rc<RefCell<dyn ControlObject>> {
ui! {
Button {
clicked: self.callback.clone(),
Text { text: &self.text }
}
}
}
}
pub struct MessageBox {
message: String,
buttons: Vec<String>,
}
impl MessageBox {
pub fn new<S: Into<String>>(message: S) -> Self {
MessageBox {
message: message.into(),
buttons: Vec::new(),
}
}
pub fn with_button<S: Into<String>>(mut self, text: S) -> Self {
self.buttons.push(text.into());
self
}
pub async fn show(self, window: &Rc<dyn WindowService>) -> i32 {
self.show_internal(window).await.unwrap()
}
fn show_internal(
self,
window: &Rc<dyn WindowService>,
) -> impl Future<Output = Result<i32, Canceled>> + use<> {
let buttons = ObservableVec::<Rc<DialogButtonViewModel>>::new();
let (sender, receiver) = oneshot::channel::<i32>();
let sender = Rc::new(RefCell::new(Some(sender)));
let content = ui! {
Border {
border_type: BorderType::None,
Style: Default { background_color: Color::rgba(1.0, 1.0, 1.0, 0.5), },
HorizontalAlignment: Alignment::Stretch,
VerticalAlignment: Alignment::Stretch,
Shadow {
Style: Default { size: 12.0f32 },
HorizontalAlignment: Alignment::Center,
VerticalAlignment: Alignment::Center,
Border {
border_type: BorderType::None,
Style: Default { background_color: Color::rgba(0.0, 0.0, 0.0, 0.8), },
Vertical {
Margin: Thickness::all(10.0f32),
Text { text: self.message },
Grid {
Margin: Thickness::top(10.0f32),
rows: 1,
&buttons
}
}
}
}
}
};
for (button_index, text) in self.buttons.into_iter().enumerate() {
let window_clone = window.clone();
let content_clone: Rc<RefCell<dyn ControlObject>> = content.clone();
let new_callback = Callback::new_sync({
let sender = sender.clone();
move |_| {
window_clone.remove_layer(&content_clone);
sender
.borrow_mut()
.take()
.unwrap()
.send(button_index as i32)
.unwrap();
}
});
buttons.push(Rc::new(DialogButtonViewModel::new(text, new_callback)));
}
window.add_layer(content);
receiver
}
}