From 99b685a7086a11abb3c37e6f6f062078d02edf4a Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 6 May 2022 22:10:08 +0100 Subject: [PATCH] scroll when drag in the editor --- lapce-data/src/data.rs | 77 ++++++++++--------------------- lapce-ui/src/editor.rs | 92 +++++++++++++++++++++++++++++++++---- lapce-ui/src/editor/view.rs | 10 ++++ 3 files changed, 118 insertions(+), 61 deletions(-) diff --git a/lapce-data/src/data.rs b/lapce-data/src/data.rs index cd26931c..5cdd705a 100644 --- a/lapce-data/src/data.rs +++ b/lapce-data/src/data.rs @@ -16,8 +16,13 @@ }; use lapce_core::{ - command::MultiSelectionCommand, editor::EditType, mode::MotionMode, - movement::Movement, register::Register, selection::Selection, + command::MultiSelectionCommand, + cursor::{Cursor, CursorMode}, + editor::EditType, + mode::MotionMode, + movement::Movement, + register::Register, + selection::Selection, }; use lapce_rpc::{ file::FileNodeItem, plugin::PluginDescription, source_control::FileDiff, @@ -1439,16 +1444,12 @@ pub fn run_workbench_command( .get_mut(&self.source_control.editor_view_id) .unwrap(); Arc::make_mut(editor).new_cursor = if self.config.lapce.modal { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Normal(0), - None, - None, - ) + Cursor::new(CursorMode::Normal(0), None, None) } else { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Insert( - lapce_core::selection::Selection::caret(0), - ), + Cursor::new( + CursorMode::Insert(lapce_core::selection::Selection::caret( + 0, + )), None, None, ) @@ -1711,20 +1712,16 @@ pub fn set_picker_pwd(&mut self, pwd: PathBuf) { .unwrap(); let editor = Arc::make_mut(editor); editor.new_cursor = if self.config.lapce.modal { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Normal( - doc.buffer().line_end_offset(0, false), - ), + Cursor::new( + CursorMode::Normal(doc.buffer().line_end_offset(0, false)), None, None, ) } else { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Insert( - lapce_core::selection::Selection::caret( - doc.buffer().line_end_offset(0, true), - ), - ), + Cursor::new( + CursorMode::Insert(Selection::caret( + doc.buffer().line_end_offset(0, true), + )), None, None, ) @@ -2400,19 +2397,9 @@ pub fn go_to_location( editor.content = BufferContent::File(path.clone()); editor.compare = location.history.clone(); editor.new_cursor = if config.lapce.modal { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Normal(offset), - None, - None, - ) + Cursor::new(CursorMode::Normal(offset), None, None) } else { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Insert( - lapce_core::selection::Selection::caret(offset), - ), - None, - None, - ) + Cursor::new(CursorMode::Insert(Selection::caret(offset)), None, None) }; if let Some(scroll_offset) = scroll_offset { @@ -2972,7 +2959,7 @@ pub struct LapceEditorData { pub compare: Option, pub code_lens: bool, pub scroll_offset: Vec2, - pub new_cursor: lapce_core::cursor::Cursor, + pub new_cursor: Cursor, pub size: Rc>, pub window_origin: Rc>, pub snippet: Option>, @@ -3003,27 +2990,11 @@ pub fn new( }, scroll_offset: Vec2::ZERO, new_cursor: if content.is_input() { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Insert( - lapce_core::selection::Selection::caret(0), - ), - None, - None, - ) + Cursor::new(CursorMode::Insert(Selection::caret(0)), None, None) } else if config.lapce.modal { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Normal(0), - None, - None, - ) + Cursor::new(CursorMode::Normal(0), None, None) } else { - lapce_core::cursor::Cursor::new( - lapce_core::cursor::CursorMode::Insert( - lapce_core::selection::Selection::caret(0), - ), - None, - None, - ) + Cursor::new(CursorMode::Insert(Selection::caret(0)), None, None) }, content, size: Rc::new(RefCell::new(Size::ZERO)), diff --git a/lapce-ui/src/editor.rs b/lapce-ui/src/editor.rs index ffc28bbe..bceb4efe 100644 --- a/lapce-ui/src/editor.rs +++ b/lapce-ui/src/editor.rs @@ -69,6 +69,7 @@ pub struct LapceEditor { /// A timer for listening for when the user has hovered for long enough to trigger showing /// of hover info (if there is any) mouse_hover_timer: TimerToken, + drag_timer: TimerToken, } impl LapceEditor { @@ -79,38 +80,96 @@ pub fn new(view_id: WidgetId) -> Self { last_left_click: None, mouse_pos: Point::ZERO, mouse_hover_timer: TimerToken::INVALID, + drag_timer: TimerToken::INVALID, + } + } + + fn mouse_drag( + &mut self, + ctx: &mut EventCtx, + editor_data: &LapceEditorBufferData, + config: &Config, + ) { + if !ctx.is_active() { + return; + } + + let line_height = config.editor.line_height as f64; + let scroll_offset = editor_data.editor.scroll_offset; + let size = *editor_data.editor.size.borrow(); + + let y_distance_1 = self.mouse_pos.y - scroll_offset.y; + let y_distance_2 = scroll_offset.y + size.height - self.mouse_pos.y; + + let y_diff = if y_distance_1 < line_height { + let shift = if y_distance_1 > 0.0 { + y_distance_1 + } else { + 0.0 + }; + -line_height + shift + } else if y_distance_2 < line_height { + let shift = if y_distance_2 > 0.0 { + y_distance_2 + } else { + 0.0 + }; + line_height - shift + } else { + 0.0 + }; + + let x_diff = if self.mouse_pos.x < editor_data.editor.scroll_offset.x { + -5.0 + } else if self.mouse_pos.x + > editor_data.editor.scroll_offset.x + + editor_data.editor.size.borrow().width + { + 5.0 + } else { + 0.0 + }; + + if x_diff != 0.0 || y_diff != 0.0 { + ctx.submit_command(Command::new( + LAPCE_UI_COMMAND, + LapceUICommand::Scroll((x_diff, y_diff)), + Target::Widget(editor_data.view_id), + )); + + self.drag_timer = ctx.request_timer(Duration::from_millis(16)); } } fn mouse_move( &mut self, ctx: &mut EventCtx, - mouse_event: &MouseEvent, + mouse_pos: Point, editor_data: &mut LapceEditorBufferData, config: &Config, ) { - self.mouse_pos = mouse_event.pos; + self.mouse_pos = mouse_pos; self.mouse_hover_timer = TimerToken::INVALID; + self.mouse_drag(ctx, editor_data, config); + if ctx.is_active() { let (new_offset, _) = editor_data.doc.offset_of_point( ctx.text(), editor_data.get_mode(), - mouse_event.pos, + mouse_pos, config.editor.font_size, config, ); let editor = Arc::make_mut(&mut editor_data.editor); - editor - .new_cursor - .set_offset(new_offset, true, mouse_event.mods.alt()); + editor.new_cursor.set_offset(new_offset, true, false); return; } let (offset, is_inside) = editor_data.doc.offset_of_point( ctx.text(), Mode::Insert, - mouse_event.pos, + mouse_pos, config.editor.font_size, config, ); @@ -1637,7 +1696,12 @@ fn event( let editor = data.main_split.editors.get(&self.view_id).unwrap().clone(); let mut editor_data = data.editor_view_content(self.view_id); - self.mouse_move(ctx, mouse_event, &mut editor_data, &data.config); + self.mouse_move( + ctx, + mouse_event.pos, + &mut editor_data, + &data.config, + ); data.update_from_editor_buffer_data(editor_data, &editor, &doc); } Event::MouseUp(_mouse_event) => { @@ -1666,6 +1730,18 @@ fn event( ); editor_data.update_hover(ctx, offset); data.update_from_editor_buffer_data(editor_data, &editor, &doc); + } else if self.drag_timer == *id { + let doc = data.main_split.editor_doc(self.view_id); + let editor = + data.main_split.editors.get(&self.view_id).unwrap().clone(); + let mut editor_data = data.editor_view_content(self.view_id); + self.mouse_move( + ctx, + self.mouse_pos, + &mut editor_data, + &data.config, + ); + data.update_from_editor_buffer_data(editor_data, &editor, &doc); } } _ => (), diff --git a/lapce-ui/src/editor/view.rs b/lapce-ui/src/editor/view.rs index 8d3e6ccf..da7fb5bf 100644 --- a/lapce-ui/src/editor/view.rs +++ b/lapce-ui/src/editor/view.rs @@ -202,6 +202,16 @@ pub fn handle_lapce_ui_command( .widget_mut() .inner_mut() .scroll_by(Vec2::new(*x, *y)); + let offset = self.editor.widget().editor.widget().inner().offset(); + if data.editor.scroll_offset != offset { + self.editor + .widget_mut() + .editor + .widget_mut() + .inner_mut() + .child_mut() + .mouse_pos += offset - data.editor.scroll_offset; + } ctx.submit_command(Command::new( LAPCE_UI_COMMAND, LapceUICommand::ResetFade,