VIM-like-text-editor/mvc/controllers.py

97 lines
4.0 KiB
Python

from abc import ABC, abstractmethod
from mvc.views import CursesAdapter
from mvc.models import VimModel, ReturnCode
def isAscii(symbolCode: int) -> bool:
if symbolCode > 126 or symbolCode < 32: return False
else: return True
class Strategy(ABC):
def __init__(self, model: VimModel, adapter: CursesAdapter, mode: str):
self.model = model
self.adapter = adapter
self.mode = model.mode = mode
def isAscii(symbolCode: int) -> bool:
if symbolCode > 126 or symbolCode < 32: return False
else: return True
@abstractmethod
def HandleInput(self, symbolCode: int) -> int:
pass
class Controller:
def __init__(self, strategy: Strategy):
self.strategy = strategy
def SetStrategy(self, strategy: Strategy):
self.strategy = strategy
def HandleInput(self, symbolCode: int):
return self.strategy.HandleInput(symbolCode)
class CommandStrategy(Strategy):
"""Режим ввода коман"""
def __init__(self, model: VimModel, adapter: CursesAdapter):
super().__init__(model, adapter, mode="COMMAND")
def HandleInput(self, symbolCode) -> int:
"""Обработка ввода пользователя"""
match symbolCode:
case self.adapter.KEY_ESCAPE: return ReturnCode.SET_BASIC_MODE
case self.adapter.KEY_LEFT: self.model.MoveLeft()
case self.adapter.KEY_RIGHT: self.model.MoveRight()
case self.adapter.KEY_UP: self.model.MoveUp()
case self.adapter.KEY_DOWN: self.model.MoveDown()
case self.adapter.KEY_CTRL_S: self.model.SaveFile()
case self.adapter.KEY_ENTER: return self.model.EnterCommand()
case self.adapter.KEY_BACKSPACE_1: self.model.BackspaceCommand()
case self.adapter.KEY_BACKSPACE_2: self.model.BackspaceCommand()
case _:
if not isAscii(symbolCode): return ReturnCode.GOOD
self.model.InsertCommandSymbol(symbolCode)
self.model.Scroll(self.adapter.lines, self.adapter.cols)
return ReturnCode.GOOD
class EditStrategy(Strategy):
"""Режим редактирования"""
def __init__(self, model: VimModel, adapter: CursesAdapter):
super().__init__(model, adapter, mode="EDIT")
def HandleInput(self, symbolCode) -> int:
"""Обработка ввода пользователя"""
match symbolCode:
case self.adapter.KEY_ESCAPE: return ReturnCode.SET_BASIC_MODE
case self.adapter.KEY_LEFT: self.model.MoveLeft()
case self.adapter.KEY_RIGHT: self.model.MoveRight()
case self.adapter.KEY_UP: self.model.MoveUp()
case self.adapter.KEY_DOWN: self.model.MoveDown()
case self.adapter.KEY_ENTER: self.model.Enter()
case self.adapter.KEY_BACKSPACE_1: self.model.Backspace()
case self.adapter.KEY_BACKSPACE_2: self.model.Backspace()
case self.adapter.KEY_CTRL_S: self.model.SaveFile()
case _:
if not isAscii(symbolCode): return ReturnCode.GOOD
self.model.InsertSymbol(symbolCode)
self.model.Scroll(self.adapter.lines, self.adapter.cols)
return ReturnCode.GOOD
class NormalStrategy(Strategy):
"""Режим навигации"""
def __init__(self, model: VimModel, adapter: CursesAdapter):
super().__init__(model, adapter, mode="NORMAL")
def HandleInput(self, symbolCode) -> int:
"""Обработка ввода пользователя"""
match symbolCode:
case self.adapter.KEY_LEFT: self.model.MoveLeft()
case self.adapter.KEY_RIGHT: self.model.MoveRight()
case self.adapter.KEY_UP: self.model.MoveUp()
case self.adapter.KEY_DOWN: self.model.MoveDown()
case self.adapter.KEY_CTRL_S: self.model.SaveFile()
case self.adapter.KEY_TWO_DOTS: return ReturnCode.SET_COMMAND_MODE
self.model.Scroll(self.adapter.lines, self.adapter.cols)
return ReturnCode.GOOD