Skip to content

Commit

Permalink
feat: add ui
Browse files Browse the repository at this point in the history
  • Loading branch information
InioX committed Dec 16, 2024
1 parent 05e7cea commit cab8f92
Show file tree
Hide file tree
Showing 8 changed files with 3,251 additions and 120 deletions.
3,016 changes: 2,918 additions & 98 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ default = ["dump-json"]
update-informer = ["dep:update-informer"]
web-image = ["dep:reqwest"]
dump-json = ["dep:serde_json"]
ui = [
"dep:egui",
"dep:eframe",
"dep:indexmap",
"dep:egui_file",
"dep:rfd",
]

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
Expand Down Expand Up @@ -69,3 +76,10 @@ reqwest = { version = "0.12.5", default-features = false, features = [
"blocking",
"rustls-tls",
], optional = true }

# gui feature
egui = { version = "0.29.1", optional = true }
eframe = { version = "0.29.1", optional = true }
indexmap = { version = "2.7.0", optional = true }
egui_file = { version = "0.19.0", optional = true }
rfd = { version = "0.15.1", optional = true }
5 changes: 4 additions & 1 deletion src/color/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ pub fn get_source_color(source: &Source) -> Result<Argb, Box<dyn std::error::Err
Source::Image { path } => {
// test
info!("Opening image in <d><u>{}</>", path);
color::get_source_color_from_image(path).expect("Could not get source color from image")
color::get_source_color_from_image(path).expect(&format!(
"Could not get source color from image {:#?}",
path
))
}
#[cfg(feature = "web-image")]
Source::WebImage { url } => {
Expand Down
237 changes: 237 additions & 0 deletions src/gui/init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
use std::path::PathBuf;

#[cfg(feature = "ui")]
use indexmap::IndexMap;

#[cfg(feature = "ui")]
use eframe::egui;
use egui::{Color32, Ui, Vec2};
use material_colors::{color::Argb, scheme::variant::SchemeFidelity};
use matugen::{
color::{
color::Source,
format::{format_hex, rgb_from_argb},
},
scheme::{SchemeTypes, Schemes},
};

use crate::{template::TemplateFile, util::arguments::Cli, State};

#[cfg(feature = "ui")]
#[derive(PartialEq)]
pub enum Tabs {
Settings,
Colors,
}

const COLOR_RECT_SIZE: [f32; 2] = [20., 20.];

#[cfg(feature = "ui")]
pub struct MyApp {
selected_file: Option<PathBuf>,
cli: Box<Cli>,
colors: ColorsMap,
selected_tab: Tabs,
app: State,
}

#[cfg(feature = "ui")]
pub struct ColorsMap {
pub light: Option<IndexMap<String, Color32>>,
pub dark: Option<IndexMap<String, Color32>>,
}

// FIXME: Cleanup code, reorganize stuff into its own functions

#[cfg(feature = "ui")]
impl MyApp {
pub fn new(_cc: &eframe::CreationContext, cli: Box<Cli>) -> Self {
Self {
selected_file: None,
app: crate::State::new(*cli.clone()),
cli,
colors: ColorsMap {
light: None,
dark: None,
},
selected_tab: Tabs::Settings,
}
}
fn body(&mut self, ui: &mut Ui) {
match self.selected_tab {
Tabs::Settings => self.settings(ui),
Tabs::Colors => self.colors(ui),
}
}

fn settings(&mut self, ui: &mut Ui) {
ui.horizontal(|ui| {
ui.label("Contrast");
ui.add(egui::Slider::new(
&mut self.app.args.contrast.unwrap(),
-1.0..=1.0,
));
});
ui.label("Scheme type");
egui::ComboBox::from_label("Select one!")
.selected_text(format!("{:?}", self.app.args.r#type.unwrap()))
.show_ui(ui, |ui| {
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeContent),
"SchemeContent",
);
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeExpressive),
"SchemeExpressive",
);
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeFidelity),
"SchemeFidelity",
);
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeFruitSalad),
"SchemeFruitSalad",
);
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeMonochrome),
"SchemeMonochrome",
);
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeNeutral),
"SchemeNeutral",
);
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeRainbow),
"SchemeRainbow",
);
ui.selectable_value(
&mut self.app.args.r#type,
Some(SchemeTypes::SchemeTonalSpot),
"SchemeTonalSpot",
);
});
}

