use crate::{Frame, widget::WidgetBuilder, WidgetState, Point};
pub struct WindowBuilder<'a> {
builder: WidgetBuilder<'a>,
state: WindowState,
}
impl<'a> WindowBuilder<'a> {
pub(crate) fn new(builder: WidgetBuilder<'a>) -> WindowBuilder<'a> {
WindowBuilder {
builder,
state: WindowState::default(),
}
}
#[must_use]
pub fn cancel_render_group(mut self) -> WindowBuilder<'a> {
self.builder.set_next_render_group(None);
self
}
#[must_use]
pub fn with_titlebar(mut self, with_titlebar: bool) -> WindowBuilder<'a> {
self.state.with_titlebar = with_titlebar;
self
}
#[must_use]
pub fn title<T: Into<String>>(mut self, title: T) -> WindowBuilder<'a> {
self.state.title = Some(title.into());
self
}
#[must_use]
pub fn with_close_button(mut self, with_close_button: bool) -> WindowBuilder<'a> {
self.state.with_close_button = with_close_button;
self
}
#[must_use]
pub fn moveable(mut self, moveable: bool) -> WindowBuilder<'a> {
self.state.moveable = moveable;
self
}
#[must_use]
pub fn resizable(mut self, resizable: bool) -> WindowBuilder<'a> {
self.state.resizable = resizable;
self
}
pub fn children<F: FnOnce(&mut Frame)>(self, children: F) -> WidgetState {
let builder = self.builder;
let state = self.state;
let id = builder.widget.id().to_string();
builder.children(|ui| {
(children)(ui);
let drag_move = if state.with_titlebar {
let result = ui.start("titlebar")
.children(|ui| {
if let Some(title) = state.title.as_ref() {
ui.start("title").text(title).finish();
} else {
ui.start("title").finish();
}
if state.with_close_button {
let clicked = ui.child("close").clicked;
if clicked {
ui.close(&id);
}
}
});
if state.moveable && result.pressed {
result.moved
} else {
Point::default()
}
} else {
Point::default()
};
if drag_move != Point::default() {
ui.modify(&id, |state| {
state.moved = state.moved + drag_move;
});
}
if state.resizable {
let result = ui.button("handle", "");
if result.pressed {
ui.modify(&id, |state| {
state.resize = state.resize + result.moved;
});
}
}
})
}
}
struct WindowState {
with_titlebar: bool,
with_close_button: bool,
moveable: bool,
resizable: bool,
title: Option<String>,
}
impl Default for WindowState {
fn default() -> Self {
Self {
with_titlebar: true,
with_close_button: true,
moveable: true,
resizable: true,
title: None,
}
}
}