diff --git a/squinnondation/squinnondation.py b/squinnondation/squinnondation.py index d14ad67..387fa6f 100644 --- a/squinnondation/squinnondation.py +++ b/squinnondation/squinnondation.py @@ -50,29 +50,21 @@ class Squinnondation: screen = term_manager.screen screen.addstr(0, 0, "Enter your nickname: ") nickname = screen.getstr().decode("UTF-8") + squirrel = Squirrel(nickname, instance.bind_address, instance.bind_port) + squirrel.refresh_history() + squirrel.refresh_input() if not instance.args.bind_only: hazelnut = Hazelnut(address=instance.client_address, port=instance.client_port) squirrel.hazelnuts[(instance.client_address, instance.client_port)] = hazelnut - squirrel.history = [] - - def refresh() -> None: - screen.clear() - screen.refresh() - for i, msg in enumerate(squirrel.history[max(0, len(squirrel.history) - curses.LINES + 2):]): - screen.addstr(i, 0, msg) - - screen.addstr(curses.LINES - 1, 0, f"<{squirrel.nickname}> ") - screen.refresh() - squirrel.refresh = refresh - Worm(squirrel).start() while True: - refresh() - msg = screen.getstr().decode("UTF-8") + squirrel.refresh_history() + squirrel.refresh_input() + msg = screen.getstr(curses.LINES - 1, 3 + len(squirrel.nickname)).decode("UTF-8") msg = f"<{squirrel.nickname}> {msg}" squirrel.history.append(msg) @@ -387,8 +379,12 @@ class Squirrel(Hazelnut): # Bind the socket self.socket.bind((str(self.address), self.port)) + self.history = [] + self.history_pad = curses.newpad(curses.LINES - 2, curses.COLS) + self.input_pad = curses.newpad(1, curses.COLS) + self.hazelnuts = dict() - print(f"Listening on {self.address}:{self.port}") + self.history.append(f" Listening on {self.address}:{self.port}") def find_hazelnut(self, address: str, port: int) -> Hazelnut: """ @@ -426,6 +422,23 @@ class Squirrel(Hazelnut): """ return self.socket.recvfrom(1024) + def refresh_history(self) -> None: + """ + Rewrite the history of the messages. + """ + self.history_pad.erase() + for i, msg in enumerate(self.history[max(0, len(self.history) - curses.LINES + 2):]): + self.history_pad.addstr(i, 0, msg) + self.history_pad.refresh(0, 0, 0, 0, curses.LINES - 2, curses.COLS) + + def refresh_input(self) -> None: + """ + Redraw input line. Must not be called while the message is not sent. + """ + self.input_pad.erase() + self.input_pad.addstr(0, 0, f"<{self.nickname}> ") + self.input_pad.refresh(0, 0, curses.LINES - 1, 0, curses.LINES - 1, curses.COLS - 1) + class Worm(Thread): """ @@ -438,12 +451,11 @@ class Worm(Thread): self.squirrel = squirrel def run(self) -> None: - self.squirrel.history = [] while True: try: pkt, hazelnut = self.squirrel.receive_packet() except ValueError as error: - print("An error occured while receiving a packet: ", error) + self.squirrel.history.append(" An error occured while receiving a packet: {}".format(error)) else: self.squirrel.history.append(pkt.body[0].data.decode('UTF-8')) - self.squirrel.refresh() + self.squirrel.refresh_history() diff --git a/squinnondation/term_manager.py b/squinnondation/term_manager.py index 1005666..aba856e 100644 --- a/squinnondation/term_manager.py +++ b/squinnondation/term_manager.py @@ -14,12 +14,8 @@ class TermManager: # pragma: no cover self.screen = curses.initscr() # convert escapes sequences to curses abstraction self.screen.keypad(True) - # stop printing typed keys to the terminal - # curses.noecho() - # send keys through without having to press - # curses.cbreak() # make cursor invisible - # curses.curs_set(False) + curses.curs_set(False) # Catch mouse events curses.mousemask(True) # Enable colors @@ -32,7 +28,5 @@ class TermManager: # pragma: no cover exc_traceback: TracebackType) -> None: # restore the terminal to its original state self.screen.keypad(False) - # curses.echo() - # curses.nocbreak() - # curses.curs_set(True) + curses.curs_set(True) curses.endwin()