fn show_single_color_scrollable(
&self,
ui: &mut Ui,
text: &str,
colors: &Option<IndexMap<String, Color32>>,
) {
ui.vertical(|ui| {
ui.label(egui::RichText::new(text).strong());
if let Some(colors) = &colors {
for (name, color) in colors {
let hex_label = format_hex(&rgb_from_argb(Argb {
alpha: color.a(),
red: color.r(),
green: color.g(),
blue: color.b(),
}));
ui.horizontal(|ui| {
ui.label(name);
egui::widgets::color_picker::show_color(
ui,
*color,
Vec2::new(COLOR_RECT_SIZE[0], COLOR_RECT_SIZE[1]),
);
ui.label(hex_label);
});
}
}
});
}

fn show_colors(&mut self, ui: &mut Ui) {
self.show_single_color_scrollable(ui, "DARK", &self.colors.dark);

self.show_single_color_scrollable(ui, "LIGHT", &self.colors.light);
}

fn colors(&mut self, ui: &mut Ui) {
egui::ScrollArea::vertical().show(ui, |ui| {
if self.colors.dark != None || self.colors.light != None {
ui.horizontal(|ui| {
self.show_colors(ui);
});
} else {
ui.label("No colors generated yet");
}
});
}

fn top_buttons(&mut self, ui: &mut Ui) {
if ui.button("Select image").clicked() {
if let Some(path) = rfd::FileDialog::new().pick_file() {
self.selected_file = Some(path);
}
}
if ui.button("Run").clicked() {
if self.selected_file != Some("".into()) || self.selected_file.is_some() {
self.update_colors_tab();
self.generate_tempalates();
};
}
}

fn generate_tempalates(&mut self) {
let mut engine = self.app.init_engine();
let mut render_data = self.app.init_render_data().unwrap();
let mut template = TemplateFile::new(&self.app, &mut engine, &mut render_data);
template.generate().unwrap();
}

fn update_colors_tab(&mut self) {
self.app.args.source = Source::Image {
path: self
.selected_file
.clone()
.unwrap()
.into_os_string()
.into_string()
.unwrap(),
};
self.app.update_themes();
let mut dark: IndexMap<String, Color32> = IndexMap::new();
let mut light: IndexMap<String, Color32> = IndexMap::new();
for (name, color) in &self.app.schemes.dark {
dark.insert(name.to_string(), argb_to_color32(color));
}
for (name, color) in &self.app.schemes.light {
light.insert(name.to_string(), argb_to_color32(color));
}
self.colors.dark = Some(dark);
self.colors.light = Some(light);
}
}

#[cfg(feature = "ui")]
fn argb_to_color32(color: &Argb) -> Color32 {
Color32::from_rgba_premultiplied(color.red, color.green, color.blue, color.alpha)
}

#[cfg(feature = "ui")]
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::TopBottomPanel::top("my_panel").show(ctx, |ui| {
ui.horizontal(|ui| {
ui.horizontal(|ui| {
ui.selectable_value(&mut self.selected_tab, Tabs::Settings, "Settings");
ui.selectable_value(&mut self.selected_tab, Tabs::Colors, "Colors");
});

ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
self.top_buttons(ui);
});
});
});
egui::CentralPanel::default().show(ctx, |ui| self.body(ui));
}
}
1 change: 1 addition & 0 deletions src/gui/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod init;

Check warning on line 1 in src/gui/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/matugen/matugen/src/gui/mod.rs

Check warning on line 1 in src/gui/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/matugen/matugen/src/gui/mod.rs
6 changes: 3 additions & 3 deletions src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::wallpaper;
use crate::wallpaper::{self, Wallpaper};
use color_eyre::{eyre::Result, Report};
use log::LevelFilter;
use matugen::color::color::Source;
Expand Down Expand Up @@ -56,7 +56,7 @@ pub fn setup_logging(args: &Cli) -> Result<(), Report> {
Ok(())
}

pub fn set_wallpaper(source: &Source) -> Result<(), Report> {
pub fn set_wallpaper(source: &Source, _wallpaper_cfg: &Wallpaper) -> Result<(), Report> {
let path = match &source {
Source::Image { path } => path,
Source::Color { .. } => return Ok(()),
Expand All @@ -69,6 +69,6 @@ pub fn set_wallpaper(source: &Source) -> Result<(), Report> {
#[cfg(target_os = "macos")]
wallpaper::macos::set(&path)?;
#[cfg(any(target_os = "linux", target_os = "netbsd"))]
wallpaper::unix::set(path, wallpaper_cfg)?;
wallpaper::unix::set(path, _wallpaper_cfg)?;
Ok(())
}
Loading

0 comments on commit cab8f92

Please sign in to comment.