documents and editor: typewriter room at both ends, open blocks scaled, a resize re-centers
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
508fee9d15
commit
f102ea0b6c
6 files changed
+189
-14
No files matched your search
@@ -100,6 +100,8 @@ pub(crate) struct Metrics {
|
||||
pub top: Pixels,
|
||||
pub advance: Pixels,
|
||||
pub line: Pixels,
|
||||
/// The view's height, under any typewriter room.
|
||||
pub height: Pixels,
|
||||
}
|
||||
|
||||
const BLINK: Duration = Duration::from_millis(530);
|
||||
@@ -122,6 +124,8 @@ pub struct CodeEditor {
|
||||
pub(crate) metrics: Metrics,
|
||||
/// The caret row typewriter scrolling last centered.
|
||||
pub(crate) centered: Option<usize>,
|
||||
/// Typewriter room past each end, as last drawn.
|
||||
pub(crate) room: Pixels,
|
||||
pub(crate) dragging: bool,
|
||||
pub(crate) caret_on: bool,
|
||||
/// Blink runs only while focused, or unseen cursors redraw forever.
|
||||
@@ -208,6 +212,7 @@ impl CodeEditor {
|
||||
composing: None,
|
||||
metrics: Metrics::default(),
|
||||
centered: None,
|
||||
room: Pixels::ZERO,
|
||||
dragging: false,
|
||||
caret_on: true,
|
||||
focused: false,
|
||||
|
||||
+24
-4
@@ -54,7 +54,8 @@ impl CodeEditor {
|
||||
|
||||
/// The first line the list shows, after scrolling.
|
||||
pub(crate) fn top_line(&self) -> Option<usize> {
|
||||
let scrolled = -self.scroll.0.borrow().base_handle.offset().y;
|
||||
// Typewriter room above the first line is no line.
|
||||
let scrolled = -self.scroll.0.borrow().base_handle.offset().y - self.room;
|
||||
let first = (scrolled / self.frame.line).floor().max(0.0) as usize;
|
||||
self.frame.rows[first.min(self.frame.rows.len().saturating_sub(1))..]
|
||||
.iter()
|
||||
@@ -270,6 +271,13 @@ impl Render for CodeEditor {
|
||||
.scroll_to_item_strict(row, ScrollStrategy::Center);
|
||||
self.centered = Some(row);
|
||||
}
|
||||
// Half a view of room: a resize keeps the center.
|
||||
let height = self.metrics.height;
|
||||
self.room = match self.options.typewriter {
|
||||
true => height / 2.0,
|
||||
false => gpui::px(0.0),
|
||||
};
|
||||
let room = self.room;
|
||||
let sticky = if self.options.sticky {
|
||||
self.sticky(cx)
|
||||
} else {
|
||||
@@ -284,7 +292,9 @@ impl Render for CodeEditor {
|
||||
}),
|
||||
)
|
||||
.track_scroll(&self.scroll)
|
||||
.size_full();
|
||||
.size_full()
|
||||
.pt(room)
|
||||
.pb(room);
|
||||
let (top, focus, input) = (cx.entity(), self.focus.clone(), cx.entity());
|
||||
let unlock = cx.entity();
|
||||
let banner = self.options.read_only.then(|| {
|
||||
@@ -303,12 +313,22 @@ impl Render for CodeEditor {
|
||||
.relative()
|
||||
.flex_1()
|
||||
.h_full()
|
||||
.min_h_0()
|
||||
.child(list)
|
||||
.children(sticky)
|
||||
.child(
|
||||
canvas(
|
||||
move |bounds, _, cx| {
|
||||
top.update(cx, |editor, _| editor.metrics.top = bounds.origin.y);
|
||||
move |bounds, window, cx| {
|
||||
let resized = top.update(cx, |editor, _| {
|
||||
editor.metrics.top = bounds.origin.y;
|
||||
let resized = editor.metrics.height != bounds.size.height;
|
||||
editor.metrics.height = bounds.size.height;
|
||||
resized
|
||||
});
|
||||
// A new height centers the caret again.
|
||||
if resized {
|
||||
window.request_animation_frame();
|
||||
}
|
||||
},
|
||||
|_, _, _, _| {},
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user