Skip to content

Commit

Permalink
Merge pull request #317 from sarub0b0/improve-focus-event-handling
Browse files Browse the repository at this point in the history
feat: improve focus event handling
  • Loading branch information
sarub0b0 authored Jun 25, 2023
2 parents 0dc7912 + 5c69c10 commit 18f7a3a
Show file tree
Hide file tree
Showing 19 changed files with 200 additions and 108 deletions.
8 changes: 0 additions & 8 deletions shell.nix

This file was deleted.

12 changes: 9 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crossbeam::channel::{bounded, Receiver, Sender};

use crossterm::{
cursor::Show,
event::{DisableMouseCapture, EnableMouseCapture},
event::{DisableFocusChange, DisableMouseCapture, EnableFocusChange, EnableMouseCapture},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
Expand Down Expand Up @@ -36,8 +36,13 @@ use ratatui::{backend::CrosstermBackend, Terminal, TerminalOptions, Viewport};
macro_rules! enable_raw_mode {
() => {
enable_raw_mode().expect("failed to enable raw mode");
execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture)
.expect("failed to enable raw mode");
execute!(
io::stdout(),
EnterAlternateScreen,
EnableMouseCapture,
EnableFocusChange
)
.expect("failed to enable raw mode");
};
}

Expand All @@ -47,6 +52,7 @@ macro_rules! disable_raw_mode {
io::stdout(),
LeaveAlternateScreen,
DisableMouseCapture,
DisableFocusChange,
Show
)
.expect("failed to restore terminal");
Expand Down
57 changes: 52 additions & 5 deletions src/ui/tab.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use super::widget::*;
use super::{
event::EventResult,
util::{MousePosition, RectContainsPoint},
widget::*,
};

use crossterm::event::{MouseButton, MouseEvent, MouseEventKind};
use ratatui::{
backend::Backend,
layout::{Constraint, Layout, Rect},
Expand Down Expand Up @@ -34,6 +39,7 @@ pub struct Tab<'a> {
layout: Layout,
active_widget_index: usize,
activatable_widget_indices: Vec<usize>,
mouse_over_widget_index: Option<usize>,
}

impl<'a> Tab<'a> {
Expand All @@ -59,6 +65,7 @@ impl<'a> Tab<'a> {
layout,
activatable_widget_indices,
active_widget_index: 0,
mouse_over_widget_index: None,
}
}

Expand Down Expand Up @@ -91,11 +98,15 @@ impl<'a> Tab<'a> {
}

pub fn activate_next_widget(&mut self) {
self.clear_mouse_over();

self.active_widget_index =
(self.active_widget_index + 1) % self.activatable_widget_indices.len();
}

pub fn activate_prev_widget(&mut self) {
self.clear_mouse_over();

let activatable_widget_len = self.activatable_widget_indices.len();

self.active_widget_index =
Expand Down Expand Up @@ -128,10 +139,16 @@ impl<'a> Tab<'a> {
.enumerate()
.find(|(_, w)| w.widget.id() == id)
{
self.clear_mouse_over();

self.active_widget_index = index;
}
}

pub fn clear_mouse_over(&mut self) {
self.mouse_over_widget_index = None;
}

pub fn find_widget(&self, id: &str) -> Option<&Widget<'a>> {
self.widgets.iter().find_map(|w| {
if w.widget.id() == id {
Expand All @@ -151,16 +168,46 @@ impl<'a> Tab<'a> {
}
})
}

pub fn on_mouse_event(&mut self, ev: MouseEvent) -> EventResult {
let pos = ev.position();

let active_widget_id = self.active_widget_id().to_string();

let Some((index, id)) = self
.as_mut_widgets()
.iter_mut()
.enumerate()
.find(|(_, w)| w.chunk().contains_point(pos))
.map(|(i, w)| (i, w.id().to_string()) ) else { return EventResult::Ignore };

match ev.kind {
MouseEventKind::Down(MouseButton::Left) => {
if id != active_widget_id {
self.activate_widget_by_id(&id);
}
}
MouseEventKind::Moved => {
self.mouse_over_widget_index = Some(index);
}
_ => {}
}

self.active_widget_mut().on_mouse_event(ev)
}
}

impl Tab<'_> {
pub fn render<B>(&mut self, f: &mut Frame<B>)
where
B: Backend,
{
self.widgets
.iter_mut()
.enumerate()
.for_each(|(i, w)| w.widget.render(f, i == self.active_widget_index));
self.widgets.iter_mut().enumerate().for_each(|(i, w)| {
w.widget.render(
f,
i == self.active_widget_index,
self.mouse_over_widget_index.is_some_and(|idx| idx == i),
)
});
}
}
2 changes: 1 addition & 1 deletion src/ui/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ pub trait WidgetTrait {

#[enum_dispatch]
pub trait RenderTrait {
fn render<B: Backend>(&mut self, f: &mut Frame<B>, is_active: bool);
fn render<B: Backend>(&mut self, f: &mut Frame<B>, is_active: bool, is_mouse_over: bool);
}

#[enum_dispatch(WidgetTrait, RenderTrait)]
Expand Down
14 changes: 7 additions & 7 deletions src/ui/widget/complex/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,22 @@ impl InputForm {
}
}

fn block(&self, selected: bool) -> Block<'static> {
self.widget_config.render_block(selected)
fn block(&self, is_active: bool) -> Block<'static> {
self.widget_config.render_block(is_active, false)
}

pub fn render<B: Backend>(&mut self, f: &mut Frame<B>, selected: bool) {
let spans = self.render_content(selected);
let block = self.block(selected);
pub fn render<B: Backend>(&mut self, f: &mut Frame<B>, is_active: bool) {
let spans = self.render_content(is_active);
let block = self.block(is_active);
let chunk = self.chunk;

let widget = Paragraph::new(spans).block(block);

f.render_widget(widget, chunk);
}

pub fn render_content(&mut self, selected: bool) -> Line<'static> {
if selected {
pub fn render_content(&mut self, is_active: bool) -> Line<'static> {
if is_active {
self.cursor.update_tick();
} else {
self.cursor.mode = Mode::Hide
Expand Down
Loading

0 comments on commit 18f7a3a

Please sign in to comment.