11import 'package:flutter/material.dart' ;
22import 'package:provider/provider.dart' ;
33import 'package:settings/view/pages/keyboard/input_source_model.dart' ;
4+ import 'package:yaru_icons/yaru_icons.dart' ;
45import 'package:yaru_widgets/yaru_widgets.dart' ;
56
67class InputSourceSelectionSection extends StatelessWidget {
@@ -18,28 +19,155 @@ class InputSourceSelectionSection extends StatelessWidget {
1819 if (! snapshot.hasData) {
1920 return const CircularProgressIndicator ();
2021 }
21- return YaruSection (headline: 'Input Sources' , children: [
22- ReorderableListView (
23- shrinkWrap: true ,
24- children: < Widget > [
25- for (int index = 0 ; index < snapshot.data! .length; index++ )
26- ListTile (
27- key: Key ('$index ' ),
28- title: Text ('${index + 1 }. ${snapshot .data ![index ]}' ),
29- ),
30- ],
31- onReorder: (int oldIndex, int newIndex) async {
32- final sources = snapshot.data! ;
33- if (oldIndex < newIndex) {
34- newIndex -= 1 ;
35- }
36- final item = snapshot.data! .removeAt (oldIndex);
37- sources.insert (newIndex, item);
38- model.setInputSources (sources);
39- },
40- )
41- ]);
22+ return YaruSection (
23+ headline: 'Input Sources' ,
24+ headerWidget: SizedBox (
25+ height: 40 ,
26+ width: 40 ,
27+ child: TextButton (
28+ onPressed: () => showDialog (
29+ context: context,
30+ builder: (context) => ChangeNotifierProvider .value (
31+ value: model,
32+ child: const _AddKeymapDialog (),
33+ )),
34+ child: const Icon (YaruIcons .plus)),
35+ ),
36+ children: [
37+ ReorderableListView (
38+ buildDefaultDragHandles: false ,
39+ shrinkWrap: true ,
40+ children: < Widget > [
41+ for (int index = 0 ; index < snapshot.data! .length; index++ )
42+ ReorderableDragStartListener (
43+ key: Key ('$index ' ),
44+ index: index,
45+ child: ChangeNotifierProvider .value (
46+ value: model,
47+ child: _InputTypeRow (
48+ inputType: snapshot.data! [index],
49+ ),
50+ ),
51+ ),
52+ ],
53+ onReorder: (int oldIndex, int newIndex) async {
54+ final sources = snapshot.data! ;
55+ if (oldIndex < newIndex) {
56+ newIndex -= 1 ;
57+ }
58+ final item = snapshot.data! .removeAt (oldIndex);
59+ sources.insert (newIndex, item);
60+ model.setInputSources (sources);
61+ },
62+ ),
63+ ]);
4264 },
4365 );
4466 }
4567}
68+
69+ class _InputTypeRow extends StatelessWidget {
70+ const _InputTypeRow ({
71+ Key ? key,
72+ required this .inputType,
73+ }) : super (key: key);
74+
75+ final String inputType;
76+
77+ @override
78+ Widget build (BuildContext context) {
79+ final model = context.watch <InputSourceModel >();
80+ return YaruRow (
81+ actionWidget: Row (
82+ children: [
83+ YaruOptionButton (
84+ onPressed: () => model.showKeyboardLayout (inputType),
85+ iconData: YaruIcons .input_keyboard),
86+ const SizedBox (
87+ width: 10 ,
88+ ),
89+ YaruOptionButton (
90+ onPressed: () => model.removeInputSource (inputType),
91+ iconData: YaruIcons .trash)
92+ ],
93+ ),
94+ trailingWidget: Text (
95+ inputType,
96+ style: const TextStyle (fontSize: 16 , fontWeight: FontWeight .normal),
97+ ),
98+ leadingWidget: Icon (
99+ YaruIcons .drag_handle,
100+ color: Theme .of (context).colorScheme.onSurface.withOpacity (0.5 ),
101+ ));
102+ }
103+ }
104+
105+ class _AddKeymapDialog extends StatefulWidget {
106+ const _AddKeymapDialog ({Key ? key}) : super (key: key);
107+
108+ @override
109+ State <_AddKeymapDialog > createState () => _AddKeymapDialogState ();
110+ }
111+
112+ class _AddKeymapDialogState extends State <_AddKeymapDialog > {
113+ int tabbedIndex = 0 ;
114+ bool variantsLoad = false ;
115+
116+ @override
117+ Widget build (BuildContext context) {
118+ final model = context.watch <InputSourceModel >();
119+ return variantsLoad == false
120+ ? YaruSimpleDialog (
121+ title: 'Add Keymap' ,
122+ closeIconData: YaruIcons .window_close,
123+ children: [
124+ for (var i = 0 ; i < model.inputSources.length; i++ )
125+ InkWell (
126+ borderRadius: BorderRadius .circular (4.0 ),
127+ onTap: () => setState (() {
128+ tabbedIndex = i;
129+ variantsLoad = true ;
130+ }),
131+ child: YaruRow (
132+ width: 100 ,
133+ description: model.inputSources[i].name,
134+ actionWidget: const SizedBox (),
135+ trailingWidget: Text (model.inputSources[i].description! ),
136+ ),
137+ ),
138+ ])
139+ : YaruSimpleDialog (
140+ title: (model.inputSources[tabbedIndex].name ?? '' ) +
141+ ': ' +
142+ (model.inputSources[tabbedIndex].description ?? '' ),
143+ closeIconData: YaruIcons .window_close,
144+ children: [
145+ for (var variant in model.inputSources[tabbedIndex].variants)
146+ InkWell (
147+ onTap: () {
148+ if (model.inputSources[tabbedIndex].name != null &&
149+ variant.name != null ) {
150+ model.addInputSource (
151+ model.inputSources[tabbedIndex].name! +
152+ '+' +
153+ variant.name! );
154+ }
155+
156+ Navigator .of (context).pop ();
157+ setState (() {});
158+ },
159+ borderRadius: BorderRadius .circular (4.0 ),
160+ child: YaruRow (
161+ width: 100 ,
162+ trailingWidget: Text (variant.description ?? '' ),
163+ description: variant.name ?? '' ,
164+ actionWidget: const SizedBox ()),
165+ ),
166+ TextButton (
167+ onPressed: () => setState (() {
168+ variantsLoad = false ;
169+ }),
170+ child: const Icon (YaruIcons .pan_start))
171+ ]);
172+ }
173+ }
0 commit comments