Skip to content

Commit

Permalink
Merge pull request #240 from woelper/phospor
Browse files Browse the repository at this point in the history
feat: add new icons using Phosphor
  • Loading branch information
woelper authored Nov 9, 2023
2 parents 6194c63 + 7e687f8 commit c6a6ce3
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 51 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ img-parts = "0.3.0"
dark-light = "1.0.0"
trash = "3.1"
lutgen = {version ="0.9.0", features = ["lutgen-palettes"]}
egui-phosphor = "0.3.0"

[features]
avif_native = ["avif-decode"]
Expand Down
28 changes: 15 additions & 13 deletions src/image_editing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use rand::{thread_rng, Rng};
use rayon::{iter::ParallelIterator, slice::ParallelSliceMut};
use serde::{Deserialize, Serialize};

use egui_phosphor::variants::regular::*;

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct EditState {
#[serde(skip)]
Expand Down Expand Up @@ -134,30 +136,30 @@ pub enum ImageOperation {
impl fmt::Display for ImageOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Self::Brightness(_) => write!(f, " Brightness"),
Self::Brightness(_) => write!(f, "{SUN} Brightness"),
Self::Noise { .. } => write!(f, "〰 Noise"),
Self::Desaturate(_) => write!(f, "🌁 Desaturate"),
Self::Posterize(_) => write!(f, "🖼 Posterize"),
Self::Contrast(_) => write!(f, "◑ Contrast"),
Self::Exposure(_) => write!(f, " Exposure"),
Self::Exposure(_) => write!(f, "{APERTURE} Exposure"),
Self::Equalize(_) => write!(f, "☯ Equalize"),
Self::Mult(_) => write!(f, "✖ Mult color"),
Self::Add(_) => write!(f, "➕ Add color"),
Self::Fill(_) => write!(f, "🍺 Fill color"),
Self::Blur(_) => write!(f, "💧 Blur"),
Self::Crop(_) => write!(f, " Crop"),
Self::Flip(_) => write!(f, " Flip"),
Self::Rotate(_) => write!(f, " Rotate"),
Self::Invert => write!(f, " Invert"),
Self::ChannelSwap(_) => write!(f, " Channel Copy"),
Self::Fill(_) => write!(f, "{PAINT_BUCKET} Fill color"),
Self::Blur(_) => write!(f, "{DROP} Blur"),
Self::Crop(_) => write!(f, "{CROP} Crop"),
Self::Flip(_) => write!(f, "{SWAP} Flip"),
Self::Rotate(_) => write!(f, "{ARROW_CLOCKWISE} Rotate"),
Self::Invert => write!(f, "{SELECTION_INVERSE} Invert"),
Self::ChannelSwap(_) => write!(f, "{FLOW_ARROW} Channel Copy"),
Self::HSV(_) => write!(f, "◔ HSV"),
Self::ChromaticAberration(_) => write!(f, "📷 Color Fringe"),
Self::Resize { .. } => write!(f, " Resize"),
Self::ChromaticAberration(_) => write!(f, "{CAMERA} Color Fringe"),
Self::Resize { .. } => write!(f, "{ARROWS_IN} Resize"),
Self::GradientMap { .. } => write!(f, "🗠 Gradient Map"),
Self::Expression(_) => write!(f, "📄 Expression"),
Self::Expression(_) => write!(f, "{FUNCTION} Expression"),
Self::MMult => write!(f, "✖ Multiply with alpha"),
Self::MDiv => write!(f, "➗ Divide by alpha"),
Self::LUT(_) => write!(f, "Apply Color LUT"),
Self::LUT(_) => write!(f, "{FILM_STRIP} Apply Color LUT"),
// _ => write!(f, "Not implemented Display"),
}
}
Expand Down
10 changes: 1 addition & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,21 +251,13 @@ fn init(gfx: &mut Graphics, plugins: &mut Plugins) -> OculanteState {
.font_data
.insert("my_font".to_owned(), FontData::from_static(FONT));

// TODO: This needs to be a monospace font
// fonts.font_data.insert(
// "my_font_mono".to_owned(),
// FontData::from_static(include_bytes!("../res/fonts/FiraCode-Regular.ttf"))
// );

// Put my font first (highest priority):
fonts
.families
.get_mut(&FontFamily::Proportional)
.unwrap()
.insert(0, "my_font".to_owned());

// fonts.families.get_mut(&FontFamily::Monospace).unwrap()
// .insert(0, "my_font_mono".to_owned());
egui_phosphor::add_to_fonts(&mut fonts, egui_phosphor::Variant::Regular);

let mut style: egui::Style = (*ctx.style()).clone();
let font_scale = 0.80;
Expand Down
85 changes: 56 additions & 29 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ use crate::{
},
};

const ICON_SIZE: f32 = 24.;

use egui_phosphor::regular::*;

use arboard::Clipboard;
use egui_plot::{Plot, PlotPoints, Points};
use image::RgbaImage;
Expand Down Expand Up @@ -212,9 +216,9 @@ pub fn info_ui(ctx: &Context, state: &mut OculanteState, gfx: &mut Graphics) {
state.cursor_relative.x / state.image_dimension.0 as f32,
(state.cursor_relative.y / state.image_dimension.1 as f32),
);

