2
2
3
3
from .align import AlignMethod
4
4
from .box import ROUNDED , Box
5
+ from .cells import cell_len
5
6
from .jupyter import JupyterMixin
6
7
from .measure import Measurement , measure_renderables
7
8
from .padding import Padding , PaddingDimensions
8
9
from .segment import Segment
9
- from .style import StyleType
10
+ from .style import Style , StyleType
10
11
from .text import Text , TextType
11
12
12
13
if TYPE_CHECKING :
@@ -149,9 +150,53 @@ def __rich_console__(
149
150
safe_box : bool = console .safe_box if self .safe_box is None else self .safe_box
150
151
box = self .box .substitute (options , safe = safe_box )
151
152
153
+ def align_text (
154
+ text : Text , width : int , align : str , character : str , style : Style
155
+ ) -> Text :
156
+ """Gets new aligned text.
157
+
158
+ Args:
159
+ text (Text): Title or subtitle text.
160
+ width (int): Desired width.
161
+ align (str): Alignment.
162
+ character (str): Character for alignment.
163
+ style (Style): Border style
164
+
165
+ Returns:
166
+ Text: New text instance
167
+ """
168
+ text = text .copy ()
169
+ text .truncate (width )
170
+ excess_space = width - cell_len (text .plain )
171
+ if excess_space :
172
+ if align == "left" :
173
+ return Text .assemble (
174
+ text ,
175
+ (character * excess_space , style ),
176
+ no_wrap = True ,
177
+ end = "" ,
178
+ )
179
+ elif align == "center" :
180
+ left = excess_space // 2
181
+ return Text .assemble (
182
+ (character * left , style ),
183
+ text ,
184
+ (character * (excess_space - left ), style ),
185
+ no_wrap = True ,
186
+ end = "" ,
187
+ )
188
+ else :
189
+ return Text .assemble (
190
+ (character * excess_space , style ),
191
+ text ,
192
+ no_wrap = True ,
193
+ end = "" ,
194
+ )
195
+ return text
196
+
152
197
title_text = self ._title
153
198
if title_text is not None :
154
- title_text .style = border_style
199
+ title_text .stylize_before ( border_style )
155
200
156
201
child_width = (
157
202
width - 2
@@ -180,7 +225,13 @@ def __rich_console__(
180
225
if title_text is None or width <= 4 :
181
226
yield Segment (box .get_top ([width - 2 ]), border_style )
182
227
else :
183
- title_text .align (self .title_align , width - 4 , character = box .top )
228
+ title_text = align_text (
229
+ title_text ,
230
+ width - 4 ,
231
+ self .title_align ,
232
+ box .top ,
233
+ border_style ,
234
+ )
184
235
yield Segment (box .top_left + box .top , border_style )
185
236
yield from console .render (title_text , child_options .update_width (width - 4 ))
186
237
yield Segment (box .top + box .top_right , border_style )
@@ -194,12 +245,18 @@ def __rich_console__(
194
245
195
246
subtitle_text = self ._subtitle
196
247
if subtitle_text is not None :
197
- subtitle_text .style = border_style
248
+ subtitle_text .stylize_before ( border_style )
198
249
199
250
if subtitle_text is None or width <= 4 :
200
251
yield Segment (box .get_bottom ([width - 2 ]), border_style )
201
252
else :
202
- subtitle_text .align (self .subtitle_align , width - 4 , character = box .bottom )
253
+ subtitle_text = align_text (
254
+ subtitle_text ,
255
+ width - 4 ,
256
+ self .subtitle_align ,
257
+ box .bottom ,
258
+ border_style ,
259
+ )
203
260
yield Segment (box .bottom_left + box .bottom , border_style )
204
261
yield from console .render (
205
262
subtitle_text , child_options .update_width (width - 4 )
0 commit comments