Center choice message correctly when it is multi-line

Also fix button wrap calculation. It was not taking the borders into
account.
This commit is contained in:
Kovid Goyal 2022-08-10 20:34:25 +05:30
parent 7be6b28011
commit cd3eeb7a95
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -6,7 +6,7 @@ import re
import sys import sys
from contextlib import suppress from contextlib import suppress
from typing import ( from typing import (
TYPE_CHECKING, Callable, Dict, List, NamedTuple, Optional, Tuple TYPE_CHECKING, Callable, Dict, Iterator, List, NamedTuple, Optional, Tuple
) )
from kitty.cli import parse_args from kitty.cli import parse_args
@ -230,29 +230,30 @@ class Choose(Handler):
def finalize(self) -> None: def finalize(self) -> None:
self.cmd.set_cursor_visible(True) self.cmd.set_cursor_visible(True)
def draw_long_text(self, text: str) -> int: def draw_long_text(self, text: str) -> Iterator[str]:
if not text: if not text:
self.print('') yield ''
return 1 return
y = 0
width = self.screen_size.cols - 2 width = self.screen_size.cols - 2
m = self.prefix_style_pat.match(text) m = self.prefix_style_pat.match(text)
prefix = m.group() if m else '' prefix = m.group() if m else ''
while text: while text:
t, text = truncate_at_space(text, width) t, text = truncate_at_space(text, width)
t = t.strip() t = t.strip()
self.print(' ' * extra_for(wcswidth(t), width), styled(prefix + t, bold=True), sep='') yield ' ' * extra_for(wcswidth(t), width) + styled(prefix + t, bold=True)
y += 1
return y
@Handler.atomic_update @Handler.atomic_update
def draw_screen(self) -> None: def draw_screen(self) -> None:
self.cmd.clear_screen() self.cmd.clear_screen()
y = max(0, self.screen_size.rows // 2 - 2) msg_lines: List[str] = []
self.print(end='\r\n'*y)
if self.cli_opts.message: if self.cli_opts.message:
for line in self.cli_opts.message.splitlines(): for line in self.cli_opts.message.splitlines():
y += self.draw_long_text(line) msg_lines.extend(self.draw_long_text(line))
y = self.screen_size.rows - len(msg_lines)
y = max(0, (y // 2) - 2)
self.print(end='\r\n'*y)
for line in msg_lines:
self.print(line)
if self.screen_size.rows > 2: if self.screen_size.rows > 2:
self.print() self.print()
y += 1 y += 1
@ -267,7 +268,8 @@ class Choose(Handler):
current_line_length = 0 current_line_length = 0
current_line: List[Tuple[str, str]] = [] current_line: List[Tuple[str, str]] = []
lines: List[List[Tuple[str, str]]] = [] lines: List[List[Tuple[str, str]]] = []
sep, sep_sz = ' ', 2 sep = ' '
sep_sz = len(sep) + 2 # for the borders
for choice in choices: for choice in choices:
self.clickable_ranges[choice.letter] = [] self.clickable_ranges[choice.letter] = []
@ -280,7 +282,7 @@ class Choose(Handler):
current_line = [] current_line = []
current_line_length = 0 current_line_length = 0
current_line.append((choice.letter, text)) current_line.append((choice.letter, text))
current_line_length += sz current_line_length += sz + sep_sz
if current_line: if current_line:
lines.append(current_line) lines.append(current_line)
@ -319,10 +321,12 @@ class Choose(Handler):
self.print(' ' * offset, line, sep='', end='' if is_last else '\r\n') self.print(' ' * offset, line, sep='', end='' if is_last else '\r\n')
y += 1 y += 1
self.cmd.set_line_wrapping(False)
for boxed_line in lines: for boxed_line in lines:
print_line(top, *boxed_line) print_line(top, *boxed_line)
print_line(middle, *boxed_line) print_line(middle, *boxed_line)
print_line(bottom, *boxed_line, is_last=boxed_line is lines[-1]) print_line(bottom, *boxed_line, is_last=boxed_line is lines[-1])
self.cmd.set_line_wrapping(True)
def draw_choice(self, y: int) -> None: def draw_choice(self, y: int) -> None:
if y + 3 <= self.screen_size.rows: if y + 3 <= self.screen_size.rows: