from abc import ABC, abstractmethod from adapter import CursesAdapter import mvc.models from mystring import MyString as MyString class Observer(ABC): @abstractmethod def Update(self) -> None: pass class VimView(Observer): def __init__(self, adapter: CursesAdapter) -> None: self.curses_adapter = adapter self.model = None def SetModel(self, model: mvc.models.VimModel) -> None: self.model = model model.attach(self) def Update(self) -> None: self.Render( self.model.displayBuffer, self.model.currentLine, self.model.currentCol, self.model.scrollX, self.model.scrollY, self.model.ModeBar(), self.model.showLineNumbers ) def Render(self, displayBuffer: list[MyString], currentLine: int, currentCol: int, scrollX: int, scrollY: int, modeBarData: str, show_line_numbers: bool = False) -> None: """Отрисовка текущего состояния""" self.curses_adapter.screen.clear() # Ширина нумерации строк (6 символов + 1 пробел) line_number_width = 7 if show_line_numbers else 0 # Отображение видимой части текста for i in range(self.curses_adapter.lines - 1): if i + scrollY < len(displayBuffer): line = displayBuffer[i + scrollY].data() # Если нужно отображать номера строк, добавляем их перед текстом if show_line_numbers: line_number = f"{i + scrollY + 1:6} " # 6 символов на номер строки # Выводим номер строки фиолетовым цветом self.curses_adapter.SetColorString(i, 0, line_number, self.curses_adapter.colorPairs[0]) # Выводим текст с учетом прокрутки и ширины нумерации visible_text_start = scrollX # Начало видимой части текста visible_text_end = scrollX + self.curses_adapter.cols - line_number_width # Конец видимой части текста visible_text = line[visible_text_start:visible_text_end] self.curses_adapter.SetString(i, line_number_width, visible_text) else: self.curses_adapter.SetString(i, 0, '') # Обновление панели режима self.SetModeBar(modeBarData) # Установка курсора с учетом прокрутки и нумерации строк cursor_x = currentLine - scrollY cursor_y = currentCol - scrollX + line_number_width # Проверка, чтобы курсор не вышел за пределы экрана if 0 <= cursor_x < self.curses_adapter.lines - 1 and 0 <= cursor_y < self.curses_adapter.cols: self.curses_adapter.SetCursor(cursor_x, cursor_y) self.curses_adapter.Refresh() def SetModeBar(self, modeBarData: str) -> None: """Print edit mode information panel""" if len(modeBarData) > self.curses_adapter.cols - 1: scrollX = len(modeBarData) - self.curses_adapter.cols self.curses_adapter.SetColorString(self.curses_adapter.lines - 1, 0, modeBarData[scrollX + 1:], self.curses_adapter.colorPairs[1]) else: self.curses_adapter.SetColorString(self.curses_adapter.lines - 1, 0, modeBarData, self.curses_adapter.colorPairs[1])