From ee2337591c8e2aa67ef03bfca98179d3779275f9 Mon Sep 17 00:00:00 2001 From: serr Date: Tue, 11 Feb 2025 16:13:36 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B2=D1=8B=D0=B4=D0=B5=D0=BB=D0=B8=D0=BB=20ad?= =?UTF-8?q?apter=20=D0=B2=20=D0=BE=D1=82=D0=B5=D0=B4=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- adapter.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 3 +- mvc/models.py | 12 +++++++ mvc/views.py | 79 ++++---------------------------------------- 4 files changed, 112 insertions(+), 73 deletions(-) create mode 100644 adapter.py diff --git a/adapter.py b/adapter.py new file mode 100644 index 0000000..c3ed7f3 --- /dev/null +++ b/adapter.py @@ -0,0 +1,91 @@ +from abc import ABC, abstractmethod +import curses + +class IController(ABC): + @abstractmethod + def GetChar(self) -> int: + pass + +class IView(ABC): + @abstractmethod + def Refresh(self) -> None: + pass + @abstractmethod + def Cleanup(self) -> None: + pass + @abstractmethod + def SetCursor(self, x: int, y: int) -> None: + pass + @abstractmethod + def SetChar(self, x: int, y: int, code: int) -> None: + pass + @abstractmethod + def SetColorString(self, x: int, y: int, data: str, attr: int) -> None: + pass + @abstractmethod + def SetString(self, x: int, y: int, data: str) -> None: + pass + +class CursesAdapter(IView, IController): + def __init__(self) -> None: + self.KEY_BACKSPACE_2 = 8 + self.KEY_ENTER = 10 + self.KEY_CTRL_S = 19 + self.KEY_ESCAPE = 27 + self.KEY_DOLLAR = 36 + self.KEY_NULL = 48 + self.KEY_TWO_DOTS = 59 + self.KEY_G = 71 + self.KEY_XOR = 94 + self.KEY_b = 98 + self.KEY_d = 100 + self.KEY_g = 103 + self.KEY_p = 112 + self.KEY_w = 119 + self.KEY_x = 120 + self.KEY_y = 121 + self.KEY_BACKSPACE_1 = 127 + self.KEY_LEFT = curses.KEY_LEFT + self.KEY_RIGHT = curses.KEY_RIGHT + self.KEY_UP = curses.KEY_UP + self.KEY_DOWN = curses.KEY_DOWN + self.KEY_PG_UP = 451 + self.KEY_PG_DOWN = 457 + + + self.screen = curses.initscr() + self.screen.keypad(True) + self.cols = curses.COLS + self.lines = curses.LINES + curses.noecho() + curses.curs_set(1) # Make cursor visible + curses.start_color() + curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK) # Фиолетовый текст на черном фоне + curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLUE) # Фиолетовый текст на черном фоне + self.colorPairs = [curses.color_pair(1), curses.color_pair(2)] + + def Refresh(self) -> None: + """Apply changes""" + self.screen.refresh() + + def Cleanup(self) -> None: + curses.endwin() + + def SetCursor(self, x: int, y: int) -> None: + """set cursor position (x, y)""" + self.screen.move(x, y) + + def SetChar(self, x: int, y: int, code: int) -> None: + """set char position (x, y)""" + self.screen.addch(x, y, code) + + def SetColorString(self, x: int, y: int, data: str, attr: int) -> None: + self.screen.addstr(x, y, data, attr) + + def SetString(self, x: int, y: int, data: str) -> None: + """set string begin position (x, y)""" + self.screen.addstr(x, y, data) + + def GetChar(self) -> int: + """Wait users input""" + return self.screen.getch() \ No newline at end of file diff --git a/main.py b/main.py index ac9ed7b..a40eae5 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,7 @@ import sys from mvc.models import VimModel -from mvc.views import VimView, CursesAdapter +from mvc.views import VimView +from adapter import CursesAdapter from mvc.controllers import Controller, ReturnCode from mvc.controllers import EditStrategy, CommandStrategy, NormalStrategy import tools diff --git a/mvc/models.py b/mvc/models.py index cee9cdd..259bc3f 100644 --- a/mvc/models.py +++ b/mvc/models.py @@ -1,3 +1,4 @@ +from abc import ABC, abstractmethod import tools from enum import Enum from typing import List @@ -12,6 +13,17 @@ class ReturnCode(Enum): SET_EDIT_MODE = -97 CONTINUE = -96 +class Observable(ABC): + @abstractmethod + def attach(self, observer): + pass + @abstractmethod + def detach(self, observer): + pass + @abstractmethod + def notify(self): + pass + class VimModel: observers: List displayLinesCount: int diff --git a/mvc/views.py b/mvc/views.py index 4e5b0c6..7f7ebe6 100644 --- a/mvc/views.py +++ b/mvc/views.py @@ -1,76 +1,11 @@ from abc import ABC, abstractmethod -import curses +from adapter import CursesAdapter import mvc.models from mystring import MyString as MyString - - -class CursesAdapter: - def __init__(self) -> None: - self.KEY_BACKSPACE_2 = 8 - self.KEY_ENTER = 10 - self.KEY_CTRL_S = 19 - self.KEY_ESCAPE = 27 - self.KEY_DOLLAR = 36 - self.KEY_NULL = 48 - self.KEY_TWO_DOTS = 59 - self.KEY_G = 71 - self.KEY_XOR = 94 - self.KEY_b = 98 - self.KEY_d = 100 - self.KEY_g = 103 - self.KEY_p = 112 - self.KEY_w = 119 - self.KEY_x = 120 - self.KEY_y = 121 - self.KEY_BACKSPACE_1 = 127 - self.KEY_LEFT = curses.KEY_LEFT - self.KEY_RIGHT = curses.KEY_RIGHT - self.KEY_UP = curses.KEY_UP - self.KEY_DOWN = curses.KEY_DOWN - self.KEY_PG_UP = 451 - self.KEY_PG_DOWN = 457 - - - self.screen = curses.initscr() - self.screen.keypad(True) - self.cols = curses.COLS - self.lines = curses.LINES - curses.noecho() - curses.curs_set(1) # Make cursor visible - curses.start_color() - curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK) # Фиолетовый текст на черном фоне - curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLUE) # Фиолетовый текст на черном фоне - self.colorPairs = [curses.color_pair(1), curses.color_pair(2)] - - def Refresh(self) -> None: - """Apply changes""" - self.screen.refresh() - - def Cleanup(self) -> None: - curses.endwin() - - def SetCursor(self, x: int, y: int): - """set cursor position (x, y)""" - self.screen.move(x, y) - - def SetChar(self, x: int, y: int, code: int): - """set char position (x, y)""" - self.screen.addch(x, y, code) - - def SetColorString(self, x: int, y: int, data: str, attr: int): - self.screen.addstr(x, y, data, attr) - - def SetString(self, x: int, y: int, data: str): - """set string begin position (x, y)""" - self.screen.addstr(x, y, data) - - def GetChar(self) -> int: - """Wait users input""" - return self.screen.getch() -class Observer: +class Observer(ABC): @abstractmethod - def Update(self): + def Update(self) -> None: pass class VimView(Observer): @@ -78,11 +13,11 @@ class VimView(Observer): self.curses_adapter = adapter self.model = None - def SetModel(self, model: mvc.models.VimModel): + def SetModel(self, model: mvc.models.VimModel) -> None: self.model = model model.attach(self) - def Update(self): + def Update(self) -> None: self.Render( self.model.displayBuffer, self.model.currentLine, @@ -98,7 +33,7 @@ class VimView(Observer): currentLine: int, currentCol: int, scrollX: int, scrollY: int, modeBarData: str, - show_line_numbers: bool = False): + show_line_numbers: bool = False) -> None: """Отрисовка текущего состояния""" self.curses_adapter.screen.clear() @@ -137,7 +72,7 @@ class VimView(Observer): self.curses_adapter.Refresh() - def SetModeBar(self, modeBarData: str): + 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