use crate::frame::context::UpdateType;
use crate::render::rectangle::param::RectParam;
use crate::render::{RenderParam, WrcRender};
use crate::{ScrollWidget, Widget};
use crate::response::Response;
use crate::size::border::Border;
use crate::size::padding::Padding;
use crate::size::radius::Radius;
use crate::size::rect::Rect;
use crate::style::color::Color;
use crate::style::{BorderStyle, ClickStyle, FillStyle, Shadow};
use crate::ui::Ui;
use crate::widgets::{WidgetChange, WidgetSize};
pub struct Popup {
pub(crate) id: String,
scroll_area: ScrollWidget,
fill_render: RenderParam<RectParam>,
size: WidgetSize,
pub(crate) open: bool,
changed: bool,
}
impl Popup {
pub fn new(ui: &mut Ui, width: f32, height: f32) -> Popup {
let shadow = Shadow {
offset: [5.0, 8.0],
spread: 10.0,
color: Color::rgba(0, 0, 0, 30),
};
let fill_param = RectParam::new(Rect::new(), Popup::popup_style())
.with_shadow(shadow);
let mut fill_render = RenderParam::new(fill_param);
fill_render.init_rectangle(ui, false, false);
let area = ScrollWidget::vertical().with_size(width, height).padding(Padding::same(5.0));
Popup {
id: crate::gen_unique_id(),
scroll_area: area,
fill_render,
size: WidgetSize::same(width, height),
open: false,
changed: false,
}
}
pub fn show(mut self, ui: &mut Ui, context: impl FnMut(&mut Ui)) {
self.fill_render.init_rectangle(ui, false, false);
self.scroll_area.draw(ui, context);
self.scroll_area.update(ui);
ui.popups.as_mut().unwrap().insert(self.id.clone(), self);
}
pub fn set_rect(&mut self, rect: Rect) {
self.fill_render.param.rect = rect;
self.changed = true;
}
pub fn rect(&self) -> &Rect {
&self.fill_render.param.rect
}
pub fn popup_style() -> ClickStyle {
ClickStyle {
fill: FillStyle {
inactive: Color::rgb(240, 240, 240),
hovered: Color::rgb(240, 240, 240),
clicked: Color::rgb(240, 240, 240),
},
border: BorderStyle {
inactive: Border {
width: 1.0,
radius: Radius::same(5),
color: Color::rgba(144, 209, 255, 255),
},
hovered: Border {
width: 1.0,
radius: Radius::same(5),
color: Color::rgba(144, 209, 255, 255),
},
clicked: Border {
width: 1.0,
radius: Radius::same(5),
color: Color::rgba(144, 209, 255, 255),
},
},
}
}
pub fn update_buffer(&mut self, ui: &mut Ui) {
if self.changed { ui.widget_changed |= WidgetChange::Value; }
self.changed = false;
if ui.widget_changed.contains(WidgetChange::Value) {
self.fill_render.update(ui, false, false);
}
}
fn redraw(&mut self, ui: &mut Ui) {
if !self.open { return; }
let pass = ui.pass.as_mut().unwrap();
ui.context.render.rectangle.render(&self.fill_render, pass);
let previous_rect = ui.draw_rect.clone();
ui.draw_rect = self.fill_render.param.rect.clone();
self.scroll_area.redraw(ui);
ui.draw_rect = previous_rect;
}
}
impl Widget for Popup {
fn update(&mut self, ui: &mut Ui) -> Response<'_> {
match ui.update_type {
UpdateType::Draw => self.redraw(ui),
UpdateType::Init | UpdateType::ReInit => { self.scroll_area.update(ui); }
_ => if self.open {
self.scroll_area.update(ui);
if let UpdateType::MouseRelease = ui.update_type {
if !ui.device.device_input.click_at(&self.fill_render.param.rect) {
self.open = false;
ui.context.window.request_redraw();
}
}
}
}
Response::new(&self.id, self.size.clone())
}
}