HUGE performance improvement on refresh. fixed #1855
This commit is contained in:
parent
24d6894b64
commit
0db8bf7d46
5 changed files with 161 additions and 109 deletions
|
@ -40,6 +40,7 @@ log = logging.getLogger(__name__)
|
|||
|
||||
import multiuserchat as muc
|
||||
import tabs
|
||||
import windows
|
||||
|
||||
from connection import connection
|
||||
from config import config
|
||||
|
@ -83,6 +84,8 @@ class Core(object):
|
|||
self.stdscr = curses.initscr()
|
||||
self.init_curses(self.stdscr)
|
||||
self.xmpp = xmpp
|
||||
self.information_buffer = TextBuffer()
|
||||
self.information_win_size = 0 # Todo, get this from config
|
||||
default_tab = tabs.InfoTab(self, "Info") if self.xmpp.anon\
|
||||
else tabs.RosterInfoTab(self)
|
||||
default_tab.on_gain_focus()
|
||||
|
@ -90,8 +93,7 @@ class Core(object):
|
|||
# a unique buffer used to store global informations
|
||||
# that are displayed in almost all tabs, in an
|
||||
# information window.
|
||||
self.information_buffer = TextBuffer()
|
||||
self.information_win_size = 2 # Todo, get this from config
|
||||
|
||||
self.resize_timer = None
|
||||
self.previous_tab_nb = 0
|
||||
self.own_nick = config.get('own_nick', self.xmpp.boundjid.bare)
|
||||
|
@ -548,7 +550,6 @@ class Core(object):
|
|||
Resize the whole screen
|
||||
"""
|
||||
with resize_lock:
|
||||
# self.resize_timer = None
|
||||
for tab in self.tabs:
|
||||
tab.resize()
|
||||
self.refresh_window()
|
||||
|
@ -1225,6 +1226,7 @@ class Core(object):
|
|||
Displays an informational message in the "Info" room window
|
||||
"""
|
||||
self.information_buffer.add_message(msg, nickname=typ)
|
||||
# TODO: refresh only the correct window in the current tab
|
||||
self.refresh_window()
|
||||
|
||||
def command_quit(self, arg):
|
||||
|
|
17
src/room.py
17
src/room.py
|
@ -14,7 +14,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from text_buffer import TextBuffer
|
||||
from text_buffer import TextBuffer, MESSAGE_NB_LIMIT
|
||||
from datetime import datetime
|
||||
from random import randrange
|
||||
from config import config
|
||||
|
@ -25,8 +25,6 @@ import common
|
|||
import theme
|
||||
|
||||
class Room(TextBuffer):
|
||||
"""
|
||||
"""
|
||||
def __init__(self, name, nick):
|
||||
TextBuffer.__init__(self)
|
||||
self.name = name
|
||||
|
@ -118,6 +116,13 @@ class Room(TextBuffer):
|
|||
if time: # History messages are colored to be distinguished
|
||||
color = theme.COLOR_INFORMATION_TEXT
|
||||
time = time if time is not None else datetime.now()
|
||||
if self.pos: # avoid scrolling of one line when one line is received
|
||||
self.pos += 1
|
||||
self.messages.append(Message(txt, time, nickname, user, color, colorized))
|
||||
message = Message(txt, time, nickname, user, color, colorized)
|
||||
while len(self.messages) > MESSAGE_NB_LIMIT:
|
||||
self.messages.pop(0)
|
||||
self.messages.append(message)
|
||||
for window in self.windows: # make the associated windows
|
||||
# build the lines from the new message
|
||||
nb = window.build_new_message(message)
|
||||
if window.pos != 0:
|
||||
window.scroll_up(nb)
|
||||
|
||||
|
|
42
src/tabs.py
42
src/tabs.py
|
@ -199,6 +199,7 @@ class InfoTab(Tab):
|
|||
self.tab_win.resize(1, self.width, self.height-2, 0, self.core.stdscr)
|
||||
self.tab_win.resize(1, self.width, self.height-2, 0, self.core.stdscr)
|
||||
self.text_win.resize(self.height-2, self.width, 0, 0, self.core.stdscr)
|
||||
self.text_win.rebuild_everything(self._room)
|
||||
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
|
||||
|
||||
def refresh(self, tabs, informations, _):
|
||||
|
@ -308,10 +309,12 @@ class MucTab(ChatTab):
|
|||
ChatTab.__init__(self, core, room)
|
||||
self.topic_win = windows.Topic()
|
||||
self.text_win = windows.TextWin()
|
||||
room.add_window(self.text_win)
|
||||
self.v_separator = windows.VerticalSeparator()
|
||||
self.user_win = windows.UserList()
|
||||
self.info_header = windows.MucInfoWin()
|
||||
self.info_win = windows.TextWin()
|
||||
self.core.information_buffer.add_window(self.info_win)
|
||||
self.tab_win = windows.GlobalInfoBar()
|
||||
self.input = windows.MessageInput()
|
||||
self.ignores = [] # set of Users
|
||||
|
@ -485,10 +488,11 @@ class MucTab(ChatTab):
|
|||
text_width = (self.width//10)*9
|
||||
self.topic_win.resize(1, self.width, 0, 0, self.core.stdscr)
|
||||
self.text_win.resize(self.height-4-self.core.information_win_size, text_width, 1, 0, self.core.stdscr)
|
||||
self.text_win.rebuild_everything(self._room)
|
||||
self.v_separator.resize(self.height-3, 1, 1, 9*(self.width//10), self.core.stdscr)
|
||||
self.user_win.resize(self.height-3, self.width-text_width-1, 1, text_width+1, self.core.stdscr)
|
||||
self.info_header.resize(1, (self.width//10)*9, self.height-3-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, (self.width//10)*9, self.height-2-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, (self.width//10)*9, self.height-2-self.core.information_win_size, 0, self.core.stdscr, self.core.information_buffer)
|
||||
self.tab_win.resize(1, self.width, self.height-2, 0, self.core.stdscr)
|
||||
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
|
||||
|
||||
|
@ -499,9 +503,9 @@ class MucTab(ChatTab):
|
|||
self.text_win.refresh(self._room)
|
||||
self.v_separator.refresh()
|
||||
self.user_win.refresh(self._room.users)
|
||||
self.info_header.refresh(self._room)
|
||||
self.info_win.refresh(informations)
|
||||
self.info_header.refresh(self._room, self.text_win)
|
||||
self.tab_win.refresh(tabs, tabs[0])
|
||||
self.info_win.refresh(informations)
|
||||
self.input.refresh()
|
||||
|
||||
def on_input(self, key):
|
||||
|
@ -549,10 +553,10 @@ class MucTab(ChatTab):
|
|||
curses.curs_set(1)
|
||||
|
||||
def on_scroll_up(self):
|
||||
self._room.scroll_up(self.text_win.height-1)
|
||||
self.text_win.scroll_up(self.text_win.height-1)
|
||||
|
||||
def on_scroll_down(self):
|
||||
self._room.scroll_down(self.text_win.height-1)
|
||||
self.text_win.scroll_down(self.text_win.height-1)
|
||||
|
||||
def on_info_win_size_changed(self):
|
||||
text_width = (self.width//10)*9
|
||||
|
@ -573,8 +577,10 @@ class PrivateTab(ChatTab):
|
|||
def __init__(self, core, room):
|
||||
ChatTab.__init__(self, core, room)
|
||||
self.text_win = windows.TextWin()
|
||||
room.add_window(self.text_win)
|
||||
self.info_header = windows.PrivateInfoWin()
|
||||
self.info_win = windows.TextWin()
|
||||
self.core.information_buffer.add_window(self.info_win)
|
||||
self.tab_win = windows.GlobalInfoBar()
|
||||
self.input = windows.MessageInput()
|
||||
# keys
|
||||
|
@ -601,8 +607,9 @@ class PrivateTab(ChatTab):
|
|||
def resize(self):
|
||||
Tab.resize(self)
|
||||
self.text_win.resize(self.height-3-self.core.information_win_size, self.width, 0, 0, self.core.stdscr)
|
||||
self.text_win.rebuild_everything(self._room)
|
||||
self.info_header.resize(1, self.width, self.height-3-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, self.core.stdscr, self.core.information_buffer)
|
||||
self.tab_win.resize(1, self.width, self.height-2, 0, self.core.stdscr)
|
||||
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
|
||||
|
||||
|
@ -610,7 +617,7 @@ class PrivateTab(ChatTab):
|
|||
if not self.visible:
|
||||
return
|
||||
self.text_win.refresh(self._room)
|
||||
self.info_header.refresh(self._room)
|
||||
self.info_header.refresh(self._room, self.text_win)
|
||||
self.info_win.refresh(informations)
|
||||
self.tab_win.refresh(tabs, tabs[0])
|
||||
self.input.refresh()
|
||||
|
@ -644,15 +651,15 @@ class PrivateTab(ChatTab):
|
|||
curses.curs_set(1)
|
||||
|
||||
def on_scroll_up(self):
|
||||
self._room.scroll_up(self.text_win.height-1)
|
||||
self.text_win.scroll_up(self.text_win.height-1)
|
||||
|
||||
def on_scroll_down(self):
|
||||
self._room.scroll_down(self.text_win.height-1)
|
||||
self.text_win.scroll_down(self.text_win.height-1)
|
||||
|
||||
def on_info_win_size_changed(self):
|
||||
self.text_win.resize(self.height-3-self.core.information_win_size, self.width, 0, 0, self.core.stdscr)
|
||||
self.info_header.resize(1, self.width, self.height-3-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, self.core.stdscr, None)
|
||||
|
||||
def get_room(self):
|
||||
return self._room
|
||||
|
@ -673,6 +680,7 @@ class RosterInfoTab(Tab):
|
|||
self.v_separator = windows.VerticalSeparator()
|
||||
self.tab_win = windows.GlobalInfoBar()
|
||||
self.info_win = windows.TextWin()
|
||||
self.core.information_buffer.add_window(self.info_win)
|
||||
self.roster_win = windows.RosterWin()
|
||||
self.contact_info_win = windows.ContactInfoWin()
|
||||
self.default_help_message = windows.HelpText("Enter commands with “/”. “o”: toggle offline show")
|
||||
|
@ -696,7 +704,7 @@ class RosterInfoTab(Tab):
|
|||
info_width = self.width-roster_width-1
|
||||
self.v_separator.resize(self.height-2, 1, 0, roster_width, self.core.stdscr)
|
||||
self.tab_win.resize(1, self.width, self.height-2, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.height-2, info_width, 0, roster_width+1, self.core.stdscr)
|
||||
self.info_win.resize(self.height-2, info_width, 0, roster_width+1, self.core.stdscr, self.core.information_buffer)
|
||||
self.roster_win.resize(self.height-2-3, roster_width, 0, 0, self.core.stdscr)
|
||||
self.contact_info_win.resize(3, roster_width, self.height-2-3, 0, self.core.stdscr)
|
||||
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
|
||||
|
@ -706,13 +714,14 @@ class RosterInfoTab(Tab):
|
|||
if isinstance(self.input, windows.CommandInput) and\
|
||||
not self.input.help_message:
|
||||
self.complete_commands(self.input)
|
||||
|
||||
|
||||
def refresh(self, tabs, informations, roster):
|
||||
if not self.visible:
|
||||
return
|
||||
self.v_separator.refresh()
|
||||
self.roster_win.refresh(roster)
|
||||
self.contact_info_win.refresh(self.roster_win.get_selected_row())
|
||||
# self.core.global_information_win.refresh(informations)
|
||||
self.info_win.refresh(informations)
|
||||
self.tab_win.refresh(tabs, tabs[0])
|
||||
self.input.refresh()
|
||||
|
@ -840,9 +849,11 @@ class ConversationTab(ChatTab):
|
|||
self.color_state = theme.COLOR_TAB_NORMAL
|
||||
self._name = jid # a conversation tab is linked to one specific full jid OR bare jid
|
||||
self.text_win = windows.TextWin()
|
||||
text_buffer.add_window(self.text_win)
|
||||
self.upper_bar = windows.ConversationStatusMessageWin()
|
||||
self.info_header = windows.ConversationInfoWin()
|
||||
self.info_win = windows.TextWin()
|
||||
self.core.information_buffer.add_window(self.info_win)
|
||||
self.tab_win = windows.GlobalInfoBar()
|
||||
self.input = windows.MessageInput()
|
||||
# keys
|
||||
|
@ -869,9 +880,10 @@ class ConversationTab(ChatTab):
|
|||
def resize(self):
|
||||
Tab.resize(self)
|
||||
self.text_win.resize(self.height-3-self.core.information_win_size, self.width, 1, 0, self.core.stdscr)
|
||||
self.text_win.rebuild_everything(self._room)
|
||||
self.upper_bar.resize(1, self.width, 0, 0, self.core.stdscr)
|
||||
self.info_header.resize(1, self.width, self.height-3-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, self.core.stdscr)
|
||||
self.info_win.resize(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, self.core.stdscr, self.core.information_buffer)
|
||||
self.tab_win.resize(1, self.width, self.height-2, 0, self.core.stdscr)
|
||||
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
|
||||
|
||||
|
@ -914,10 +926,10 @@ class ConversationTab(ChatTab):
|
|||
curses.curs_set(1)
|
||||
|
||||
def on_scroll_up(self):
|
||||
self._room.scroll_up(self.text_win.height-1)
|
||||
self.text_win.scroll_up(self.text_win.height-1)
|
||||
|
||||
def on_scroll_down(self):
|
||||
self._room.scroll_down(self.text_win.height-1)
|
||||
self.text_win.scroll_down(self.text_win.height-1)
|
||||
|
||||
def on_info_win_size_changed(self):
|
||||
self.text_win.resize(self.height-3-self.core.information_win_size, self.width, 0, 0, self.core.stdscr)
|
||||
|
|
|
@ -18,10 +18,15 @@
|
|||
Define the TextBuffer class
|
||||
"""
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
from message import Message
|
||||
from datetime import datetime
|
||||
import theme
|
||||
|
||||
MESSAGE_NB_LIMIT = 16384
|
||||
|
||||
class TextBuffer(object):
|
||||
"""
|
||||
This class just keep trace of messages, in a list with various
|
||||
|
@ -29,15 +34,28 @@ class TextBuffer(object):
|
|||
"""
|
||||
def __init__(self):
|
||||
self.messages = [] # Message objects
|
||||
self.pos = 0
|
||||
self.windows = [] # we keep track of one or more windows
|
||||
# so we can pass the new messages to them, as they are added, so
|
||||
# they (the windows) can built the lines from the new message
|
||||
|
||||
def add_window(self, win):
|
||||
self.windows.append(win)
|
||||
|
||||
def add_message(self, txt, time=None, nickname=None, colorized=False):
|
||||
color = theme.COLOR_NORMAL_TEXT
|
||||
user = None
|
||||
time = time or datetime.now()
|
||||
if self.pos: # avoid scrolling of one line when one line is received
|
||||
self.pos += 1
|
||||
self.messages.append(Message(txt, time, nickname, user, color, colorized))
|
||||
# if self.pos: # avoid scrolling of one line when one line is received
|
||||
# self.pos += 1
|
||||
msg = Message(txt, time, nickname, user, color, colorized)
|
||||
self.messages.append(msg)
|
||||
while len(self.messages) > MESSAGE_NB_LIMIT:
|
||||
self.messages.pop(0)
|
||||
for window in self.windows: # make the associated windows
|
||||
# build the lines from the new message
|
||||
nb = window.build_new_message(msg)
|
||||
if window.pos != 0:
|
||||
window.scroll_up(nb)
|
||||
|
||||
def remove_line_separator(self):
|
||||
"""
|
||||
|
@ -52,15 +70,3 @@ class TextBuffer(object):
|
|||
"""
|
||||
if None not in self.messages:
|
||||
self.messages.append(None)
|
||||
|
||||
def scroll_up(self, dist=14):
|
||||
# The pos can grow a lot over the top of the number of
|
||||
# available lines, it will be fixed on the next refresh of the
|
||||
# screen anyway
|
||||
self.pos += dist
|
||||
|
||||
def scroll_down(self, dist=14):
|
||||
self.pos -= dist
|
||||
if self.pos <= 0:
|
||||
self.pos = 0
|
||||
|
||||
|
|
165
src/windows.py
165
src/windows.py
|
@ -49,6 +49,8 @@ import theme
|
|||
|
||||
g_lock = Lock()
|
||||
|
||||
LINES_NB_LIMIT = 16384
|
||||
|
||||
class Win(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
@ -186,14 +188,14 @@ class InfoWin(Win):
|
|||
def __init__(self):
|
||||
Win.__init__(self)
|
||||
|
||||
def print_scroll_position(self, text_buffer):
|
||||
def print_scroll_position(self, window):
|
||||
"""
|
||||
Print, link in Weechat, a -PLUS(n)- where n
|
||||
is the number of available lines to scroll
|
||||
down
|
||||
"""
|
||||
if text_buffer.pos > 0:
|
||||
plus = ' -PLUS(%s)-' % text_buffer.pos
|
||||
if window.pos > 0:
|
||||
plus = ' -PLUS(%s)-' % window.pos
|
||||
self.addstr(plus, curses.color_pair(theme.COLOR_SCROLLABLE_NUMBER) | curses.A_BOLD)
|
||||
|
||||
class PrivateInfoWin(InfoWin):
|
||||
|
@ -341,14 +343,15 @@ class MucInfoWin(InfoWin):
|
|||
def resize(self, height, width, y, x, stdscr):
|
||||
self._resize(height, width, y, x, stdscr)
|
||||
|
||||
def refresh(self, room):
|
||||
def refresh(self, room, window=None):
|
||||
with g_lock:
|
||||
self._win.erase()
|
||||
self.write_room_name(room)
|
||||
self.write_own_nick(room)
|
||||
self.write_disconnected(room)
|
||||
self.write_role(room)
|
||||
self.print_scroll_position(room)
|
||||
if window:
|
||||
self.print_scroll_position(window)
|
||||
self.finish_line(theme.COLOR_INFORMATION_BAR)
|
||||
self._refresh()
|
||||
|
||||
|
@ -397,64 +400,81 @@ class MucInfoWin(InfoWin):
|
|||
class TextWin(Win):
|
||||
def __init__(self):
|
||||
Win.__init__(self)
|
||||
self.pos = 0
|
||||
self.built_lines = [] # Each new message is built and kept here.
|
||||
# on resize, we rebuild all the messages
|
||||
|
||||
def build_lines_from_messages(self, messages):
|
||||
def scroll_up(self, dist=14):
|
||||
# The pos can grow a lot over the top of the number of
|
||||
# available lines, it will be fixed on the next refresh of the
|
||||
# screen anyway
|
||||
self.pos += dist
|
||||
|
||||
def scroll_down(self, dist=14):
|
||||
self.pos -= dist
|
||||
if self.pos <= 0:
|
||||
self.pos = 0
|
||||
|
||||
def build_new_message(self, message):
|
||||
"""
|
||||
From all the existing messages in the window, create the that will
|
||||
be displayed on the screen
|
||||
Take one message, build it and add it to the list
|
||||
Return the number of lines that are built for the given
|
||||
message.
|
||||
"""
|
||||
lines = []
|
||||
for message in messages:
|
||||
if message == None: # line separator
|
||||
lines.append(None)
|
||||
continue
|
||||
txt = message.txt
|
||||
if not txt:
|
||||
continue
|
||||
if message == None: # line separator
|
||||
self.built_lines.append(None)
|
||||
return 0
|
||||
txt = message.txt
|
||||
if not txt:
|
||||
return 0
|
||||
# length of the time
|
||||
offset = 9+len(theme.CHAR_TIME_LEFT[:1])+len(theme.CHAR_TIME_RIGHT[:1])
|
||||
if message.nickname and len(message.nickname) >= 30:
|
||||
nick = message.nickname[:30]+'…'
|
||||
offset = 9+len(theme.CHAR_TIME_LEFT[:1])+len(theme.CHAR_TIME_RIGHT[:1])
|
||||
if message.nickname and len(message.nickname) >= 30:
|
||||
nick = message.nickname[:30]+'…'
|
||||
else:
|
||||
nick = message.nickname
|
||||
if nick:
|
||||
offset += len(nick) + 2 # + nick + spaces length
|
||||
first = True
|
||||
this_line_was_broken_by_space = False
|
||||
nb = 0
|
||||
while txt != '':
|
||||
if txt[:self.width-offset].find('\n') != -1:
|
||||
limit = txt[:self.width-offset].find('\n')
|
||||
else:
|
||||
nick = message.nickname
|
||||
if nick:
|
||||
offset += len(nick) + 2 # + nick + spaces length
|
||||
first = True
|
||||
this_line_was_broken_by_space = False
|
||||
while txt != '':
|
||||
if txt[:self.width-offset].find('\n') != -1:
|
||||
limit = txt[:self.width-offset].find('\n')
|
||||
else:
|
||||
# break between words if possible
|
||||
if len(txt) >= self.width-offset:
|
||||
limit = txt[:self.width-offset].rfind(' ')
|
||||
this_line_was_broken_by_space = True
|
||||
if limit <= 0:
|
||||
limit = self.width-offset
|
||||
this_line_was_broken_by_space = False
|
||||
else:
|
||||
limit = self.width-offset-1
|
||||
# break between words if possible
|
||||
if len(txt) >= self.width-offset:
|
||||
limit = txt[:self.width-offset].rfind(' ')
|
||||
this_line_was_broken_by_space = True
|
||||
if limit <= 0:
|
||||
limit = self.width-offset
|
||||
this_line_was_broken_by_space = False
|
||||
color = message.user.color if message.user else None
|
||||
if not first:
|
||||
nick = None
|
||||
time = None
|
||||
else:
|
||||
time = message.time
|
||||
l = Line(nick, color,
|
||||
time,
|
||||
txt[:limit], message.color,
|
||||
offset,
|
||||
message.colorized)
|
||||
lines.append(l)
|
||||
if this_line_was_broken_by_space:
|
||||
txt = txt[limit+1:] # jump the space at the start of the line
|
||||
else:
|
||||
txt = txt[limit:]
|
||||
if txt.startswith('\n'):
|
||||
txt = txt[1:]
|
||||
first = False
|
||||
return lines
|
||||
limit = self.width-offset-1
|
||||
this_line_was_broken_by_space = False
|
||||
color = message.user.color if message.user else None
|
||||
if not first:
|
||||
nick = None
|
||||
time = None
|
||||
else:
|
||||
time = message.time
|
||||
l = Line(nick, color,
|
||||
time,
|
||||
txt[:limit], message.color,
|
||||
offset,
|
||||
message.colorized)
|
||||
self.built_lines.append(l)
|
||||
nb += 1
|
||||
if this_line_was_broken_by_space:
|
||||
txt = txt[limit+1:] # jump the space at the start of the line
|
||||
else:
|
||||
txt = txt[limit:]
|
||||
if txt.startswith('\n'):
|
||||
txt = txt[1:]
|
||||
first = False
|
||||
while len(self.built_lines) > LINES_NB_LIMIT:
|
||||
self.built_lines.pop(0)
|
||||
return nb
|
||||
|
||||
def refresh(self, room):
|
||||
"""
|
||||
|
@ -465,13 +485,14 @@ class TextWin(Win):
|
|||
return
|
||||
with g_lock:
|
||||
self._win.erase()
|
||||
lines = self.build_lines_from_messages(room.messages)
|
||||
if room.pos + self.height > len(lines):
|
||||
room.pos = len(lines) - self.height
|
||||
if room.pos < 0:
|
||||
room.pos = 0
|
||||
if room.pos != 0:
|
||||
lines = lines[-self.height-room.pos:-room.pos]
|
||||
# lines = self.build_lines_from_messages(room.messages)
|
||||
lines = self.built_lines
|
||||
if self.pos + self.height > len(lines):
|
||||
self.pos = len(lines) - self.height
|
||||
if self.pos < 0:
|
||||
self.pos = 0
|
||||
if self.pos != 0:
|
||||
lines = lines[-self.height-self.pos:-self.pos]
|
||||
else:
|
||||
lines = lines[-self.height:]
|
||||
y = 0
|
||||
|
@ -562,8 +583,15 @@ class TextWin(Win):
|
|||
self.addnstr(theme.CHAR_TIME_RIGHT, curses.color_pair(theme.COLOR_TIME_LIMITER))
|
||||
self.addstr(' ')
|
||||
|
||||
def resize(self, height, width, y, x, stdscr):
|
||||
def resize(self, height, width, y, x, stdscr, room=None):
|
||||
self._resize(height, width, y, x, stdscr)
|
||||
if room:
|
||||
self.rebuild_everything(room)
|
||||
|
||||
def rebuild_everything(self, room):
|
||||
self.built_lines = []
|
||||
for message in room.messages:
|
||||
self.build_new_message(message)
|
||||
|
||||
class HelpText(Win):
|
||||
"""
|
||||
|
@ -824,7 +852,6 @@ class Input(Win):
|
|||
begin = self.text.split()[-1].lower()
|
||||
else:
|
||||
begin = ''
|
||||
log.debug('BEGIN: [%s]\n' % begin)
|
||||
hit_list = [] # list of matching nicks
|
||||
for word in word_list:
|
||||
if word.lower().startswith(begin):
|
||||
|
@ -895,15 +922,15 @@ class Input(Win):
|
|||
def do_command(self, key, reset=True):
|
||||
if key in self.key_func:
|
||||
return self.key_func[key]()
|
||||
if not key or len(key) > 1:
|
||||
return False # ignore non-handled keyboard shortcuts
|
||||
# if not key or len(key) > 1:
|
||||
# return False # ignore non-handled keyboard shortcuts
|
||||
self.reset_completion()
|
||||
self.text = self.text[:self.pos+self.line_pos]+key+self.text[self.pos+self.line_pos:]
|
||||
(y, x) = self._win.getyx()
|
||||
if x == self.width-1:
|
||||
self.line_pos += 1
|
||||
self.line_pos += len(key)
|
||||
else:
|
||||
self.pos += 1
|
||||
self.pos += len(key)
|
||||
if reset:
|
||||
self.rewrite_text()
|
||||
return True
|
||||
|
|
Loading…
Reference in a new issue