Skip to content

Commit

Permalink
v0.0.11
Browse files Browse the repository at this point in the history
  • Loading branch information
ksk001100 committed May 27, 2022
1 parent 408b2a3 commit 421fe1c
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 101 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "picterm"
version = "0.0.10"
version = "0.0.11"
authors = ["Keisuke Toyota <[email protected]>"]
edition = "2018"
repository = "https://github.com/ksk001100/picterm"
Expand Down
16 changes: 12 additions & 4 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use crate::{
actions::{Action, Actions},
state::AppState,
},
image::ImageMode,
inputs::key::Key,
io::IoEvent,
utils::ImageMode,
};

#[derive(Debug, PartialEq, Eq)]
Expand All @@ -18,25 +18,33 @@ pub enum AppReturn {
Continue,
}

#[derive(Debug, Clone)]
pub struct AppConfig {
pub image_mode: ImageMode,
}

#[derive(Clone)]
pub struct App<'a> {
io_tx: tokio::sync::mpsc::Sender<IoEvent>,
actions: Actions,
is_loading: bool,
pub state: AppState<'a>,
pub config: AppConfig,
}

impl<'a> App<'a> {
pub fn new(io_tx: tokio::sync::mpsc::Sender<IoEvent>) -> Self {
pub fn new(io_tx: tokio::sync::mpsc::Sender<IoEvent>, image_mode: ImageMode) -> Self {
let actions = vec![Action::Quit].into();
let is_loading = false;
let state = AppState::default();
let config = AppConfig { image_mode };

Self {
io_tx,
actions,
is_loading,
state,
config,
}
}

Expand Down Expand Up @@ -89,15 +97,15 @@ impl<'a> App<'a> {
self.is_loading
}

pub fn initialized(&mut self, path: &str, mode: ImageMode) {
pub fn initialized(&mut self, path: &str) {
self.actions = vec![
Action::Quit,
Action::Increment,
Action::Decrement,
Action::Show,
]
.into();
self.state = AppState::initialized(path, mode);
self.state = AppState::initialized(path);
}

pub fn loaded(&mut self) {
Expand Down
20 changes: 2 additions & 18 deletions src/app/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{image::ImageMode, utils};
use crate::utils;
use std::path::PathBuf;
use tui::text::Spans;

Expand All @@ -11,7 +11,6 @@ pub enum AppState<'a> {
term_size: Option<TermSize>,
current_image: Option<Vec<Spans<'a>>>,
current_image_info: Option<ImageInfo>,
mode: ImageMode,
},
}

Expand All @@ -29,7 +28,7 @@ pub struct ImageInfo {
}

impl<'a> AppState<'a> {
pub fn initialized(path: &str, mode: ImageMode) -> Self {
pub fn initialized(path: &str) -> Self {
let paths = utils::get_image_paths(path);
let selected_index = 0;
let current_image = None;
Expand All @@ -41,7 +40,6 @@ impl<'a> AppState<'a> {
term_size,
current_image,
current_image_info,
mode,
}
}

Expand Down Expand Up @@ -145,20 +143,6 @@ impl<'a> AppState<'a> {
None
}
}

pub fn set_image_mode(&mut self, m: ImageMode) {
if let Self::Initialized { mode, .. } = self {
*mode = m;
}
}

pub fn get_image_mode(&self) -> Option<ImageMode> {
if let Self::Initialized { mode, .. } = self {
Some(mode.clone())
} else {
None
}
}
}

impl<'a> Default for AppState<'a> {
Expand Down
7 changes: 1 addition & 6 deletions src/image.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
use crate::utils::ImageMode;
use ansi_rgb::Background;
use image::{DynamicImage, GenericImageView, LumaA, Rgba};
use rgb::RGB8;

#[derive(Debug, Clone)]
pub enum ImageMode {
Rgba,
GrayScale,
}

pub fn image_fit_size(img: &DynamicImage, term_w: u32, term_h: u32) -> (u32, u32) {
let (img_width, img_height) = img.dimensions();
let (w, h) = get_dimensions(img_width, img_height, term_w, term_h);
Expand Down
87 changes: 43 additions & 44 deletions src/io/handler.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{
app::{state::ImageInfo, App},
image::{image_fit_size, ImageMode},
image::image_fit_size,
io::IoEvent,
utils::ImageMode,
};
use eyre::Result;
use image::{GenericImageView, LumaA, Rgba};
Expand All @@ -22,17 +23,17 @@ impl<'a> IoAsyncHandler<'a> {

pub async fn handle_io_event(&mut self, io_event: IoEvent) {
let _ = match io_event {
IoEvent::Initialize(path, mode) => self.do_initialize(&path, mode).await,
IoEvent::Initialize(path) => self.do_initialize(&path).await,
IoEvent::LoadImage => self.do_load_image().await,
};

let mut app = self.app.lock().await;
app.loaded();
}

async fn do_initialize(&mut self, path: &str, mode: ImageMode) -> Result<()> {
async fn do_initialize(&mut self, path: &str) -> Result<()> {
let mut app = self.app.lock().await;
app.initialized(path, mode);
app.initialized(path);

Ok(())
}
Expand All @@ -58,9 +59,9 @@ impl<'a> IoAsyncHandler<'a> {
app.state.get_term_size()
};

let opt_mode = {
let mode = {
let app = self.app.lock().await;
app.state.get_image_mode()
app.config.image_mode.clone()
};

{
Expand Down Expand Up @@ -89,49 +90,47 @@ impl<'a> IoAsyncHandler<'a> {

let mut r = result.lock().await;

if let Some(mode) = opt_mode {
match mode {
ImageMode::Rgba => {
let imgbuf = imgbuf.to_rgba8();
for y in 0..height {
let mut line = vec![];
for x in 0..width {
let pixel = imgbuf.get_pixel(x, y);
let Rgba(data) = *pixel;

if data[3] == 0 {
line.push(Span::from(" "));
} else {
line.push(Span::styled(
" ",
Style::default()
.bg(Color::Rgb(data[0], data[1], data[2])),
));
}
match mode {
ImageMode::Rgba => {
let imgbuf = imgbuf.to_rgba8();
for y in 0..height {
let mut line = vec![];
for x in 0..width {
let pixel = imgbuf.get_pixel(x, y);
let Rgba(data) = *pixel;

if data[3] == 0 {
line.push(Span::from(" "));
} else {
line.push(Span::styled(
" ",
Style::default()
.bg(Color::Rgb(data[0], data[1], data[2])),
));
}
(*r).push(Spans::from(line))
}
(*r).push(Spans::from(line))
}
ImageMode::GrayScale => {
let imgbuf = imgbuf.to_luma_alpha8();
for y in 0..height {
let mut line = vec![];
for x in 0..width {
let pixel = imgbuf.get_pixel(x, y);
let LumaA(data) = *pixel;

if data[1] == 0 {
line.push(Span::from(" "));
} else {
line.push(Span::styled(
" ",
Style::default()
.bg(Color::Rgb(data[0], data[0], data[0])),
));
}
}
ImageMode::GrayScale => {
let imgbuf = imgbuf.to_luma_alpha8();
for y in 0..height {
let mut line = vec![];
for x in 0..width {
let pixel = imgbuf.get_pixel(x, y);
let LumaA(data) = *pixel;

if data[1] == 0 {
line.push(Span::from(" "));
} else {
line.push(Span::styled(
" ",
Style::default()
.bg(Color::Rgb(data[0], data[0], data[0])),
));
}
(*r).push(Spans::from(line))
}
(*r).push(Spans::from(line))
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
pub mod handler;

use crate::image::ImageMode;

#[derive(Debug, Clone)]
pub enum IoEvent {
Initialize(String, ImageMode),
Initialize(String),
LoadImage,
}
9 changes: 2 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub mod utils;

use crate::{
app::{ui, App, AppReturn},
image::ImageMode,
io::IoEvent,
};
use crossterm::{
Expand All @@ -19,11 +18,7 @@ use inputs::{events::Events, InputEvent};
use std::{io::stdout, sync::Arc, time::Duration};
use tui::{backend::CrosstermBackend, Terminal};

pub async fn start_ui<'a>(
app: &Arc<tokio::sync::Mutex<App<'a>>>,
path: String,
mode: ImageMode,
) -> Result<()> {
pub async fn start_ui<'a>(app: &Arc<tokio::sync::Mutex<App<'a>>>, path: String) -> Result<()> {
let mut stdout = stdout();
enable_raw_mode()?;
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
Expand All @@ -37,7 +32,7 @@ pub async fn start_ui<'a>(

{
let mut app = app.lock().await;
app.dispatch(IoEvent::Initialize(path, mode)).await;
app.dispatch(IoEvent::Initialize(path)).await;
}

loop {
Expand Down
23 changes: 11 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use eyre::Result;
use picterm::{
app::App,
image::{print_term_image, ImageMode},
image::print_term_image,
io::{handler::IoAsyncHandler, IoEvent},
start_ui,
utils::{select_mode, Mode},
utils::{select_mode, ImageMode, RunMode},
};
use seahorse::{App as SeahorseApp, Context, Flag, FlagType};
use std::{env, sync::Arc};
Expand Down Expand Up @@ -33,8 +33,8 @@ fn main() -> Result<()> {

fn action(c: &Context) {
match select_mode(&c.args) {
Mode::CLI => cli_main(c),
Mode::TUI => tui_main(c),
RunMode::CLI => cli_main(c),
RunMode::TUI => tui_main(c),
}
}

Expand All @@ -53,28 +53,27 @@ fn tui_main(c: &Context) {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let (sync_io_tx, mut sync_io_rx) = tokio::sync::mpsc::channel::<IoEvent>(1000);
let mode = if c.bool_flag("gray") {
ImageMode::GrayScale
} else {
ImageMode::Rgba
};

let app = Arc::new(tokio::sync::Mutex::new(App::new(sync_io_tx.clone())));
let app = Arc::new(tokio::sync::Mutex::new(App::new(sync_io_tx.clone(), mode)));
let app_ui = Arc::clone(&app);

let path = match c.args.len() {
1 => c.args[0].clone(),
_ => "./".to_string(),
};

let mode = if c.bool_flag("gray") {
ImageMode::GrayScale
} else {
ImageMode::Rgba
};

tokio::spawn(async move {
let mut handler = IoAsyncHandler::new(app);
while let Some(io_event) = sync_io_rx.recv().await {
handler.handle_io_event(io_event).await;
}
});

start_ui(&app_ui, path, mode).await.unwrap();
start_ui(&app_ui, path).await.unwrap();
});
}
Loading

0 comments on commit 421fe1c

Please sign in to comment.