зеркало из
https://github.com/glebtv/tui-textarea.git
synced 2026-09-07 16:05:50 +03:00
smoothly slide the line number part into screen on scrolling left
Этот коммит содержится в:
@@ -80,14 +80,18 @@ impl Viewport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TextArea<'a> {
|
#[inline]
|
||||||
fn lnum_width(&self) -> u8 {
|
fn next_scroll_top(prev_top: u16, cursor: u16, len: u16) -> u16 {
|
||||||
if self.line_number_style().is_none() {
|
if cursor < prev_top {
|
||||||
return 0;
|
cursor
|
||||||
}
|
} else if prev_top + len <= cursor {
|
||||||
num_digits(self.lines().len()) + 2
|
cursor + 1 - len
|
||||||
|
} else {
|
||||||
|
prev_top
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TextArea<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn text_widget(&'a self, top_row: usize, height: usize) -> Text<'a> {
|
fn text_widget(&'a self, top_row: usize, height: usize) -> Text<'a> {
|
||||||
let lines_len = self.lines().len();
|
let lines_len = self.lines().len();
|
||||||
@@ -106,6 +110,24 @@ impl<'a> TextArea<'a> {
|
|||||||
let text = Span::raw(self.placeholder.as_str());
|
let text = Span::raw(self.placeholder.as_str());
|
||||||
Text::from(Line::from(vec![cursor, text]))
|
Text::from(Line::from(vec![cursor, text]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn scroll_top_row(&self, prev_top: u16, height: u16) -> u16 {
|
||||||
|
next_scroll_top(prev_top, self.cursor().0 as u16, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn scroll_top_col(&self, prev_top: u16, width: u16) -> u16 {
|
||||||
|
let mut cursor = self.cursor().1 as u16;
|
||||||
|
if self.line_number_style().is_some() {
|
||||||
|
// Adjust the cursor position due to the width of line number. `+ 2` for margins
|
||||||
|
let lnum = num_digits(self.lines().len()) as u16 + 2;
|
||||||
|
if cursor <= lnum {
|
||||||
|
cursor *= 2; // Smoothly slide the line number into the screen on scrolling left
|
||||||
|
} else {
|
||||||
|
cursor += lnum; // The cursor position is shifted by the line number part
|
||||||
|
};
|
||||||
|
}
|
||||||
|
next_scroll_top(prev_top, cursor, width)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for &TextArea<'_> {
|
impl Widget for &TextArea<'_> {
|
||||||
@@ -116,21 +138,9 @@ impl Widget for &TextArea<'_> {
|
|||||||
area
|
area
|
||||||
};
|
};
|
||||||
|
|
||||||
fn next_scroll_top(prev_top: u16, cursor: u16, length: u16) -> u16 {
|
|
||||||
if cursor < prev_top {
|
|
||||||
cursor
|
|
||||||
} else if prev_top + length <= cursor {
|
|
||||||
cursor + 1 - length
|
|
||||||
} else {
|
|
||||||
prev_top
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let cursor = self.cursor();
|
|
||||||
let (top_row, top_col) = self.viewport.scroll_top();
|
let (top_row, top_col) = self.viewport.scroll_top();
|
||||||
let top_row = next_scroll_top(top_row, cursor.0 as u16, height);
|
let top_row = self.scroll_top_row(top_row, height);
|
||||||
let scroll_width = width.saturating_sub(self.lnum_width() as _);
|
let top_col = self.scroll_top_col(top_col, width);
|
||||||
let top_col = next_scroll_top(top_col, cursor.1 as u16, scroll_width);
|
|
||||||
|
|
||||||
let (text, style) = if !self.placeholder.is_empty() && self.is_empty() {
|
let (text, style) = if !self.placeholder.is_empty() && self.is_empty() {
|
||||||
(self.placeholder_widget(), self.placeholder_style)
|
(self.placeholder_widget(), self.placeholder_style)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user