summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2021-01-19 13:10:36 -0500
committerJeff Zhao <jeff.no.zhao@gmail.com>2021-01-19 13:10:36 -0500
commita0fffdc01b04aa560ff249e6686a841f1349a88f (patch)
treef4dfa03522772038591b11a897f6f330d7669485 /src
parentf07eee4abb6fec4cb57b535143720763c9e0848b (diff)
add mouse clicking support
- add optional features
Diffstat (limited to 'src')
-rw-r--r--src/fs/entry.rs5
-rw-r--r--src/run.rs9
-rw-r--r--src/ui/views/tui_worker_view.rs4
-rw-r--r--src/ui/widgets/tui_menu.rs6
-rw-r--r--src/ui/widgets/tui_prompt.rs4
-rw-r--r--src/ui/widgets/tui_textfield.rs4
-rw-r--r--src/util/input.rs148
-rw-r--r--src/util/input_process.rs104
-rw-r--r--src/util/key_mapping.rs46
-rw-r--r--src/util/mod.rs5
-rw-r--r--src/util/to_string.rs47
11 files changed, 218 insertions, 164 deletions
diff --git a/src/fs/entry.rs b/src/fs/entry.rs
index 5362c76..d2a694b 100644
--- a/src/fs/entry.rs
+++ b/src/fs/entry.rs
@@ -3,6 +3,8 @@ use std::{fs, path};
use tui::style::Style;
use crate::fs::{FileType, JoshutoMetadata};
+
+#[cfg(feature = "devicons")]
use crate::util::devicons::*;
use crate::util::unix;
@@ -28,6 +30,7 @@ impl JoshutoDirEntry {
.to_string_lossy()
.to_string();
+ #[cfg(feature = "devicons")]
let label = if show_icons {
let icon = match metadata.file_type() {
FileType::Directory => DIR_NODE_EXACT_MATCHES
@@ -56,6 +59,8 @@ impl JoshutoDirEntry {
} else {
name.clone()
};
+ #[cfg(not(feature = "devicons"))]
+ let label = name.clone();
Ok(Self {
name,
diff --git a/src/run.rs b/src/run.rs
index d65b4f7..36bdfd1 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -8,8 +8,9 @@ use crate::ui;
use crate::ui::views::TuiView;
use crate::ui::widgets::TuiCommandMenu;
use crate::util::event::JoshutoEvent;
-use crate::util::input_process;
+use crate::util::input;
use crate::util::load_child::LoadChild;
+use crate::util::to_string::ToString;
pub fn run(config_t: JoshutoConfig, keymap_t: JoshutoCommandMapping) -> std::io::Result<()> {
let mut backend: ui::TuiBackend = ui::TuiBackend::new()?;
@@ -38,7 +39,7 @@ pub fn run(config_t: JoshutoConfig, keymap_t: JoshutoCommandMapping) -> std::io:
};
match event {
JoshutoEvent::Termion(Event::Mouse(event)) => {
- input_process::process_mouse(event, &mut context, &mut backend);
+ input::process_mouse(event, &mut context, &mut backend);
}
JoshutoEvent::Termion(key) => {
if !context.message_queue_ref().is_empty() {
@@ -46,7 +47,7 @@ pub fn run(config_t: JoshutoConfig, keymap_t: JoshutoCommandMapping) -> std::io:
}
match keymap_t.as_ref().get(&key) {
None => {
- context.push_msg(format!("Unmapped input: {:?}", key));
+ context.push_msg(format!("Unmapped input: {}", key.to_string()));
}
Some(CommandKeybind::SimpleKeybind(command)) => {
if let Err(e) = command.execute(&mut context, &mut backend) {
@@ -68,7 +69,7 @@ pub fn run(config_t: JoshutoConfig, keymap_t: JoshutoCommandMapping) -> std::io:
}
context.flush_event();
}
- event => input_process::process_noninteractive(event, &mut context),
+ event => input::process_noninteractive(event, &mut context),
}
}
diff --git a/src/ui/views/tui_worker_view.rs b/src/ui/views/tui_worker_view.rs
index 58eaef2..09b43b9 100644
--- a/src/ui/views/tui_worker_view.rs
+++ b/src/ui/views/tui_worker_view.rs
@@ -6,7 +6,7 @@ use crate::context::JoshutoContext;
use crate::ui::widgets::TuiWorker;
use crate::ui::TuiBackend;
use crate::util::event::JoshutoEvent;
-use crate::util::input_process;
+use crate::util::input;
pub struct TuiWorkerView {}
@@ -42,7 +42,7 @@ impl TuiWorkerView {
}
context.flush_event();
}
- event => input_process::process_noninteractive(event, context),
+ event => input::process_noninteractive(event, context),
};
}
}
diff --git a/src/ui/widgets/tui_menu.rs b/src/ui/widgets/tui_menu.rs
index 38eed64..0f2570d 100644
--- a/src/ui/widgets/tui_menu.rs
+++ b/src/ui/widgets/tui_menu.rs
@@ -12,8 +12,8 @@ use crate::context::JoshutoContext;
use crate::ui::views::TuiView;
use crate::ui::TuiBackend;
use crate::util::event::JoshutoEvent;
-use crate::util::input_process;
-use crate::util::key_mapping::ToString;
+use crate::util::input;
+use crate::util::to_string::ToString;
const BORDER_HEIGHT: usize = 1;
const BOTTOM_MARGIN: usize = 1;
@@ -95,7 +95,7 @@ impl TuiCommandMenu {
}
context.flush_event();
}
- event => input_process::process_noninteractive(event, context),
+ event => input::process_noninteractive(event, context),
}
}
}
diff --git a/src/ui/widgets/tui_prompt.rs b/src/ui/widgets/tui_prompt.rs
index c4d0c1c..581149c 100644
--- a/src/ui/widgets/tui_prompt.rs
+++ b/src/ui/widgets/tui_prompt.rs
@@ -8,7 +8,7 @@ use crate::context::JoshutoContext;
use crate::ui::views::TuiView;
use crate::ui::TuiBackend;
use crate::util::event::JoshutoEvent;
-use crate::util::input_process;
+use crate::util::input;
pub struct TuiPrompt<'a> {
prompt: &'a str,
@@ -62,7 +62,7 @@ impl<'a> TuiPrompt<'a> {
JoshutoEvent::Termion(_) => {
context.flush_event();
}
- event => input_process::process_noninteractive(event, context),
+ event => input::process_noninteractive(event, context),
};
}
}
diff --git a/src/ui/widgets/tui_textfield.rs b/src/ui/widgets/tui_textfield.rs
index d6e9371..0aed6df 100644
--- a/src/ui/widgets/tui_textfield.rs
+++ b/src/ui/widgets/tui_textfield.rs
@@ -12,7 +12,7 @@ use crate::ui::views::TuiView;
use crate::ui::widgets::TuiMenu;
use crate::ui::TuiBackend;
use crate::util::event::JoshutoEvent;
-use crate::util::input_process;
+use crate::util::input;
struct CompletionTracker {
pub index: usize,
@@ -240,7 +240,7 @@ impl<'a> TuiTextField<'a> {
JoshutoEvent::Termion(_) => {
context.flush_event();
}
- event => input_process::process_noninteractive(event, context),
+ event => input::process_noninteractive(event, context),
};
}
}
diff --git a/src/util/input.rs b/src/util/input.rs
new file mode 100644
index 0000000..af9e326
--- /dev/null
+++ b/src/util/input.rs
@@ -0,0 +1,148 @@
+use signal_hook::consts::signal;
+use termion::event::{MouseButton, MouseEvent};
+use tui::layout::{Constraint, Direction, Layout};
+
+use crate::commands::{cursor_move, parent_cursor_move, JoshutoRunnable, KeyCommand};
+use crate::context::JoshutoContext;
+use crate::history::DirectoryHistory;
+use crate::io::{FileOp, IOWorkerProgress};
+use crate::ui;
+use crate::util::event::JoshutoEvent;
+use crate::util::format;
+
+pub fn process_mouse(
+ event: MouseEvent,
+ context: &mut JoshutoContext,
+ backend: &mut ui::TuiBackend,
+) {
+ let f_size = backend.terminal.as_ref().unwrap().size().unwrap();
+
+ let constraints: &[Constraint; 3] = &context.config_ref().default_layout;
+ let layout_rect = Layout::default()
+ .direction(Direction::Horizontal)
+ .vertical_margin(1)
+ .constraints(constraints.as_ref())
+ .split(f_size);
+
+ match event {
+ MouseEvent::Press(MouseButton::WheelUp, x, _) => {
+ if x < layout_rect[1].x {
+ let command = KeyCommand::ParentCursorMoveUp(1);
+ if let Err(e) = command.execute(context, backend) {
+ context.push_msg(e.to_string());
+ }
+ } else if x < layout_rect[2].x {
+ let command = KeyCommand::CursorMoveUp(1);
+ if let Err(e) = command.execute(context, backend) {
+ context.push_msg(e.to_string());
+ }
+ } else {
+ // TODO: scroll in child list
+ let command = KeyCommand::CursorMoveUp(1);
+ if let Err(e) = command.execute(context, backend) {
+ context.push_msg(e.to_string());
+ }
+ }
+ }
+ MouseEvent::Press(MouseButton::WheelDown, x, _) => {
+ if x < layout_rect[1].x {
+ let command = KeyCommand::ParentCursorMoveDown(1);
+ if let Err(e) = command.execute(context, backend) {
+ context.push_msg(e.to_string());
+ }
+ } else if x < layout_rect[2].x {
+ let command = KeyCommand::CursorMoveDown(1);
+ if let Err(e) = command.execute(context, backend) {
+ context.push_msg(e.to_string());
+ }
+ } else {
+ // TODO: scroll in child list
+ let command = KeyCommand::CursorMoveDown(1);
+ if let Err(e) = command.execute(context, backend) {
+ context.push_msg(e.to_string());
+ }
+ }
+ }
+ MouseEvent::Press(MouseButton::Left, x, y)
+ if y > layout_rect[1].y && y <= layout_rect[1].y + layout_rect[1].height =>
+ {
+ if x < layout_rect[1].x {
+ if let Some(dirlist) = context.tab_context_ref().curr_tab_ref().curr_list_ref() {
+ if let Some(curr_index) = dirlist.index {
+ let skip_dist = curr_index / layout_rect[1].height as usize
+ * layout_rect[1].height as usize;
+
+ let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize;
+ if let Err(e) = parent_cursor_move::parent_cursor_move(new_index, context) {
+ context.push_msg(e.to_string());
+ }
+ }
+ }
+ } else if x < layout_rect[2].x {
+ if let Some(dirlist) = context.tab_context_ref().curr_tab_ref().curr_list_ref() {
+ if let Some(curr_index) = dirlist.index {
+ let skip_dist = curr_index / layout_rect[1].height as usize
+ * layout_rect[1].height as usize;
+
+ let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize;
+ if let Err(e) = cursor_move::cursor_move(new_index, context) {
+ context.push_msg(e.to_string());
+ }
+ }
+ }
+ } else {
+ }
+ }
+ MouseEvent::Press(MouseButton::Left, x, y)
+ if y > layout_rect[1].y && y <= layout_rect[1].y + layout_rect[1].height => {}
+ _ => {}
+ }
+ context.flush_event();
+}
+
+pub fn process_noninteractive(event: JoshutoEvent, context: &mut JoshutoContext) {
+ match event {
+ JoshutoEvent::IOWorkerProgress(res) => process_worker_progress(context, res),
+ JoshutoEvent::IOWorkerResult(res) => process_finished_worker(context, res),
+ JoshutoEvent::Signal(signal::SIGWINCH) => {}
+ _ => {}
+ }
+}
+
+pub fn process_worker_progress(context: &mut JoshutoContext, res: IOWorkerProgress) {
+ context.set_worker_progress(res);
+ context.update_worker_msg();
+}
+
+pub fn process_finished_worker(
+ context: &mut JoshutoContext,
+ res: std::io::Result<IOWorkerProgress>,
+) {
+ let observer = context.remove_job().unwrap();
+ let options = context.config_ref().sort_option.clone();
+ for tab in context.tab_context_mut().iter_mut() {
+ let _ = tab.history_mut().reload(observer.dest_path(), &options);
+ let _ = tab.history_mut().reload(observer.src_path(), &options);
+ }
+ observer.join();
+ match res {
+ Ok(progress) => {
+ let op = match progress.kind() {
+ FileOp::Copy => "copied",
+ FileOp::Cut => "moved",
+ };
+ let size_str = format::file_size_to_string(progress.processed());
+ let msg = format!(
+ "successfully {} {} items ({})",
+ op,
+ progress.len(),
+ size_str
+ );
+ context.push_msg(msg);
+ }
+ Err(e) => {
+ let msg = format!("{}", e);
+ context.push_msg(msg);
+ }
+ }
+}
diff --git a/src/util/input_process.rs b/src/util/input_process.rs
deleted file mode 100644
index 942703b..0000000
--- a/src/util/input_process.rs
+++ /dev/null
@@ -1,104 +0,0 @@
-use signal_hook::consts::signal;
-use termion::event::{MouseButton, MouseEvent};
-use tui::layout::{Constraint, Direction, Layout};
-
-use crate::commands::{JoshutoRunnable, KeyCommand};
-use crate::context::JoshutoContext;
-use crate::history::DirectoryHistory;
-use crate::io::{FileOp, IOWorkerProgress};
-use crate::ui;
-use crate::util::event::JoshutoEvent;
-use crate::util::format;
-
-pub fn process_mouse(
- event: MouseEvent,
- context: &mut JoshutoContext,
- backend: &mut ui::TuiBackend,
-) {
- let f_size = backend.terminal.as_ref().unwrap().size().unwrap();
-
- let constraints: &[Constraint; 3] = &context.config_ref().default_layout;
- let layout_rect = Layout::default()
- .direction(Direction::Horizontal)
- .vertical_margin(1)
- .constraints(constraints.as_ref())
- .split(f_size);
-
- let command = match event {
- MouseEvent::Press(MouseButton::WheelUp, x, _) => {
- if x < layout_rect[1].x {
- Some(KeyCommand::ParentCursorMoveUp(1))
- } else if x < layout_rect[2].x {
- Some(KeyCommand::CursorMoveUp(1))
- } else {
- // TODO: scroll in child list
- Some(KeyCommand::CursorMoveUp(1))
- }
- }
- MouseEvent::Press(MouseButton::WheelDown, x, _) => {
- if x < layout_rect[1].x {
- Some(KeyCommand::ParentCursorMoveDown(1))
- } else if x < layout_rect[2].x {
- Some(KeyCommand::CursorMoveDown(1))
- } else {
- // TODO: scroll in child list
- Some(KeyCommand::CursorMoveDown(1))
- }
- }
- _ => None,
- };
-
- if let Some(command) = command {
- if let Err(e) = command.execute(context, backend) {
- context.push_msg(e.to_string());
- }
- }
- context.flush_event();
-}
-
-pub fn process_noninteractive(event: JoshutoEvent, context: &mut JoshutoContext) {
- match event {
- JoshutoEvent::IOWorkerProgress(res) => process_worker_progress(context, res),
- JoshutoEvent::IOWorkerResult(res) => process_finished_worker(context, res),
- JoshutoEvent::Signal(signal::SIGWINCH) => {}
- _ => {}
- }
-}
-
-pub fn process_worker_progress(context: &mut JoshutoContext, res: IOWorkerProgress) {
- context.set_worker_progress(res);
- context.update_worker_msg();
-}
-
-pub fn process_finished_worker(
- context: &mut JoshutoContext,
- res: std::io::Result<IOWorkerProgress>,
-) {
- let observer = context.remove_job().unwrap();
- let options = context.config_ref().sort_option.clone();
- for tab in context.tab_context_mut().iter_mut() {
- let _ = tab.history_mut().reload(observer.dest_path(), &options);
- let _ = tab.history_mut().reload(observer.src_path(), &options);
- }
- observer.join();
- match res {
- Ok(progress) => {
- let op = match progress.kind() {
- FileOp::Copy => "copied",
- FileOp::Cut => "moved",
- };
- let size_str = format::file_size_to_string(progress.processed());
- let msg = format!(
- "successfully {} {} items ({})",
- op,
- progress.len(),
- size_str
- );
- context.push_msg(msg);
- }
- Err(e) => {
- let msg = format!("{}", e);
- context.push_msg(msg);
- }
- }
-}
diff --git a/src/util/key_mapping.rs b/src/util/key_mapping.rs
index 0ac7ee7..de1e0dd 100644
--- a/src/util/key_mapping.rs
+++ b/src/util/key_mapping.rs
@@ -1,51 +1,5 @@
use termion::event::{Event, Key, MouseButton, MouseEvent};
-pub trait ToString {
- fn to_string(&self) -> String;
-}
-
-impl ToString for Key {
- fn to_string(&self) -> String {
- match *self {
- Key::Char(c) => format!("{}", c),
- Key::Ctrl(c) => format!("ctrl+{}", c),
- Key::Left => "arrow_left".to_string(),
- Key::Right => "arrow_right".to_string(),
- Key::Up => "arrow_up".to_string(),
- Key::Down => "arrow_down".to_string(),
- Key::Backspace => "backspace".to_string(),
- Key::Home => "home".to_string(),
- Key::End => "end".to_string(),
- Key::PageUp => "page_up".to_string(),
- Key::PageDown => "page_down".to_string(),
- Key::BackTab => "backtab".to_string(),
- Key::Insert => "insert".to_string(),
- Key::Delete => "delete".to_string(),
- Key::Esc => "escape".to_string(),
- Key::F(i) => format!("f{}", i),
- k => format!("{:?}", k),
- }
- }
-}
-
-impl ToString for MouseEvent {
- fn to_string(&self) -> String {
- match *self {
- k => format!("{:?}", k),
- }
- }
-}
-
-impl ToString for Event {
- fn to_string(&self) -> String {
- match self {
- Event::Key(key) => key.to_string(),
- Event::Mouse(mouse) => mouse.to_string(),
- Event::Unsupported(v) => format!("{:?}", v),
- }
- }
-}
-
pub fn str_to_event(s: &str) -> Option<Event> {
if let Some(k) = str_to_key(s) {
Some(Event::Key(k))
diff --git a/src/util/mod.rs b/src/util/mod.rs
index bca6387..a85e78d 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -1,8 +1,11 @@
+#[cfg(feature = "devicons")]
pub mod devicons;
+
pub mod event;
pub mod format;
-pub mod input_process;
+pub mod input;
pub mod key_mapping;
pub mod load_child;
pub mod sort;
+pub mod to_string;
pub mod unix;
diff --git a/src/util/to_string.rs b/src/util/to_string.rs
new file mode 100644
index 0000000..22d1f02
--- /dev/null
+++ b/src/util/to_string.rs
@@ -0,0 +1,47 @@
+use termion::event::{Event, Key, MouseButton, MouseEvent};
+
+pub trait ToString {
+ fn to_string(&self) -> String;
+}
+
+impl ToString for Key {
+ fn to_string(&self) -> String {
+ match *self {
+ Key::Char(c) => format!("{}", c),
+ Key::Ctrl(c) => format!("ctrl+{}", c),
+ Key::Left => "arrow_left".to_string(),
+ Key::Right => "arrow_right".to_string(),
+ Key::Up => "arrow_up".to_string(),
+ Key::Down => "arrow_down".to_string(),
+ Key::Backspace => "backspace".to_string(),
+ Key::Home => "home".to_string(),
+ Key::End => "end".to_string(),
+ Key::PageUp => "page_up".to_string(),
+ Key::PageDown => "page_down".to_string(),
+ Key::BackTab => "backtab".to_string(),
+ Key::Insert => "insert".to_string(),
+ Key::Delete => "delete".to_string(),
+ Key::Esc => "escape".to_string(),
+ Key::F(i) => format!("f{}", i),
+ k => format!("{:?}", k),
+ }
+ }
+}
+
+impl ToString for MouseEvent {
+ fn to_string(&self) -> String {
+ match *self {
+ k => format!("{:?}", k),
+ }
+ }
+}
+
+impl ToString for Event {
+ fn to_string(&self) -> String {
+ match self {
+ Event::Key(key) => key.to_string(),
+ Event::Mouse(mouse) => mouse.to_string(),
+ Event::Unsupported(v) => format!("{:?}", v),
+ }
+ }
+}