Skip to content

Commit

Permalink
Merge pull request ArturKovacs#81 from Aloso/title-config
Browse files Browse the repository at this point in the history
Config for displaying part of the file path and hiding the program name
  • Loading branch information
ArturKovacs authored Jun 2, 2020
2 parents b8180ac + 7fffa71 commit 5f78ec3
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 55 deletions.
36 changes: 34 additions & 2 deletions src/cmd_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ use crate::Version;
use clap::{App, Arg};
use std::path::PathBuf;

pub struct Args {
pub file_path: Option<String>,
pub displayed_folders: Option<u32>,
}

/// Parses the command-line arguments and returns the file path
pub fn parse_args(config_path: &PathBuf, cache_path: &PathBuf) -> Option<String> {
pub fn parse_args(config_path: &PathBuf, cache_path: &PathBuf) -> Args {
let config = format!(
"CONFIGURATION:\n config file: {}\n cache file: {}",
config_path.to_string_lossy(),
Expand All @@ -18,8 +23,35 @@ pub fn parse_args(config_path: &PathBuf, cache_path: &PathBuf) -> Option<String>
https://arturkovacs.github.io/emulsion-website/",
)
.after_help(config.as_str())
.arg(
Arg::with_name("FOLDERS")
.long("folders")
.short("f")
.help("Number of folders to display")
.takes_value(true)
.validator(|v| match v.parse::<u32>() {
Ok(_) => Ok(()),
Err(e) => Err(format!("{}: '{}'", e, v)),
}),
)
.arg(
Arg::with_name("absolute")
.long("absolute")
.short("a")
.help("Show absolute file path")
.takes_value(false)
.conflicts_with("FOLDERS"),
)
.arg(Arg::with_name("PATH").help("The file path of the image").index(1))
.get_matches();

matches.value_of("PATH").map(ToString::to_string)
let file_path = matches.value_of("PATH").map(ToString::to_string);

let displayed_folders = if matches.is_present("absolute") {
Some(std::u32::MAX)
} else {
matches.value_of("FOLDERS").map(|s| s.parse::<u32>().unwrap())
};

Args { file_path, displayed_folders }
}
43 changes: 42 additions & 1 deletion src/configuration.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::fs;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -141,11 +142,51 @@ pub struct Command {
pub envs: Option<Vec<EnvVar>>,
}

#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
pub struct TitleSection {
pub displayed_folders: Option<u32>,
pub show_program_name: Option<bool>,
}

impl TitleSection {
pub fn format_file_path<'a>(&self, file_path: &'a PathBuf) -> Cow<'a, str> {
match self.displayed_folders {
Some(0) | None => file_path.file_name().unwrap().to_string_lossy(),
Some(n) => {
let mut component_count = 0;
// On Windows the root can be the second component, when a `Prefix` is the first.
let mut root_index = 0;
for (idx, c) in file_path.components().enumerate() {
component_count += 1;
if c == std::path::Component::RootDir {
root_index = idx as u32;
}
}
let path = if (component_count - root_index) <= (1 + n) {
file_path.to_string_lossy().trim_start_matches("\\\\?\\").to_owned().into()
} else {
let ancestor = file_path.ancestors().take(2 + n as usize).last().unwrap();
file_path.strip_prefix(ancestor).unwrap().to_string_lossy()
};
path
}
}
}

