Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ enum AppInput {
ToggleToolbarsDisplay,
ToolSwitchShortcut(Tools),
ColorSwitchShortcut(u64),
CropDimensionsUpdate((i32, i32)),
CropToolActivated(bool),
}

#[derive(Debug)]
Expand Down Expand Up @@ -226,6 +228,26 @@ impl Component for App {
ui::toolbars::ColorButtons::Palette(index),
));
}
AppInput::CropDimensionsUpdate((width, height)) => {
let dimensions = if (width, height) == (0, 0) {
self.image_dimensions
} else {
(width, height)
};
self.style_toolbar
.sender()
.emit(StyleToolbarInput::CropDimensionsChanged(dimensions));
}
AppInput::CropToolActivated(active) => {
if !active {
// Show full image dimensions when crop tool is deactivated
self.style_toolbar
.sender()
.emit(StyleToolbarInput::CropDimensionsChanged(
self.image_dimensions,
));
}
}
}
}

Expand Down Expand Up @@ -261,6 +283,12 @@ impl Component for App {
SketchBoardOutput::ColorSwitchShortcut(index) => {
AppInput::ColorSwitchShortcut(index)
}
SketchBoardOutput::CropDimensionsUpdate(dimensions) => {
AppInput::CropDimensionsUpdate(dimensions)
}
SketchBoardOutput::CropToolActivated(active) => {
AppInput::CropToolActivated(active)
}
});

// Toolbars
Expand All @@ -280,6 +308,12 @@ impl Component for App {
image_dimensions,
};

// Initialize style toolbar with full image dimensions
model
.style_toolbar
.sender()
.emit(StyleToolbarInput::CropDimensionsChanged(image_dimensions));

let widgets = view_output!();

