Compare commits

..
2 changed files with 38 additions and 73 deletions

View file

@ -1,7 +1,7 @@
use std::{borrow::Cow, env, ffi::OsStr, path::Path}; use std::{env, path::Path};
use iced::{ use iced::{
Alignment, Color, Element, Length, Renderer, Subscription, Task, Theme, event, Alignment, Color, Element, Length, Renderer, Subscription, Task, Theme, color, event,
keyboard::{self, Key, key}, keyboard::{self, Key, key},
theme, widget, window, theme, widget, window,
}; };
@ -20,53 +20,44 @@ enum Message {
struct State { struct State {
image: Option<RgbaImage>, image: Option<RgbaImage>,
image_display: Option<widget::image::Allocation>, image_display: Option<widget::image::Allocation>,
image_filter: widget::image::FilterMethod,
error: Option<String>, error: Option<String>,
info: Option<String>,
infobar_shown: bool,
} }
impl State { impl State {
fn new() -> (Self, Task<Message>) { fn new() -> (Self, Task<Message>) {
let mut state = State::default(); let mut state = State::default();
if let Some(path) = env::args().nth(1) { state.error = env::args().nth(1).and_then(|path| {
match state.load_image(path) { utils::load_image(path)
Err(e) => state.error = Some(e), .map(|image| state.image = Some(image))
Ok(task) => return (state, task), .err()
} });
} let allocate_image = state.allocate_image();
(state, Task::none()) (state, allocate_image)
} }
fn view(&self) -> Element<'_, Message, Theme, Renderer> { fn view(&self) -> Element<'_, Message, Theme, Renderer> {
let mut main = Vec::new(); widget::column([
if let Some(allocation) = self.image_display.as_ref() {
main.push(if let Some(allocation) = self.image_display.as_ref() { widget::image::viewer(allocation.handle().clone())
widget::image::viewer(allocation.handle().clone()) .width(Length::Fill)
.filter_method(self.image_filter) .height(Length::Fill)
.max_scale(50.) .into()
.min_scale(1.) } else {
.width(Length::Fill) widget::container(widget::text(include_str!("usage.txt")))
.height(Length::Fill) .height(Length::Fill)
.into() .width(Length::Fill)
} else { .align_x(Alignment::Center)
widget::container(widget::text(include_str!("usage.txt"))) .align_y(Alignment::Center)
.height(Length::Fill) .into()
.width(Length::Fill) },
.align_x(Alignment::Center) if let Some(error) = self.error.as_ref() {
.align_y(Alignment::Center) widget::text(error).style(widget::text::danger).into()
.into() } else {
}); widget::space().into()
},
if let Some(error) = self.error.as_ref() { ])
main.push(widget::text(error).style(widget::text::danger).into()); .into()
}
if self.infobar_shown && self.info.is_some() {
main.push(widget::text(self.title()).into());
}
widget::column(main).into()
} }
fn update(&mut self, message: Message) -> Task<Message> { fn update(&mut self, message: Message) -> Task<Message> {
match message { match message {
@ -116,15 +107,6 @@ impl State {
} }
}; };
} }
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,
}
}
Key::Character("b") => {
self.infobar_shown = !self.infobar_shown;
}
Key::Character("s") => { Key::Character("s") => {
self.save_image(); self.save_image();
@ -154,16 +136,7 @@ impl State {
} }
fn load_image(&mut self, path: impl AsRef<Path>) -> Result<Task<Message>, String> { fn load_image(&mut self, path: impl AsRef<Path>) -> Result<Task<Message>, String> {
utils::load_image(&path).map(|image| { utils::load_image(path).map(|image| {
self.info = Some(format!(
"{} {}x{}",
path.as_ref()
.file_name()
.map(OsStr::to_string_lossy)
.unwrap_or(Cow::Borrowed("[no file]")),
image.width(),
image.height(),
));
self.image = Some(image); self.image = Some(image);
self.allocate_image() self.allocate_image()
}) })
@ -194,11 +167,8 @@ impl State {
event::listen().map(Message::Event) event::listen().map(Message::Event)
} }
fn title(&self) -> String { fn title(&self) -> String {
match self.info.as_ref() { match self.image.as_ref() {
Some(info) => format!( Some(image) => format!("imagey {}x{}", image.width(), image.height()),
"imagey {info} {}",
utils::string_from_filter_type(self.image_filter),
),
None => "imagey".into(), None => "imagey".into(),
} }
} }
@ -213,9 +183,12 @@ fn main() -> Result<(), iced::Error> {
.theme(Theme::custom( .theme(Theme::custom(
"custom", "custom",
theme::Palette { theme::Palette {
background: Color::BLACK, background: color!(0x080808),
text: Color::WHITE, text: Color::WHITE,
..theme::Palette::DARK primary: color!(0xff00ff),
success: color!(0x00ff00),
warning: color!(0x880000),
danger: color!(0xff0000),
}, },
)) ))
.run() .run()

View file

@ -1,6 +1,5 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use iced::widget;
use image::{DynamicImage, ImageDecoder, ImageReader, RgbaImage}; use image::{DynamicImage, ImageDecoder, ImageReader, RgbaImage};
use rfd::FileDialog; use rfd::FileDialog;
@ -80,10 +79,3 @@ pub fn save_image(image: Option<&RgbaImage>) -> Result<(), String> {
Ok(()) Ok(())
} }
pub fn string_from_filter_type(f: widget::image::FilterMethod) -> &'static str {
match f {
widget::image::FilterMethod::Linear => "bilinear",
widget::image::FilterMethod::Nearest => "nearest neighbor",
}
}