Skip to content

Commit

Permalink
Add the ability to set the window icon
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-edmondson committed Aug 23, 2024
1 parent 8286619 commit 640f2a3
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
50 changes: 49 additions & 1 deletion ImGuiApp/ImGuiApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

namespace ktsu.io.ImGuiApp;

using System.Collections.ObjectModel;
using System.Numerics;
using System.Runtime.InteropServices;
using ImGuiNET;
using Silk.NET.Input;
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Extensions.ImGui;
using Silk.NET.Windowing;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Color = System.Drawing.Color;

public class ImGuiAppWindowState

Expand Down Expand Up @@ -48,6 +53,8 @@ public static ImGuiAppWindowState WindowState
private static bool showImGuiMetrics;
private static bool showImGuiDemo;

public static string WindowIconPath { get; set; } = string.Empty;

public static void Stop() => window?.Close();

public static void Start(string windowTitle, ImGuiAppWindowState initialWindowState, Action? onStart, Action<float>? onTick) => Start(windowTitle, initialWindowState, onStart, onTick, onMenu: null, onWindowResized: null);

Check warning on line 60 in ImGuiApp/ImGuiApp.cs

View workflow job for this annotation

GitHub Actions / build-dotnet-library / ktsu-io/ImGuiApp build-dotnet-library

Split this 222 characters long line (which is greater than 200 authorized). (https://rules.sonarsource.com/csharp/RSPEC-103)
Expand All @@ -62,6 +69,7 @@ public static void Start(string windowTitle, ImGuiAppWindowState initialWindowSt
options.Size = new((int)initialWindowState.Size.X, (int)initialWindowState.Size.Y);
options.Position = new((int)initialWindowState.Pos.X, (int)initialWindowState.Pos.Y);
options.WindowState = initialWindowState.LayoutState;

LastNormalWindowState = initialWindowState;

// Adapted from: https://github.com/dotnet/Silk.NET/blob/main/examples/CSharp/OpenGL%20Demos/ImGui/Program.cs
Expand All @@ -77,6 +85,11 @@ public static void Start(string windowTitle, ImGuiAppWindowState initialWindowSt
// Our loading function
window.Load += () =>
{
if (!string.IsNullOrEmpty(WindowIconPath))
{
SetWindowIcon(WindowIconPath);
}

gl = window.CreateOpenGL(); // load OpenGL
inputContext = window.CreateInput(); // create an input context
controller = new ImGuiController
Expand Down Expand Up @@ -123,7 +136,7 @@ public static void Start(string windowTitle, ImGuiAppWindowState initialWindowSt

// This is where you'll do any rendering beneath the ImGui context
// Here, we just have a blank screen.
gl?.ClearColor(System.Drawing.Color.FromArgb(255, (int)(.45f * 255), (int)(.55f * 255), (int)(.60f * 255)));
gl?.ClearColor(Color.FromArgb(255, (int)(.45f * 255), (int)(.55f * 255), (int)(.60f * 255)));

Check warning on line 139 in ImGuiApp/ImGuiApp.cs

View workflow job for this annotation

GitHub Actions / build-dotnet-library / ktsu-io/ImGuiApp build-dotnet-library

Assign this magic number '0.45' to a well-named variable or constant, and use that instead. (https://rules.sonarsource.com/csharp/RSPEC-109)

Check warning on line 139 in ImGuiApp/ImGuiApp.cs

View workflow job for this annotation

GitHub Actions / build-dotnet-library / ktsu-io/ImGuiApp build-dotnet-library

Assign this magic number '255' to a well-named variable or constant, and use that instead. (https://rules.sonarsource.com/csharp/RSPEC-109)

Check warning on line 139 in ImGuiApp/ImGuiApp.cs

View workflow job for this annotation

GitHub Actions / build-dotnet-library / ktsu-io/ImGuiApp build-dotnet-library

Assign this magic number '0.55' to a well-named variable or constant, and use that instead. (https://rules.sonarsource.com/csharp/RSPEC-109)
gl?.Clear((uint)ClearBufferMask.ColorBufferBit);

RenderMenu(onMenu);
Expand Down Expand Up @@ -208,4 +221,39 @@ public static void RenderWindowContents(Action<float>? tickDelegate, float dt)
ImGui.ShowMetricsWindow(ref showImGuiMetrics);
}
}

public static void SetWindowIcon(string iconPath)
{
using var stream = File.OpenRead(iconPath);
using var image = Image.Load<Rgba32>(stream);

int[] iconSizes = [128, 64, 48, 32, 28, 24, 22, 20, 18, 16];

var icons = new Collection<Silk.NET.Core.RawImage>();

foreach (int size in iconSizes)
{
var resizeImage = image.Clone();
int sourceSize = Math.Min(image.Width, image.Height);
resizeImage.Mutate(x => x.Crop(sourceSize, sourceSize).Resize(size, size, KnownResamplers.Welch));
byte[] iconData = new byte[size * size * 4];
resizeImage.ProcessPixelRows(pixelAccessor =>
{
for (int r = 0; r < size; ++r)
{
var rowSpan = pixelAccessor.GetRowSpan(r);
for (int c = 0; c < size; ++c)
{
byte[] pixelBytes = BitConverter.GetBytes(rowSpan[c].PackedValue);
pixelBytes.CopyTo(iconData, ((r * size) + c) * 4);
}
}
});

icons.Add(new(size, size, new Memory<byte>(iconData)));
}

window?.SetWindowIcon([.. icons]);
}
}

1 change: 1 addition & 0 deletions ImGuiApp/ImGuiApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="Silk.NET" Version="2.21.0" />
<PackageReference Include="Silk.NET.OpenGL.Extensions.ImGui" Version="2.21.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.0-alpha.15
1.0.0-alpha.16

0 comments on commit 640f2a3

Please sign in to comment.