Skip to content
Merged

Dev #69

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
be527af
Add EXE / DLL extraction of icons
TheJoeFin Mar 27, 2026
3716766
Add a checker background option behind the image previews
TheJoeFin Mar 27, 2026
2d8caf5
code style
TheJoeFin Mar 27, 2026
39554ce
Update NuGet package dependencies to latest versions
TheJoeFin Mar 28, 2026
ac20254
Refactor CreateCheckerBrush for dynamic tile scaling
TheJoeFin Mar 28, 2026
2d6c34a
Update navigation, permissions, and UI behaviors
TheJoeFin Mar 28, 2026
8010b4d
Fix checker background blurriness and prime-width tiny-square bug
TheJoeFin Mar 29, 2026
1a00eae
Add theme switcher & rating/feedback to About page
TheJoeFin Mar 30, 2026
1a06a12
Add "gh issue view" to allowed Bash commands
TheJoeFin Mar 30, 2026
cc3b62c
Update LoadingText to reflect enabled icon sizes only
TheJoeFin Mar 30, 2026
9a77d94
Expand allowed permissions for web search and fetch
TheJoeFin Mar 30, 2026
021c990
Add image cropping feature with new dialog
TheJoeFin Mar 30, 2026
1915925
Refactor image init and UI logic in PreviewStack
TheJoeFin Mar 30, 2026
7dc5405
Add SVG image support with vector preview and processing
TheJoeFin Mar 30, 2026
3ba5cf4
Add FileGroupItem model with observable properties
TheJoeFin Mar 31, 2026
b4495a8
Add PreCheckDialog for folder image summary and selection
TheJoeFin Mar 31, 2026
989453c
Add pre-check dialog for bulk image folder loading
TheJoeFin Mar 31, 2026
333d94b
Enable conditional execution for CropImage command
TheJoeFin Apr 4, 2026
643cd2d
Improve checkerboard tiling to avoid partial edge tiles
TheJoeFin Apr 4, 2026
7cd9a36
Add CancelLoading command and refactor file group logic
TheJoeFin Apr 4, 2026
ed699a7
Reformat XAML bindings and update Cancel button command
TheJoeFin Apr 4, 2026
b1e2a40
Update Windows SDK BuildTools to 10.0.28000.1721
TheJoeFin Apr 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"permissions": {
"allow": [
"Bash(dotnet build:*)",
"Bash(grep -E \"\\\\.\\(cs|xaml\\)$\")",
"Bash(gh issue view:*)",
"WebSearch",
"WebFetch(domain:raw.githubusercontent.com)"
]
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>

<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
Expand All @@ -10,7 +10,7 @@
<Identity
Name="40087JoeFinApps.SimpleIconFileMaker"
Publisher="CN=153F3B0F-BA3D-4964-8098-71AC78A1DF6A"
Version="1.15.1.0" />
Version="1.16.0.0" />


<Properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.260209005">
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.260317003">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7705">
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.28000.1721">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
<PackageReference Include="WinUIEx" Version="2.9.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ namespace Simple_Icon_File_Maker.Constants;

public static class FileTypes
{
public static readonly HashSet<string> SupportedImageFormats = [".png", ".bmp", ".jpeg", ".jpg", ".ico"];
public static readonly HashSet<string> SupportedImageFormats = [".png", ".bmp", ".jpeg", ".jpg", ".ico", ".svg"];

public static readonly HashSet<string> SupportedDllFormats = [".dll", ".exe", ".mun"];

public static bool IsSupportedImageFormat(this StorageFile file)
{
return SupportedImageFormats.Contains(file.FileType, StringComparer.OrdinalIgnoreCase);
}

public static bool IsSupportedDllFormat(this StorageFile file)
{
return SupportedDllFormats.Contains(file.FileType, StringComparer.OrdinalIgnoreCase);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using System.Diagnostics;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel.DataTransfer;
using Windows.Foundation;
using Windows.Storage;
Expand All @@ -21,18 +23,43 @@ public sealed partial class PreviewImage : UserControl
private readonly StorageFile _imageFile;
private readonly int _sideLength = 0;

public PreviewImage(StorageFile imageFile, int sideLength, string originalName)
public PreviewImage(StorageFile imageFile, int sideLength, string originalName, bool showCheckerBackground)
{
InitializeComponent();
_imageFile = imageFile;
_sideLength = sideLength;
ShowCheckerBackground = showCheckerBackground;
ToolTipService.SetToolTip(this, $"{sideLength} x {sideLength}");
OriginalName = originalName;
ActualThemeChanged += (_, _) =>
{
int size = isZooming ? ZoomedWidthSpace : _sideLength;
mainImageCanvas.Background = _showCheckerBackground
? CreateCheckerBrush(size, _sideLength, ActualTheme)
: new SolidColorBrush(Colors.Transparent);
};
}

private bool isZooming = false;
private bool _showCheckerBackground = true;
public int ZoomedWidthSpace = 100;

public bool ShowCheckerBackground
{
get => _showCheckerBackground;
set
{
if (value != _showCheckerBackground)
{
_showCheckerBackground = value;
int size = isZooming ? ZoomedWidthSpace : _sideLength;
mainImageCanvas.Background = _showCheckerBackground
? CreateCheckerBrush(size, _sideLength, ActualTheme)
: new SolidColorBrush(Colors.Transparent);
}
}
}

public bool ZoomPreview
{
get => isZooming;
Expand All @@ -41,9 +68,8 @@ public bool ZoomPreview
if (value != isZooming)
{
isZooming = value;
mainImageCanvas.Children.Clear();
LoadImageOnToCanvas();
InvalidateMeasure();
InvalidateArrange();
}
}
}
Expand All @@ -52,17 +78,13 @@ protected override Size ArrangeOverride(Size finalSize)
{
double dim = Math.Min(finalSize.Width, finalSize.Height);
mainImageCanvas.Arrange(new Rect(new Point((finalSize.Width - dim) / 2, (finalSize.Height - dim) / 2), new Size(dim, dim)));
LoadImageOnToCanvas();
return finalSize;
}

protected override Size MeasureOverride(Size availableSize)
{
double dim = Math.Min(availableSize.Width, availableSize.Height);
// smallerAvailableSize = (int)dim;
if (double.IsPositiveInfinity(dim))
dim = 3000;
return new Size(dim, dim);
int size = isZooming ? ZoomedWidthSpace : _sideLength;
return new Size(size, size);
}

private async void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
Expand Down Expand Up @@ -106,6 +128,12 @@ private void UserControl_Loaded(object sender, RoutedEventArgs e)
private void LoadImageOnToCanvas()
{
mainImageCanvas.Children.Clear();

int size = isZooming ? ZoomedWidthSpace : _sideLength;
mainImageCanvas.Background = ShowCheckerBackground
? CreateCheckerBrush(size, _sideLength, ActualTheme)
: new SolidColorBrush(Colors.Transparent);

// from StackOverflow
// user:
// https://stackoverflow.com/users/403671/simon-mourier
Expand All @@ -128,10 +156,6 @@ private void LoadImageOnToCanvas()
LoadedImageSurface image = LoadedImageSurface.StartLoadFromUri(new Uri(_imageFile.Path));
brush.Surface = image;

int size = isZooming ? ZoomedWidthSpace : _sideLength;
Width = size;
Height = size;

// set the visual size when the image has loaded
image.LoadCompleted += (s, e) =>
{
Expand All @@ -153,6 +177,42 @@ private void LoadImageOnToCanvas()
mainImageCanvas.Children.Add(tempGrid);
}

private static ImageBrush CreateCheckerBrush(int size, int baseSideLength, ElementTheme theme)
{
// idealTileSize targets ~8 px at the baseSideLength and scales proportionally for
// zoomed views. NearestDivisor then rounds it to the closest exact divisor of
// 'size', guaranteeing size % tileSize == 0 — no partial tile, no sliver at the
// edge regardless of the canvas size or DPI scale.
int idealTileSize = Math.Max(1, (int)Math.Round(8.0 * size / baseSideLength));

WriteableBitmap bitmap = new(size, size);

// Light mode: #F0F0F0 / #C4C4C4 — Dark mode: #404040 / #2A2A2A
bool isDark = theme == ElementTheme.Dark;
byte tileLight = isDark ? (byte)0x40 : (byte)0xF0;
byte tileDark = isDark ? (byte)0x2A : (byte)0xC4;

byte[] pixels = new byte[size * size * 4]; // BGRA format
for (int row = 0; row < size; row++)
{
for (int col = 0; col < size; col++)
{
bool isLightTile = ((row / idealTileSize) + (col / idealTileSize)) % 2 == 0;
byte val = isLightTile ? tileLight : tileDark;
int idx = (row * size + col) * 4;
pixels[idx] = val; // B
pixels[idx + 1] = val; // G
pixels[idx + 2] = val; // R
pixels[idx + 3] = 255; // A
}
}

using Stream stream = bitmap.PixelBuffer.AsStream();
stream.Write(pixels, 0, pixels.Length);

return new ImageBrush { ImageSource = bitmap, Stretch = Stretch.Fill };
}

private async void ImagePreview_DragStarting(UIElement sender, DragStartingEventArgs args)
{
DragOperationDeferral deferral = args.GetDeferral();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,42 @@
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Name="FileNameText"
HorizontalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
TextWrapping="WrapWholeWords" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Name="FileNameText"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
TextWrapping="WrapWholeWords" />
<DropDownButton
Name="SaveColumnButton"
Grid.Column="1"
Height="28"
Padding="6,0"
VerticalAlignment="Center"
ToolTipService.ToolTip="Save this icon"
Visibility="Collapsed">
<FontIcon FontSize="12" Glyph="&#xE74E;" />
<DropDownButton.Flyout>
<MenuFlyout>
<MenuFlyoutItem Click="SaveIconMenuItem_Click" Text="Save icon (.ico)">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE74E;" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem Click="SaveAllImagesMenuItem_Click" Text="Save all images...">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE78C;" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
</DropDownButton.Flyout>
</DropDownButton>
</Grid>
<StackPanel
Name="PreviewStackPanel"
Grid.Row="1"
Expand Down
Loading
Loading