Commit 280c77f3 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Allow UIs to override the window size

The console widget is slightly smaller than the terminal size, so the
column UI should help get_terminal_size a bit to determine the correct
size.
parent cf9ee528
...@@ -23,12 +23,6 @@ import re ...@@ -23,12 +23,6 @@ import re
from collections import namedtuple from collections import namedtuple
from datetime import date from datetime import date
# shutil.get_terminal_size was added to the standard library in Python 3.3
try:
from shutil import get_terminal_size as _get_terminal_size # pylint: disable=no-name-in-module
except ImportError:
from backports.shutil_get_terminal_size import get_terminal_size as _get_terminal_size # pylint: disable=import-error
def date_string_to_date(p_date): def date_string_to_date(p_date):
""" """
...@@ -61,19 +55,42 @@ def escape_ansi(p_string): ...@@ -61,19 +55,42 @@ def escape_ansi(p_string):
escape_ansi.pattern = re.compile(r'\x1b[^m]*m') escape_ansi.pattern = re.compile(r'\x1b[^m]*m')
def get_terminal_size(): def get_terminal_size(p_getter=None):
""" """
Try to determine terminal size at run time. If that is not possible, Try to determine terminal size at run time. If that is not possible,
returns the default size of 80x24. returns the default size of 80x24.
By default, the size is determined with provided get_terminal_size by
shutil. Sometimes an UI may want to specify the desired width, then it can
provide a getter that returns a named tuple (columns, lines) with the size.
""" """
try: try:
sz = _get_terminal_size() return get_terminal_size.getter()
except ValueError: except AttributeError:
""" if p_getter:
This can result from the 'underlying buffer being detached', which get_terminal_size.getter = p_getter
occurs during running the unittest on Windows (but not on Linux?) else:
""" def inner():
terminal_size = namedtuple('Terminal_Size', 'columns lines') try:
sz = terminal_size((80, 24)) # shutil.get_terminal_size was added to the standard
# library in Python 3.3
return sz try:
from shutil import get_terminal_size as _get_terminal_size # pylint: disable=no-name-in-module
except ImportError:
from backports.shutil_get_terminal_size import get_terminal_size as _get_terminal_size # pylint: disable=import-error
sz = _get_terminal_size()
except ValueError:
"""
This can result from the 'underlying buffer being detached', which
occurs during running the unittest on Windows (but not on Linux?)
"""
terminal_size = namedtuple('Terminal_Size', 'columns lines')
sz = terminal_size((80, 24))
return sz
get_terminal_size.getter = inner
return get_terminal_size.getter()
...@@ -21,6 +21,8 @@ class ConsoleWidget(urwid.LineBox): ...@@ -21,6 +21,8 @@ class ConsoleWidget(urwid.LineBox):
urwid.register_signal(ConsoleWidget, ['close']) urwid.register_signal(ConsoleWidget, ['close'])
self.text = urwid.Text(p_text) self.text = urwid.Text(p_text)
self.width = 0
super().__init__(self.text) super().__init__(self.text)
def keypress(self, p_size, p_key): def keypress(self, p_size, p_key):
...@@ -29,6 +31,14 @@ class ConsoleWidget(urwid.LineBox): ...@@ -29,6 +31,14 @@ class ConsoleWidget(urwid.LineBox):
# don't return the key, 'enter', 'escape' or 'q' are your only escape. # don't return the key, 'enter', 'escape' or 'q' are your only escape.
def render(self, p_size, focus):
"""
This override intercepts the width of the widget such that it can be
stored. The width is used for rendering `ls` output.
"""
self.width = p_size[0]
return super().render(p_size, focus)
def selectable(self): def selectable(self):
return True return True
...@@ -37,3 +47,7 @@ class ConsoleWidget(urwid.LineBox): ...@@ -37,3 +47,7 @@ class ConsoleWidget(urwid.LineBox):
def clear(self): def clear(self):
self.text.set_text("") self.text.set_text("")
def console_width(self):
# return the last known width (last render)
return self.width
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from collections import namedtuple
import shlex import shlex
import urwid import urwid
...@@ -27,6 +28,7 @@ from topydo.ui.ColumnLayout import columns ...@@ -27,6 +28,7 @@ from topydo.ui.ColumnLayout import columns
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Sorter import Sorter from topydo.lib.Sorter import Sorter
from topydo.lib.Filter import get_filter_list, RelevanceFilter, DependencyFilter from topydo.lib.Filter import get_filter_list, RelevanceFilter, DependencyFilter
from topydo.lib.Utils import get_terminal_size
from topydo.lib.View import View from topydo.lib.View import View
from topydo.lib import TodoFile from topydo.lib import TodoFile
from topydo.lib import TodoList from topydo.lib import TodoList
...@@ -81,6 +83,7 @@ class UIApplication(CLIApplicationBase): ...@@ -81,6 +83,7 @@ class UIApplication(CLIApplicationBase):
# console widget # console widget
self.console = ConsoleWidget() self.console = ConsoleWidget()
get_terminal_size(self._console_width)
urwid.connect_signal(self.commandline, 'blur', self._blur_commandline) urwid.connect_signal(self.commandline, 'blur', self._blur_commandline)
urwid.connect_signal(self.commandline, 'execute_command', urwid.connect_signal(self.commandline, 'execute_command',
...@@ -355,6 +358,13 @@ class UIApplication(CLIApplicationBase): ...@@ -355,6 +358,13 @@ class UIApplication(CLIApplicationBase):
return user_input[0] return user_input[0]
def _console_width(self):
terminal_size = namedtuple('Terminal_Size', 'columns lines')
width = self.console.console_width() - 2
sz = terminal_size(width, 1)
return sz
def run(self): def run(self):
layout = columns() layout = columns()
if len(layout) > 0: if len(layout) > 0:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment