Make the size modular, remove small-size lock (also seems to fix #2155)

some stuff is now hidden wen the window size gets too small (might need
some adjustments). The info buffer in the roster tab, the userlist in
mucs, the vertical tab list, the info buffer everywhere, etc…
This commit is contained in:
mathieui 2014-04-28 23:29:21 +02:00
parent 069283e349
commit 0caf9417b2
11 changed files with 233 additions and 85 deletions

View file

@ -41,6 +41,7 @@ from keyboard import Keyboard
from logger import logger
from plugin_manager import PluginManager
from roster import roster
from size_manager import SizeManager
from text_buffer import TextBuffer
from theming import get_theme
from windows import g_lock
@ -105,6 +106,7 @@ class Core(object):
self.plugin_manager = PluginManager(self)
self.events = events.EventHandler()
self.size = SizeManager(self, windows.Win)
# global commands, available from all tabs
# a command is tuple of the form:
@ -1498,20 +1500,25 @@ class Core(object):
Resize the global_information_win only once at each resize.
"""
with g_lock:
height = (tabs.Tab.height - 1 - self.information_win_size
- tabs.Tab.tab_win_height())
self.information_win.resize(self.information_win_size,
tabs.Tab.width,
height,
0)
height = min(tabs.Tab.height - 1 - self.information_win_size
- tabs.Tab.tab_win_height(),
tabs.Tab.height - 5)
if not self.size.core_degrade_y:
self.information_win.resize(self.information_win_size,
tabs.Tab.width,
height,
0)
def resize_global_info_bar(self):
"""
Resize the GlobalInfoBar only once at each resize
"""
with g_lock:
self.tab_win.resize(1, tabs.Tab.width, tabs.Tab.height - 2, 0)
if config.get('enable_vertical_tab_list', False):
height, width = self.stdscr.getmaxyx()
if not self.size.core_degrade_y:
self.tab_win.resize(1, tabs.Tab.width, tabs.Tab.height - 2, 0)
if (config.get('enable_vertical_tab_list', False)
and not self.size.core_degrade_x):
try:
height, _ = self.stdscr.getmaxyx()
truncated_win = self.stdscr.subwin(height,
@ -1550,7 +1557,10 @@ class Core(object):
# window to each Tab class, so the draw themself in the portion
# of the screen that the can occupy, and we draw the tab list
# on the left remaining space
if config.get('enable_vertical_tab_list', False):
with g_lock:
height, width = self.stdscr.getmaxyx()
if (config.get('enable_vertical_tab_list', False) and
not self.size.core_degrade_x):
with g_lock:
try:
scr = self.stdscr.subwin(0,

View file

@ -617,7 +617,8 @@ def on_chatstate_groupchat_conversation(self, message, state):
self.events.trigger('muc_chatstate', message, tab)
tab.get_user_by_name(nick).chatstate = state
if tab == self.current_tab():
tab.user_win.refresh(tab.users)
if not self.size.tab_degrade_x:
tab.user_win.refresh(tab.users)
tab.input.refresh()
self.doupdate()
else:

View file

@ -1,4 +1,5 @@
from . basetabs import Tab, ChatTab, GapTab, STATE_PRIORITY
from . basetabs import Tab, ChatTab, GapTab
from . basetabs import STATE_PRIORITY
from . rostertab import RosterInfoTab
from . muctab import MucTab, NS_MUC_USER
from . privatetab import PrivateTab

View file

@ -38,9 +38,6 @@ from theming import get_theme
from windows import g_lock
MIN_WIDTH = 42
MIN_HEIGHT = 6
# getters for tab colors (lambdas, so that they are dynamic)
STATE_COLORS = {
'disconnected': lambda: get_theme().COLOR_TAB_DISCONNECTED,
@ -88,6 +85,7 @@ STATE_PRIORITY = {
class Tab(object):
tab_core = None
size_manager = None
plugin_commands = {}
plugin_keys = {}
@ -102,6 +100,12 @@ class Tab(object):
self.commands = {} # and their own commands
@property
def size(self):
if not Tab.size_manager:
Tab.size_manager = self.core.size
return Tab.size_manager
@property
def core(self):
if not Tab.tab_core:
@ -182,11 +186,7 @@ class Tab(object):
@staticmethod
def resize(scr):
with g_lock:
Tab.size = (Tab.height, Tab.width) = scr.getmaxyx()
if Tab.height < MIN_HEIGHT or Tab.width < MIN_WIDTH:
Tab.visible = False
else:
Tab.visible = True
Tab.height, Tab.width = scr.getmaxyx()
windows.Win._tab_win = scr
def register_command(self, name, func, *, desc='', shortdesc='', completion=None, usage=''):
@ -283,9 +283,9 @@ class Tab(object):
return False
def refresh_tab_win(self):
if self.left_tab_win:
if self.left_tab_win and not self.size.core_degrade_x:
self.left_tab_win.refresh()
else:
elif not self.size.core_degrade_y:
self.tab_win.refresh()
def refresh(self):

View file

@ -260,23 +260,44 @@ class ConversationTab(ChatTab):
callback=callback)
def resize(self):
if self.core.information_win_size >= self.height-3 or not self.visible:
return
self.need_resize = False
self.text_win.resize(self.height-3-self.core.information_win_size - Tab.tab_win_height(), self.width, 1, 0)
if self.size.tab_degrade_y:
display_bar = False
info_win_height = 0
tab_win_height = 0
bar_height = 0
else:
display_bar = True
info_win_height = self.core.information_win_size
tab_win_height = Tab.tab_win_height()
bar_height = 1
self.text_win.resize(self.height - 2 - bar_height - info_win_height
- tab_win_height,
self.width, bar_height, 0)
self.text_win.rebuild_everything(self._text_buffer)
self.upper_bar.resize(1, self.width, 0, 0)
self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0)
self.input.resize(1, self.width, self.height-1, 0)
if display_bar:
self.upper_bar.resize(1, self.width, 0, 0)
self.info_header.resize(1, self.width,
self.height - 2 - bar_height - info_win_height
- tab_win_height,
0)
self.input.resize(1, self.width, self.height - 1, 0)
def refresh(self):
if self.need_resize:
self.resize()
log.debug(' TAB Refresh: %s', self.__class__.__name__)
display_bar = display_info_win = not self.size.tab_degrade_y
self.text_win.refresh()
self.upper_bar.refresh(self.get_dest_jid(), roster[self.get_dest_jid()])
if display_bar:
self.upper_bar.refresh(self.get_dest_jid(), roster[self.get_dest_jid()])
self.info_header.refresh(self.get_dest_jid(), roster[self.get_dest_jid()], self.text_win, self.chatstate, ConversationTab.additional_informations)
self.info_win.refresh()
if display_info_win:
self.info_win.refresh()
self.refresh_tab_win()
self.input.refresh()
@ -439,14 +460,21 @@ class DynamicConversationTab(ConversationTab):
if self.need_resize:
self.resize()
log.debug(' TAB Refresh: %s', self.__class__.__name__)
display_bar = display_info_win = not self.size.tab_degrade_y
self.text_win.refresh()
self.upper_bar.refresh(self.get_name(), roster[self.get_name()])
if display_bar:
self.upper_bar.refresh(self.get_name(), roster[self.get_name()])
if self.locked_resource:
displayed_jid = "%s/%s" % (self.get_name(), self.locked_resource)
else:
displayed_jid = self.get_name()
self.info_header.refresh(displayed_jid, roster[self.get_name()], self.text_win, self.chatstate, ConversationTab.additional_informations)
self.info_win.refresh()
self.info_header.refresh(displayed_jid, roster[self.get_name()],
self.text_win, self.chatstate,
ConversationTab.additional_informations)
if display_info_win:
self.info_win.refresh()
self.refresh_tab_win()
self.input.refresh()

View file

@ -63,26 +63,41 @@ class MucListTab(Tab):
if self.need_resize:
self.resize()
log.debug(' TAB Refresh: %s', self.__class__.__name__)
if self.size.tab_degrade_y:
display_info_win = False
else:
display_info_win = True
self.info_header.refresh(window=self.listview)
self.info_win.refresh()
if display_info_win:
self.info_win.refresh()
self.refresh_tab_win()
self.list_header.refresh()
self.listview.refresh()
self.input.refresh()
self.update_commands()
def resize(self):
if self.core.information_win_size >= self.height-3 or not self.visible:
return
self.need_resize = False
self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0)
column_size = {'node-part': int(self.width*2/8),
'name': int(self.width*5/8),
'users': self.width-int(self.width*2/8)-int(self.width*5/8)}
if self.size.tab_degrade_y:
info_win_height = 0
tab_win_height = 0
else:
info_win_height = self.core.information_win_size
tab_win_height = Tab.tab_win_height()
self.info_header.resize(1, self.width,
self.height - 2 - info_win_height
- tab_win_height,
0)
column_size = {'node-part': int(self.width* 2 / 8),
'name': int(self.width * 5 / 8),
'users': self.width - int(self.width * 2 / 8)
- int(self.width * 5 / 8)}
self.list_header.resize_columns(column_size)
self.list_header.resize(1, self.width, 0, 0)
self.listview.resize_columns(column_size)
self.listview.resize(self.height-3-self.core.information_win_size - Tab.tab_win_height(), self.width, 1, 0)
self.listview.resize(self.height - 3 - info_win_height - tab_win_height,
self.width, 1, 0)
self.input.resize(1, self.width, self.height-1, 0)
def on_slash(self):

View file

@ -796,29 +796,42 @@ class MucTab(ChatTab):
"""
Resize the whole window. i.e. all its sub-windows
"""
if not self.visible:
return
self.need_resize = False
if config.get("hide_user_list", False):
if config.get("hide_user_list", False) or self.size.tab_degrade_x:
display_user_list = False
text_width = self.width
else:
text_width = (self.width//10)*9
self.user_win.resize(self.height - 3 - self.core.information_win_size
- Tab.tab_win_height(),
self.width - (self.width // 10) * 9 - 1,
1,
(self.width // 10) * 9 + 1)
display_user_list = True
text_width = (self.width // 10) * 9
if self.size.tab_degrade_y:
display_info_win = False
tab_win_height = 0
info_win_height = 0
else:
display_info_win = True
tab_win_height = Tab.tab_win_height()
info_win_height = self.core.information_win_size
if display_user_list:
self.user_win.resize(self.height - 3 - info_win_height
- tab_win_height,
self.width - (self.width // 10) * 9 - 1,
1,
(self.width // 10) * 9 + 1)
self.v_separator.resize(self.height - 2 - tab_win_height,
1, 1, 9 * (self.width // 10))
self.topic_win.resize(1, self.width, 0, 0)
self.v_separator.resize(self.height - 2 - Tab.tab_win_height(),
1, 1, 9 * (self.width // 10))
self.text_win.resize(self.height - 3 - self.core.information_win_size
- Tab.tab_win_height(),
text_width, 1, 0)
self.text_win.resize(self.height - 3 - info_win_height
- tab_win_height,
text_width, 1, 0)
self.text_win.rebuild_everything(self._text_buffer)
self.info_header.resize(1, self.width,
self.height - 2
- self.core.information_win_size
- Tab.tab_win_height(),
self.height - 2 - info_win_height
- tab_win_height,
0)
self.input.resize(1, self.width, self.height-1, 0)
@ -826,14 +839,21 @@ class MucTab(ChatTab):
if self.need_resize:
self.resize()
log.debug(' TAB Refresh: %s', self.__class__.__name__)
if config.get("hide_user_list", False) or self.size.tab_degrade_x:
display_user_list = False
else:
display_user_list = True
display_info_win = not self.size.tab.degrade_y
self.topic_win.refresh(self.get_single_line_topic())
self.text_win.refresh()
if not config.get("hide_user_list", False):
if display_user_list:
self.v_separator.refresh()
self.user_win.refresh(self.users)
self.info_header.refresh(self, self.text_win)
self.refresh_tab_win()
self.info_win.refresh()
if display_info_win:
self.info_win.refresh()
self.input.refresh()
def on_input(self, key, raw):

View file

@ -237,21 +237,36 @@ class PrivateTab(ChatTab):
self.parent_muc.command_info(user)
def resize(self):
if self.core.information_win_size >= self.height-3 or not self.visible:
return
self.need_resize = False
self.text_win.resize(self.height-2-self.core.information_win_size - Tab.tab_win_height(), self.width, 0, 0)
if self.size.tab_degrade_y:
info_win_height = 0
tab_win_height = 0
else:
info_win_height = self.core.information_win_size
tab_win_height = Tab.tab_win_height()
self.text_win.resize(self.height - 2 - info_win_height - tab_win_height,
self.width, 0, 0)
self.text_win.rebuild_everything(self._text_buffer)
self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0)
self.info_header.resize(1, self.width,
self.height - 2 - info_win_height
- tab_win_height,
0)
self.input.resize(1, self.width, self.height-1, 0)
def refresh(self):
if self.need_resize:
self.resize()
log.debug(' TAB Refresh: %s', self.__class__.__name__)
display_info_win = not self.size.tab_degrade_y
self.text_win.refresh()
self.info_header.refresh(self.name, self.text_win, self.chatstate, PrivateTab.additional_informations)
self.info_win.refresh()
self.info_header.refresh(self.name, self.text_win, self.chatstate,
PrivateTab.additional_informations)
if display_info_win:
self.info_win.refresh()
self.refresh_tab_win()
self.input.refresh()

View file

@ -266,15 +266,40 @@ class RosterInfoTab(Tab):
self.core.command_last_activity(jid)
def resize(self):
if not self.visible:
return
self.need_resize = False
roster_width = self.width//2
info_width = self.width-roster_width-1
self.v_separator.resize(self.height-1 - Tab.tab_win_height(), 1, 0, roster_width)
self.information_win.resize(self.height-2-4, info_width, 0, roster_width+1, self.core.information_buffer)
self.roster_win.resize(self.height-1 - Tab.tab_win_height(), roster_width, 0, 0)
self.contact_info_win.resize(5 - Tab.tab_win_height(), info_width, self.height-2-4, roster_width+1)
if self.size.tab_degrade_x:
display_info = False
roster_width = self.width
else:
display_info = True
roster_width = self.width // 2
if self.size.tab_degrade_y:
display_contact_win = False
contact_win_h = 0
else:
display_contact_win = True
contact_win_h = 5
if self.size.tab_degrade_y:
tab_win_height = 0
else:
tab_win_height = Tab.tab_win_height()
info_width = self.width - roster_width - 1
if display_info:
self.v_separator.resize(self.height - 1 - tab_win_height,
1, 0, roster_width)
self.information_win.resize(self.height - 1 - tab_win_height
- contact_win_h,
info_width, 0, roster_width + 1,
self.core.information_buffer)
if display_contact_win:
self.contact_info_win.resize(contact_win_h - tab_win_height,
info_width,
self.height - tab_win_height
- contact_win_h - 1,
roster_width + 1)
self.roster_win.resize(self.height - 1 - Tab.tab_win_height(),
roster_width, 0, 0)
self.input.resize(1, self.width, self.height-1, 0)
self.default_help_message.resize(1, self.width, self.height-1, 0)
@ -699,10 +724,17 @@ class RosterInfoTab(Tab):
if self.need_resize:
self.resize()
log.debug(' TAB Refresh: %s', self.__class__.__name__)
self.v_separator.refresh()
display_info = not self.size.tab_degrade_x
display_contact_win = not self.size.tab_degrade_y
self.roster_win.refresh(roster)
self.contact_info_win.refresh(self.roster_win.get_selected_row())
self.information_win.refresh()
if display_info:
self.v_separator.refresh()
self.information_win.refresh()
if display_contact_win:
self.contact_info_win.refresh(
self.roster_win.get_selected_row())
self.refresh_tab_win()
self.input.refresh()

View file

@ -163,23 +163,38 @@ class XMLTab(Tab):
self.core.close_tab()
def resize(self):
if self.core.information_win_size >= self.height-3 or not self.visible:
return
self.need_resize = False
min = 1 if self.left_tab_win else 2
self.text_win.resize(self.height-self.core.information_win_size - Tab.tab_win_height() - 2, self.width, 0, 0)
if self.size.tab_degrade_y:
info_win_size = 0
tab_win_height = 0
else:
info_win_size = self.core.information_win_size
tab_win_height = Tab.tab_win_height()
self.text_win.resize(self.height - info_win_size - tab_win_height - 2,
self.width, 0, 0)
self.text_win.rebuild_everything(self.core.xml_buffer)
self.info_header.resize(1, self.width, self.height-2-self.core.information_win_size - Tab.tab_win_height(), 0)
self.info_header.resize(1, self.width,
self.height - 2 - info_win_size
- tab_win_height,
0)
self.input.resize(1, self.width, self.height-1, 0)
def refresh(self):
if self.need_resize:
self.resize()
log.debug(' TAB Refresh: %s', self.__class__.__name__)
if self.size.tab_degrade_y:
display_info_win = False
else:
display_info_win = True
self.text_win.refresh()
self.info_header.refresh(self.filter_type, self.filter, self.text_win)
self.refresh_tab_win()
self.info_win.refresh()
if display_info_win:
self.info_win.refresh()
self.input.refresh()
def on_lose_focus(self):

View file

@ -52,6 +52,16 @@ g_lock = RLock()
LINES_NB_LIMIT = 4096
class DummyWin(object):
def __getattribute__(self, name):
if name != '__bool__':
return lambda *args, **kwargs: (0, 0)
else:
return object.__getattribute__(self, name)
def __bool__(self):
return False
def find_first_format_char(text):
pos = -1
for char in format_chars:
@ -103,6 +113,7 @@ class Win(object):
_tab_win = None
def __init__(self):
self._win = None
self.height, self.width = 0, 0
def _resize(self, height, width, y, x):
if height == 0 or width == 0:
@ -113,8 +124,8 @@ class Win(object):
self._win = Win._tab_win.derwin(height, width, y, x)
except:
log.debug('DEBUG: mvwin returned ERR. Please investigate')
# If this ever fail, uncomment that ^
if self._win is None:
self._win = DummyWin()
def resize(self, height, width, y, x):
"""