@@ -139,18 +139,41 @@ public override void initState() {
139
139
this . insertAll ( this . widget . initialEntries ) ;
140
140
}
141
141
142
- public void insert ( OverlayEntry entry , OverlayEntry above = null ) {
143
- D . assert ( entry . _overlay == null ) ;
144
- D . assert ( above == null || ( above . _overlay == this && this . _entries . Contains ( above ) ) ) ;
145
- entry . _overlay = this ;
146
- this . setState ( ( ) => {
147
- int index = above == null ? this . _entries . Count : this . _entries . IndexOf ( above ) + 1 ;
148
- this . _entries . Insert ( index , entry ) ;
149
- } ) ;
142
+ internal int _insertionIndex ( OverlayEntry below , OverlayEntry above ) {
143
+ D . assert ( below == null || above == null ) ;
144
+ if ( below != null ) {
145
+ return this . _entries . IndexOf ( below ) ;
146
+ }
147
+
148
+ if ( above != null ) {
149
+ return this . _entries . IndexOf ( above ) + 1 ;
150
+ }
151
+
152
+ return this . _entries . Count ;
150
153
}
151
154
152
- public void insertAll ( ICollection < OverlayEntry > entries , OverlayEntry above = null ) {
153
- D . assert ( above == null || ( above . _overlay == this && this . _entries . Contains ( above ) ) ) ;
155
+ public void insert ( OverlayEntry entry , OverlayEntry below = null , OverlayEntry above = null ) {
156
+ D . assert ( above == null || below == null , ( ) => "Only one of `above` and `below` may be specified." ) ;
157
+ D . assert ( above == null || ( above . _overlay == this && this . _entries . Contains ( above ) ) ,
158
+ ( ) => "The provided entry for `above` is not present in the Overlay." ) ;
159
+ D . assert ( below == null || ( below . _overlay == this && this . _entries . Contains ( below ) ) ,
160
+ ( ) => "The provided entry for `below` is not present in the Overlay." ) ;
161
+ D . assert ( ! this . _entries . Contains ( entry ) , ( ) => "The specified entry is already present in the Overlay." ) ;
162
+ D . assert ( entry . _overlay == null , ( ) => "The specified entry is already present in another Overlay." ) ;
163
+ entry . _overlay = this ;
164
+ this . setState ( ( ) => { this . _entries . Insert ( this . _insertionIndex ( below , above ) , entry ) ; } ) ;
165
+ }
166
+
167
+ public void insertAll ( ICollection < OverlayEntry > entries , OverlayEntry below = null , OverlayEntry above = null ) {
168
+ D . assert ( above == null || below == null , ( ) => "Only one of `above` and `below` may be specified." ) ;
169
+ D . assert ( above == null || ( above . _overlay == this && this . _entries . Contains ( above ) ) ,
170
+ ( ) => "The provided entry for `above` is not present in the Overlay." ) ;
171
+ D . assert ( below == null || ( below . _overlay == this && this . _entries . Contains ( below ) ) ,
172
+ ( ) => "The provided entry for `below` is not present in the Overlay." ) ;
173
+ D . assert ( entries . All ( entry => ! this . _entries . Contains ( entry ) ) ,
174
+ ( ) => "One or more of the specified entries are already present in the Overlay." ) ;
175
+ D . assert ( entries . All ( entry => entry . _overlay == null ) ,
176
+ ( ) => "One or more of the specified entries are already present in another Overlay." ) ;
154
177
if ( entries . isEmpty ( ) ) {
155
178
return ;
156
179
}
@@ -161,16 +184,48 @@ public void insertAll(ICollection<OverlayEntry> entries, OverlayEntry above = nu
161
184
}
162
185
163
186
this . setState ( ( ) => {
164
- int index = above == null ? this . _entries . Count : this . _entries . IndexOf ( above ) + 1 ;
165
- this . _entries . InsertRange ( index , entries ) ;
187
+ this . _entries . InsertRange ( this . _insertionIndex ( below , above ) , entries ) ;
188
+ } ) ;
189
+ }
190
+
191
+ public void rearrange ( IEnumerable < OverlayEntry > newEntries , OverlayEntry below = null , OverlayEntry above = null ) {
192
+ List < OverlayEntry > newEntriesList =
193
+ newEntries is List < OverlayEntry > ? ( newEntries as List < OverlayEntry > ) : newEntries . ToList ( ) ;
194
+ D . assert ( above == null || below == null , ( ) => "Only one of `above` and `below` may be specified." ) ;
195
+ D . assert ( above == null || ( above . _overlay == this && this . _entries . Contains ( above ) ) ,
196
+ ( ) => "The provided entry for `above` is not present in the Overlay." ) ;
197
+ D . assert ( below == null || ( below . _overlay == this && this . _entries . Contains ( below ) ) ,
198
+ ( ) => "The provided entry for `below` is not present in the Overlay." ) ;
199
+ D . assert ( newEntriesList . All ( entry => ! this . _entries . Contains ( entry ) ) ,
200
+ ( ) => "One or more of the specified entries are already present in the Overlay." ) ;
201
+ D . assert ( newEntriesList . All ( entry => entry . _overlay == null ) ,
202
+ ( ) => "One or more of the specified entries are already present in another Overlay." ) ;
203
+ if ( newEntriesList . isEmpty ( ) ) {
204
+ return ;
205
+ }
206
+
207
+ if ( this . _entries . SequenceEqual ( newEntriesList ) ) {
208
+ return ;
209
+ }
210
+
211
+ HashSet < OverlayEntry > old = new HashSet < OverlayEntry > ( this . _entries ) ;
212
+ foreach ( OverlayEntry entry in newEntriesList ) {
213
+ entry . _overlay = entry . _overlay ?? this ;
214
+ }
215
+ this . setState ( ( ) => {
216
+ this . _entries . Clear ( ) ;
217
+ this . _entries . AddRange ( newEntriesList ) ;
218
+ foreach ( OverlayEntry entry in newEntriesList ) {
219
+ old . Remove ( entry ) ;
220
+ }
221
+
222
+ this . _entries . InsertRange ( this . _insertionIndex ( below , above ) , old ) ;
166
223
} ) ;
167
224
}
168
225
169
226
internal void _remove ( OverlayEntry entry ) {
170
227
if ( this . mounted ) {
171
- this . setState ( ( ) => {
172
- this . _entries . Remove ( entry ) ;
173
- } ) ;
228
+ this . setState ( ( ) => { this . _entries . Remove ( entry ) ; } ) ;
174
229
}
175
230
}
176
231
0 commit comments