@@ -23,6 +23,8 @@ class _SearchDialogState extends State<SearchDialog> {
23
23
late TextEditingController _controller;
24
24
late List <int >? _offsets;
25
25
late int _index;
26
+ bool _case_sensitive = false ;
27
+ bool _whole_word = false ;
26
28
27
29
@override
28
30
void initState () {
@@ -35,87 +37,113 @@ class _SearchDialogState extends State<SearchDialog> {
35
37
36
38
@override
37
39
Widget build (BuildContext context) {
38
- return StatefulBuilder (builder: (context, setState) {
39
- var label = '' ;
40
- if (_offsets != null ) {
41
- label = '${_offsets !.length } ${'matches' .i18n }' ;
42
- if (_offsets! .isNotEmpty) {
43
- label += ', ${'showing match' .i18n } ${_index + 1 }' ;
44
- }
40
+ var matchShown = '' ;
41
+ if (_offsets != null ) {
42
+ if (_offsets! .isEmpty) {
43
+ matchShown = '0/0' ;
44
+ } else {
45
+ matchShown = '${_index + 1 }/${_offsets !.length }' ;
45
46
}
46
- return AlertDialog (
47
- backgroundColor: widget.dialogTheme? .dialogBackgroundColor,
48
- content: Container (
49
- height: 100 ,
50
- child: Column (
51
- children: [
52
- TextField (
53
- keyboardType: TextInputType .multiline,
54
- style: widget.dialogTheme? .inputTextStyle,
55
- decoration: InputDecoration (
56
- labelText: 'Search' .i18n,
57
- labelStyle: widget.dialogTheme? .labelTextStyle,
58
- floatingLabelStyle: widget.dialogTheme? .labelTextStyle),
59
- autofocus: true ,
60
- onChanged: _textChanged,
61
- controller: _controller,
47
+ }
48
+
49
+ return Dialog (
50
+ shape: RoundedRectangleBorder (
51
+ borderRadius: BorderRadius .circular (5 ),
52
+ ),
53
+ backgroundColor: widget.dialogTheme? .dialogBackgroundColor,
54
+ alignment: Alignment .bottomCenter,
55
+ insetPadding: EdgeInsets .zero,
56
+ child: SizedBox (
57
+ height: 45 ,
58
+ child: Row (
59
+ children: [
60
+ Tooltip (
61
+ message: 'Case sensitivity and whole word search' ,
62
+ child: ToggleButtons (
63
+ onPressed: (int index) {
64
+ if (index == 0 ) {
65
+ _changeCaseSensitivity ();
66
+ } else if (index == 1 ) {
67
+ _changeWholeWord ();
68
+ }
69
+ },
70
+ borderRadius: const BorderRadius .all (Radius .circular (2 )),
71
+ isSelected: [_case_sensitive, _whole_word],
72
+ children: const [
73
+ Text (
74
+ '\u 0391\u 03b1' ,
75
+ style: TextStyle (
76
+ fontFamily: 'MaterialIcons' ,
77
+ fontSize: 24 ,
78
+ ),
79
+ ),
80
+ Text (
81
+ '\u 201c\u 2026\u 201d' ,
82
+ style: TextStyle (
83
+ fontFamily: 'MaterialIcons' ,
84
+ fontSize: 24 ,
85
+ ),
86
+ ),
87
+ ],
62
88
),
63
- if (_offsets != null )
64
- Padding (
65
- padding: const EdgeInsets .all (8 ),
66
- child: Text (label, textAlign: TextAlign .left),
89
+ ),
90
+ Expanded (
91
+ child: Padding (
92
+ padding: const EdgeInsets .only (bottom: 12 , left: 5 ),
93
+ child: TextField (
94
+ style: widget.dialogTheme? .inputTextStyle,
95
+ decoration: InputDecoration (
96
+ isDense: true ,
97
+ suffixText: (_offsets != null ) ? matchShown : '' ,
98
+ suffixStyle: widget.dialogTheme? .labelTextStyle,
99
+ ),
100
+ autofocus: true ,
101
+ onChanged: _textChanged,
102
+ textInputAction: TextInputAction .done,
103
+ onEditingComplete: _findText,
104
+ controller: _controller,
67
105
),
68
- ],
69
- ),
70
- ),
71
- actions: [
72
- if (_offsets != null && _offsets! .isNotEmpty && _index > 0 )
73
- TextButton (
74
- onPressed: () {
75
- setState (() {
76
- _index -= 1 ;
77
- });
78
- _moveToPosition ();
79
- },
80
- child: Text (
81
- 'Prev' .i18n,
82
- style: widget.dialogTheme? .labelTextStyle,
83
106
),
84
107
),
85
- if (_offsets != null &&
86
- _offsets! .isNotEmpty &&
87
- _index < _offsets! .length - 1 )
88
- TextButton (
89
- onPressed: () {
90
- setState (() {
91
- _index += 1 ;
92
- });
93
- _moveToPosition ();
94
- },
95
- child: Text (
96
- 'Next' .i18n,
97
- style: widget.dialogTheme? .labelTextStyle,
108
+ if (_offsets == null )
109
+ IconButton (
110
+ icon: const Icon (Icons .search),
111
+ tooltip: 'Find text' ,
112
+ onPressed: _findText,
98
113
),
99
- ),
100
- if (_offsets == null && _text.isNotEmpty)
101
- TextButton (
102
- onPressed: () {
103
- setState (() {
104
- _offsets = widget.controller.document.search (_text);
105
- _index = 0 ;
106
- });
107
- if (_offsets! .isNotEmpty) {
108
- _moveToPosition ();
109
- }
110
- },
111
- child: Text (
112
- 'Ok' .i18n,
113
- style: widget.dialogTheme? .labelTextStyle,
114
+ if (_offsets != null )
115
+ IconButton (
116
+ icon: const Icon (Icons .keyboard_arrow_up),
117
+ tooltip: 'Move to previous occurrence' ,
118
+ onPressed: (_offsets! .isNotEmpty) ? _moveToPrevious : null ,
114
119
),
115
- ),
116
- ],
120
+ if (_offsets != null )
121
+ IconButton (
122
+ icon: const Icon (Icons .keyboard_arrow_down),
123
+ tooltip: 'Move to next occurrence' ,
124
+ onPressed: (_offsets! .isNotEmpty) ? _moveToNext : null ,
125
+ ),
126
+ ],
127
+ ),
128
+ ),
129
+ );
130
+ }
131
+
132
+ void _findText () {
133
+ if (_text.isEmpty) {
134
+ return ;
135
+ }
136
+ setState (() {
137
+ _offsets = widget.controller.document.search (
138
+ _text,
139
+ caseSensitive: _case_sensitive,
140
+ wholeWord: _whole_word,
117
141
);
142
+ _index = 0 ;
118
143
});
144
+ if (_offsets! .isNotEmpty) {
145
+ _moveToPosition ();
146
+ }
119
147
}
120
148
121
149
void _moveToPosition () {
@@ -126,11 +154,55 @@ class _SearchDialogState extends State<SearchDialog> {
126
154
ChangeSource .LOCAL );
127
155
}
128
156
157
+ void _moveToPrevious () {
158
+ if (_offsets! .isEmpty) {
159
+ return ;
160
+ }
161
+ setState (() {
162
+ if (_index > 0 ) {
163
+ _index -= 1 ;
164
+ } else {
165
+ _index = _offsets! .length - 1 ;
166
+ }
167
+ });
168
+ _moveToPosition ();
169
+ }
170
+
171
+ void _moveToNext () {
172
+ if (_offsets! .isEmpty) {
173
+ return ;
174
+ }
175
+ setState (() {
176
+ if (_index < _offsets! .length - 1 ) {
177
+ _index += 1 ;
178
+ } else {
179
+ _index = 0 ;
180
+ }
181
+ });
182
+ _moveToPosition ();
183
+ }
184
+
129
185
void _textChanged (String value) {
130
186
setState (() {
131
187
_text = value;
132
188
_offsets = null ;
133
189
_index = 0 ;
134
190
});
135
191
}
192
+
193
+ void _changeCaseSensitivity () {
194
+ setState (() {
195
+ _case_sensitive = ! _case_sensitive;
196
+ _offsets = null ;
197
+ _index = 0 ;
198
+ });
199
+ }
200
+
201
+ void _changeWholeWord () {
202
+ setState (() {
203
+ _whole_word = ! _whole_word;
204
+ _offsets = null ;
205
+ _index = 0 ;
206
+ });
207
+ }
136
208
}
0 commit comments