refactor: match keyboard keys in State::subscription
this is more flexible, and maybe more performant
This commit is contained in:
parent
869e38f3a5
commit
63f6b6f81b
1 changed files with 101 additions and 79 deletions
178
src/main.rs
178
src/main.rs
|
|
@ -19,11 +19,24 @@ mod utils;
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Message {
|
||||
Open,
|
||||
Rotate,
|
||||
Invert,
|
||||
Filter,
|
||||
Bar,
|
||||
Save,
|
||||
Quit,
|
||||
|
||||
Yank,
|
||||
Put,
|
||||
|
||||
FocusNext,
|
||||
FocusPrevious,
|
||||
|
||||
ImagePicked(Result<PathBuf, String>),
|
||||
ImageDisplayReady(Result<widget::image::Allocation, widget::image::Error>),
|
||||
SavePathPicked(Result<PathBuf, String>),
|
||||
|
||||
KeyPressed(keyboard::Key, keyboard::Modifiers),
|
||||
FileDropped(PathBuf),
|
||||
}
|
||||
|
||||
|
|
@ -116,101 +129,91 @@ impl State {
|
|||
.err();
|
||||
}
|
||||
|
||||
Message::KeyPressed(key, modifiers) => match key.as_ref() {
|
||||
// input field cycling
|
||||
Key::Named(key::Named::Tab) => {
|
||||
if modifiers.shift() {
|
||||
return widget::operation::focus_previous();
|
||||
}
|
||||
return widget::operation::focus_next();
|
||||
}
|
||||
Message::FocusNext => return widget::operation::focus_next(),
|
||||
Message::FocusPrevious => return widget::operation::focus_previous(),
|
||||
|
||||
Key::Character("o") => {
|
||||
return Task::perform(utils::pick_image(), Message::ImagePicked);
|
||||
}
|
||||
Message::Open => {
|
||||
return Task::perform(utils::pick_image(), Message::ImagePicked);
|
||||
}
|
||||
|
||||
Key::Character("r") => match self.image.as_ref() {
|
||||
None => self.error = Some("no image to rotate".into()),
|
||||
Some(image) => {
|
||||
self.error = None;
|
||||
self.image = Some(imageops::rotate90(image));
|
||||
return self.allocate_image();
|
||||
}
|
||||
},
|
||||
Key::Character("i") => match self.image.as_mut() {
|
||||
None => self.error = Some("no image to invert".into()),
|
||||
Some(image) => {
|
||||
self.error = None;
|
||||
imageops::invert(image);
|
||||
return self.allocate_image();
|
||||
}
|
||||
},
|
||||
Key::Character("f") => {
|
||||
self.image_filter = match self.image_filter {
|
||||
widget::image::FilterMethod::Linear => widget::image::FilterMethod::Nearest,
|
||||
widget::image::FilterMethod::Nearest => widget::image::FilterMethod::Linear,
|
||||
}
|
||||
Message::Rotate => match self.image.as_ref() {
|
||||
None => self.error = Some("no image to rotate".into()),
|
||||
Some(image) => {
|
||||
self.error = None;
|
||||
self.image = Some(imageops::rotate90(image));
|
||||
return self.allocate_image();
|
||||
}
|
||||
Key::Character("b") => {
|
||||
self.infobar_shown = !self.infobar_shown;
|
||||
},
|
||||
Message::Invert => match self.image.as_mut() {
|
||||
None => self.error = Some("no image to invert".into()),
|
||||
Some(image) => {
|
||||
self.error = None;
|
||||
imageops::invert(image);
|
||||
return self.allocate_image();
|
||||
}
|
||||
},
|
||||
Message::Filter => {
|
||||
self.image_filter = match self.image_filter {
|
||||
widget::image::FilterMethod::Linear => widget::image::FilterMethod::Nearest,
|
||||
widget::image::FilterMethod::Nearest => widget::image::FilterMethod::Linear,
|
||||
}
|
||||
}
|
||||
Message::Bar => {
|
||||
self.infobar_shown = !self.infobar_shown;
|
||||
}
|
||||
|
||||
Key::Character("s") => {
|
||||
if self.image.is_some() {
|
||||
self.error = None;
|
||||
return Task::perform(utils::pick_save_path(), Message::SavePathPicked);
|
||||
}
|
||||
self.error = Some("no image to save".into());
|
||||
Message::Save => {
|
||||
if self.image.is_some() {
|
||||
self.error = None;
|
||||
return Task::perform(utils::pick_save_path(), Message::SavePathPicked);
|
||||
}
|
||||
self.error = Some("no image to save".into());
|
||||
}
|
||||
|
||||
Key::Character("q") => return window::latest().and_then(window::close),
|
||||
Message::Quit => return window::latest().and_then(window::close),
|
||||
|
||||
Key::Character("y") | Key::Character("c") => {
|
||||
if let Some(image) = self.image.as_ref() {
|
||||
match match self.clipboard.take() {
|
||||
Some(c) => Ok(c),
|
||||
None => Clipboard::new(),
|
||||
} {
|
||||
Ok(mut clipboard) => {
|
||||
self.error = clipboard
|
||||
.set_image(utils::arboard_from_rgbaimage(image))
|
||||
.map_err(|e| e.to_string())
|
||||
.err();
|
||||
self.clipboard = Some(clipboard);
|
||||
}
|
||||
Err(e) => self.error = Some(e.to_string()),
|
||||
}
|
||||
} else {
|
||||
self.error = Some("no image to yank".into());
|
||||
}
|
||||
}
|
||||
Key::Character("p") | Key::Character("v") => {
|
||||
Message::Yank => {
|
||||
if let Some(image) = self.image.as_ref() {
|
||||
match match self.clipboard.take() {
|
||||
Some(c) => Ok(c),
|
||||
None => Clipboard::new(),
|
||||
} {
|
||||
Ok(mut clipboard) => {
|
||||
let result = clipboard.get_image().map(utils::rgbaimage_from_arboard);
|
||||
|
||||
self.error = result.as_ref().map_err(|e| e.to_string()).err();
|
||||
self.error = clipboard
|
||||
.set_image(utils::arboard_from_rgbaimage(image))
|
||||
.map_err(|e| e.to_string())
|
||||
.err();
|
||||
self.clipboard = Some(clipboard);
|
||||
|
||||
if let Ok(image) = result {
|
||||
self.info = Some(format!("{}x{}", image.width(), image.height(),));
|
||||
if image.dimensions() < (100, 100) {
|
||||
self.image_filter = widget::image::FilterMethod::Nearest;
|
||||
}
|
||||
self.image = Some(image);
|
||||
return self.allocate_image();
|
||||
}
|
||||
}
|
||||
Err(e) => self.error = Some(e.to_string()),
|
||||
}
|
||||
} else {
|
||||
self.error = Some("no image to yank".into());
|
||||
}
|
||||
}
|
||||
Message::Put => {
|
||||
match match self.clipboard.take() {
|
||||
Some(c) => Ok(c),
|
||||
None => Clipboard::new(),
|
||||
} {
|
||||
Ok(mut clipboard) => {
|
||||
let result = clipboard.get_image().map(utils::rgbaimage_from_arboard);
|
||||
|
||||
// ignore unused keys
|
||||
_ => {}
|
||||
},
|
||||
self.error = result.as_ref().map_err(|e| e.to_string()).err();
|
||||
self.clipboard = Some(clipboard);
|
||||
|
||||
if let Ok(image) = result {
|
||||
self.info = Some(format!("{}x{}", image.width(), image.height(),));
|
||||
if image.dimensions() < (100, 100) {
|
||||
self.image_filter = widget::image::FilterMethod::Nearest;
|
||||
}
|
||||
self.image = Some(image);
|
||||
return self.allocate_image();
|
||||
}
|
||||
}
|
||||
Err(e) => self.error = Some(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
Message::FileDropped(path) => match self.load_image(path) {
|
||||
Ok(task) => {
|
||||
|
|
@ -278,7 +281,26 @@ impl State {
|
|||
fn subscription(&self) -> Subscription<Message> {
|
||||
event::listen().filter_map(|event| match event {
|
||||
iced::Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) => {
|
||||
Some(Message::KeyPressed(key, modifiers))
|
||||
match key.as_ref() {
|
||||
Key::Named(key::Named::Tab) => Some(if modifiers.shift() {
|
||||
Message::FocusPrevious
|
||||
} else {
|
||||
Message::FocusNext
|
||||
}),
|
||||
|
||||
Key::Character("o") => Some(Message::Open),
|
||||
Key::Character("r") => Some(Message::Rotate),
|
||||
Key::Character("i") => Some(Message::Invert),
|
||||
Key::Character("f") => Some(Message::Filter),
|
||||
Key::Character("b") => Some(Message::Bar),
|
||||
Key::Character("s") => Some(Message::Save),
|
||||
Key::Character("q") => Some(Message::Quit),
|
||||
|
||||
Key::Character("y") | Key::Character("c") => Some(Message::Yank),
|
||||
Key::Character("p") | Key::Character("v") => Some(Message::Put),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
iced::Event::Window(window::Event::FileDropped(path)) => {
|
||||
Some(Message::FileDropped(path))
|
||||
|
|
|
|||
Loading…
Reference in a new issue