diff --git a/television/preview/mod.rs b/television/preview/mod.rs index a873550..fd6cc9e 100644 --- a/television/preview/mod.rs +++ b/television/preview/mod.rs @@ -10,8 +10,8 @@ pub mod previewers; // previewer types use crate::utils::cache::RingSet; -use crate::utils::syntax::HighlightedLines; use crate::utils::image::Image; +use crate::utils::syntax::HighlightedLines; pub use previewers::basic::BasicPreviewer; pub use previewers::basic::BasicPreviewerConfig; pub use previewers::command::CommandPreviewer; @@ -32,7 +32,7 @@ pub enum PreviewContent { PlainText(Vec), PlainTextWrapped(String), AnsiText(String), - Image(Image) + Image(Image), } impl PreviewContent { @@ -170,7 +170,11 @@ impl Previewer { } } - fn dispatch_request(&mut self, entry: &Entry, preview_window: Option) -> Option> { + fn dispatch_request( + &mut self, + entry: &Entry, + preview_window: Option, + ) -> Option> { match &entry.preview_type { PreviewType::Basic => Some(self.basic.preview(entry)), PreviewType::EnvVar => Some(self.env_var.preview(entry)), @@ -189,7 +193,11 @@ impl Previewer { } } - pub fn preview(&mut self, entry: &Entry, preview_window: Option) -> Option> { + pub fn preview( + &mut self, + entry: &Entry, + preview_window: Option, + ) -> Option> { // if we haven't acknowledged the request yet, acknowledge it self.requests.push(entry.clone()); diff --git a/television/preview/previewers/files.rs b/television/preview/previewers/files.rs index d7d2e56..f3e1bcd 100644 --- a/television/preview/previewers/files.rs +++ b/television/preview/previewers/files.rs @@ -1,6 +1,8 @@ use crate::utils::files::{read_into_lines_capped, ReadResult}; use crate::utils::syntax::HighlightedLines; +use image::ImageReader; use parking_lot::Mutex; +use ratatui::layout::Rect; use rustc_hash::{FxBuildHasher, FxHashSet}; use std::collections::HashSet; use std::fs::File; @@ -10,17 +12,15 @@ use std::sync::{ atomic::{AtomicU8, Ordering}, Arc, }; -use ratatui::layout::Rect; use syntect::{highlighting::Theme, parsing::SyntaxSet}; use tracing::{debug, warn}; -use image::ImageReader; use crate::channels::entry; use crate::preview::cache::PreviewCache; use crate::preview::{previewers::meta, Preview, PreviewContent}; use crate::utils::{ - image::Image, files::FileType, + image::Image, strings::preprocess_line, syntax::{self, load_highlighting_assets, HighlightingAssetsExt}, }; @@ -80,14 +80,22 @@ impl FilePreviewer { self.cache.lock().get(&entry.name) } - pub fn preview(&mut self, entry: &entry::Entry, preview_window: Option) -> Option> { + pub fn preview( + &mut self, + entry: &entry::Entry, + preview_window: Option, + ) -> Option> { if let Some(preview) = self.cached(entry) { debug!("Preview cache hit for {:?}", entry.name); if preview.partial_offset.is_some() { // preview is partial, spawn a task to compute the next chunk // and return the partial preview debug!("Spawning partial preview task for {:?}", entry.name); - self.handle_preview_request(entry, Some(preview.clone()), preview_window); + self.handle_preview_request( + entry, + Some(preview.clone()), + preview_window, + ); } Some(preview) } else { @@ -241,15 +249,18 @@ pub fn try_preview( cache.lock().insert(entry.name.clone(), &p); } } - - } else if matches!(FileType::from(&path), FileType::Image) - { + } else if matches!(FileType::from(&path), FileType::Image) { debug!("File is an image: {:?}", entry.name); - let (window_height, window_width) = if let Some(preview_window) = preview_window{ + let (window_height, window_width) = if let Some(preview_window) = + preview_window + { // it should be a better way to know the size of the border to remove than this magic number let padding = 5; - ((preview_window.height - padding /2 ) * 2, preview_window.width - padding) - }else{ + ( + (preview_window.height - padding / 2) * 2, + preview_window.width - padding, + ) + } else { warn!("Error opening image, impossible to display without information about the size of the preview window"); let p = meta::not_supported(&entry.name); cache.lock().insert(entry.name.clone(), &p); @@ -259,8 +270,13 @@ pub fn try_preview( Ok(image) => { debug!("Width: {:}", window_width); - let image = Image::from_dynamic_image(image, window_height as u32, window_width as u32); - let total_lines = image.pixel_grid.len().try_into().unwrap_or(u16::MAX); + let image = Image::from_dynamic_image( + image, + u32::from(window_height), + u32::from(window_width), + ); + let total_lines = + image.pixel_grid.len().try_into().unwrap_or(u16::MAX); let content = PreviewContent::Image(image); let preview = Arc::new(Preview::new( entry.name.clone(), @@ -277,7 +293,6 @@ pub fn try_preview( cache.lock().insert(entry.name.clone(), &p); } } - } else { debug!("File isn't text-based: {:?}", entry.name); let preview = meta::not_supported(&entry.name); diff --git a/television/screen/preview.rs b/television/screen/preview.rs index 1c4ed36..9691a34 100644 --- a/television/screen/preview.rs +++ b/television/screen/preview.rs @@ -7,6 +7,7 @@ use crate::screen::{ cache::RenderedPreviewCache, colors::{Colorscheme, PreviewColorscheme}, }; +use crate::utils::image::{Image, ImageColor, PIXEL}; use crate::utils::strings::{ replace_non_printable, shrink_with_ellipsis, ReplaceNonPrintableConfig, EMPTY_STRING, @@ -21,7 +22,6 @@ use ratatui::{ }; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use crate::utils::image::{Image, ImageColor, PIXEL}; #[allow(dead_code)] const FILL_CHAR_SLANTED: char = '╱'; @@ -70,7 +70,7 @@ pub fn build_preview_paragraph<'a>( ) } PreviewContent::Image(image) => { - build_image_paragraph(image, preview_block,colorscheme.preview) + build_image_paragraph(image, preview_block, colorscheme.preview) } // meta @@ -226,16 +226,25 @@ fn build_image_paragraph( preview_block: Block<'_>, colorscheme: PreviewColorscheme, ) -> Paragraph<'_> { - let lines = image.pixel_grid.iter().map(|double_pixel_line| - Line::from_iter( - double_pixel_line.iter().map(|(color_up, color_down)| - convert_pixel_to_span(*color_up, *color_down, Some(colorscheme.highlight_bg))) - ) - ).collect::>(); + let lines = image + .pixel_grid + .into_iter() + .map(|double_pixel_line| { + Line::from_iter(double_pixel_line.iter().map( + |(color_up, color_down)| { + convert_pixel_to_span( + *color_up, + *color_down, + Some(colorscheme.highlight_bg), + ) + }, + )) + }) + .collect::>(); let text = Text::from(lines); Paragraph::new(text) .block(preview_block) - .wrap(Wrap { trim: true }) + .wrap(Wrap { trim: false }) } pub fn build_meta_preview_paragraph<'a>( @@ -538,8 +547,8 @@ pub fn convert_pixel_to_span<'a>( background: Option, ) -> Span<'a> { let bg_color = match background { - Some(Color::Rgb(r, g, b)) => Some((r,g,b)), - _ => {None} + Some(Color::Rgb(r, g, b)) => Some((r, g, b)), + _ => None, }; let (color_up, color_down) = if let Some(bg_color) = bg_color { let color_up_with_alpha = Color::Rgb( @@ -548,25 +557,26 @@ pub fn convert_pixel_to_span<'a>( (color_up.b * color_up.a + bg_color.2 * 255 - color_up.a) / 255, ); let color_down_with_alpha = Color::Rgb( - (color_down.r * color_down.a + bg_color.0 * 255 - color_down.a) / 255, - (color_down.b * color_down.a + bg_color.1 * 255 - color_down.a) / 255, - (color_down.b * color_down.a + bg_color.2 * 255 - color_down.a) / 255, + (color_down.r * color_down.a + bg_color.0 * 255 - color_down.a) + / 255, + (color_down.b * color_down.a + bg_color.1 * 255 - color_down.a) + / 255, + (color_down.b * color_down.a + bg_color.2 * 255 - color_down.a) + / 255, ); - (color_up_with_alpha,color_down_with_alpha) - }else{ - (convert_image_color_to_ratatui_color(color_up), - convert_image_color_to_ratatui_color(color_down)) + (color_up_with_alpha, color_down_with_alpha) + } else { + ( + convert_image_color_to_ratatui_color(color_up), + convert_image_color_to_ratatui_color(color_down), + ) }; - let style = Style::default() - .fg(color_up) - .bg(color_down); + let style = Style::default().fg(color_up).bg(color_down); Span::styled(String::from(PIXEL), style) } -fn convert_image_color_to_ratatui_color( - color: ImageColor, -) -> Color { +fn convert_image_color_to_ratatui_color(color: ImageColor) -> Color { Color::Rgb(color.r, color.g, color.b) -} \ No newline at end of file +} diff --git a/television/television.rs b/television/television.rs index 7f043a9..8e9d437 100644 --- a/television/television.rs +++ b/television/television.rs @@ -587,11 +587,14 @@ impl Television { if self.config.ui.show_preview_panel && !matches!(selected_entry.preview_type, PreviewType::None) { - // preview content - let maybe_preview = self.previewer.preview(&selected_entry, layout.preview_window); + let maybe_preview = self + .previewer + .preview(&selected_entry, layout.preview_window); - let _ = self.previewer.preview(&selected_entry, layout.preview_window); + let _ = self + .previewer + .preview(&selected_entry, layout.preview_window); if let Some(preview) = &maybe_preview { self.current_preview_total_lines = preview.total_lines; diff --git a/television/utils/files.rs b/television/utils/files.rs index e462f53..d3670e7 100644 --- a/television/utils/files.rs +++ b/television/utils/files.rs @@ -119,7 +119,7 @@ where if is_known_text_extension(p) { return FileType::Text; } - if is_accepted_image_extension(p){ + if is_accepted_image_extension(p) { return FileType::Image; } if let Ok(mut f) = File::open(p) { @@ -503,7 +503,7 @@ lazy_static! { //"farbfeld", "gif", //"hdr", - //"ico", + "ico", "jpeg", "jpg", //"exr", @@ -518,4 +518,4 @@ lazy_static! { .iter() .copied() .collect(); -} \ No newline at end of file +} diff --git a/television/utils/mod.rs b/television/utils/mod.rs index 254ef5c..dfacc32 100644 --- a/television/utils/mod.rs +++ b/television/utils/mod.rs @@ -1,6 +1,7 @@ pub mod cache; pub mod command; pub mod files; +pub mod image; pub mod indices; pub mod input; pub mod metadata; @@ -9,4 +10,3 @@ pub mod stdin; pub mod strings; pub mod syntax; pub mod threads; -pub mod image;