pub fn format_program_name(&self) -> &'static str {
match self.show_program_name {
Some(false) => "",
_ => " : E M U L S I O N",
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
pub struct Configuration {
pub bindings: Option<BTreeMap<String, Vec<String>>>,
pub commands: Option<Vec<Command>>,
pub updates: Option<ConfigUpdateSection>,
pub title: Option<TitleSection>,
}

impl Configuration {
Expand Down
14 changes: 7 additions & 7 deletions src/image_cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ impl ImageCache {
display: &glium::Display,
index: usize,
frame_id: Option<isize>,
) -> Result<(AnimationFrameTexture, OsString)> {
) -> Result<(AnimationFrameTexture, PathBuf)> {
let path = self
.dir_files
.get(index)
Expand All @@ -276,7 +276,7 @@ impl ImageCache {

let result = self.load_specific(display, &path, frame_id)?;
self.current_file_idx = index;
Ok((result, path.file_name().unwrap_or_else(|| OsStr::new("")).to_owned()))
Ok((result, path))
}

/// Returns `Err(errors::Error::from_kind(errors::ErrorKind::WaitingOnLoader))`
Expand Down Expand Up @@ -370,13 +370,13 @@ impl ImageCache {
pub fn load_next(
&mut self,
display: &glium::Display,
) -> Result<(AnimationFrameTexture, OsString)> {
) -> Result<(AnimationFrameTexture, PathBuf)> {
self.load_jump(display, 1, 0)
}
pub fn load_prev(
&mut self,
display: &glium::Display,
) -> Result<(AnimationFrameTexture, OsString)> {
) -> Result<(AnimationFrameTexture, PathBuf)> {
self.load_jump(display, -1, 0)
}

Expand All @@ -385,15 +385,15 @@ impl ImageCache {
display: &glium::Display,
file_jump_count: i32,
frame_jump_count: isize,
) -> Result<(AnimationFrameTexture, OsString)> {
) -> Result<(AnimationFrameTexture, PathBuf)> {
if file_jump_count == 0 {
let _path = self.current_file_path();
// Here, it is possible that the current image was already
// requested but not yet loaded.
let target_frame = self.current_frame_idx as isize + frame_jump_count;
let requested =
self.try_getting_requested_image(display, self.current_file_idx, target_frame);
return requested.map(|t| (t, self.current_filename()));
return requested.map(|t| (t, self.current_file_path()));
} else {
self.current_frame_idx = 0;
}
Expand All @@ -412,7 +412,7 @@ impl ImageCache {
let result = self.load_specific(display, &target_path, None)?;
self.current_file_idx = target_index as usize;

Ok((result, target_path.file_name().unwrap_or_else(|| OsStr::new("")).to_owned()))
Ok((result, target_path))
}

fn receive_prefetched(&mut self) {
Expand Down
9 changes: 7 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn main() {
// Load configuration and cache files
let (config_path, cache_path) = get_config_and_cache_paths();

let file_path = cmd_line::parse_args(&config_path, &cache_path);
let args = cmd_line::parse_args(&config_path, &cache_path);

let cache = Cache::load(&cache_path);
let config = Configuration::load(&config_path);
Expand All @@ -79,6 +79,11 @@ fn main() {
let cache = Arc::new(Mutex::new(cache.unwrap_or_default()));
let config = Rc::new(RefCell::new(config.unwrap_or_default()));

if args.displayed_folders.is_some() {
config.borrow_mut().title.get_or_insert_with(Default::default).displayed_folders =
args.displayed_folders;
}

let mut application = Application::new();
let window: Rc<Window> = {
let window = &cache.lock().unwrap().window;
Expand Down Expand Up @@ -107,7 +112,7 @@ fn main() {
let picture_widget =
make_picture_widget(&window, bottom_bar.slider(), bottom_bar.widget(), config.clone());

if let Some(file_path) = file_path {
if let Some(file_path) = args.file_path {
picture_widget.jump_to_path(file_path);
}

Expand Down
43 changes: 20 additions & 23 deletions src/picture_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,29 @@ impl PictureWidgetData {
self.prev_draw_size = self.drawn_bounds.size;
}

fn set_window_title_filename<T: AsRef<str>>(
fn set_window_title_filename(
&self,
window: &Window,
playback_state: PlaybackState,
name: T,
file_path: &Option<PathBuf>,
) {
let playback;
match playback_state {
PlaybackState::Forward => playback = " : Playing",
PlaybackState::Present => playback = " : Presenting",
PlaybackState::RandomPresent => playback = " : Presenting Shuffled",
PlaybackState::Paused => playback = "",
}
let title = format!("{}{} : E M U L S I O N", name.as_ref(), playback);
let playback = match playback_state {
PlaybackState::Forward => " : Playing",
PlaybackState::Present => " : Presenting",
PlaybackState::RandomPresent => " : Presenting Shuffled",
PlaybackState::Paused => "",
};

let config = self.configuration.borrow();
let title_config = config.title.clone().unwrap_or_default();

let name = match file_path {
Some(file_path) => title_config.format_file_path(file_path),
None => "[ none ]".into(),
};
let title = format!("{}{}{}", name, playback, title_config.format_program_name());
let display = window.display_mut();
display.gl_window().window().set_title(title.as_ref());
display.gl_window().window().set_title(title.as_str());
}

fn get_texture(&self) -> Option<Rc<SrgbTexture2d>> {
Expand Down Expand Up @@ -314,18 +322,7 @@ impl Widget for PictureWidget {
data.slider.set_steps(curr_dir_len, curr_file_index);
//data.slider.set_step_bg(data.playback_manager.cached_from_dir());
let playback_state = data.playback_manager.playback_state();
match data.playback_manager.filename() {
Some(name) => {
PictureWidgetData::set_window_title_filename(
window,
playback_state,
name.to_str().unwrap(),
);
}
None => {
PictureWidgetData::set_window_title_filename(window, playback_state, "[ none ]");
}
}
data.set_window_title_filename(window, playback_state, data.playback_manager.file_path());
}

fn draw(&self, target: &mut Frame, context: &DrawContext) -> Result<NextUpdate, WidgetError> {
Expand Down
31 changes: 11 additions & 20 deletions src/playback_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ impl PlaybackManager {
self.image_player.image_texture()
}

pub fn filename(&self) -> &Option<OsString> {
&self.folder_player.filename
pub fn file_path(&self) -> &Option<PathBuf> {
&self.folder_player.file_path
}

pub fn update_image(&mut self, window: &Window) -> gelatin::NextUpdate {
Expand All @@ -248,7 +248,7 @@ impl PlaybackManager {
}
}

type FrameLoadResult = image_cache::Result<(AnimationFrameTexture, OsString)>;
type FrameLoadResult = image_cache::Result<(AnimationFrameTexture, PathBuf)>;

struct ImgSequencePlayer {
playback_state: PlaybackState,
Expand All @@ -260,7 +260,7 @@ struct ImgSequencePlayer {
load_request: LoadRequest,

image_texture: Option<AnimationFrameTexture>,
filename: Option<OsString>,
file_path: Option<PathBuf>,

load_next: &'static dyn Fn(&mut ImageCache, &glium::Display) -> FrameLoadResult,
load_prev: &'static dyn Fn(&mut ImageCache, &glium::Display) -> FrameLoadResult,
Expand Down Expand Up @@ -297,7 +297,7 @@ impl ImgSequencePlayer {
load_request: LoadRequest::None,
//should_sleep: true,
image_texture: None,
filename: None,
file_path: None,
load_next,
load_prev,
load_jump,
Expand Down Expand Up @@ -345,10 +345,6 @@ impl ImgSequencePlayer {
self.image_texture.clone().map(|t| t.texture)
}

pub fn _filename(&self) -> &Option<OsString> {
&self.filename
}

pub fn update_image(
&mut self,
display: &glium::Display,
Expand Down Expand Up @@ -462,14 +458,9 @@ impl ImgSequencePlayer {
let load_result = match load_request {
LoadRequest::LoadNext => Some((self.load_next)(image_cache, display)),
LoadRequest::LoadPrevious => Some((self.load_prev)(image_cache, display)),
LoadRequest::FilePath(ref file_path) => {
Some(if let Some(file_name) = file_path.file_name() {
let load_path = self.load_path;
load_path(image_cache, display, file_path.as_ref())
.map(|x| (x, OsString::from(file_name)))
} else {
Err(String::from("Could not extract filename").into())
})
LoadRequest::FilePath(file_path) => {
let load_path = self.load_path;
Some(load_path(image_cache, display, &file_path).map(|x| (x, file_path)))
}
LoadRequest::LoadAtIndex(index) => {
Some((self.load_at_index)(image_cache, display, index))
Expand All @@ -481,9 +472,9 @@ impl ImgSequencePlayer {
};
if let Some(result) = load_result {
match result {
Ok((frame, filename)) => {
Ok((frame, file_path)) => {
self.image_texture = Some(frame);
self.filename = Some(filename);
self.file_path = Some(file_path);
}
Err(image_cache::errors::Error(
image_cache::errors::ErrorKind::WaitingOnLoader,
Expand All @@ -496,7 +487,7 @@ impl ImgSequencePlayer {
}
Err(err) => {
self.image_texture = None;
self.filename = None;
self.file_path = None;
let stderr = &mut ::std::io::stderr();
let stderr_errmsg = "Error writing to stderr";
writeln!(stderr, "Error occured while loading image: {}", err)
Expand Down

0 comments on commit 5f78ec3

Please sign in to comment.