@@ -47,37 +47,37 @@ class _FocusAwareAppBarState extends State<FocusAwareAppBar>
4747 return widget! ;
4848 },
4949 child: AppBar (
50- title: Selector <SettingsService , bool >(
51- selector: (_, settings) => settings.showNetworkIndicatorInStatusBar,
52- builder: (context, showNetwork, _) => Selector <SettingsService , bool >(
53- selector: (_, settings) => settings.showWifiWidgetInStatusBar,
54- builder: (context, showWifi, _) => Row (
55- mainAxisSize: MainAxisSize .min,
56- children: [
57- if (showNetwork)
58- const Padding (
59- padding: EdgeInsets .only (right: 12 ),
60- child: NetworkWidget (),
61- ),
62- if (showWifi) const DailyWifiUsageWidget (),
63- ],
50+ // Left side: Settings, Network indicator, WiFi usage
51+ title: Row (
52+ mainAxisSize: MainAxisSize .min,
53+ children: [
54+ // Settings button (moved to left side)
55+ _FocusableIconButton (
56+ icon: Icons .settings_outlined,
57+ onPressed: () => showDialog (context: context, builder: (_) => const SettingsPanel ()),
6458 ),
65- ),
59+ const SizedBox (width: 16 ),
60+ // Network indicator (conditionally shown)
61+ Selector <SettingsService , bool >(
62+ selector: (_, settings) => settings.showNetworkIndicatorInStatusBar,
63+ builder: (context, showNetwork, _) => showNetwork
64+ ? Padding (
65+ padding: const EdgeInsets .only (right: 12 ),
66+ child: _FocusableNetworkWidget (),
67+ )
68+ : const SizedBox .shrink (),
69+ ),
70+ // WiFi usage widget
71+ Selector <SettingsService , bool >(
72+ selector: (_, settings) => settings.showWifiWidgetInStatusBar,
73+ builder: (context, showWifi, _) => showWifi
74+ ? const DailyWifiUsageWidget ()
75+ : const SizedBox .shrink (),
76+ ),
77+ ],
6678 ),
79+ // Right side: Date/Time only
6780 actions: [
68- IconButton (
69- padding: const EdgeInsets .all (2 ),
70- constraints: const BoxConstraints (),
71- splashRadius: 20 ,
72- icon: const Icon (Icons .settings_outlined,
73- shadows: [
74- Shadow (color: Colors .black54, blurRadius: 8 , offset: Offset (0 , 2 ))
75- ],
76- ),
77- onPressed: () => showDialog (context: context, builder: (_) => const SettingsPanel ()),
78- // sometime after Flutter 3.7.5, no later than 3.16.8, the focus highlight went away
79- focusColor: Theme .of (context).primaryColorLight,
80- ),
8181 Padding (
8282 padding: const EdgeInsets .only (left: 16 , right: 32 ),
8383 child: Selector <SettingsService ,
@@ -92,16 +92,13 @@ class _FocusAwareAppBarState extends State<FocusAwareAppBar>
9292 dateFormat: service.dateFormat,
9393 timeFormat: service.timeFormat),
9494 builder: (context, dateTimeSettings, _) {
95- // TODO: Disabling the "show date" option while both are enabled causes the *time* to disappear,
96- // then re-enabling that same option causes the time to appear twice.
97- // A restart (or just changing to the full screen clock) fixes the issue, but why does this happen?
9895 return Row (
9996 mainAxisSize: MainAxisSize .min,
10097 children: [
10198 if (dateTimeSettings.showDateInStatusBar)
10299 Flexible (
103100 child: DateTimeWidget (dateTimeSettings.dateFormat,
104- key: const ValueKey ('date' ), // Unique key for date widget
101+ key: const ValueKey ('date' ),
105102 updateInterval: const Duration (minutes: 1 ),
106103 textStyle: Theme .of (context).textTheme.titleLarge! .copyWith (
107104 shadows: [
@@ -115,7 +112,7 @@ class _FocusAwareAppBarState extends State<FocusAwareAppBar>
115112 if (dateTimeSettings.showTimeInStatusBar)
116113 Flexible (
117114 child: DateTimeWidget (dateTimeSettings.timeFormat,
118- key: const ValueKey ('time' ), // Unique key for time widget
115+ key: const ValueKey ('time' ),
119116 textStyle: Theme .of (context).textTheme.titleLarge! .copyWith (
120117 shadows: [
121118 const Shadow (color: Colors .black54, offset: Offset (0 , 2 ), blurRadius: 8 )
@@ -132,4 +129,76 @@ class _FocusAwareAppBarState extends State<FocusAwareAppBar>
132129 )
133130 );
134131 }
132+ }
133+
134+ /// Reusable focusable icon button with consistent outline focus indicator
135+ class _FocusableIconButton extends StatefulWidget {
136+ final IconData icon;
137+ final VoidCallback onPressed;
138+
139+ const _FocusableIconButton ({required this .icon, required this .onPressed});
140+
141+ @override
142+ State <_FocusableIconButton > createState () => _FocusableIconButtonState ();
143+ }
144+
145+ class _FocusableIconButtonState extends State <_FocusableIconButton > {
146+ bool _focused = false ;
147+
148+ @override
149+ Widget build (BuildContext context) {
150+ return Focus (
151+ onFocusChange: (hasFocus) => setState (() => _focused = hasFocus),
152+ child: InkWell (
153+ onTap: widget.onPressed,
154+ borderRadius: BorderRadius .circular (8 ),
155+ child: Container (
156+ padding: const EdgeInsets .all (4 ), // Match network indicator padding
157+ decoration: BoxDecoration (
158+ borderRadius: BorderRadius .circular (8 ),
159+ border: _focused
160+ ? Border .all (color: Colors .white, width: 2 )
161+ : null ,
162+ boxShadow: _focused
163+ ? const [BoxShadow (color: Colors .black54, blurRadius: 8 , spreadRadius: 1 )]
164+ : null ,
165+ ),
166+ child: Icon (widget.icon,
167+ shadows: const [
168+ Shadow (color: Colors .black54, blurRadius: 8 , offset: Offset (0 , 2 ))
169+ ],
170+ ),
171+ ),
172+ ),
173+ );
174+ }
175+ }
176+
177+ /// Network widget with consistent focus indicator
178+ class _FocusableNetworkWidget extends StatefulWidget {
179+ @override
180+ State <_FocusableNetworkWidget > createState () => _FocusableNetworkWidgetState ();
181+ }
182+
183+ class _FocusableNetworkWidgetState extends State <_FocusableNetworkWidget > {
184+ bool _focused = false ;
185+
186+ @override
187+ Widget build (BuildContext context) {
188+ return Focus (
189+ onFocusChange: (hasFocus) => setState (() => _focused = hasFocus),
190+ child: Container (
191+ decoration: BoxDecoration (
192+ borderRadius: BorderRadius .circular (8 ),
193+ border: _focused
194+ ? Border .all (color: Colors .white, width: 2 )
195+ : null ,
196+ boxShadow: _focused
197+ ? const [BoxShadow (color: Colors .black54, blurRadius: 8 , spreadRadius: 1 )]
198+ : null ,
199+ ),
200+ child: const NetworkWidget (),
201+ ),
202+ );
203+ }
135204}
0 commit comments