|
|
@ -25,7 +25,9 @@ const STANDARD_CORNERS: &[(f32, f32); 4] = &[(-0.5, -0.5), (0.5, -0.5), (0.5, 0.
|
|
|
|
pub struct CursorSettings {
|
|
|
|
pub struct CursorSettings {
|
|
|
|
antialiasing: bool,
|
|
|
|
antialiasing: bool,
|
|
|
|
animation_length: f32,
|
|
|
|
animation_length: f32,
|
|
|
|
|
|
|
|
distance_length_adjust: bool,
|
|
|
|
animate_in_insert_mode: bool,
|
|
|
|
animate_in_insert_mode: bool,
|
|
|
|
|
|
|
|
animate_command_line: bool,
|
|
|
|
trail_size: f32,
|
|
|
|
trail_size: f32,
|
|
|
|
vfx_mode: cursor_vfx::VfxMode,
|
|
|
|
vfx_mode: cursor_vfx::VfxMode,
|
|
|
|
vfx_opacity: f32,
|
|
|
|
vfx_opacity: f32,
|
|
|
@ -42,7 +44,9 @@ impl Default for CursorSettings {
|
|
|
|
antialiasing: true,
|
|
|
|
antialiasing: true,
|
|
|
|
animation_length: 0.13,
|
|
|
|
animation_length: 0.13,
|
|
|
|
animate_in_insert_mode: true,
|
|
|
|
animate_in_insert_mode: true,
|
|
|
|
|
|
|
|
animate_command_line: true,
|
|
|
|
trail_size: 0.7,
|
|
|
|
trail_size: 0.7,
|
|
|
|
|
|
|
|
distance_length_adjust: false,
|
|
|
|
vfx_mode: cursor_vfx::VfxMode::Disabled,
|
|
|
|
vfx_mode: cursor_vfx::VfxMode::Disabled,
|
|
|
|
vfx_opacity: 200.0,
|
|
|
|
vfx_opacity: 200.0,
|
|
|
|
vfx_particle_lifetime: 1.2,
|
|
|
|
vfx_particle_lifetime: 1.2,
|
|
|
@ -60,6 +64,7 @@ pub struct Corner {
|
|
|
|
current_position: Point,
|
|
|
|
current_position: Point,
|
|
|
|
relative_position: Point,
|
|
|
|
relative_position: Point,
|
|
|
|
previous_destination: Point,
|
|
|
|
previous_destination: Point,
|
|
|
|
|
|
|
|
length_multiplier: f32,
|
|
|
|
t: f32,
|
|
|
|
t: f32,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -70,6 +75,7 @@ impl Corner {
|
|
|
|
current_position: Point::new(0.0, 0.0),
|
|
|
|
current_position: Point::new(0.0, 0.0),
|
|
|
|
relative_position: Point::new(0.0, 0.0),
|
|
|
|
relative_position: Point::new(0.0, 0.0),
|
|
|
|
previous_destination: Point::new(-1000.0, -1000.0),
|
|
|
|
previous_destination: Point::new(-1000.0, -1000.0),
|
|
|
|
|
|
|
|
length_multiplier: 1.0,
|
|
|
|
t: 0.0,
|
|
|
|
t: 0.0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -86,6 +92,11 @@ impl Corner {
|
|
|
|
self.t = 0.0;
|
|
|
|
self.t = 0.0;
|
|
|
|
self.start_position = self.current_position;
|
|
|
|
self.start_position = self.current_position;
|
|
|
|
self.previous_destination = destination;
|
|
|
|
self.previous_destination = destination;
|
|
|
|
|
|
|
|
self.length_multiplier = if settings.distance_length_adjust {
|
|
|
|
|
|
|
|
(destination - self.current_position).length().log10()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
1.0
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check first if animation's over
|
|
|
|
// Check first if animation's over
|
|
|
@ -135,7 +146,7 @@ impl Corner {
|
|
|
|
(1.0 - settings.trail_size).max(0.0).min(1.0),
|
|
|
|
(1.0 - settings.trail_size).max(0.0).min(1.0),
|
|
|
|
-direction_alignment,
|
|
|
|
-direction_alignment,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
self.t = (self.t + corner_dt / settings.animation_length).min(1.0)
|
|
|
|
self.t = (self.t + corner_dt / (settings.animation_length * self.length_multiplier)).min(1.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
self.current_position = ease_point(
|
|
|
|
self.current_position = ease_point(
|
|
|
@ -155,6 +166,7 @@ pub struct CursorRenderer {
|
|
|
|
destination: Point,
|
|
|
|
destination: Point,
|
|
|
|
blink_status: BlinkStatus,
|
|
|
|
blink_status: BlinkStatus,
|
|
|
|
previous_cursor_shape: Option<CursorShape>,
|
|
|
|
previous_cursor_shape: Option<CursorShape>,
|
|
|
|
|
|
|
|
previous_editor_mode: EditorMode,
|
|
|
|
cursor_vfx: Option<Box<dyn cursor_vfx::CursorVfx>>,
|
|
|
|
cursor_vfx: Option<Box<dyn cursor_vfx::CursorVfx>>,
|
|
|
|
previous_vfx_mode: cursor_vfx::VfxMode,
|
|
|
|
previous_vfx_mode: cursor_vfx::VfxMode,
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -167,6 +179,7 @@ impl CursorRenderer {
|
|
|
|
destination: (0.0, 0.0).into(),
|
|
|
|
destination: (0.0, 0.0).into(),
|
|
|
|
blink_status: BlinkStatus::new(),
|
|
|
|
blink_status: BlinkStatus::new(),
|
|
|
|
previous_cursor_shape: None,
|
|
|
|
previous_cursor_shape: None,
|
|
|
|
|
|
|
|
previous_editor_mode: EditorMode::Normal,
|
|
|
|
cursor_vfx: None,
|
|
|
|
cursor_vfx: None,
|
|
|
|
previous_vfx_mode: cursor_vfx::VfxMode::Disabled,
|
|
|
|
previous_vfx_mode: cursor_vfx::VfxMode::Disabled,
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -213,22 +226,25 @@ impl CursorRenderer {
|
|
|
|
font_width: f32,
|
|
|
|
font_width: f32,
|
|
|
|
font_height: f32,
|
|
|
|
font_height: f32,
|
|
|
|
windows: &HashMap<u64, RenderedWindow>,
|
|
|
|
windows: &HashMap<u64, RenderedWindow>,
|
|
|
|
|
|
|
|
current_mode: &EditorMode,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
let (cursor_grid_x, cursor_grid_y) = self.cursor.grid_position;
|
|
|
|
let (cursor_grid_x, cursor_grid_y) = self.cursor.grid_position;
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(window) = windows.get(&self.cursor.parent_window_id) {
|
|
|
|
if let Some(window) = windows.get(&self.cursor.parent_window_id) {
|
|
|
|
let grid_x = cursor_grid_x as f32 + window.grid_current_position.x;
|
|
|
|
if cursor_grid_y < window.grid_height-1 || matches!(current_mode, EditorMode::CmdLine) {
|
|
|
|
let mut grid_y = cursor_grid_y as f32 + window.grid_current_position.y
|
|
|
|
let grid_x = cursor_grid_x as f32 + window.grid_current_position.x;
|
|
|
|
- (window.current_scroll - window.current_surfaces.top_line);
|
|
|
|
let mut grid_y = cursor_grid_y as f32 + window.grid_current_position.y
|
|
|
|
|
|
|
|
- (window.current_scroll - window.current_surfaces.top_line);
|
|
|
|
// Prevent the cursor from targeting a position outside its current window. Since only
|
|
|
|
|
|
|
|
// the vertical direction is effected by scrolling, we only have to clamp the vertical
|
|
|
|
// Prevent the cursor from targeting a position outside its current window. Since only
|
|
|
|
// grid position.
|
|
|
|
// the vertical direction is effected by scrolling, we only have to clamp the vertical
|
|
|
|
grid_y = grid_y
|
|
|
|
// grid position.
|
|
|
|
.max(window.grid_current_position.y)
|
|
|
|
grid_y = grid_y
|
|
|
|
.min(window.grid_current_position.y + window.grid_height as f32 - 1.0);
|
|
|
|
.max(window.grid_current_position.y)
|
|
|
|
|
|
|
|
.min(window.grid_current_position.y + window.grid_height as f32 - 1.0);
|
|
|
|
self.destination = (grid_x * font_width, grid_y * font_height).into();
|
|
|
|
|
|
|
|
|
|
|
|
self.destination = (grid_x * font_width, grid_y * font_height).into();
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
self.destination = (
|
|
|
|
self.destination = (
|
|
|
|
cursor_grid_x as f32 * font_width,
|
|
|
|
cursor_grid_x as f32 * font_width,
|
|
|
@ -269,6 +285,8 @@ impl CursorRenderer {
|
|
|
|
let font_dimensions: Point = (font_width, font_height).into();
|
|
|
|
let font_dimensions: Point = (font_width, font_height).into();
|
|
|
|
|
|
|
|
|
|
|
|
let in_insert_mode = matches!(current_mode, EditorMode::Insert);
|
|
|
|
let in_insert_mode = matches!(current_mode, EditorMode::Insert);
|
|
|
|
|
|
|
|
let changed_to_from_cmdline = !matches!(self.previous_editor_mode, EditorMode::CmdLine)
|
|
|
|
|
|
|
|
^ matches!(current_mode, EditorMode::CmdLine);
|
|
|
|
|
|
|
|
|
|
|
|
let center_destination = self.destination + font_dimensions * 0.5;
|
|
|
|
let center_destination = self.destination + font_dimensions * 0.5;
|
|
|
|
let new_cursor = Some(self.cursor.shape.clone());
|
|
|
|
let new_cursor = Some(self.cursor.shape.clone());
|
|
|
@ -296,7 +314,8 @@ impl CursorRenderer {
|
|
|
|
font_dimensions,
|
|
|
|
font_dimensions,
|
|
|
|
center_destination,
|
|
|
|
center_destination,
|
|
|
|
dt,
|
|
|
|
dt,
|
|
|
|
!settings.animate_in_insert_mode && in_insert_mode,
|
|
|
|
!settings.animate_in_insert_mode && in_insert_mode
|
|
|
|
|
|
|
|
|| !settings.animate_command_line && !changed_to_from_cmdline,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
animating |= corner_animating;
|
|
|
|
animating |= corner_animating;
|
|
|
@ -313,6 +332,8 @@ impl CursorRenderer {
|
|
|
|
|
|
|
|
|
|
|
|
if animating {
|
|
|
|
if animating {
|
|
|
|
REDRAW_SCHEDULER.queue_next_frame();
|
|
|
|
REDRAW_SCHEDULER.queue_next_frame();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
self.previous_editor_mode = current_mode.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if self.cursor.enabled && render {
|
|
|
|
if self.cursor.enabled && render {
|
|
|
|