if APP_CONFIG.read().focus_toggles_toolbars() {
Expand Down
22 changes: 22 additions & 0 deletions src/sketch_board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,16 @@ pub enum SketchBoardInput {
RenderResult(RenderedImage, Vec<Action>),
CommitEvent(TextEventMsg),
Refresh,
Output(SketchBoardOutput),
}

#[derive(Debug, Clone)]
pub enum SketchBoardOutput {
ToggleToolbarsDisplay,
ToolSwitchShortcut(Tools),
ColorSwitchShortcut(u64),
CropDimensionsUpdate((i32, i32)),
CropToolActivated(bool),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -574,6 +577,15 @@ impl SketchBoard {
) -> ToolUpdateResult {
match toolbar_event {
ToolbarEvent::ToolSelected(tool) => {
let crop_was_active = self.active_tool.borrow().get_tool_type() == Tools::Crop;
let crop_is_active = tool == Tools::Crop;

if crop_was_active != crop_is_active {
sender
.output_sender()
.emit(SketchBoardOutput::CropToolActivated(crop_is_active));
}

// deactivate old tool and save drawable, if any
let old_tool = self.active_tool.clone();
let mut deactivate_result =
Expand Down Expand Up @@ -651,6 +663,12 @@ impl SketchBoard {
ToolbarEvent::SaveFileAs => self.handle_action(&[Action::SaveToFileAs]),
ToolbarEvent::Resize => self.handle_resize(),
ToolbarEvent::OriginalScale => self.handle_original_scale(),
ToolbarEvent::CropDimensionsUpdated((width, height)) => {
sender
.output_sender()
.emit(SketchBoardOutput::CropDimensionsUpdate((width, height)));
ToolUpdateResult::Unmodified
}
}
}

Expand Down Expand Up @@ -996,6 +1014,10 @@ impl Component for SketchBoard {
ToolUpdateResult::Unmodified
}
SketchBoardInput::Refresh => ToolUpdateResult::Redraw,
SketchBoardInput::Output(output) => {
sender.output_sender().emit(output);
ToolUpdateResult::Unmodified
}
};

// println!(" Result={:?}", result);
Expand Down
42 changes: 34 additions & 8 deletions src/tools/crop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use std::f32::consts::PI;

use crate::{
math::{self, Vec2D},
sketch_board::{KeyEventMsg, MouseButton, MouseEventMsg, MouseEventType, SketchBoardInput},
sketch_board::{
KeyEventMsg, MouseButton, MouseEventMsg, MouseEventType, SketchBoardInput,
SketchBoardOutput,
},
};
use anyhow::Result;
use femtovg::{Color, Paint, Path};
Expand Down Expand Up @@ -269,6 +272,19 @@ impl CropTool {
crop.size = br - tl;
}

fn emit_crop_dimensions_update(&self) {
if let (Some(crop), Some(sender)) = (&self.crop, &self.sender) {
let (_pos, size) = crop.get_rectangle();
let width = size.x.round() as i32;
let height = size.y.round() as i32;
sender
.send(SketchBoardInput::Output(
SketchBoardOutput::CropDimensionsUpdate((width, height)),
))
.ok();
}
}

fn begin_drag(&mut self, pos: Vec2D) -> ToolUpdateResult {
match &self.crop {
None => {
Expand Down Expand Up @@ -319,10 +335,12 @@ impl CropTool {
match action {
CropToolAction::NewCrop => {
crop.size = direction;
self.emit_crop_dimensions_update();
ToolUpdateResult::Redraw
}
CropToolAction::DragHandle(state) => {
Self::apply_drag_handle_transformation(crop, state, direction);
self.emit_crop_dimensions_update();
ToolUpdateResult::Redraw
}
CropToolAction::Move(state) => {
Expand All @@ -347,16 +365,19 @@ impl CropTool {
CropToolAction::NewCrop => {
crop.size = direction;
self.action = None;
self.emit_crop_dimensions_update();
ToolUpdateResult::Redraw
}
CropToolAction::DragHandle(state) => {
Self::apply_drag_handle_transformation(crop, state, direction);
self.action = None;
self.emit_crop_dimensions_update();
ToolUpdateResult::Redraw
}
CropToolAction::Move(state) => {
crop.pos = state.start + direction;
self.action = None;
self.emit_crop_dimensions_update();
ToolUpdateResult::Redraw
}
}
Expand All @@ -377,15 +398,20 @@ impl Tool for CropTool {
}

fn handle_key_event(&mut self, event: KeyEventMsg) -> ToolUpdateResult {
if event.key == Key::Escape {
if let Some(crop) = &self.crop {
if crop.active {
// Crop is active, deactivate it
return self.handle_deactivated();
}
if event.key == Key::Escape && self.crop.is_some() {
self.crop = None;
self.action = None;

if let Some(sender) = &self.sender {
sender
.send(SketchBoardInput::Output(
SketchBoardOutput::CropDimensionsUpdate((0, 0)),
))
.ok();
}

return ToolUpdateResult::Redraw;
}
// No crop exists or crop is inactive - let event bubble to global handler
ToolUpdateResult::Unmodified
}

Expand Down
17 changes: 17 additions & 0 deletions src/ui/toolbars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct StyleToolbar {
annotation_size: f32,
annotation_size_formatted: String,
annotation_dialog_controller: Option<Controller<AnnotationSizeDialog>>,
crop_dimensions: String,
}

pub struct AnnotationSizeDialog {
Expand All @@ -54,6 +55,7 @@ pub enum ToolbarEvent {
SaveFileAs,
Resize,
OriginalScale,
CropDimensionsUpdated((i32, i32)),
}

#[derive(Debug, Copy, Clone)]
Expand All @@ -72,6 +74,7 @@ pub enum StyleToolbarInput {
ToggleVisibility,
ShowAnnotationDialog,
AnnotationDialogFinished(Option<f32>),
CropDimensionsChanged((i32, i32)),
}

#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -555,6 +558,16 @@ impl Component for StyleToolbar {
connect_clicked => StyleToolbarInput::ShowAnnotationDialog
},
gtk::Separator {},
gtk::Label {
set_focusable: false,
set_hexpand: false,
set_margin_start: 10,

#[watch]
set_text: &model.crop_dimensions,
set_tooltip: "Crop dimensions (width x height)",
},
gtk::Separator {},
gtk::Button {
set_focusable: false,
set_hexpand: false,
Expand Down Expand Up @@ -625,6 +638,9 @@ impl Component for StyleToolbar {
StyleToolbarInput::ToggleVisibility => {
self.visible = !self.visible;
}
StyleToolbarInput::CropDimensionsChanged((width, height)) => {
self.crop_dimensions = format!("{}x{}", width, height);
}
}
}

Expand Down Expand Up @@ -692,6 +708,7 @@ impl Component for StyleToolbar {
APP_CONFIG.read().annotation_size_factor()
),
annotation_dialog_controller: None,
crop_dimensions: String::new(),
};

// create widgets
Expand Down
Loading