@@ -82,13 +82,216 @@ class AccessibilityOverridesPane extends StatelessWidget {
8282
8383 @override
8484 Widget build (BuildContext context) {
85- return const DevToolsAreaPane (
86- header: AreaPaneHeader (title: Text ('Accessibility Overrides' )),
87- child: CenteredMessage (
88- message:
89- 'Accessibility overrides placeholder.\n '
90- '// TODO(hannah-hyj): Implement setting overrides (brightness, text scale, bold text, screen reader, high contrast).' ,
85+ final theme = Theme .of (context);
86+ final controller = screenControllers.lookup <AccessibilityController >();
87+ return DevToolsAreaPane (
88+ header: const AreaPaneHeader (title: Text ('Accessibility Overrides' )),
89+ child: Scrollbar (
90+ child: SingleChildScrollView (
91+ padding: const EdgeInsets .all (defaultSpacing),
92+ child: Column (
93+ crossAxisAlignment: CrossAxisAlignment .start,
94+ children: [
95+ Text (
96+ 'Simulate and test accessibility settings on the connected device in real-time.' ,
97+ style: theme.subtleTextStyle,
98+ ),
99+ const SizedBox (height: defaultSpacing),
100+ const Divider (),
101+ const SizedBox (height: denseSpacing),
102+ _BrightnessOverride (controller: controller),
103+ const SizedBox (height: defaultSpacing),
104+ _TextScaleOverride (controller: controller),
105+ const SizedBox (height: defaultSpacing),
106+ _SwitchOverride (
107+ label: 'Bold Text' ,
108+ description: 'Forces all text in the application to be bold.' ,
109+ notifier: controller.boldText,
110+ ),
111+ const SizedBox (height: defaultSpacing),
112+ _SwitchOverride (
113+ label: 'Screen Reader Debugger' ,
114+ description:
115+ 'Enables interactive screen reader simulation semantics.' ,
116+ notifier: controller.screenReader,
117+ ),
118+ const SizedBox (height: defaultSpacing),
119+ _SwitchOverride (
120+ label: 'High Contrast' ,
121+ description: 'Increases the contrast of text and icons.' ,
122+ notifier: controller.highContrast,
123+ ),
124+ ],
125+ ),
126+ ),
91127 ),
92128 );
93129 }
94130}
131+
132+ class _BrightnessOverride extends StatelessWidget {
133+ const _BrightnessOverride ({required this .controller});
134+
135+ final AccessibilityController controller;
136+
137+ @override
138+ Widget build (BuildContext context) {
139+ final theme = Theme .of (context);
140+ return Column (
141+ crossAxisAlignment: CrossAxisAlignment .start,
142+ children: [
143+ Text (
144+ 'Brightness' ,
145+ style: theme.boldTextStyle,
146+ ),
147+ const SizedBox (height: densePadding),
148+ Text (
149+ 'Override the color scheme mode of the app.' ,
150+ style: theme.subtleTextStyle,
151+ ),
152+ const SizedBox (height: denseSpacing),
153+ ValueListenableBuilder <String >(
154+ valueListenable: controller.brightness,
155+ builder: (context, value, _) {
156+ return RoundedDropDownButton <String >(
157+ isExpanded: true ,
158+ value: value,
159+ items: const [
160+ DropdownMenuItem (
161+ value: 'System' ,
162+ child: Text ('System Default' ),
163+ ),
164+ DropdownMenuItem (
165+ value: 'Light' ,
166+ child: Text ('Light Mode' ),
167+ ),
168+ DropdownMenuItem (
169+ value: 'Dark' ,
170+ child: Text ('Dark Mode' ),
171+ ),
172+ ],
173+ onChanged: (newValue) {
174+ if (newValue != null ) {
175+ controller.brightness.value = newValue;
176+ }
177+ },
178+ );
179+ },
180+ ),
181+ ],
182+ );
183+ }
184+ }
185+
186+ class _TextScaleOverride extends StatelessWidget {
187+ const _TextScaleOverride ({required this .controller});
188+
189+ final AccessibilityController controller;
190+
191+ static const _minTextScale = 0.5 ;
192+ static const _maxTextScale = 3.0 ;
193+ static const _textScaleDivisions = 25 ;
194+
195+ @override
196+ Widget build (BuildContext context) {
197+ final theme = Theme .of (context);
198+ return Column (
199+ crossAxisAlignment: CrossAxisAlignment .start,
200+ children: [
201+ ValueListenableBuilder <double >(
202+ valueListenable: controller.textScale,
203+ builder: (context, value, _) {
204+ return Row (
205+ mainAxisAlignment: MainAxisAlignment .spaceBetween,
206+ children: [
207+ Column (
208+ crossAxisAlignment: CrossAxisAlignment .start,
209+ children: [
210+ Text (
211+ 'Text Scale' ,
212+ style: theme.boldTextStyle,
213+ ),
214+ const SizedBox (height: densePadding),
215+ Text (
216+ 'Scale the system font size.' ,
217+ style: theme.subtleTextStyle,
218+ ),
219+ ],
220+ ),
221+ Text (
222+ '${value .toStringAsFixed (2 )}x' ,
223+ style: theme.boldTextStyle,
224+ ),
225+ ],
226+ );
227+ },
228+ ),
229+ const SizedBox (height: densePadding),
230+ ValueListenableBuilder <double >(
231+ valueListenable: controller.textScale,
232+ builder: (context, value, _) {
233+ return Slider (
234+ value: value,
235+ min: _minTextScale,
236+ max: _maxTextScale,
237+ divisions: _textScaleDivisions,
238+ onChanged: (newValue) {
239+ controller.textScale.value = newValue;
240+ },
241+ );
242+ },
243+ ),
244+ ],
245+ );
246+ }
247+ }
248+
249+ class _SwitchOverride extends StatelessWidget {
250+ const _SwitchOverride ({
251+ required this .label,
252+ required this .description,
253+ required this .notifier,
254+ });
255+
256+ final String label;
257+ final String description;
258+ final ValueNotifier <bool > notifier;
259+
260+ @override
261+ Widget build (BuildContext context) {
262+ final theme = Theme .of (context);
263+ return Row (
264+ children: [
265+ Expanded (
266+ child: Column (
267+ crossAxisAlignment: CrossAxisAlignment .start,
268+ children: [
269+ Text (
270+ label,
271+ style: theme.boldTextStyle,
272+ ),
273+ const SizedBox (height: densePadding),
274+ Text (
275+ description,
276+ style: theme.subtleTextStyle,
277+ ),
278+ ],
279+ ),
280+ ),
281+ ValueListenableBuilder <bool >(
282+ valueListenable: notifier,
283+ builder: (context, enabled, _) {
284+ return Switch (
285+ value: enabled,
286+ onChanged: (newValue) {
287+ notifier.value = newValue;
288+ },
289+ );
290+ },
291+ ),
292+ ],
293+ );
294+ }
295+ }
296+
297+
0 commit comments