diff --git a/core/src/command.rs b/core/src/command.rs index c0844cde..b6588563 100644 --- a/core/src/command.rs +++ b/core/src/command.rs @@ -226,7 +226,9 @@ pub enum LapceUICommand { UpdateLineChanges(BufferId), ReloadBuffer(BufferId, u64, String), EnsureVisible((Rect, (f64, f64), Option)), + EnsureRectVisible(Rect), EnsureCursorVisible, + EnsureCursorCenter, EditorViewSize(Size), Scroll((f64, f64)), ScrollTo((f64, f64)), diff --git a/core/src/data.rs b/core/src/data.rs index 5aaf9de6..173b7eab 100644 --- a/core/src/data.rs +++ b/core/src/data.rs @@ -13,7 +13,7 @@ use crossbeam_utils::sync::WaitGroup; use druid::{ theme, Color, Command, Data, Env, EventCtx, ExtEventSink, FontDescriptor, - FontFamily, KeyEvent, Lens, Rect, Size, Target, Vec2, WidgetId, WindowId, + FontFamily, KeyEvent, Lens, Point, Rect, Size, Target, Vec2, WidgetId, WindowId, }; use im; use parking_lot::Mutex; @@ -572,10 +572,10 @@ pub struct LapceEditorViewData { } impl LapceEditorViewData { - pub fn key_down(&mut self, ctx: &mut EventCtx, key_event: &KeyEvent) { + pub fn key_down(&mut self, ctx: &mut EventCtx, key_event: &KeyEvent, env: &Env) { let mut keypress = self.keypress.clone(); let k = Arc::make_mut(&mut keypress); - k.key_down(ctx, key_event, self); + k.key_down(ctx, key_event, self, env); self.keypress = keypress; } @@ -666,6 +666,32 @@ fn toggle_visual(&mut self, visual_mode: VisualMode) { } } + fn page_move(&mut self, ctx: &mut EventCtx, down: bool, env: &Env) { + let line_height = env.get(LapceTheme::EDITOR_LINE_HEIGHT); + let lines = (self.editor.size.height / line_height / 2.0).round() as usize; + let offset = self.editor.cursor.offset(); + let (offset, horiz) = self.buffer.move_offset( + offset, + self.editor.cursor.horiz.as_ref(), + lines, + if down { &Movement::Down } else { &Movement::Up }, + false, + false, + ); + self.set_cursor(Cursor::new(CursorMode::Normal(offset), Some(horiz))); + let rect = Rect::ZERO + .with_origin( + self.editor.scroll_offset.to_point() + + Vec2::new(0.0, (lines as f64) * line_height), + ) + .with_size(self.editor.size.clone()); + ctx.submit_command(Command::new( + LAPCE_UI_COMMAND, + LapceUICommand::EnsureRectVisible(rect), + Target::Widget(self.editor.editor_id), + )); + } + pub fn do_move(&mut self, movement: &Movement, count: usize) { match &self.editor.cursor.mode { &CursorMode::Normal(offset) => { @@ -860,6 +886,7 @@ fn run_command( ctx: &mut EventCtx, cmd: &LapceCommand, count: Option, + env: &Env, ) { if let Some(movement) = self.move_command(count, cmd) { self.do_move(&movement, count.unwrap_or(1)); @@ -1111,6 +1138,12 @@ fn run_command( LapceCommand::ToggleBlockwiseVisualMode => { self.toggle_visual(VisualMode::Blockwise); } + LapceCommand::PageDown => { + self.page_move(ctx, true, env); + } + LapceCommand::PageUp => { + self.page_move(ctx, false, env); + } LapceCommand::NormalMode => { let offset = match &self.editor.cursor.mode { CursorMode::Insert(selection) => { diff --git a/core/src/editor.rs b/core/src/editor.rs index dd4b4483..da21cb40 100644 --- a/core/src/editor.rs +++ b/core/src/editor.rs @@ -263,6 +263,12 @@ pub fn handle_lapce_ui_command( LapceUICommand::EnsureCursorVisible => { self.ensure_cursor_visible(ctx, data, env); } + LapceUICommand::EnsureCursorCenter => { + self.ensure_cursor_center(ctx, data, env); + } + LapceUICommand::EnsureRectVisible(rect) => { + self.ensure_rect_visible(ctx, data, *rect, env); + } LapceUICommand::UpdateSize => { Arc::make_mut(&mut data.editor).size = self.editor.widget().child_size(); @@ -283,6 +289,52 @@ pub fn handle_lapce_ui_command( } } + pub fn ensure_cursor_center( + &mut self, + ctx: &mut EventCtx, + data: &LapceEditorViewData, + env: &Env, + ) { + let rect = data + .cusor_region(env) + .inflate(0.0, (data.editor.size.height / 2.0).ceil()); + if self + .editor + .widget_mut() + .child_mut() + .inner_mut() + .scroll_to_visible(rect) + { + ctx.submit_command(Command::new( + LAPCE_UI_COMMAND, + LapceUICommand::ResetFade, + Target::Widget(self.scroll_id), + )); + } + } + + pub fn ensure_rect_visible( + &mut self, + ctx: &mut EventCtx, + data: &LapceEditorViewData, + rect: Rect, + env: &Env, + ) { + if self + .editor + .widget_mut() + .child_mut() + .inner_mut() + .scroll_to_visible(rect) + { + ctx.submit_command(Command::new( + LAPCE_UI_COMMAND, + LapceUICommand::ResetFade, + Target::Widget(self.scroll_id), + )); + } + } + pub fn ensure_cursor_visible( &mut self, ctx: &mut EventCtx, @@ -325,7 +377,7 @@ fn event( } } Event::KeyDown(key_event) => { - data.key_down(ctx, key_event); + data.key_down(ctx, key_event, env); self.ensure_cursor_visible(ctx, data, env); ctx.set_handled(); } diff --git a/core/src/keypress.rs b/core/src/keypress.rs index 74757fad..22e13f67 100644 --- a/core/src/keypress.rs +++ b/core/src/keypress.rs @@ -52,6 +52,7 @@ fn run_command( ctx: &mut EventCtx, command: &LapceCommand, count: Option, + env: &Env, ); fn insert(&mut self, ctx: &mut EventCtx, c: &str); } @@ -78,9 +79,10 @@ fn run_command( command: &str, count: Option, focus: &mut T, + env: &Env, ) -> Result<()> { let cmd = LapceCommand::from_str(command)?; - focus.run_command(ctx, &cmd, count); + focus.run_command(ctx, &cmd, count, env); Ok(()) } @@ -109,6 +111,7 @@ pub fn key_down( ctx: &mut EventCtx, key_event: &KeyEvent, focus: &mut T, + env: &Env, ) { if key_event.key == KbKey::Shift { return; @@ -139,7 +142,7 @@ pub fn key_down( match keymatch { KeymapMatch::Full(command) => { let count = self.count.take(); - self.run_command(ctx, &command, count, focus); + self.run_command(ctx, &command, count, focus, env); self.pending_keypress = Vec::new(); return; }