Skip to content
This repository has been archived by the owner on Apr 10, 2024. It is now read-only.

Commit

Permalink
Added .config file & autoscroll command line option.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrueger committed Feb 26, 2024
1 parent 5bff6b3 commit 351f98a
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 37 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "icy_view"
version = "0.6.0"
version = "0.6.1"
edition = "2021"
description = "A fast ansi art viewer."
authors = ["Mike Krüger <[email protected]>"]
Expand Down
18 changes: 13 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::PathBuf;

use clap::Parser;
use semver::Version;
use view_library::MainWindow;
use view_library::{options::Options, MainWindow};

lazy_static::lazy_static! {
static ref VERSION: Version = Version::parse( env!("CARGO_PKG_VERSION")).unwrap();
Expand All @@ -23,14 +23,22 @@ lazy_static::lazy_static! {
}

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct Cli {
path: Option<PathBuf>,

#[clap(long, default_value_t = false, help = "Enable auto-scrolling")]
auto: bool,
}

fn main() {
let args = Cli::parse();
let mut options = Options::load_options();
if args.auto {
options.auto_scroll_enabled = true;
}

let options = eframe::NativeOptions {
let native_options = eframe::NativeOptions {
//initial_window_size: Some(egui::vec2(1284. + 8., 839.)),
multisampling: 0,
renderer: eframe::Renderer::Glow,
Expand All @@ -40,16 +48,16 @@ fn main() {
// options.viewport.icon = Some(IconData::from( &include_bytes!("../build/linux/256x256.png")[..]).unwrap());
eframe::run_native(
&DEFAULT_TITLE,
options,
native_options,
Box::new(|cc| {
let gl = cc.gl.as_ref().expect("You need to run eframe with the glow backend");
egui_extras::install_image_loaders(&cc.egui_ctx);

let mut fd = MainWindow::new(gl, args.path);
let mut fd = MainWindow::new(gl, args.path, options);
fd.store_options = true;
if *VERSION < *LATEST_VERSION {
fd.file_view.upgrade_version = Some(LATEST_VERSION.to_string());
}

let cmd = fd.file_view.refresh();
fd.handle_command(cmd);
Box::new(fd)
Expand Down
2 changes: 2 additions & 0 deletions view_library/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ egui-modal = "0.3.3"
egui-notify = "0.13.0"
thiserror = "1.0"
anyhow = "1.0.75"
serde = "1.0.197"
toml = "0.8.10"

image = { version = "0.24", features = ["jpeg", "png", "gif", "bmp"] }
icy_engine = { git = "https://github.com/mkrueger/icy_engine.git" }
Expand Down
21 changes: 10 additions & 11 deletions view_library/src/ui/file_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use std::{
path::{Path, PathBuf},
};

use super::options::{Options, ScrollSpeed};

pub enum Message {
Select(usize, bool),
Open(usize),
Expand Down Expand Up @@ -103,14 +105,13 @@ pub struct FileView {
pub files: Vec<FileEntry>,
pub upgrade_version: Option<String>,

pub auto_scroll_enabled: bool,
pub scroll_speed: usize,
pub options: super::options::Options,
pub filter: String,
pre_select_file: Option<String>,
}

impl FileView {
pub fn new(initial_path: Option<PathBuf>) -> Self {
pub fn new(initial_path: Option<PathBuf>, options: Options) -> Self {
let mut path = if let Some(path) = initial_path {
path
} else if let Some(user_dirs) = UserDirs::new() {
Expand Down Expand Up @@ -138,8 +139,7 @@ impl FileView {
scroll_pos: None,
files: Vec::new(),
filter: String::new(),
auto_scroll_enabled: true,
scroll_speed: 1,
options,
upgrade_version: None,
}
}
Expand Down Expand Up @@ -228,18 +228,17 @@ impl FileView {
ui.close_menu();
}
ui.separator();
let mut b = self.auto_scroll_enabled;
let mut b = self.options.auto_scroll_enabled;
if ui.checkbox(&mut b, fl!(crate::LANGUAGE_LOADER, "menu-item-auto-scroll")).clicked() {
command = Some(Message::ToggleAutoScroll);
ui.close_menu();
}
let title = match self.scroll_speed {
2 => fl!(crate::LANGUAGE_LOADER, "menu-item-scroll-speed-slow"),
0 => {
let title = match self.options.scroll_speed {
ScrollSpeed::Slow => fl!(crate::LANGUAGE_LOADER, "menu-item-scroll-speed-slow"),
ScrollSpeed::Medium => {
fl!(crate::LANGUAGE_LOADER, "menu-item-scroll-speed-medium")
}
1 => fl!(crate::LANGUAGE_LOADER, "menu-item-scroll-speed-fast"),
_ => panic!(),
ScrollSpeed::Fast => fl!(crate::LANGUAGE_LOADER, "menu-item-scroll-speed-fast"),
};

let r = ui.selectable_label(false, title);
Expand Down
49 changes: 29 additions & 20 deletions view_library/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ use std::{
time::Duration,
};

use self::file_view::{FileEntry, FileView, Message};
use self::{
file_view::{FileEntry, FileView, Message},
options::{Options, ScrollSpeed},
};

mod file_view;
mod help_dialog;
pub mod options;
mod sauce_dialog;

pub struct MainWindow<'a> {
Expand All @@ -45,11 +49,10 @@ pub struct MainWindow<'a> {
toasts: egui_notify::Toasts,
is_closed: bool,
pub opened_file: Option<FileEntry>,

pub store_options: bool,
// animations
animation: Option<Arc<Mutex<Animator>>>,
}
const SCROLL_SPEED: [f32; 3] = [80.0, 160.0, 320.0];
const EXT_WHITE_LIST: [&str; 5] = ["seq", "diz", "nfo", "ice", "bbs"];

const EXT_BLACK_LIST: [&str; 8] = ["zip", "rar", "gz", "tar", "7z", "pdf", "exe", "com"];
Expand All @@ -73,7 +76,7 @@ impl<'a> App for MainWindow<'a> {
ui.set_enabled(self.sauce_dialog.is_none() && self.help_dialog.is_none());
self.paint_main_area(ui)
});
self.in_scroll &= self.file_view.auto_scroll_enabled;
self.in_scroll &= self.file_view.options.auto_scroll_enabled;
if self.in_scroll {
// ctx.request_repaint_after(Duration::from_millis(10));
ctx.request_repaint();
Expand Down Expand Up @@ -121,10 +124,17 @@ impl<'a> App for MainWindow<'a> {
}
}
}

fn on_exit(&mut self, _gl: Option<&glow::Context>) {
println!("store options: {}", self.store_options);
if self.store_options {
self.file_view.options.store_options();
}
}
}

impl<'a> MainWindow<'a> {
pub fn new(gl: &Arc<glow::Context>, mut initial_path: Option<PathBuf>) -> Self {
pub fn new(gl: &Arc<glow::Context>, mut initial_path: Option<PathBuf>, options: Options) -> Self {
let mut view = BufferView::new(gl);
view.interactive = false;

Expand All @@ -137,9 +147,10 @@ impl<'a> MainWindow<'a> {
}
}
}

Self {
buffer_view: Arc::new(eframe::epaint::mutex::Mutex::new(view)),
file_view: FileView::new(initial_path),
file_view: FileView::new(initial_path, options),
in_scroll: false,
retained_image: None,
texture_handle: None,
Expand All @@ -157,6 +168,7 @@ impl<'a> MainWindow<'a> {
opened_file: None,
is_closed: false,
animation: None,
store_options: false,
}
}

Expand Down Expand Up @@ -193,7 +205,7 @@ impl<'a> MainWindow<'a> {
.inner_margin(egui::style::Margin::same(0.0))
.fill(Color32::BLACK);
egui::CentralPanel::default().frame(frame_no_margins).show(ctx, |ui| self.paint_main_area(ui));
self.in_scroll &= self.file_view.auto_scroll_enabled;
self.in_scroll &= self.file_view.options.auto_scroll_enabled;
if self.in_scroll {
// ctx.request_repaint_after(Duration::from_millis(10));
ctx.request_repaint();
Expand Down Expand Up @@ -389,7 +401,7 @@ impl<'a> MainWindow<'a> {

let dt = ui.input(|i| i.unstable_dt);
let sp = if self.in_scroll {
(self.cur_scroll_pos + SCROLL_SPEED[self.file_view.scroll_speed] * dt).round()
(self.cur_scroll_pos + self.file_view.options.scroll_speed.get_speed() * dt).round()
} else {
self.cur_scroll_pos.round()
};
Expand Down Expand Up @@ -514,9 +526,7 @@ impl<'a> MainWindow<'a> {
result.buffer_type = icy_engine::BufferType::Unicode;
}
match parse_with_parser(&mut result, &mut rip_parser, &text, true) {
Ok(_) => {
rip_parser
}
Ok(_) => rip_parser,
Err(err) => {
log::error!("Error while parsing rip file: {err}");
rip_parser
Expand Down Expand Up @@ -607,10 +617,10 @@ impl<'a> MainWindow<'a> {
}
}
Message::ToggleAutoScroll => {
self.file_view.auto_scroll_enabled = !self.in_scroll;
self.in_scroll = self.file_view.auto_scroll_enabled;
self.file_view.options.auto_scroll_enabled = !self.file_view.options.auto_scroll_enabled;
self.in_scroll = self.file_view.options.auto_scroll_enabled;

if self.file_view.auto_scroll_enabled {
if self.file_view.options.auto_scroll_enabled {
self.toasts
.info(fl!(crate::LANGUAGE_LOADER, "toast-auto-scroll-on"))
.set_duration(Some(Duration::from_secs(3)));
Expand All @@ -631,25 +641,24 @@ impl<'a> MainWindow<'a> {
self.help_dialog = Some(help_dialog::HelpDialog::new());
}
Message::ChangeScrollSpeed => {
self.file_view.scroll_speed = (self.file_view.scroll_speed + 1) % SCROLL_SPEED.len();
self.file_view.options.scroll_speed = self.file_view.options.scroll_speed.next();

match self.file_view.scroll_speed {
0 => {
match self.file_view.options.scroll_speed {
ScrollSpeed::Slow => {
self.toasts
.info(fl!(crate::LANGUAGE_LOADER, "toast-scroll-slow"))
.set_duration(Some(Duration::from_secs(3)));
}
1 => {
ScrollSpeed::Medium => {
self.toasts
.info(fl!(crate::LANGUAGE_LOADER, "toast-scroll-medium"))
.set_duration(Some(Duration::from_secs(3)));
}
2 => {
ScrollSpeed::Fast => {
self.toasts
.info(fl!(crate::LANGUAGE_LOADER, "toast-scroll-fast"))
.set_duration(Some(Duration::from_secs(3)));
}
_ => {}
}
}
}
Expand Down
81 changes: 81 additions & 0 deletions view_library/src/ui/options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use serde::{Deserialize, Serialize};
use std::fs;

const SCROLL_SPEED: [f32; 3] = [80.0, 160.0, 320.0];

#[derive(Serialize, Deserialize, Debug)]
pub enum ScrollSpeed {
Slow,
Medium,
Fast,
}

impl ScrollSpeed {
pub fn get_speed(&self) -> f32 {
match self {
ScrollSpeed::Slow => SCROLL_SPEED[0],
ScrollSpeed::Medium => SCROLL_SPEED[1],
ScrollSpeed::Fast => SCROLL_SPEED[2],
}
}

pub(crate) fn next(&self) -> ScrollSpeed {
match self {
ScrollSpeed::Slow => ScrollSpeed::Medium,
ScrollSpeed::Medium => ScrollSpeed::Fast,
ScrollSpeed::Fast => ScrollSpeed::Slow,
}
}
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Options {
pub auto_scroll_enabled: bool,
pub scroll_speed: ScrollSpeed,
}

impl Default for Options {
fn default() -> Self {
Self {
auto_scroll_enabled: true,
scroll_speed: ScrollSpeed::Medium,
}
}
}

impl Options {
pub fn load_options() -> Self {
if let Some(proj_dirs) = directories::ProjectDirs::from("com", "GitHub", "icy_view") {
if !proj_dirs.config_dir().exists() && fs::create_dir_all(proj_dirs.config_dir()).is_err() {
log::error!("Can't create configuration directory {:?}", proj_dirs.config_dir());
return Self::default();
}
let options_file = proj_dirs.config_dir().join("options.toml");
if options_file.exists() {
match fs::read_to_string(options_file) {
Ok(txt) => {
if let Ok(result) = toml::from_str(&txt) {
return result;
}
}
Err(err) => log::error!("Error reading options file: {}", err),
}
}
}
Self::default()
}

pub fn store_options(&self) {
if let Some(proj_dirs) = directories::ProjectDirs::from("com", "GitHub", "icy_view") {
let file_name = proj_dirs.config_dir().join("options.toml");
match toml::to_string(self) {
Ok(text) => {
if let Err(err) = fs::write(file_name, text) {
log::error!("Error writing options file: {}", err);
}
}
Err(err) => log::error!("Error writing options file: {}", err),
}
}
}
}

0 comments on commit 351f98a

Please sign in to comment.