2
2
using Avalonia . Controls . Selection ;
3
3
using Avalonia . Media . Imaging ;
4
4
using Avalonia . Threading ;
5
+ using OpenLoco . Common . Logging ;
5
6
using OpenLoco . Dat ;
6
7
using OpenLoco . Dat . Types ;
7
8
using ReactiveUI ;
10
11
using SixLabors . ImageSharp . PixelFormats ;
11
12
using System ;
12
13
using System . Collections . Generic ;
14
+ using System . Collections . Immutable ;
13
15
using System . IO ;
14
16
using System . Linq ;
15
17
using System . Reactive . Linq ;
18
+ using System . Text . RegularExpressions ;
16
19
using System . Threading . Tasks ;
17
20
using System . Windows . Input ;
18
21
using Image = SixLabors . ImageSharp . Image ;
@@ -23,13 +26,15 @@ public class ImageTableViewModel : ReactiveObject, IExtraContentViewModel, ILoco
23
26
{
24
27
readonly IHasG1Elements G1Provider ;
25
28
readonly IImageTableNameProvider NameProvider ;
29
+ readonly ILogger Logger ;
26
30
27
- public ImageTableViewModel ( IHasG1Elements g1ElementProvider , IImageTableNameProvider imageNameProvider , PaletteMap paletteMap , IList < Image < Rgba32 > > images )
31
+ public ImageTableViewModel ( IHasG1Elements g1ElementProvider , IImageTableNameProvider imageNameProvider , PaletteMap paletteMap , IList < Image < Rgba32 > > images , ILogger logger )
28
32
{
29
33
G1Provider = g1ElementProvider ;
30
34
NameProvider = imageNameProvider ;
31
35
PaletteMap = paletteMap ;
32
36
Images = images ;
37
+ Logger = logger ;
33
38
34
39
_ = this . WhenAnyValue ( o => o . G1Provider )
35
40
. Subscribe ( _ => this . RaisePropertyChanged ( nameof ( Images ) ) ) ;
@@ -60,6 +65,7 @@ public ImageTableViewModel(IHasG1Elements g1ElementProvider, IImageTableNameProv
60
65
} ;
61
66
animationTimer . Tick += AnimationTimer_Tick ;
62
67
animationTimer . Start ( ) ;
68
+ Logger = logger ;
63
69
}
64
70
65
71
readonly DispatcherTimer animationTimer ;
@@ -172,6 +178,7 @@ public UIG1Element32? SelectedG1Element
172
178
? null
173
179
: new UIG1Element32 ( SelectedImageIndex , GetImageName ( NameProvider , SelectedImageIndex ) , G1Provider . G1Elements [ SelectedImageIndex ] ) ;
174
180
181
+ //todo: second half should be model
175
182
public async Task ImportImages ( )
176
183
{
177
184
var folders = await PlatformSpecific . OpenFolderPicker ( ) ;
@@ -182,10 +189,32 @@ public async Task ImportImages()
182
189
}
183
190
184
191
var dirPath = dir . Path . LocalPath ;
185
- if ( Directory . Exists ( dirPath ) && Directory . EnumerateFiles ( dirPath ) . Any ( ) )
192
+ if ( ! Directory . Exists ( dirPath ) )
186
193
{
187
- var files = Directory . GetFiles ( dirPath ) ;
188
- var sorted = files . OrderBy ( f => int . Parse ( Path . GetFileNameWithoutExtension ( f ) . Split ( '-' ) [ 0 ] ) ) ;
194
+ return ;
195
+ }
196
+
197
+ var files = Directory . GetFiles ( dirPath ) ;
198
+ if ( files . Length == 0 )
199
+ {
200
+ return ;
201
+ }
202
+
203
+ try
204
+ {
205
+ var sorted = files . OrderBy ( static f =>
206
+ {
207
+ var match = Regex . Match ( Path . GetFileNameWithoutExtension ( f ) , @".*?(\d+).*?" ) ;
208
+ return match . Success
209
+ ? int . Parse ( match . Groups [ 1 ] . Value )
210
+ : throw new InvalidDataException ( $ "Directory contains file that doesn't contain a number={ f } ") ;
211
+ } ) ;
212
+
213
+ var sortedH = sorted . ToImmutableHashSet ( ) ;
214
+ if ( G1Provider . G1Elements . Count != sortedH . Count )
215
+ {
216
+ throw new ArgumentOutOfRangeException ( $ "Directory doesn't contain the same number of images as expected Directory={ sortedH . Count } Expected={ G1Provider . G1Elements . Count } ") ;
217
+ }
189
218
190
219
var g1Elements = new List < G1Element32 > ( ) ;
191
220
var i = 0 ;
@@ -196,11 +225,16 @@ public async Task ImportImages()
196
225
var currG1 = G1Provider . G1Elements [ i ++ ] ;
197
226
currG1 . ImageData = PaletteMap . ConvertRgba32ImageToG1Data ( img , currG1 . Flags ) ; // simply overwrite existing pixel data
198
227
}
199
- }
200
228
201
- this . RaisePropertyChanged ( nameof ( Bitmaps ) ) ;
229
+ this . RaisePropertyChanged ( nameof ( Bitmaps ) ) ;
230
+ }
231
+ catch ( Exception ex )
232
+ {
233
+ Logger . Error ( ex ) ;
234
+ }
202
235
}
203
236
237
+ // todo: second half should be in model
204
238
public async Task ExportImages ( )
205
239
{
206
240
var folders = await PlatformSpecific . OpenFolderPicker ( ) ;
0 commit comments