feat: optional infobar
literally the title; except on the bottom
This commit is contained in:
parent
97ce6754dd
commit
7ce87e2870
2 changed files with 56 additions and 28 deletions
76
src/main.rs
76
src/main.rs
|
|
@ -1,4 +1,4 @@
|
|||
use std::{env, path::Path};
|
||||
use std::{borrow::Cow, env, ffi::OsStr, path::Path};
|
||||
|
||||
use iced::{
|
||||
Alignment, Color, Element, Length, Renderer, Subscription, Task, Theme, color, event,
|
||||
|
|
@ -23,6 +23,8 @@ struct State {
|
|||
image_filter: widget::image::FilterMethod,
|
||||
|
||||
error: Option<String>,
|
||||
info: Option<String>,
|
||||
infobar_shown: bool,
|
||||
}
|
||||
impl State {
|
||||
fn new() -> (Self, Task<Message>) {
|
||||
|
|
@ -38,30 +40,33 @@ impl State {
|
|||
(state, allocate_image)
|
||||
}
|
||||
fn view(&self) -> Element<'_, Message, Theme, Renderer> {
|
||||
widget::column([
|
||||
if let Some(allocation) = self.image_display.as_ref() {
|
||||
widget::image::viewer(allocation.handle().clone())
|
||||
.filter_method(self.image_filter)
|
||||
.max_scale(50.)
|
||||
.min_scale(1.)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.into()
|
||||
} else {
|
||||
widget::container(widget::text(include_str!("usage.txt")))
|
||||
.height(Length::Fill)
|
||||
.width(Length::Fill)
|
||||
.align_x(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.into()
|
||||
},
|
||||
if let Some(error) = self.error.as_ref() {
|
||||
widget::text(error).style(widget::text::danger).into()
|
||||
} else {
|
||||
widget::space().into()
|
||||
},
|
||||
])
|
||||
.into()
|
||||
let mut main = Vec::new();
|
||||
|
||||
main.push(if let Some(allocation) = self.image_display.as_ref() {
|
||||
widget::image::viewer(allocation.handle().clone())
|
||||
.filter_method(self.image_filter)
|
||||
.max_scale(50.)
|
||||
.min_scale(1.)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.into()
|
||||
} else {
|
||||
widget::container(widget::text(include_str!("usage.txt")))
|
||||
.height(Length::Fill)
|
||||
.width(Length::Fill)
|
||||
.align_x(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.into()
|
||||
});
|
||||
|
||||
if let Some(error) = self.error.as_ref() {
|
||||
main.push(widget::text(error).style(widget::text::danger).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> {
|
||||
match message {
|
||||
|
|
@ -117,6 +122,9 @@ impl State {
|
|||
widget::image::FilterMethod::Nearest => widget::image::FilterMethod::Linear,
|
||||
}
|
||||
}
|
||||
Key::Character("b") => {
|
||||
self.infobar_shown = !self.infobar_shown;
|
||||
}
|
||||
|
||||
Key::Character("s") => {
|
||||
self.save_image();
|
||||
|
|
@ -146,7 +154,16 @@ impl State {
|
|||
}
|
||||
|
||||
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.allocate_image()
|
||||
})
|
||||
|
|
@ -177,8 +194,11 @@ impl State {
|
|||
event::listen().map(Message::Event)
|
||||
}
|
||||
fn title(&self) -> String {
|
||||
match self.image.as_ref() {
|
||||
Some(image) => format!("imagey {}x{}", image.width(), image.height()),
|
||||
match self.info.as_ref() {
|
||||
Some(info) => format!(
|
||||
"imagey {info} {}",
|
||||
utils::string_from_filter_type(self.image_filter),
|
||||
),
|
||||
None => "imagey".into(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use iced::widget;
|
||||
use image::{DynamicImage, ImageDecoder, ImageReader, RgbaImage};
|
||||
use rfd::FileDialog;
|
||||
|
||||
|
|
@ -79,3 +80,10 @@ pub fn save_image(image: Option<&RgbaImage>) -> Result<(), String> {
|
|||
|
||||
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",
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue