Skip to content

Commit

Permalink
Let selection update while scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
misson20000 committed Apr 28, 2024
1 parent 1fd28b6 commit ba07e81
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 47 deletions.
59 changes: 41 additions & 18 deletions src/view/listing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub struct PickResult {
#[derive(Default)]
pub struct ListingWidgetImp {
interior: once_cell::unsync::OnceCell<sync::Arc<parking_lot::RwLock<Interior>>>,
should_repick: sync::atomic::AtomicBool,
}

#[glib::object_subclass]
Expand Down Expand Up @@ -363,6 +364,9 @@ impl ListingWidget {
lw.imp().interior.get().unwrap().write().drag_update(&lw, &ecs, dx, dy);
ecs.set_state(gtk::EventSequenceState::Claimed);
}));
ec_select.connect_drag_end(clone!(@weak self as lw => move |ecs, dx, dy| {
lw.imp().interior.get().unwrap().write().drag_end(&lw, &ecs, dx, dy);
}));
ec_select.set_button(1);
ec_select.set_exclusive(true);
self.add_controller(ec_select.clone());
Expand Down Expand Up @@ -406,7 +410,7 @@ impl ListingWidget {
interior.cursor.goto(document.clone(), path, offset).expect("lost cursor");
interior.scroll.ensure_cursor_is_in_view(&mut interior.window, &mut interior.cursor, facet::scroll::EnsureCursorInViewDirection::Any)
}

fn document_updated(&self, new_document: &sync::Arc<document::Document>) {
let mut interior = self.imp().interior.get().unwrap().write();
interior.document_updated(new_document);
Expand Down Expand Up @@ -548,6 +552,10 @@ impl Interior {
self.scroll.animate(&mut self.window, &self.cursor, delta);

self.collect_events(widget);

if widget.imp().should_repick.swap(false, sync::atomic::Ordering::Relaxed) {
self.update_rubber_band_from_hover();
}

self.last_frame = frame_time;

Expand Down Expand Up @@ -601,7 +609,7 @@ impl Interior {

fn scroll(&mut self, widget: &ListingWidget, _dx: f64, dy: f64) -> glib::Propagation {
self.scroll.scroll_wheel_impulse(dy);

self.collect_events(widget);

glib::Propagation::Stop
Expand All @@ -626,25 +634,40 @@ impl Interior {
widget.queue_draw();
}

fn drag_update(&mut self, widget: &ListingWidget, gesture: &gtk::GestureDrag, dx: f64, dy: f64) {
if let (Some(rbb), Some((x, y))) = (&self.rubber_band_begin, gesture.start_point()) {
if let Some(rbe) = self.pick(x+dx, y+dy) {
match self.selection_host.change(selection::listing::Change::AssignStructure(PickResult::to_structure_selection(&self.document, rbb, &rbe))) {
Ok(new_selection) => { self.selection_updated(&new_selection); },
Err((error, attempted_version)) => { self.charm_window.upgrade().map(|window| window.report_error(error::Error {
while_attempting: error::Action::RubberBandSelection,
trouble: error::Trouble::ListingSelectionUpdateFailure {
error,
attempted_version,
},
level: error::Level::Warning,
is_bug: true,
})); }
}
fn update_rubber_band_from_hover(&mut self) {
if let Some((x, y)) = self.hover {
self.update_rubber_band(x, y);
}
}

fn update_rubber_band(&mut self, x: f64, y: f64) {
if let (Some(rbb), Some(rbe)) = (&self.rubber_band_begin, self.pick(x, y)) {
match self.selection_host.change(selection::listing::Change::AssignStructure(PickResult::to_structure_selection(&self.document, rbb, &rbe))) {
Ok(new_selection) => {
self.selection_updated(&new_selection);
},
Err((error, attempted_version)) => { self.charm_window.upgrade().map(|window| window.report_error(error::Error {
while_attempting: error::Action::RubberBandSelection,
trouble: error::Trouble::ListingSelectionUpdateFailure {
error,
attempted_version,
},
level: error::Level::Warning,
is_bug: true,
})); }
}
}
}

fn drag_update(&mut self, widget: &ListingWidget, gesture: &gtk::GestureDrag, dx: f64, dy: f64) {
if let Some((x, y)) = gesture.start_point() {
self.update_rubber_band(x+dx, y+dy);
widget.queue_draw();
}
}

widget.queue_draw();
fn drag_end(&mut self, _widget: &ListingWidget, _gesture: &gtk::GestureDrag, _dx: f64, _dy: f64) {
self.rubber_band_begin = None;
}

fn hover(&mut self, widget: &ListingWidget, hover: Option<(f64, f64)>) {
Expand Down
15 changes: 2 additions & 13 deletions src/view/listing/facet/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::view::config;
use crate::view::listing::facet;

use std::sync;
use std::task;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Mode {
Expand All @@ -24,7 +23,6 @@ pub struct CursorView {

config: sync::Arc<config::Config>,
ev_draw: facet::Event,
ev_work: facet::Event,

blink_timer: f64,
bonk_timer: f32,
Expand All @@ -38,7 +36,6 @@ impl std::fmt::Debug for CursorView {
.field("has_focus", &self.has_focus)
.field("insert", &self.insert)
.field("ev_draw", &self.ev_draw)
.field("ev_work", &self.ev_work)
.field("blink_timer", &self.blink_timer)
.field("bonk_timer", &self.bonk_timer)
.finish_non_exhaustive()
Expand All @@ -55,7 +52,6 @@ impl CursorView {

config,
ev_draw: facet::Event::new(),
ev_work: facet::Event::new(),

blink_timer: 0.0,
bonk_timer: 0.0,
Expand Down Expand Up @@ -173,14 +169,7 @@ impl CursorView {
}

impl facet::Facet for CursorView {
fn wants_draw(&mut self) -> &mut facet::Event {
&mut self.ev_draw
}

fn wants_work(&mut self) -> &mut facet::Event {
&mut self.ev_work
}

fn work(&mut self, _doc: &sync::Arc<document::Document>, _cx: &mut task::Context) {
fn wants_draw(&self) -> &facet::Event {
&self.ev_draw
}
}
37 changes: 29 additions & 8 deletions src/view/listing/facet/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
use std::sync;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::task;

use crate::model::document;
use crate::util;

use gtk::subclass::prelude::*;
use gtk::prelude::*;

pub mod scroll;
pub mod cursor;

pub trait Facet {
fn wants_draw(&mut self) -> &mut Event;
fn wants_work(&mut self) -> &mut Event;
fn wants_draw(&self) -> &Event {
&UNUSED_EVENT
}

fn wants_work(&self) -> &Event {
&UNUSED_EVENT
}

fn wants_repick(&self) -> &Event {
&UNUSED_EVENT
}

fn work(&mut self, _document: &sync::Arc<document::Document>, _cx: &mut task::Context) {
}

Expand All @@ -23,32 +36,40 @@ pub trait Facet {
if self.wants_work().collect() {
work_notifier.notify();
}

if self.wants_repick().collect() {
widget.imp().should_repick.store(true, Ordering::Relaxed);
}
}
}

#[derive(Debug)]
pub struct Event {
wanted: bool,
wanted: AtomicBool,
}

impl Event {
pub fn new() -> Event {
Event {
wanted: false,
wanted: AtomicBool::new(false),
}
}

pub fn new_wanted() -> Event {
Event {
wanted: true,
wanted: AtomicBool::new(true),
}
}

pub fn want(&mut self) {
self.wanted = true;
self.wanted.store(true, Ordering::Relaxed);
}

pub fn collect(&mut self) -> bool {
std::mem::replace(&mut self.wanted, false)
pub fn collect(&self) -> bool {
self.wanted.swap(false, Ordering::Relaxed)
}
}

static UNUSED_EVENT: Event = Event {
wanted: AtomicBool::new(false),
};
14 changes: 10 additions & 4 deletions src/view/listing/facet/scroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct Scroller {
config: sync::Arc<config::Config>,
ev_draw: facet::Event,
ev_work: facet::Event,
ev_repick: facet::Event,

position: f64,
velocity: f64,
Expand All @@ -30,6 +31,7 @@ impl Scroller {
config,
ev_draw: facet::Event::new(),
ev_work: facet::Event::new(),
ev_repick: facet::Event::new(),

position: 0.0,
velocity: 0.0,
Expand Down Expand Up @@ -157,6 +159,7 @@ impl Scroller {
self.position+= self.velocity * delta;

if f64::abs(self.velocity) > 0.01 {
self.ev_repick.want();
self.ev_draw.want();
} else {
self.velocity = 0.0;
Expand Down Expand Up @@ -269,12 +272,15 @@ impl EnsureCursorInViewDirection {
}

impl facet::Facet for Scroller {
fn wants_draw(&mut self) -> &mut facet::Event {
&mut self.ev_draw
fn wants_draw(&self) -> &facet::Event {
&self.ev_draw
}

fn wants_work(&self) -> &facet::Event {
&self.ev_work
}

fn wants_work(&mut self) -> &mut facet::Event {
&mut self.ev_work
fn wants_repick(&self) -> &facet::Event {
&self.ev_repick
}
}
8 changes: 4 additions & 4 deletions src/view/listing/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,12 @@ impl Line {
}

impl facet::Facet for Line {
fn wants_draw(&mut self) -> &mut facet::Event {
&mut self.ev_draw
fn wants_draw(&self) -> &facet::Event {
&self.ev_draw
}

fn wants_work(&mut self) -> &mut facet::Event {
&mut self.ev_work
fn wants_work(&self) -> &facet::Event {
&self.ev_work
}

fn work(&mut self, document: &sync::Arc<document::Document>, cx: &mut task::Context) {
Expand Down

0 comments on commit ba07e81

Please sign in to comment.