Skip to content

Commit 3de55eb

Browse files
authored
Add image bounding box and origin overlay (#119)
add colour selections
1 parent 2b882a3 commit 3de55eb

File tree

2 files changed

+111
-63
lines changed

2 files changed

+111
-63
lines changed

Gui/ViewModels/SubObjectTypes/ImageTableViewModel.cs

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public ImageTableViewModel(IHasG1Elements g1ElementProvider, IImageTableNameProv
7979
.Subscribe(_ => this.RaisePropertyChanged(nameof(Images)));
8080
_ = this.WhenAnyValue(o => o.SelectedImageIndex)
8181
.Subscribe(_ => this.RaisePropertyChanged(nameof(SelectedG1Element)));
82+
_ = this.WhenAnyValue(o => o.SelectedBitmapPreview)
83+
.Subscribe(_ => this.RaisePropertyChanged(nameof(SelectedBitmapPreviewBorder)));
8284
_ = this.WhenAnyValue(o => o.Images)
8385
.Subscribe(_ => this.RaisePropertyChanged(nameof(Images)));
8486
_ = this.WhenAnyValue(o => o.AnimationSpeed)
@@ -108,11 +110,10 @@ public ImageTableViewModel(IHasG1Elements g1ElementProvider, IImageTableNameProv
108110

109111
public IList<Bitmap> SelectedBitmaps { get; set; }
110112

111-
[Reactive]
112-
public Bitmap SelectedBitmapPreview { get; set; }
113+
[Reactive] public Bitmap SelectedBitmapPreview { get; set; }
114+
public Avalonia.Size SelectedBitmapPreviewBorder => SelectedBitmapPreview == null ? new Avalonia.Size() : new Avalonia.Size(SelectedBitmapPreview.Size.Width + 2, SelectedBitmapPreview.Size.Height + 2);
113115

114-
[Reactive]
115-
public int AnimationWindowHeight { get; set; }
116+
[Reactive] public int AnimationWindowHeight { get; set; }
116117

117118
void SelectionChanged(object sender, SelectionModelSelectionChangedEventArgs e)
118119
{
@@ -203,6 +204,7 @@ public IList<Bitmap?> Bitmaps
203204
prevValue = list[i];
204205
}
205206
}
207+
206208
return list;
207209
}
208210
}
@@ -224,60 +226,62 @@ public async Task ImportImages()
224226
animationTimer.Stop();
225227

226228
var folders = await PlatformSpecific.OpenFolderPicker();
227-
var dir = folders.FirstOrDefault();
228-
if (dir == null)
229+
using (var dir = folders.FirstOrDefault())
229230
{
230-
return;
231-
}
232-
233-
var dirPath = dir.Path.LocalPath;
234-
if (!Directory.Exists(dirPath))
235-
{
236-
return;
237-
}
231+
if (dir == null)
232+
{
233+
return;
234+
}
238235

239-
try
240-
{
241-
var offsetsFile = Path.Combine(dirPath, "sprites.json");
242-
if (File.Exists(offsetsFile))
236+
var dirPath = dir.Path.LocalPath;
237+
if (!Directory.Exists(dirPath))
243238
{
244-
// found blender folder
245-
var offsets = JsonSerializer.Deserialize<ICollection<SpriteOffset>>(File.ReadAllText(offsetsFile)); // sprites.json is an unnamed array so we need ICollection here, not IEnumerable
246-
Logger.Debug("Found sprites.json file, using that");
239+
return;
240+
}
247241

248-
if (offsets?.Count != G1Provider.G1Elements.Count)
242+
try
243+
{
244+
var offsetsFile = Path.Combine(dirPath, "sprites.json");
245+
if (File.Exists(offsetsFile))
249246
{
250-
Logger.Warning($"Expected {G1Provider.G1Elements.Count} offsets, got {offsets?.Count} offsets. Continue at your peril.");
247+
// found blender folder
248+
var offsets = JsonSerializer.Deserialize<ICollection<SpriteOffset>>(File.ReadAllText(offsetsFile)); // sprites.json is an unnamed array so we need ICollection here, not IEnumerable
249+
Logger.Debug("Found sprites.json file, using that");
250+
251+
if (offsets?.Count != G1Provider.G1Elements.Count)
252+
{
253+
Logger.Warning($"Expected {G1Provider.G1Elements.Count} offsets, got {offsets?.Count} offsets. Continue at your peril.");
254+
}
255+
256+
foreach (var offset in offsets)
257+
{
258+
var filename = Path.Combine(dirPath, offset.Path);
259+
LoadSprite(filename, offset);
260+
}
251261
}
252-
253-
foreach (var offset in offsets)
262+
else
254263
{
255-
var filename = Path.Combine(dirPath, offset.Path);
256-
LoadSprite(filename, offset);
264+
Logger.Debug("No sprites.json file found");
265+
var files = Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories);
266+
267+
if (files.Length != G1Provider.G1Elements.Count)
268+
{
269+
Logger.Warning($"Expected {G1Provider.G1Elements.Count} images, got {files.Length} images. Continue at your peril.");
270+
}
271+
272+
foreach (var filename in files)
273+
{
274+
LoadSprite(filename);
275+
}
257276
}
277+
278+
Logger.Debug("Import successful");
279+
this.RaisePropertyChanged(nameof(Bitmaps));
258280
}
259-
else
281+
catch (Exception ex)
260282
{
261-
Logger.Debug("No sprites.json file found");
262-
var files = Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories);
263-
264-
if (files.Length != G1Provider.G1Elements.Count)
265-
{
266-
Logger.Warning($"Expected {G1Provider.G1Elements.Count} images, got {files.Length} images. Continue at your peril.");
267-
}
268-
269-
foreach (var filename in files)
270-
{
271-
LoadSprite(filename);
272-
}
283+
Logger.Error(ex);
273284
}
274-
275-
Logger.Debug("Import successful");
276-
this.RaisePropertyChanged(nameof(Bitmaps));
277-
}
278-
catch (Exception ex)
279-
{
280-
Logger.Error(ex);
281285
}
282286

