191 lines
6.6 KiB
Rust
191 lines
6.6 KiB
Rust
use druid::{
|
|
widget::{Container, Controller, Flex, Label, Padding, Painter, Svg, SvgData},
|
|
Color, Data, LifeCycle, RenderContext, Widget, WidgetExt,
|
|
};
|
|
|
|
use crate::AppData;
|
|
|
|
pub fn app_header_ui() -> impl Widget<AppData> {
|
|
let open_svg = include_str!("../assets/folder-open.svg")
|
|
.parse::<SvgData>()
|
|
.unwrap_or_default();
|
|
|
|
let disk_svg = include_str!("../assets/floppy-disk.svg")
|
|
.parse::<SvgData>()
|
|
.unwrap_or_default();
|
|
|
|
let run_svg = include_str!("../assets/play.svg")
|
|
.parse::<SvgData>()
|
|
.unwrap_or_default();
|
|
|
|
let plus_svg = include_str!("../assets/plus.svg")
|
|
.parse::<SvgData>()
|
|
.unwrap_or_default();
|
|
|
|
let abacus_svg = include_str!("../assets/abacus.svg")
|
|
.parse::<SvgData>()
|
|
.unwrap_or_default();
|
|
|
|
Container::new(
|
|
Flex::row()
|
|
.must_fill_main_axis(true)
|
|
.with_spacer(10.0)
|
|
.with_child(
|
|
Container::new(Padding::new(5.0, Svg::new(abacus_svg).fix_width(20.0)))
|
|
.controller(ToolbarButtonController::new(Color::rgb8(50, 50, 50)))
|
|
.on_click(|_ctx, _, _| {}),
|
|
)
|
|
.with_spacer(20.0)
|
|
.with_child(
|
|
Container::new(Padding::new(10.0, Svg::new(open_svg).fix_width(10.0)))
|
|
.controller(ToolbarButtonController::new(Color::rgb8(50, 50, 50)))
|
|
.on_click(|ctx, _, _| {
|
|
let abacus = druid::FileSpec::new("Abacus File", &["abacus"]);
|
|
let json = druid::FileSpec::new("JSON File", &["json"]);
|
|
|
|
let open_dialog_options = druid::FileDialogOptions::new()
|
|
.allowed_types(vec![abacus, json])
|
|
.default_type(abacus)
|
|
.name_label("Source")
|
|
.title("Open Workbook")
|
|
.button_text("Open");
|
|
|
|
ctx.submit_command(
|
|
druid::commands::SHOW_OPEN_PANEL.with(open_dialog_options),
|
|
);
|
|
}),
|
|
)
|
|
.with_spacer(10.0)
|
|
.with_child(
|
|
Container::new(Padding::new(10.0, Svg::new(disk_svg).fix_width(10.0)))
|
|
.controller(ToolbarButtonController::new(Color::rgb8(50, 50, 50)))
|
|
.on_click(|ctx, data: &mut AppData, _| {
|
|
let abacus = druid::FileSpec::new("Abacus File", &["abacus"]);
|
|
let json = druid::FileSpec::new("JSON File", &["json"]);
|
|
if data.filename.is_some() {
|
|
data.save();
|
|
} else {
|
|
let save_dialog_options = druid::FileDialogOptions::new()
|
|
.allowed_types(vec![abacus, json])
|
|
.default_type(abacus)
|
|
.name_label("Target")
|
|
.title("Save workbook")
|
|
.button_text("Save");
|
|
|
|
ctx.submit_command(
|
|
druid::commands::SHOW_SAVE_PANEL.with(save_dialog_options),
|
|
);
|
|
}
|
|
}),
|
|
)
|
|
.with_spacer(20.0)
|
|
.with_flex_child(
|
|
Padding::new(
|
|
5.0,
|
|
Container::new(Padding::new(
|
|
3.0,
|
|
Label::dynamic(|data: &AppData, _| {
|
|
data.filename
|
|
.clone()
|
|
.unwrap_or_else(|| String::from("Scratch file"))
|
|
})
|
|
.with_text_size(12.0)
|
|
.center(),
|
|
))
|
|
.background(Color::rgb8(35, 35, 35))
|
|
.rounded(4.0)
|
|
.border(Color::rgb8(10, 10, 10), 1.0)
|
|
.expand_width(),
|
|
),
|
|
1.0,
|
|
)
|
|
.with_spacer(20.0)
|
|
.with_child(
|
|
Container::new(Padding::new(10.0, Svg::new(plus_svg).fix_width(10.0)))
|
|
.controller(ToolbarButtonController::new(Color::rgb8(50, 50, 50)))
|
|
.on_click(|_ctx, data: &mut AppData, _env| {
|
|
data.blocks.push_back(crate::Block::new(
|
|
&format!("Block #{}", data.blocks.len() + 1),
|
|
data.blocks.len(),
|
|
));
|
|
}),
|
|
)
|
|
.with_spacer(10.0)
|
|
.with_child(
|
|
Container::new(Padding::new(10.0, Svg::new(run_svg).fix_width(10.0)))
|
|
.controller(ToolbarButtonController::new(Color::rgb8(50, 50, 50)))
|
|
.on_click(|ctx, _data: &mut AppData, _env| {
|
|
ctx.submit_command(crate::commands::PROCESS_WORKBOOK);
|
|
}),
|
|
)
|
|
.with_spacer(20.0)
|
|
.expand_width(),
|
|
)
|
|
.background(Color::rgb8(20, 20, 20))
|
|
}
|
|
|
|
pub fn header_separater() -> impl Widget<AppData> {
|
|
Painter::new(|ctx, _data, _env| {
|
|
let rect = ctx.size().to_rect();
|
|
ctx.fill(rect, &Color::rgb8(0, 0, 0))
|
|
})
|
|
.fix_height(1.0)
|
|
}
|
|
|
|
pub struct ToolbarButtonController {
|
|
color: Color,
|
|
}
|
|
|
|
impl ToolbarButtonController {
|
|
pub fn new(color: Color) -> Self {
|
|
Self { color }
|
|
}
|
|
}
|
|
|
|
impl<T: Data> Controller<T, Container<T>> for ToolbarButtonController {
|
|
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(self.color.clone());
|
|
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)
|
|
}
|
|
}
|