Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add double and triple click selection #295

46 changes: 18 additions & 28 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod opts;
mod panic_hook;
pub mod positioner;
pub mod renderer;
pub mod selection;
pub mod table;
pub mod test_utils;
pub mod text;
Expand Down Expand Up @@ -56,6 +57,7 @@ use tracing_subscriber::util::SubscriberInitExt;
use utils::{ImageCache, Point, Rect, Size};

use crate::opts::{Commands, ConfigCmd, MetricsExporter};
use crate::selection::Selection;
use anyhow::Context;
use clap::Parser;
use taffy::Taffy;
Expand Down Expand Up @@ -147,6 +149,7 @@ pub struct Inlyne {
keycombos: KeyCombos,
need_repositioning: bool,
watcher: Watcher,
selection: Selection,
}

impl Inlyne {
Expand Down Expand Up @@ -221,6 +224,7 @@ impl Inlyne {
keycombos,
need_repositioning: false,
watcher,
selection: Selection::new(),
})
}

Expand Down Expand Up @@ -280,9 +284,7 @@ impl Inlyne {
let mut scrollbar_held = None;
let mut mouse_down = false;
let mut modifiers = ModifiersState::empty();
let mut last_loc = (0.0, 0.0);
let mut selection_cache = String::new();
let mut selecting = false;
let mut mouse_position: Point = Point::default();
kokoISnoTarget marked this conversation as resolved.
Show resolved Hide resolved

let event_loop = self.event_loop.take().unwrap();
let event_loop_proxy = event_loop.create_proxy();
Expand Down Expand Up @@ -330,12 +332,9 @@ impl Inlyne {
);
self.renderer.set_scroll_y(self.renderer.scroll_y);
self.renderer
.redraw(&mut self.elements)
.redraw(&mut self.elements, &mut self.selection)
.context("Renderer failed to redraw the screen")
.unwrap();
if selecting {
selection_cache.clone_from(&self.renderer.selection_text);
}

histogram!(HistTag::Redraw).record(redraw_start.elapsed());
}
Expand Down Expand Up @@ -426,34 +425,24 @@ impl Inlyne {
* self.renderer.positioner.reserved_height;
self.renderer.set_scroll_y(target_scroll);
self.window.request_redraw();
} else if let Some(selection) = &mut self.renderer.selection {
if mouse_down {
selection.1 = loc;
selecting = true;
self.window.request_redraw();
}
} else if mouse_down && self.selection.handle_drag(loc) {
self.window.request_redraw();
}
last_loc = loc;
mouse_position = loc;
}
WindowEvent::MouseInput {
state,
button: MouseButton::Left,
..
} => match state {
ElementState::Pressed => {
// Reset selection
if self.renderer.selection.is_some() {
self.renderer.selection = None;
self.window.request_redraw();
}

// Try to click a link
let screen_size = self.renderer.screen_size();
if let Some(hoverable) = Self::find_hoverable(
&mut self.renderer.text_system,
&mut self.renderer.positioner.taffy,
&self.elements,
last_loc,
mouse_position,
screen_size,
self.renderer.zoom,
) {
Expand Down Expand Up @@ -504,20 +493,21 @@ impl Inlyne {
event_loop_proxy
.send_event(InlyneEvent::Reposition)
.unwrap();
self.renderer.selection = Some((last_loc, last_loc))
self.selection.add_position(mouse_position);
},
_ => self.renderer.selection = Some((last_loc, last_loc)),
_ => {
self.selection.add_position(mouse_position);
self.window.request_redraw();
}
};
} else if self.renderer.selection.is_none() {
self.renderer.selection = Some((last_loc, last_loc));
} else {
self.selection.add_position(mouse_position);
}

mouse_down = true;
}
ElementState::Released => {
scrollbar_held = None;
mouse_down = false;
selecting = false;
}
},
WindowEvent::ModifiersChanged(new_state) => modifiers = new_state,
Expand Down Expand Up @@ -587,7 +577,7 @@ impl Inlyne {
self.window.request_redraw();
}
Action::Copy => clipboard
.set_contents(selection_cache.trim().to_owned()),
.set_contents(self.selection.text.trim().to_owned()),
Action::Quit => *control_flow = ControlFlow::Exit,
Action::History(hist_dir) => {
let changed_path = match hist_dir {
Expand Down
80 changes: 37 additions & 43 deletions src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ use crate::image::ImageRenderer;
use crate::metrics::{histogram, HistTag};
use crate::opts::FontOptions;
use crate::positioner::{Positioned, Positioner, DEFAULT_MARGIN};
use crate::selection::Selection;
use crate::table::TABLE_ROW_GAP;
use crate::text::{CachedTextArea, TextCache, TextSystem};
use crate::utils::{Point, Rect, Selection, Size};
use crate::utils::{Point, Rect, Size};
use crate::Element;

use anyhow::{Context, Ok};
Expand Down Expand Up @@ -45,8 +46,6 @@ pub struct Renderer {
pub page_width: f32,
pub image_renderer: ImageRenderer,
pub theme: Theme,
pub selection: Option<Selection>,
pub selection_text: String,
pub zoom: f32,
pub positioner: Positioner,
}
Expand Down Expand Up @@ -186,8 +185,6 @@ impl Renderer {
zoom: 1.,
image_renderer,
theme,
selection: None,
selection_text: String::new(),
positioner,
})
}
Expand All @@ -211,6 +208,7 @@ impl Renderer {
fn render_elements(
&mut self,
elements: &[Positioned<Element>],
selection: &mut Selection,
) -> anyhow::Result<Vec<CachedTextArea>> {
let mut text_areas: Vec<CachedTextArea> = Vec::new();
let screen_size = self.screen_size();
Expand Down Expand Up @@ -337,16 +335,13 @@ impl Renderer {
let max = (line.max.0, line.max.1 + 2. * self.hidpi_scale * self.zoom);
self.draw_rectangle(Rect::from_min_max(min, max), line.color)?;
}
if let Some(selection) = self.selection {
let (selection_rects, selection_text) = text_box.render_selection(
&mut self.text_system,
pos,
bounds,
self.zoom,
selection,
);
self.selection_text.push_str(&selection_text);
self.selection_text.push('\n');
if let Some(selection_rects) = text_box.render_selection(
&mut self.text_system,
pos,
bounds,
self.zoom,
selection,
) {
for rect in selection_rects {
self.draw_rectangle(
Rect::from_min_max(
Expand Down Expand Up @@ -379,16 +374,13 @@ impl Renderer {
self.zoom,
self.scroll_y,
));
if let Some(selection) = self.selection {
let (selection_rects, selection_text) = text_box.render_selection(
&mut self.text_system,
(pos.0 + node.location.x, pos.1 + node.location.y),
(node.size.width, node.size.height),
self.zoom,
selection,
);
self.selection_text.push_str(&selection_text);
self.selection_text.push('\n');
if let Some(selection_rects) = text_box.render_selection(
&mut self.text_system,
(pos.0 + node.location.x, pos.1 + node.location.y),
(node.size.width, node.size.height),
self.zoom,
selection,
) {
for rect in selection_rects {
self.draw_rectangle(
Rect::from_min_max(
Expand Down Expand Up @@ -442,17 +434,13 @@ impl Renderer {
self.scroll_y,
));

if let Some(selection) = self.selection {
let (selection_rects, selection_text) = text_box
.render_selection(
&mut self.text_system,
(pos.0 + node.location.x, pos.1 + node.location.y),
(node.size.width, node.size.height),
self.zoom,
selection,
);
self.selection_text.push_str(&selection_text);
self.selection_text.push('\n');
if let Some(selection_rects) = text_box.render_selection(
&mut self.text_system,
(pos.0 + node.location.x, pos.1 + node.location.y),
(node.size.width, node.size.height),
self.zoom,
selection,
) {
for rect in selection_rects {
self.draw_rectangle(
Rect::from_min_max(
Expand Down Expand Up @@ -512,7 +500,9 @@ impl Renderer {
)?;
}
}
Element::Row(row) => text_areas.append(&mut self.render_elements(&row.elements)?),
Element::Row(row) => {
text_areas.append(&mut self.render_elements(&row.elements, selection)?)
}
Element::Section(section) => {
if let Some(ref summary) = *section.summary {
let bounds = summary.bounds.as_ref().unwrap();
Expand All @@ -525,15 +515,16 @@ impl Renderer {
native_color(self.theme.text_color, &self.surface_format),
*section.hidden.borrow(),
)?;
text_areas.append(&mut self.render_elements(std::slice::from_ref(summary))?)
text_areas.append(
&mut self.render_elements(std::slice::from_ref(summary), selection)?,
)
}
if !*section.hidden.borrow() {
text_areas.append(&mut self.render_elements(&section.elements)?)
text_areas.append(&mut self.render_elements(&section.elements, selection)?)
}
}
}
}

self.draw_scrollbar()?;
Ok(text_areas)
}
Expand Down Expand Up @@ -721,7 +712,11 @@ impl Renderer {
bind_groups
}

pub fn redraw(&mut self, elements: &mut [Positioned<Element>]) -> anyhow::Result<()> {
pub fn redraw(
&mut self,
elements: &mut [Positioned<Element>],
selection: &mut Selection,
) -> anyhow::Result<()> {
let frame = self
.surface
.get_current_texture()
Expand All @@ -736,8 +731,7 @@ impl Renderer {
// Prepare and render elements that use lyon
self.lyon_buffer.indices.clear();
self.lyon_buffer.vertices.clear();
self.selection_text = String::new();
let cached_text_areas = self.render_elements(elements)?;
let cached_text_areas = self.render_elements(elements, selection)?;
let vertex_buf = self
.device
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
Expand Down
Loading