@@ -576,9 +576,11 @@ def _build_left_panel(self):
576576 outer_layout = QVBoxLayout (self .left_container )
577577 outer_layout .setContentsMargins (0 , 0 , 0 , 0 )
578578 outer_layout .setSpacing (0 )
579+ self ._left_outer_layout = outer_layout
579580
580581 center_widget = QWidget (self .left_container )
581582 center_widget .setSizePolicy (QSizePolicy .Fixed , QSizePolicy .Fixed )
583+ self ._left_center_widget = center_widget
582584 ring_layer = QGridLayout (center_widget )
583585 ring_layer .setContentsMargins (0 , 0 , 0 , 0 )
584586 ring_layer .setSpacing (0 )
@@ -590,7 +592,8 @@ def _build_left_panel(self):
590592 ring_layer .addWidget (self .digit_panel , 0 , 0 , 1 , 1 )
591593
592594 outer_layout .addStretch (1 )
593- outer_layout .addWidget (center_widget , 0 , Qt .AlignCenter )
595+ outer_layout .addWidget (center_widget , 0 )
596+ outer_layout .setAlignment (center_widget , Qt .AlignHCenter | Qt .AlignVCenter )
594597 outer_layout .addStretch (1 )
595598
596599 def _build_digit_panel (self , parent_widget = None ):
@@ -634,7 +637,7 @@ def _build_digit_panel(self, parent_widget=None):
634637
635638 digits_row = QHBoxLayout ()
636639 digits_row .setContentsMargins (0 , 0 , 0 , 0 )
637- digits_row .setSpacing (4 )
640+ digits_row .setSpacing (0 )
638641 digits_row .setAlignment (Qt .AlignCenter )
639642
640643 minus_row = QHBoxLayout ()
@@ -679,6 +682,13 @@ def _build_digit_panel(self, parent_widget=None):
679682 self ._ms_minus_placeholder .setVisible (False )
680683 minus_row .addWidget (self ._ms_minus_placeholder )
681684
685+ for row in (plus_row , digits_row , minus_row ):
686+ row .insertStretch (0 , 1 )
687+ row .addStretch (1 )
688+ self ._digit_plus_row_layout = plus_row
689+ self ._digit_digits_row_layout = digits_row
690+ self ._digit_minus_row_layout = minus_row
691+
682692 digit_v .addLayout (plus_row )
683693 digit_v .addLayout (digits_row )
684694 digit_v .addLayout (minus_row )
@@ -757,7 +767,7 @@ def _build_controls_panel(self):
757767 onClick = lambda : self ._set_preset_category ("recent" ),
758768 )
759769 self .preset_segment .setCurrentItem ("common" )
760- preset_panel_layout .addWidget (self .preset_segment , 0 , Qt .AlignCenter )
770+ preset_panel_layout .addWidget (self .preset_segment , 0 , Qt .AlignLeft )
761771
762772 self ._common_presets = [
763773 _Preset ("05:00" , 5 * 60 ),
@@ -785,7 +795,7 @@ def _build_controls_panel(self):
785795 preset_panel_layout .addLayout (self .preset_grid )
786796 self ._sync_preset_buttons ()
787797
788- controls_layout .addWidget (self .preset_panel , 0 , Qt .AlignTop )
798+ controls_layout .addWidget (self .preset_panel , 0 , Qt .AlignTop | Qt . AlignLeft )
789799 self ._build_stopwatch_panel (controls_layout )
790800 controls_layout .addStretch (1 )
791801
@@ -1209,25 +1219,42 @@ def _apply_time_font(self, mode: str):
12091219 int (digit_metrics .horizontalAdvance ("0" )),
12101220 int (digit_metrics .horizontalAdvance ("8" )),
12111221 )
1212- + 8
1222+ + 4
12131223 )
12141224
12151225 sample_colon_font = QFont (self ._font_family , int (colon_size ))
12161226 sample_colon_font .setBold (True )
12171227 colon_metrics = QFontMetrics (sample_colon_font )
1218- colon_width = int (colon_metrics .horizontalAdvance (":" )) + 6
1228+ colon_width = int (colon_metrics .horizontalAdvance (":" )) + 2
12191229
12201230 sample_ms_font = QFont (self ._font_family , int (ms_size ))
12211231 sample_ms_font .setBold (True )
12221232 ms_metrics = QFontMetrics (sample_ms_font )
1223- ms_width = int (ms_metrics .horizontalAdvance (".000" )) + 10
1233+ ms_width = int (ms_metrics .horizontalAdvance (".000" )) + 2
12241234 else :
12251235 digit_size = 50
1226- digit_width = 42
12271236 colon_size = 42
12281237 ms_size = 32
1229- ms_width = 84
1230- colon_width = 14
1238+ sample_digit_font = QFont (self ._font_family , int (digit_size ))
1239+ sample_digit_font .setBold (True )
1240+ digit_metrics = QFontMetrics (sample_digit_font )
1241+ digit_width = (
1242+ max (
1243+ int (digit_metrics .horizontalAdvance ("0" )),
1244+ int (digit_metrics .horizontalAdvance ("8" )),
1245+ )
1246+ + 4
1247+ )
1248+
1249+ sample_colon_font = QFont (self ._font_family , int (colon_size ))
1250+ sample_colon_font .setBold (True )
1251+ colon_metrics = QFontMetrics (sample_colon_font )
1252+ colon_width = int (colon_metrics .horizontalAdvance (":" )) + 2
1253+
1254+ sample_ms_font = QFont (self ._font_family , int (ms_size ))
1255+ sample_ms_font .setBold (True )
1256+ ms_metrics = QFontMetrics (sample_ms_font )
1257+ ms_width = int (ms_metrics .horizontalAdvance (".000" )) + 2
12311258 date_size = 18 if mode == "clock" else 16
12321259
12331260 for lab in self ._digit_labels :
@@ -1381,6 +1408,7 @@ def _sync_controls_state(self):
13811408 or force_compact_by_width
13821409 )
13831410 self ._set_compact_view (desired_compact )
1411+
13841412 if not is_mini :
13851413 self .left_container .setSizePolicy (
13861414 QSizePolicy .Minimum , QSizePolicy .Expanding
@@ -1482,21 +1510,68 @@ def _sync_controls_state(self):
14821510 and self ._center_between_spacer is not None
14831511 and self ._center_right_spacer is not None
14841512 ):
1513+ digit_rows = [
1514+ getattr (self , "_digit_plus_row_layout" , None ),
1515+ getattr (self , "_digit_digits_row_layout" , None ),
1516+ getattr (self , "_digit_minus_row_layout" , None ),
1517+ ]
1518+ for row in digit_rows :
1519+ if row is not None and row .count () >= 2 :
1520+ row .setStretch (0 , 1 )
1521+ row .setStretch (row .count () - 1 , 1 )
1522+
1523+ base_margin = 20 if w and (w .isFullScreen () or w .isMaximized ()) else 0
1524+ between_w = 0
1525+ if not is_mini and not desired_compact :
1526+ if mode == "clock" :
1527+ between_w = 0
1528+ elif window_width > 550 :
1529+ between_w = 20
1530+ else :
1531+ between_w = 0
1532+
1533+ extra_left = 0
1534+ if not is_mini :
1535+ if (
1536+ mode == "countdown"
1537+ and getattr (self , "preset_panel" , None ) is not None
1538+ and self .preset_panel .isVisible ()
1539+ and getattr (self , "right_container" , None ) is not None
1540+ and self .right_container .isVisible ()
1541+ ):
1542+ extra_left = between_w + max (
1543+ 0 , int (self .right_container .sizeHint ().width ())
1544+ )
1545+ elif (
1546+ mode == "stopwatch"
1547+ and getattr (self , "right_container" , None ) is not None
1548+ and self .right_container .isVisible ()
1549+ ):
1550+ extra_left = between_w + max (
1551+ 0 , int (self .right_container .sizeHint ().width ())
1552+ )
1553+
1554+ try :
1555+ cap = max (
1556+ 0 ,
1557+ int (window_width )
1558+ - max (0 , int (self .left_container .sizeHint ().width ()))
1559+ - 10 ,
1560+ )
1561+ extra_left = min (int (extra_left ), int (cap ))
1562+ except Exception :
1563+ extra_left = int (extra_left )
1564+
14851565 self ._center_left_spacer .changeSize (
1486- 0 , 0 , QSizePolicy .Expanding , QSizePolicy .Minimum
1566+ int (base_margin ) + int (extra_left ),
1567+ 0 ,
1568+ QSizePolicy .Expanding ,
1569+ QSizePolicy .Minimum ,
14871570 )
14881571 self ._center_right_spacer .changeSize (
1489- 0 , 0 , QSizePolicy .Expanding , QSizePolicy .Minimum
1572+ int ( base_margin ) , 0 , QSizePolicy .Expanding , QSizePolicy .Minimum
14901573 )
14911574
1492- if w and (w .isFullScreen () or w .isMaximized ()):
1493- self ._center_left_spacer .changeSize (
1494- 20 , 0 , QSizePolicy .Expanding , QSizePolicy .Minimum
1495- )
1496- self ._center_right_spacer .changeSize (
1497- 20 , 0 , QSizePolicy .Expanding , QSizePolicy .Minimum
1498- )
1499-
15001575 if not is_mini and not desired_compact :
15011576 # For clock mode the right panel is hidden; keep the center
15021577 # spacer fixed so the left clock container stays centered.
@@ -1506,7 +1581,7 @@ def _sync_controls_state(self):
15061581 )
15071582 elif window_width > 550 :
15081583 self ._center_between_spacer .changeSize (
1509- 20 , 0 , QSizePolicy .MinimumExpanding , QSizePolicy .Minimum
1584+ 20 , 0 , QSizePolicy .Fixed , QSizePolicy .Minimum
15101585 )
15111586 else :
15121587 self ._center_between_spacer .changeSize (
0 commit comments