egui::Grid::new("info").show(ui, |ui| {
ui.label_i("⬜ Size");
ui.label_i(&format!("{ARROWS_OUT} Size",));

ui.label(
RichText::new(format!(
Expand All @@ -232,7 +236,7 @@ pub fn info_ui(ctx: &Context, state: &mut OculanteState, gfx: &mut Graphics) {
let file_name = path.file_name().unwrap_or_default().to_string_lossy();
let skip_symbol = if file_name.chars().count() > max_chars {".."} else {""};

ui.label_i("🖻 File");
ui.label_i(&format!("{} File", IMAGE_SQUARE));
ui.label(
RichText::new(format!(
"{skip_symbol}{}",
Expand All @@ -244,15 +248,15 @@ pub fn info_ui(ctx: &Context, state: &mut OculanteState, gfx: &mut Graphics) {
ui.end_row();
}

ui.label_i("🌗 RGBA");
ui.label_i(&format!("{PALETTE} RGBA"));
ui.label(
RichText::new(disp_col(state.sampled_color))
.monospace()
.background_color(Color32::from_rgba_unmultiplied(255, 255, 255, 6)),
);
ui.end_row();

ui.label_i("🌗 RGBA");
ui.label_i(&format!("{PALETTE} RGBA"));
ui.label(
RichText::new(disp_col_norm(state.sampled_color, 255.))
.monospace()
Expand Down Expand Up @@ -737,7 +741,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
ui,
);

ui.label_i("🔁 Reset");
ui.label_i(&format!("{RECYCLE} Reset"));
ui.centered_and_justified(|ui| {
if ui.button("Reset all edits").clicked() {
state.edit_state = Default::default();
Expand All @@ -746,7 +750,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
});
ui.end_row();

ui.label_i("❓ Compare");
ui.label_i(&format!("{GIT_DIFF} Compare"));
let available_w_single_spacing =
ui.available_width() - ui.style().spacing.item_spacing.x;
ui.horizontal(|ui| {
Expand Down Expand Up @@ -805,7 +809,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
{
state.edit_state.painting = false;
}
} else if ui.button("🖊 Paint mode").clicked() {
} else if ui.button(format!("{PAINT_BRUSH_HOUSEHOLD} Paint mode")).clicked() {
state.edit_state.painting = true;
}
});
Expand Down Expand Up @@ -957,7 +961,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu

ui.vertical_centered_justified(|ui| {
if ui
.button("⤵ Apply all edits")
.button(format!("{STACK} Apply all edits"))
.on_hover_text("Apply all edits to the image and reset edit controls")
.clicked()
{
Expand Down Expand Up @@ -1085,7 +1089,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
ui.vertical_centered_justified(|ui| {
if let Some(path) = &state.current_path {
if ui
.button("⟳ Reload image")
.button(format!("{RECYCLE} Restore original"))
.on_hover_text("Completely reload image, destroying all edits.")
.clicked()
{
Expand Down Expand Up @@ -1141,7 +1145,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu

#[cfg(feature = "file_open")]
if state.current_image.is_some() {
if ui.button("Save as...").clicked() {
if ui.button(format!("{FLOPPY_DISK} Save as...")).clicked() {

let start_directory = state.persistent_settings.last_open_directory.clone();

Expand Down Expand Up @@ -1201,9 +1205,9 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
// .with_extension(&state.edit_state.export_extension)
.exists()
{
"💾 Overwrite"
format!("{FLOPPY_DISK} Overwrite")
} else {
"💾 Save"
format!("{FLOPPY_DISK} Save")
};

if ui.button(text).on_hover_text("Save the image. This will create a new file or overwrite.").clicked() {
Expand Down Expand Up @@ -1233,12 +1237,12 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu
}
}

if ui.button("💾 Save edits").on_hover_text("Saves an .oculante metafile in the same directory as the image. This file will contain all edits and will be restored automatically if you open the image again. This leaves the original image unmodified and allows you to continue editing later.").clicked() {
if ui.button(format!("{ARCHIVE_TRAY} Save edits")).on_hover_text("Saves an .oculante metafile in the same directory as the image. This file will contain all edits and will be restored automatically if you open the image again. This leaves the original image unmodified and allows you to continue editing later.").clicked() {
if let Ok(f) = std::fs::File::create(p.with_extension("oculante")) {
_ = serde_json::to_writer_pretty(&f, &state.edit_state);
}
}
if ui.button("💾 Save edits for directory").on_hover_text("Saves an .oculante metafile in the same directory as the image. This file will contain all edits and will be restored automatically if you open the image again. This leaves the original image unmodified and allows you to continue editing later.").clicked() {
if ui.button(format!("{ARCHIVE_TRAY} Save directory edits")).on_hover_text("Saves an .oculante metafile in the same directory as the image. This file will contain all edits and will be restored automatically if you open the image again. This leaves the original image unmodified and allows you to continue editing later.").clicked() {
if let Some(parent) = p.parent() {
if let Ok(f) = std::fs::File::create(parent.join(".oculante")) {
_ = serde_json::to_writer_pretty(&f, &state.edit_state);
Expand Down Expand Up @@ -1283,21 +1287,27 @@ pub fn tooltip(r: Response, tooltip: &str, hotkey: &str, _ui: &mut Ui) -> Respon

// TODO redo as impl UI
pub fn unframed_button(text: impl Into<String>, ui: &mut Ui) -> Response {
ui.add(egui::Button::new(RichText::new(text)).frame(false))
ui.add(egui::Button::new(RichText::new(text).size(ICON_SIZE)).frame(false))
}

pub fn unframed_button_colored(text: impl Into<String>, is_colored: bool, ui: &mut Ui) -> Response {
if is_colored {
ui.add(
egui::Button::new(
RichText::new(text)
.heading()
.size(ICON_SIZE)
// .heading()
.color(ui.style().visuals.selection.bg_fill),
)
.frame(false),
)
} else {
ui.add(egui::Button::new(RichText::new(text).heading()).frame(false))
ui.add(
egui::Button::new(
RichText::new(text).size(ICON_SIZE), // .heading()
)
.frame(false),
)
}
}

Expand Down Expand Up @@ -1722,7 +1732,7 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu
// ui.label("Channels");

#[cfg(feature = "file_open")]
if unframed_button("🗁", ui)
if unframed_button(FOLDER, ui)
.on_hover_text("Browse for image")
.clicked()
{
Expand Down Expand Up @@ -1761,14 +1771,18 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu
// hack to center combo box in Y

ui.spacing_mut().button_padding = Vec2::new(10., 0.);
let combobox_text_size = 16.;
egui::ComboBox::from_id_source("channels")
.selected_text(format!("{:?}", state.persistent_settings.current_channel))
.selected_text(
RichText::new(state.persistent_settings.current_channel.to_string())
.size(combobox_text_size),
)
.show_ui(ui, |ui| {
for channel in ColorChannel::iter() {
let r = ui.selectable_value(
&mut state.persistent_settings.current_channel,
channel,
channel.to_string(),
RichText::new(channel.to_string()).size(combobox_text_size),
);

if tooltip(
Expand Down Expand Up @@ -1802,7 +1816,7 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu

if state.current_path.is_some() {
if tooltip(
unframed_button("◀", ui),
unframed_button(CARET_LEFT, ui),
"Previous image",
&lookup(&state.persistent_settings.shortcuts, &PreviousImage),
ui,
Expand All @@ -1812,7 +1826,7 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu
prev_image(state)
}
if tooltip(
unframed_button("▶", ui),
unframed_button(CARET_RIGHT, ui),
"Next image",
&lookup(&state.persistent_settings.shortcuts, &NextImage),
ui,
Expand All @@ -1826,7 +1840,10 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu
if state.current_image.is_some() {
if tooltip(
// ui.checkbox(&mut state.info_enabled, "ℹ Info"),
ui.selectable_label(state.persistent_settings.info_enabled, "ℹ Info"),
ui.selectable_label(
state.persistent_settings.info_enabled,
RichText::new(format!("{}", INFO)).size(ICON_SIZE * 0.8),
),
"Show image info",
&lookup(&state.persistent_settings.shortcuts, &InfoMode),
ui,
Expand All @@ -1842,7 +1859,10 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu
}

if tooltip(
ui.selectable_label(state.persistent_settings.edit_enabled, "✏ Edit"),
ui.selectable_label(
state.persistent_settings.edit_enabled,
RichText::new(format!("{}", PENCIL_SIMPLE_LINE)).size(ICON_SIZE * 0.8),
),
"Edit the image",
&lookup(&state.persistent_settings.shortcuts, &EditMode),
ui,
Expand All @@ -1865,12 +1885,19 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu
// toggle_fullscreen(app, state);
// }

if unframed_button("⛶", ui).clicked() {
if tooltip(
unframed_button(ARROWS_OUT_SIMPLE, ui),
"Toggle fullscreen",
&lookup(&state.persistent_settings.shortcuts, &Fullscreen),
ui,
)
.clicked()
{
toggle_fullscreen(app, state);
}

if tooltip(
unframed_button_colored("📌", state.always_on_top, ui),
unframed_button_colored(ARROW_LINE_UP, state.always_on_top, ui),
"Always on top",
&lookup(&state.persistent_settings.shortcuts, &AlwaysOnTop),
ui,
Expand All @@ -1883,7 +1910,7 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu

if let Some(p) = &state.current_path {
if tooltip(
unframed_button_colored("🗑", state.always_on_top, ui),
unframed_button(TRASH, ui),
"Move file to trash",
&lookup(&state.persistent_settings.shortcuts, &DeleteFile),
ui,
Expand All @@ -1908,7 +1935,7 @@ pub fn main_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App, gfx: &mu

ui.style_mut().override_text_style = Some(egui::TextStyle::Heading);

ui.menu_button("☰", |ui| {
ui.menu_button(RichText::new(LIST).size(ICON_SIZE), |ui| {
if ui.button("Reset view").clicked() {
state.reset_image = true;
ui.close_menu();
Expand Down

0 comments on commit c6a6ce3

Please sign in to comment.