scroll_controller.rs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. use crate::errors::*;
  2. use crate::{buffer::Buffer, view::terminal::Terminal};
  3. use std::sync::Arc;
  4. /// 对于滚动操作的抽象对象
  5. ///
  6. /// 外部通过line_offset方法获取滚动后buffer的offset
  7. pub struct ScrollController {
  8. terminal: Arc<Box<dyn Terminal>>,
  9. line_offset: usize,
  10. }
  11. impl ScrollController {
  12. pub fn new(terminal: Arc<Box<dyn Terminal>>, init_line_index: usize) -> ScrollController {
  13. ScrollController {
  14. terminal,
  15. line_offset: init_line_index,
  16. }
  17. }
  18. // 若将buffer指针指向的行滚动到显示区域顶部
  19. pub fn scroll_into_monitor(&mut self, buffer: &Buffer) -> Result<()> {
  20. let terminal_height = self.terminal.height()? - 1;
  21. if self.line_offset > buffer.cursor.line {
  22. self.line_offset = buffer.cursor.line;
  23. } else if self.line_offset + terminal_height - 1 < buffer.cursor.line {
  24. self.line_offset = buffer.cursor.line - terminal_height + 1;
  25. }
  26. Ok(())
  27. }
  28. // 将buffer指针指向的行滚动到显示区域中间区域
  29. pub fn scroll_to_center(&mut self, buffer: &Buffer) -> Result<()> {
  30. self.line_offset = buffer
  31. .cursor
  32. .line
  33. .saturating_sub(self.terminal.height()?.saturating_div(2));
  34. Ok(())
  35. }
  36. // 向上滚动n行
  37. pub fn scroll_up(&mut self, line_count: usize) {
  38. self.line_offset = self.line_offset.saturating_sub(line_count);
  39. }
  40. // 向下滚动n行
  41. pub fn scroll_down(&mut self, line_count: usize) {
  42. self.line_offset = self.line_offset.saturating_add(line_count);
  43. }
  44. // 返回当前的offset
  45. pub fn line_offset(&mut self) -> usize {
  46. self.line_offset
  47. }
  48. }