283287
animationTimer.Start();

Gui/Views/MainWindow.axaml

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@
382382
</Button>
383383
<!--<ComboBox ItemsSource="{Binding ColourSwatchesArr}" SelectedItem="{Binding SelectedColourSwatch}" HorizontalAlignment="Stretch" VerticalAlignment="Center" />-->
384384
</StackPanel>
385-
<Grid ColumnDefinitions="*, Auto, 256">
385+
<Grid ColumnDefinitions="*, Auto, 384">
386386
<ScrollViewer>
387387
<Border BorderThickness="1">
388388
<ListBox ItemsSource="{Binding Bitmaps}" SelectionMode="Multiple" Selection="{Binding SelectionModel}" Background="{Binding #ImageBackgroundColorView.Color, ConverterParameter={x:Static Brushes.Transparent}, Converter={StaticResource ColorToBrushConverter}}">
@@ -402,22 +402,66 @@
402402
<GridSplitter Grid.Column="1" />
403403
<Border BorderThickness="1" Grid.Column="2">
404404
<DockPanel>
405-
<Border BorderThickness="1" DockPanel.Dock="Top">
406-
<StackPanel Orientation="Vertical" MaxHeight="512">
407-
<Grid>
408-
<Image Name="AnimationPreviewPP" Source="{Binding SelectedBitmapPreview}" RenderOptions.BitmapInterpolationMode="None" Stretch="None" Margin="4" MaxHeight="1024" MinHeight="64" Height="{Binding AnimationWindowHeight}" Width="256">
409-
<Image.RenderTransform>
410-
<ScaleTransform ScaleX="{Binding Zoom}" ScaleY="{Binding Zoom}" />
411-
</Image.RenderTransform>
412-
</Image>
413-
<Rectangle Fill="Red" Width="40" Height="40" Opacity="0.5" />
414-
</Grid>
415-
<TextBlock HorizontalAlignment="Center" Text="{Binding AnimationSpeed, StringFormat='Animation FPS: {0}'}"></TextBlock>
416-
<Slider Minimum="1" Maximum="80" Value="{Binding AnimationSpeed}" />
417-
<TextBlock HorizontalAlignment="Center" Text="{Binding Zoom, StringFormat='Zoom: {0}x'}"></TextBlock>
418-
<Slider Minimum="1" Maximum="10" Value="{Binding Zoom}" />
405+
<StackPanel Orientation="Vertical" MaxHeight="512" DockPanel.Dock="Top">
406+
<StackPanel Orientation="Horizontal">
407+
<Button HorizontalAlignment="Stretch" Margin="2" Padding="2" ToolTip.Tip="Select preview background colour">
408+
<DockPanel>
409+
<materialIcons:MaterialIcon Kind="Palette" Width="24" Height="24" Margin="2" />
410+
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="4">Background</TextBlock>
411+
</DockPanel>
412+
<Button.Flyout >
413+
<Flyout>
414+
<ColorView Name="ImageColorViewPreviewBackground" Palette="" Color="SteelBlue" IsColorModelVisible="False" IsColorSpectrumVisible="False" IsColorComponentsVisible="False" />
415+
</Flyout>
416+
</Button.Flyout>
417+
</Button>
418+
<Button HorizontalAlignment="Stretch" Margin="2" Padding="2" ToolTip.Tip="Select border preview colour">
419+
<DockPanel>
420+
<materialIcons:MaterialIcon Kind="Palette" Width="24" Height="24" Margin="2" />
421+
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="4">Border</TextBlock>
422+
</DockPanel>
423+
<Button.Flyout >
424+
<Flyout>
425+
<ColorView Name="ImageColorViewBorder" Palette="" Color="Gray" IsColorModelVisible="False" IsColorSpectrumVisible="False" IsColorComponentsVisible="False" />
426+
</Flyout>
427+
</Button.Flyout>
428+
</Button>
429+
<Button HorizontalAlignment="Stretch" Margin="2" Padding="2" ToolTip.Tip="Select origin point colour">
430+
<DockPanel>
431+
<materialIcons:MaterialIcon Kind="Palette" Width="24" Height="24" Margin="2" />
432+
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="4">Origin</TextBlock>
433+
</DockPanel>
434+
<Button.Flyout >
435+
<Flyout>
436+
<ColorView Name="ImageColorViewOriginPoint" Palette="" Color="Red" IsColorModelVisible="False" IsColorSpectrumVisible="False" IsColorComponentsVisible="False" />
437+
</Flyout>
438+
</Button.Flyout>
439+
</Button>
419440
</StackPanel>
420-
</Border>
441+
<Grid>
442+
<!-- Bounding box -->
443+
<Rectangle Fill="{Binding #ImageColorViewPreviewBackground.Color, ConverterParameter={x:Static Brushes.Transparent}, Converter={StaticResource ColorToBrushConverter}}" Stroke="{Binding #ImageColorViewBorder.Color, ConverterParameter={x:Static Brushes.Transparent}, Converter={StaticResource ColorToBrushConverter}}" StrokeThickness="1.0" Width="{Binding SelectedBitmapPreviewBorder.Width}" Height="{Binding SelectedBitmapPreviewBorder.Height}" Opacity="1.0">
444+
<Rectangle.RenderTransform>
445+
<ScaleTransform ScaleX="{Binding Zoom}" ScaleY="{Binding Zoom}" />
446+
</Rectangle.RenderTransform>
447+
</Rectangle>
448+
<Image Name="AnimationPreviewPP" Source="{Binding SelectedBitmapPreview}" RenderOptions.BitmapInterpolationMode="None" Stretch="None" Height="{Binding AnimationWindowHeight}" Width="256">
449+
<Image.RenderTransform>
450+
<ScaleTransform ScaleX="{Binding Zoom}" ScaleY="{Binding Zoom}" />
451+
</Image.RenderTransform>
452+
</Image>
453+
<!-- Origin point -->
454+
<Rectangle Fill="{Binding #ImageColorViewOriginPoint.Color, ConverterParameter={x:Static Brushes.Transparent}, Converter={StaticResource ColorToBrushConverter}}" Width="1" Height="1" Opacity="1.0">
455+
<Rectangle.RenderTransform>
456+
<ScaleTransform ScaleX="{Binding Zoom}" ScaleY="{Binding Zoom}" />
457+
</Rectangle.RenderTransform>
458+
</Rectangle>
459+
</Grid>
460+
<TextBlock HorizontalAlignment="Center" Text="{Binding AnimationSpeed, StringFormat='Animation FPS: {0}'}"></TextBlock>
461+
<Slider Minimum="1" Maximum="80" Value="{Binding AnimationSpeed}" />
462+
<TextBlock HorizontalAlignment="Center" Text="{Binding Zoom, StringFormat='Zoom: {0}x'}"></TextBlock>
463+
<Slider Minimum="1" Maximum="10" Value="{Binding Zoom}" />
464+
</StackPanel>
421465
<ScrollViewer>
422466
<pgc:PropertyGrid x:Name="propertyGrid_imageProps" Margin="8" MinWidth="256" DataContext="{Binding SelectedG1Element}" DockPanel.Dock="Right" ShowTitle="False" AllowFilter="False" AllowQuickFilter="False" ShowStyle="Builtin"></pgc:PropertyGrid>
423467
</ScrollViewer>

0 commit comments

Comments
 (0)