Better terminal refresh
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
This commit is contained in:
		@@ -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"<system> 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("<system> 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()
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <enter>
 | 
			
		||||
        # 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()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user