Compare commits

..

1 Commits

Author SHA1 Message Date
Enrico Lumetti bf63d5880f Add Viewport up/down scroll and some misc improvements 2021-02-28 15:31:59 +01:00
4 changed files with 29 additions and 46 deletions

View File

@ -161,6 +161,11 @@ impl Canvas {
self.elements.push_back(element); self.elements.push_back(element);
} }
pub fn remove_element_at(&mut self, index: usize) {
// TODO(enrico): content size should be recomputed
self.elements.remove(index);
}
pub fn elements(&self) -> &Vector<CanvasElement> { pub fn elements(&self) -> &Vector<CanvasElement> {
&self.elements &self.elements
} }

View File

@ -24,7 +24,7 @@ use druid::widget::prelude::*;
use druid::widget::{Align, Button, CrossAxisAlignment, Flex, List, SizedBox, WidgetExt}; use druid::widget::{Align, Button, CrossAxisAlignment, Flex, List, SizedBox, WidgetExt};
use druid::{ use druid::{
AppDelegate, AppLauncher, Color, Command, Data, DelegateCtx, Env, FileDialogOptions, FileSpec, AppDelegate, AppLauncher, Color, Command, Data, DelegateCtx, Env, FileDialogOptions, FileSpec,
Handled, Lens, Target, WidgetId, WindowDesc, Handled, Lens, LocalizedString, Target, WidgetId, WindowDesc,
}; };
use im::Vector; use im::Vector;
@ -106,7 +106,6 @@ fn build_ui() -> impl Widget<StilettoState> {
let save_dialog_options = FileDialogOptions::new() let save_dialog_options = FileDialogOptions::new()
.allowed_types(vec![stlt]) .allowed_types(vec![stlt])
.default_type(stlt); .default_type(stlt);
let save_dialog_options_clone = save_dialog_options.clone();
let open_dialog_options = save_dialog_options.clone(); let open_dialog_options = save_dialog_options.clone();
let save_buttons = Flex::row() let save_buttons = Flex::row()
@ -121,30 +120,19 @@ fn build_ui() -> impl Widget<StilettoState> {
ctx.submit_command(Command::new(SCROLL, 30.0, canvas_id)); ctx.submit_command(Command::new(SCROLL, 30.0, canvas_id));
}, },
)) ))
.with_child(Button::new("Save").on_click(move |ctx, data: &mut StilettoState, _| {
if data.current_file_path.is_some() {
ctx.submit_command(Command::new(commands::SAVE_FILE, (), Target::Auto));
} else {
ctx.submit_command(Command::new(
druid::commands::SHOW_SAVE_PANEL,
save_dialog_options_clone.clone(),
Target::Auto,
))
}
}))
.with_child(Button::new("Save As").on_click(move |ctx, _, _| {
ctx.submit_command(Command::new(
druid::commands::SHOW_SAVE_PANEL,
save_dialog_options.clone(),
Target::Auto,
))
}))
.with_child(Button::new("Open").on_click(move |ctx, _, _| { .with_child(Button::new("Open").on_click(move |ctx, _, _| {
ctx.submit_command(Command::new( ctx.submit_command(Command::new(
druid::commands::SHOW_OPEN_PANEL, druid::commands::SHOW_OPEN_PANEL,
open_dialog_options.clone(), open_dialog_options.clone(),
Target::Auto, Target::Auto,
)) ))
}))
.with_child(Button::new("Save").on_click(move |ctx, _, _| {
ctx.submit_command(Command::new(
druid::commands::SHOW_SAVE_PANEL,
save_dialog_options.clone(),
Target::Auto,
))
})); }));
let tool_buttons = Flex::row() let tool_buttons = Flex::row()
@ -188,7 +176,6 @@ fn build_ui() -> impl Widget<StilettoState> {
struct Delegate; struct Delegate;
impl AppDelegate<StilettoState> for Delegate { impl AppDelegate<StilettoState> for Delegate {
fn command( fn command(
&mut self, &mut self,
_ctx: &mut DelegateCtx, _ctx: &mut DelegateCtx,
@ -199,21 +186,20 @@ impl AppDelegate<StilettoState> for Delegate {
) -> Handled { ) -> Handled {
use std::fs::File; use std::fs::File;
if cmd.get(commands::SAVE_FILE_AS).is_some() || cmd.get(commands::SAVE_FILE).is_some() { if cmd.get(commands::SAVE_FILE).is_some() {
let mut path_buf = cmd.get(commands::SAVE_FILE_AS) //let path = data.current_file_path.as_ref().unwrap();
.map(|file_info| file_info.path().to_path_buf()) // TODO
.unwrap_or(data.current_file_path.as_ref().cloned().unwrap()); }
path_buf.set_extension("stlt"); if let Some(file_info) = cmd.get(commands::SAVE_FILE_AS) {
let res_file = File::create(file_info.path());
let res_file = File::create(&path_buf);
if let Ok(f) = res_file { if let Ok(f) = res_file {
let write_res = let write_res =
serde_json::to_writer_pretty(f, &data.canvas.get_document_snapshot()); serde_json::to_writer_pretty(f, &data.canvas.get_document_snapshot());
if write_res.is_err() { if write_res.is_err() {
warn!("Error while saving: {:?}", write_res.err()); warn!("Error while saving: {:?}", write_res.err());
} else { } else {
info!("Written to file: {}", &path_buf.display()); data.current_file_path = Some(file_info.path().to_path_buf());
data.current_file_path = Some(path_buf); info!("Written to file: {}", file_info.path().display());
} }
} else { } else {
warn!("Cannot create file: {:?}", res_file.err()); warn!("Cannot create file: {:?}", res_file.err());

View File

@ -99,20 +99,13 @@ impl CanvasToolCtx {
(CanvasToolState::Erasing, Event::MouseMove(mouse_event)) => { (CanvasToolState::Erasing, Event::MouseMove(mouse_event)) => {
let eraser_rect = let eraser_rect =
druid::Rect::from_center_size(transform * mouse_event.pos, (5.0, 5.0)); druid::Rect::from_center_size(transform * mouse_event.pos, (5.0, 5.0));
let old_elements = vcanvas.get().elements(); let elements = vcanvas.get().find_intersections(eraser_rect);
let mut new_elements = old_elements.clone();
new_elements.retain(|elem| { if !elements.is_empty() {
// Check if the element intersects the eraser rect
if elem.bounding_box().intersect(eraser_rect).area() > 0.0 {
if elem.intersects_rect(eraser_rect) {
return false;
}
}
return true;
});
if new_elements.len() != old_elements.len() {
vcanvas.update(|canvas: &mut Canvas| { vcanvas.update(|canvas: &mut Canvas| {
*canvas = Canvas::new_with_elements(new_elements); for i in elements {
canvas.remove_element_at(i);
}
}); });
} }
} }

View File

@ -25,7 +25,7 @@ use druid::scroll_component::ScrollComponent;
use druid::widget::prelude::*; use druid::widget::prelude::*;
use druid::widget::Viewport; use druid::widget::Viewport;
use druid::{Affine, Color, Data, Env, Event}; use druid::{Affine, Color, Data, Env, Event};
use druid::{Selector}; use druid::{Command, Selector, Target};
pub const SCROLL: Selector<f64> = Selector::new("scroll_canvas"); pub const SCROLL: Selector<f64> = Selector::new("scroll_canvas");
@ -182,9 +182,8 @@ impl Widget<CanvasState> for CanvasWidget {
let size = ctx.size(); let size = ctx.size();
let rect = size.to_rect(); let rect = size.to_rect();
ctx.fill(rect, &Color::WHITE);
let page_content_size = data.versioned_canvas.get().content_size(); let page_content_size = data.versioned_canvas.get().content_size();
ctx.fill(rect, &Color::WHITE);
self.viewport.rect = self.viewport.rect.with_size(size); self.viewport.rect = self.viewport.rect.with_size(size);
self.viewport.content_size = druid::Size::new( self.viewport.content_size = druid::Size::new(
self.viewport.rect.x1.max(page_content_size.width), self.viewport.rect.x1.max(page_content_size.width),