Skip to content

Commit

Permalink
Merge branch 'dynamicimage' of github.com:woelper/oculante into dynam…
Browse files Browse the repository at this point in the history
…icimage
  • Loading branch information
woelper committed Dec 9, 2024
2 parents 295165f + 1475720 commit cd1efd5
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 71 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ perf.*
flamegraph.svg
.notes
TODO
debug.png
debug.png
.idea
64 changes: 42 additions & 22 deletions src/filebrowser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::ui::{render_file_icon, EguiExt, BUTTON_HEIGHT_LARGE, BUTTON_HEIGHT_SM

use anyhow::{Context, Result};
use dirs;
use log::debug;
use log::{debug, info};
use notan::egui::{self, *};
use std::io::Write;
use std::{
Expand Down Expand Up @@ -57,7 +57,8 @@ pub fn browse_modal<F: FnMut(&PathBuf)>(
.collapsible(false)
.open(&mut open)
.resizable(true)
.default_width(750.)
//TODO: Change default_width to 815 after folder misalignment fix, discord this comment and use another closest to reference design value if the slider can be combined into the image area BG
.default_width(818.)
.default_height(600.)
.show(ctx, |ui| {
browse(
Expand Down Expand Up @@ -237,7 +238,7 @@ pub fn browse<F: FnMut(&PathBuf)>(
};

let cp = path.clone();
// Too many folders make the dialog too large, cap them at this amount
// Too many folders make the dialog too large, cap them at this amount
let max_nav_items = 6;
let mut ancestors = cp.ancestors().take(max_nav_items).collect::<Vec<_>>();
ancestors.reverse();
Expand Down Expand Up @@ -378,29 +379,52 @@ pub fn browse<F: FnMut(&PathBuf)>(
false => Color32::from_gray(217),
};

egui::ScrollArea::new([false, true])
.min_scrolled_height(400.)
.auto_shrink([false, false])
let r = ui.available_rect_before_wrap();
let spacing = ui.style().spacing.item_spacing.x;
let w = r.width() - spacing * 3.;

let thumbs_per_row = (w / (THUMB_SIZE[0] as f32 + spacing)).floor();
let num_rows = entries.len() / thumbs_per_row as usize;

info!("tpr {thumbs_per_row} {w}, rows: {num_rows}");
// let all_rows = THUMB_SIZE

// ui.painter().debug_rect(r, Color32::LIGHT_RED, "yo");

egui::Frame::none()
.fill(panel_bg_color)
.rounding(ui.style().visuals.widgets.active.rounding * 2.0)
.inner_margin(Margin::same(10.))
.show(ui, |ui| {
egui::Frame::none()
.fill(panel_bg_color)
.rounding(ui.style().visuals.widgets.active.rounding * 2.0)
.inner_margin(Margin::same(6.))
.show(ui, |ui| {
egui::ScrollArea::new([false, true])
.min_scrolled_height(400.)
.auto_shrink([false, false])
// .show_viewport(ui, |ui, rect| {
.show_rows(ui, THUMB_SIZE[1] as f32, num_rows, |ui, row_range| {
// .show(ui, |ui| {
// ui.painter().debug_rect(rect, Color32::LIGHT_GREEN, "scroll rect");

info!("range {:?}", row_range);
let entries = entries
.clone()
.drain(
(row_range.start * thumbs_per_row as usize)
..(row_range.end * thumbs_per_row as usize),
)
.collect::<Vec<_>>();

if state.listview_active {
} else {
ui.horizontal_wrapped(|ui| {
if entries.is_empty() {
ui.label("Empty directory");
} else {
let dirs = entries
.iter()
.filter(|d| d.is_dir())
.collect::<Vec<_>>();

for de in dirs.iter() {
for de in entries.iter().filter(|e| e.is_dir()) {
let folder_response = ui.allocate_response(
Vec2::new(THUMB_SIZE[0] as f32, 30.),
Vec2::new(
THUMB_SIZE[0] as f32,
THUMB_SIZE[1] as f32,
),
Sense::click(),
);

Expand Down Expand Up @@ -439,10 +463,6 @@ pub fn browse<F: FnMut(&PathBuf)>(
);
}

if !dirs.is_empty() {
ui.end_row();
}

for de in entries {
if de.is_file() {
if render_file_icon(&de, ui, &mut state.thumbnails)
Expand Down
1 change: 0 additions & 1 deletion src/shortcuts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ pub fn key_pressed(app: &mut App, state: &mut OculanteState, command: InputEvent
if format!("{:?}", dn) == key {
debug!("REPEAT: Number of keys down: {}", app.keyboard.down.len());
debug!("Matched {:?} / {:?}", command, key);
debug!("d {}", app.system_timer.delta_f32());
return true;
}
}
Expand Down
147 changes: 103 additions & 44 deletions src/texture_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use log::error;
use log::warn;
use notan::draw::*;
use notan::prelude::{BlendMode, Graphics, ShaderSource, Texture, TextureFilter};
use zune_png::zune_core::bit_depth::ByteEndian;
pub struct TexWrap {
texture_array: Vec<TexturePair>,
pub col_count: u32,
Expand Down Expand Up @@ -48,7 +49,7 @@ impl TextureWrapperManager {
&& tex.height() as u32 == img.height()
&& img.color() == tex.image_format
{
debug!("Re-using texture as it is the same size.");
debug!("Re-using texture as it is the same size and type.");
tex.update_textures(gfx, img);
return;
}
Expand Down Expand Up @@ -215,25 +216,64 @@ impl TexWrap {
}*/

fn image_color_supported(img: &DynamicImage) -> bool {
let supported_type =
img.color() == image::ColorType::L8 || img.color() == image::ColorType::Rgba8;
return supported_type;
}

fn image_bytesize_expected(img: &DynamicImage) -> usize {
let pixel_count = (img.width() * img.height()) as usize;
let mut byte_count: usize;
match img.color() {
image::ColorType::L8 => byte_count = pixel_count,
image::ColorType::Rgba8 => byte_count = pixel_count * 4,
_ => {
error!("Passed non supported colored image!");
byte_count = 0;
}
}

if img.as_bytes().len() < byte_count {
error!("Pixel buffer is smaller than expected!");
byte_count = 0;
}
return byte_count;
}

fn image_bytes_slice(img: &DynamicImage) -> Option<&[u8]> {
let byte_buffer = img.as_bytes();
let byte_count = Self::image_bytesize_expected(img);
if byte_count == 0 {
return None;
}
if byte_count < byte_buffer.len() {
warn!("Image byte buffer is bigger than expected. Will truncate.");
}
let (buff, _) = byte_buffer.split_at(byte_count);
return Some(buff);
}

fn get_dyn_image_part(
image: &DynamicImage,
offset: (u32, u32),
size: (u32, u32),
) -> Option<DynamicImage> {
let color_supported = Self::image_color_supported(image);
if !color_supported {
debug!(
"Current image pixel type {:?} is not supported, will convert to rgba8",
image.color()
);
}
if offset.0 == 0 && offset.1 == 0 && size.0 == image.width() && size.1 == image.height() {
//Whole image
match image {
DynamicImage::ImageRgb8(_rgb8_image) => {
let img_rgba = image.to_rgba8();
return Some(DynamicImage::ImageRgba8(img_rgba));
}
/*DynamicImage::ImageLumaA8(_la8_image) => {
let img_rgba = image.to_rgba8();
return Some(DynamicImage::ImageRgba8(img_rgba));
}*/
_other_image_type => {
return None;
}
if color_supported {
return None;
} else {
//Convert to rgba8 if current image is not supported
let img_rgba = image.to_rgba8();
return Some(DynamicImage::ImageRgba8(img_rgba));
}
} else {
match image {
Expand All @@ -258,6 +298,7 @@ impl TexWrap {
return Some(DynamicImage::ImageLuma8(gi));
}
other_image_type => {
//rgba8 automatically
let sub_img =
imageops::crop_imm(other_image_type, offset.0, offset.1, size.0, size.1);
let my_img = sub_img.to_image();
Expand Down Expand Up @@ -340,7 +381,7 @@ impl TexWrap {
let tex_start_x = col_index * col_increment;
let tex_width = std::cmp::min(col_increment, im_w - tex_start_x);

let tex: Option<Texture>;
let mut tex: Option<Texture> = None;

let sub_img_opt = Self::get_dyn_image_part(
image,
Expand All @@ -349,25 +390,31 @@ impl TexWrap {
);

if let Some(suba_img) = sub_img_opt {
tex = texture_generator_function(
gfx,
suba_img.as_bytes(),
tex_width,
tex_height,
format,
settings,
allow_mipmap,
);
let byte_slice = Self::image_bytes_slice(&suba_img);
if let Some(bt_slice) = byte_slice {
tex = texture_generator_function(
gfx,
bt_slice,
tex_width,
tex_height,
format,
settings,
allow_mipmap,
);
}
} else {
tex = texture_generator_function(
gfx,
image.as_bytes(),
tex_width,
tex_height,
format,
settings,
allow_mipmap,
);
let byte_slice = Self::image_bytes_slice(&image);
if let Some(bt_slice) = byte_slice {
tex = texture_generator_function(
gfx,
bt_slice,
tex_width,
tex_height,
format,
settings,
allow_mipmap,
);
}
}

if let Some(t) = tex {
Expand Down Expand Up @@ -566,21 +613,33 @@ impl TexWrap {
);

if let Some(suba_img) = sub_img_opt {
if let Err(e) = gfx
.update_texture(&mut self.texture_array[tex_index].texture)
.with_data(suba_img.as_bytes())
.update()
{
error!("{e}");
let byte_slice = Self::image_bytes_slice(&suba_img);
if let Some(bt_slice) = byte_slice {
if let Err(e) = gfx
.update_texture(&mut self.texture_array[tex_index].texture)
.with_data(bt_slice)
.update()
{
error!("{e}");
return;
}
} else {
//Error!
return;
}
} else {
if let Err(e) = gfx
.update_texture(&mut self.texture_array[tex_index].texture)
.with_data(image.as_bytes())
.update()
{
error!("{e}");
let byte_slice = Self::image_bytes_slice(&image);
if let Some(bt_slice) = byte_slice {
if let Err(e) = gfx
.update_texture(&mut self.texture_array[tex_index].texture)
.with_data(bt_slice)
.update()
{
error!("{e}");
return;
}
} else {
//Error!
return;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/thumbnails.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub const THUMB_SIZE: [u32; 2] = [120, 90];
pub const THUMB_SIZE: [u32; 2] = [120, 80];

use std::{
fs::create_dir_all,
Expand Down
2 changes: 0 additions & 2 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2614,11 +2614,9 @@ pub fn render_file_icon(icon_path: &Path, ui: &mut Ui, thumbnails: &mut Thumbnai
.data_mut(|w| w.get_temp::<f32>("ZM".into()))
.unwrap_or(0.997);
let delta = ui.input(|r| r.zoom_delta()).clamp(0.9999, 1.0001);
debug!("d {:?}", delta);
zoom *= delta;
zoom = zoom.clamp(0.5, 1.3);
ui.data_mut(|w| w.insert_temp("ZM".into(), zoom));
debug!("z {:?}", zoom);
let size = Vec2::new(THUMB_SIZE[0] as f32, THUMB_SIZE[1] as f32) * zoom;
let response = ui.allocate_response(size, Sense::click());
let rounding = Rounding::same(4.);
Expand Down

0 comments on commit cd1efd5

Please sign in to comment.