Rename modal

This commit is contained in:
Joe Bellus 2022-10-13 23:23:22 -04:00
parent 235e14dcea
commit a315260faf
4 changed files with 173 additions and 9 deletions

View File

@ -115,7 +115,6 @@ pub fn header_separater() -> impl Widget<AppData> {
ctx.fill(rect, &Color::rgb8(0, 0, 0))
})
.fix_height(1.0)
.expand_width()
}
pub struct ToolbarButtonController {

View File

@ -5,3 +5,5 @@ pub const PROCESS_BLOCK: Selector<usize> = Selector::new("process-block");
pub const DELETE_BLOCK: Selector<usize> = Selector::new("delete-block");
pub const RENAME_BLOCK: Selector<usize> = Selector::new("rename-block");
pub const CLOSE_MODAL: Selector<()> = Selector::new("close-modal");

View File

@ -9,5 +9,5 @@ pub struct RenameBlock {
#[derive(Clone, Data, Lens, Default, Debug)]
pub struct Modals {
pub rename_block: Option<RenameBlock>,
pub rename_block: RenameBlock,
}

View File

@ -1,8 +1,10 @@
use crate::data;
use druid::widget::{Controller, Padding};
use druid::{
widget::{Container, Label},
RenderContext, Widget, WidgetPod,
widget::{Container, Flex, Label, LensWrap, TextBox},
Color, FontDescriptor, FontFamily, FontWeight, RenderContext, Widget, WidgetExt, WidgetPod,
};
use druid::{Data, LifeCycle, TextAlignment};
pub struct ModalContainer {
child: WidgetPod<data::AppData, Box<dyn Widget<data::AppData>>>,
@ -26,25 +28,40 @@ impl Widget<data::AppData> for ModalContainer {
data: &mut data::AppData,
env: &druid::Env,
) {
if let druid::Event::Notification(n) = event {
if n.is(crate::commands::CLOSE_MODAL) {
self.modal = None;
data.modals.rename_block = data::RenameBlock::default();
ctx.children_changed();
return;
}
}
if let druid::Event::Command(c) = event {
if let Some(idx) = c.get(crate::commands::RENAME_BLOCK) {
println!("rename block");
data.modals.rename_block = Some(data::RenameBlock {
data.modals.rename_block = data::RenameBlock {
block_index: *idx,
name: data
.blocks
.get(*idx)
.map(|i| i.name.clone())
.unwrap_or_default(),
input: String::new(),
});
input: data
.blocks
.get(*idx)
.map(|i| i.name.clone())
.unwrap_or_default(),
};
self.modal = Some(WidgetPod::new(rename_block()).boxed());
ctx.children_changed();
return;
}
}
if self.modal.is_none() {
if let Some(m) = self.modal.as_mut() {
m.event(ctx, event, data, env);
} else {
self.child.event(ctx, event, data, env);
}
}
@ -56,6 +73,9 @@ impl Widget<data::AppData> for ModalContainer {
data: &data::AppData,
env: &druid::Env,
) {
if let Some(modal) = self.modal.as_mut() {
modal.lifecycle(ctx, event, data, env);
}
self.child.lifecycle(ctx, event, data, env);
}
@ -66,6 +86,9 @@ impl Widget<data::AppData> for ModalContainer {
data: &data::AppData,
env: &druid::Env,
) {
if let Some(modal) = self.modal.as_mut() {
modal.update(ctx, data, env);
}
self.child.update(ctx, data, env);
}
@ -76,6 +99,9 @@ impl Widget<data::AppData> for ModalContainer {
data: &data::AppData,
env: &druid::Env,
) -> druid::Size {
if let Some(modal) = self.modal.as_mut() {
modal.layout(ctx, bc, data, env);
}
self.child.layout(ctx, bc, data, env)
}
@ -92,5 +118,142 @@ impl Widget<data::AppData> for ModalContainer {
}
fn rename_block() -> impl Widget<data::AppData> {
Container::new(Label::new("rename block").with_text_color(druid::Color::WHITE))
modal_container(
"Rename Block",
(300.0, 150.0),
Flex::column()
.with_child(
Label::new("Block name")
.with_text_color(druid::Color::WHITE)
.with_text_alignment(TextAlignment::Start)
.with_font(
FontDescriptor::new(FontFamily::SYSTEM_UI)
.with_weight(FontWeight::BOLD)
.with_size(14.0),
)
.fix_width(300.0),
)
.with_spacer(5.0)
.with_child(LensWrap::new(
LensWrap::new(
TextBox::default()
.lens(data::RenameBlock::input)
.fix_width(300.0),
data::Modals::rename_block,
),
data::AppData::modals,
))
.with_spacer(20.0)
.with_child(
Flex::row()
.must_fill_main_axis(true)
.with_child(modal_action("Cancel").on_click(|ctx, _, _| {
ctx.submit_notification(crate::commands::CLOSE_MODAL)
}))
.with_flex_spacer(1.0)
.with_child(modal_action("Rename").on_click(
|ctx, data: &mut data::AppData, _| {
let input = data.modals.rename_block.input.clone();
if let Some(blk) =
data.blocks.get_mut(data.modals.rename_block.block_index)
{
blk.name = input;
data.modals.rename_block = data::RenameBlock::default();
ctx.submit_notification(crate::commands::CLOSE_MODAL)
}
},
))
.fix_width(300.0),
),
)
}
fn modal_container<S: Into<druid::Size>>(
title: &str,
size: S,
child: impl Widget<data::AppData> + 'static,
) -> impl Widget<data::AppData> {
let size = size.into();
Flex::column()
.with_child(modal_title(title, size.width))
.with_child(Padding::new(15.0, child))
.background(Color::rgb8(20, 20, 20))
.center()
.fix_size(size.width, size.height)
}
fn modal_title(title: &str, width: f64) -> impl Widget<data::AppData> {
Container::new(Padding::new(
8.0,
Flex::row()
.with_spacer(10.0)
.with_child(
Label::new(title)
.with_text_color(Color::rgb8(150, 150, 150))
.with_text_alignment(TextAlignment::Start)
.with_font(
FontDescriptor::new(FontFamily::SYSTEM_UI)
.with_weight(FontWeight::BOLD)
.with_size(14.0),
)
.fix_width(width),
)
.with_spacer(10.0),
))
.background(Color::rgb8(10, 10, 10))
}
fn modal_action<T: Data>(text: &str) -> impl Widget<T> {
Container::new(Padding::new(5.0, Label::new(text)))
.rounded(4.0)
.controller(ModalActionController)
}
pub struct ModalActionController;
impl<T: Data> Controller<T, Container<T>> for ModalActionController {
fn event(
&mut self,
child: &mut Container<T>,
ctx: &mut druid::EventCtx,
event: &druid::Event,
data: &mut T,
env: &druid::Env,
) {
ctx.set_cursor(&druid::Cursor::Pointer);
child.event(ctx, event, data, env)
}
fn lifecycle(
&mut self,
child: &mut Container<T>,
ctx: &mut druid::LifeCycleCtx,
event: &druid::LifeCycle,
data: &T,
env: &druid::Env,
) {
match event {
LifeCycle::HotChanged(true) => {
child.set_background(Color::rgb8(100, 100, 100));
ctx.request_paint();
}
LifeCycle::HotChanged(false) => {
child.set_background(Color::TRANSPARENT);
ctx.request_paint();
}
_ => {}
}
child.lifecycle(ctx, event, data, env)
}
fn update(
&mut self,
child: &mut Container<T>,
ctx: &mut druid::UpdateCtx,
old_data: &T,
data: &T,
env: &druid::Env,
) {
child.update(ctx, old_data, data, env)
}
}