Skip to content

Commit

Permalink
Improve ThemedMessageBox with wrapping logic and default system icons.
Browse files Browse the repository at this point in the history
Move Eto.IO.SystemIcons to Eto.Drawing, and add Information, Warning, Error, and Question icons.
  • Loading branch information
cwensley committed Mar 1, 2024
1 parent da62e2c commit b3c72c2
Show file tree
Hide file tree
Showing 31 changed files with 1,093 additions and 596 deletions.
19 changes: 19 additions & 0 deletions src/Eto.Gtk/Drawing/SystemIconsHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Eto.GtkSharp.Drawing;

public class SystemIconsHandler : SystemIcons.IHandler
{
#region ISystemIcons Members

public Icon GetFileIcon(string fileName, SystemIconSize size)
{
return null;
}

public Icon Get(SystemIconType type, SystemIconSize size)
{
return null;
}

#endregion

}
22 changes: 0 additions & 22 deletions src/Eto.Gtk/IO/SystemIcons.cs

This file was deleted.

6 changes: 3 additions & 3 deletions src/Eto.Gtk/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public struct FcFontSet
static class NMWindows
{

#if NETCOREAPP
#if NET

static NMWindows()
{
Expand Down Expand Up @@ -255,7 +255,7 @@ static NMWindows()
static class NMLinux
{

#if NETCOREAPP
#if NET

static NMLinux()
{
Expand Down Expand Up @@ -480,7 +480,7 @@ static NMLinux()
static class NMMac
{

#if NETCOREAPP
#if NET

static NMMac()
{
Expand Down
2 changes: 0 additions & 2 deletions src/Eto.Gtk/Platform.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using Eto.IO;
using Eto.GtkSharp.Drawing;
using Eto.GtkSharp.Forms.Cells;
using Eto.GtkSharp.Forms.Controls;
using Eto.GtkSharp.Forms.Printing;
using Eto.GtkSharp.Forms;
using Eto.GtkSharp.IO;
using Eto.Forms.ThemedControls;
using Eto.GtkSharp.Forms.Menu;
using Eto.GtkSharp.Forms.ToolBar;
Expand Down
54 changes: 54 additions & 0 deletions src/Eto.Mac/Drawing/SystemIconsHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Eto.Mac.Drawing;

namespace Eto.Mac.Drawing;

public class SystemIconsHandler : SystemIcons.IHandler
{

public Icon GetFileIcon(string fileName, SystemIconSize size)
{
var ws = new NSWorkspace();
var image = ws.IconForFileType(Path.GetExtension(fileName));
return WithSize(new Icon(new IconHandler(image)), size);
}

public Icon Get(SystemIconType type, SystemIconSize size)
{
var icon = type switch
{
SystemIconType.OpenDirectory => new Icon(new IconHandler(NSImage.ImageNamed(NSImageName.Folder))),
SystemIconType.CloseDirectory => new Icon(new IconHandler(NSImage.ImageNamed(NSImageName.Folder))),
SystemIconType.Question => GetResourceIcon("GenericQuestionMarkIcon.icns"),
SystemIconType.Error => GetResourceIcon("AlertStopIcon.icns"),
SystemIconType.Information => GetResourceIcon("AlertNoteIcon.icns"),
SystemIconType.Warning => new Icon(new IconHandler(NSImage.ImageNamed(NSImageName.Caution))),
_ => throw new NotSupportedException(),
};

return WithSize(icon, size);
}

private static Icon WithSize(Icon icon, SystemIconSize size)
{
var pixels = size switch
{
SystemIconSize.Large => 32,
SystemIconSize.Small => 16,
_ => throw new NotSupportedException()
};

return icon.WithSize(pixels, pixels);
}

private static Icon GetResourceIcon(string name)
{
const string basePath = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources";
var path = Path.Combine(basePath, name);
if (File.Exists(path))
{
return new Icon(path);
}
return null;
}
}

35 changes: 0 additions & 35 deletions src/Eto.Mac/IO/SystemIconsHandler.cs

This file was deleted.

8 changes: 8 additions & 0 deletions src/Eto.Mac/MacConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -658,5 +658,13 @@ public static NSTextAlignment ToNS(this FormattedTextAlignment align)
throw new NotSupportedException();
}
}

public static Image ToEto(this NSImage image)
{
if (image.Representations().Length == 1)
return new Bitmap(new BitmapHandler(image));
else
return new Icon(new IconHandler(image));
}
}
}
2 changes: 0 additions & 2 deletions src/Eto.Mac/Platform.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Eto.IO;
using Eto.Mac.Drawing;
using Eto.Mac.IO;
using Eto.Mac.Forms.Controls;
using Eto.Mac.Forms.Printing;
using Eto.Mac.Forms;
Expand Down
113 changes: 66 additions & 47 deletions src/Eto.WinForms/Drawing/IconHandler.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Windows.Controls;

namespace Eto.WinForms.Drawing
{
public interface IWindowsIconSource
Expand All @@ -7,14 +9,20 @@ public interface IWindowsIconSource

public class IconHandler : WidgetHandler<sd.Icon, Icon>, Icon.IHandler, IWindowsImage, IWindowsIconSource
{
Dictionary<int, sd.Image> cachedImages;
List<IconFrame> frames;
IconFrame idealFrame;
Dictionary<int, sd.Image> _cachedImages;
List<IconFrame> _frames;
IconFrame _idealFrame;
bool _destroyIcon;

public IconHandler(sd.Icon control)
{
this.Control = control;
}
public IconHandler(sd.Icon control, bool destroyIcon)
{
this.Control = control;
_destroyIcon = destroyIcon;
}

public IconHandler()
{
Expand All @@ -33,7 +41,7 @@ public IEnumerable<IconFrame> Frames
{
get
{
return frames ?? SplitIcon(Control);
return _frames ?? SplitIcon(Control);
}
}

Expand All @@ -49,11 +57,11 @@ public void Create(string fileName)

public IconFrame GetIdealIcon()
{
if (idealFrame != null)
return idealFrame;
if (_idealFrame != null)
return _idealFrame;
var orderedFrames = SplitIcon(Control).OrderByDescending(r => r.PixelSize.Width * r.PixelSize.Height);
idealFrame = orderedFrames.FirstOrDefault(r => r.Scale == 1) ?? orderedFrames.First();
return idealFrame;
_idealFrame = orderedFrames.FirstOrDefault(r => r.Scale == 1) ?? orderedFrames.First();
return _idealFrame;
}

public sd.Icon GetIconClosestToSize(int width)
Expand All @@ -75,8 +83,8 @@ public sd.Icon GetIconClosestToSize(int width)

public List<IconFrame> SplitIcon(sd.Icon icon)
{
if (frames != null)
return frames;
if (_frames != null)
return _frames;
if (icon == null)
{
throw new ArgumentNullException("icon");
Expand All @@ -94,54 +102,65 @@ public List<IconFrame> SplitIcon(sd.Icon icon)
var splitIcons = new List<sd.Icon>();
int count = BitConverter.ToInt16(srcBuf, 4); // ICONDIR.idCount

for (int i = 0; i < count; i++)
if (count == 1)
{
splitIcons.Add(icon);
}
else
{
using (var destStream = new MemoryStream())
using (var writer = new BinaryWriter(destStream))
for (int i = 0; i < count; i++)
{
// Copy ICONDIR and ICONDIRENTRY.
int pos = 0;
writer.Write(srcBuf, pos, sICONDIR - 2);
writer.Write((short)1); // ICONDIR.idCount == 1;

pos += sICONDIR;
pos += sICONDIRENTRY * i;

writer.Write(srcBuf, pos, sICONDIRENTRY - 4); // write out icon info (minus old offset)
writer.Write(sICONDIR + sICONDIRENTRY); // write offset of icon data
pos += 8;

// Copy picture and mask data.
int imgSize = BitConverter.ToInt32(srcBuf, pos); // ICONDIRENTRY.dwBytesInRes
pos += 4;
int imgOffset = BitConverter.ToInt32(srcBuf, pos); // ICONDIRENTRY.dwImageOffset
if (imgOffset + imgSize > srcBuf.Length)
throw new ArgumentException("ugh");
writer.Write(srcBuf, imgOffset, imgSize);
writer.Flush();

// Create new icon.
destStream.Seek(0, SeekOrigin.Begin);
splitIcons.Add(new sd.Icon(destStream));
using (var destStream = new MemoryStream())
using (var writer = new BinaryWriter(destStream))
{
// Copy ICONDIR and ICONDIRENTRY.
int pos = 0;
writer.Write(srcBuf, pos, sICONDIR - 2);
writer.Write((short)1); // ICONDIR.idCount == 1;

pos += sICONDIR;
pos += sICONDIRENTRY * i;

writer.Write(srcBuf, pos, sICONDIRENTRY - 4); // write out icon info (minus old offset)
writer.Write(sICONDIR + sICONDIRENTRY); // write offset of icon data
pos += 8;

// Copy picture and mask data.
int imgSize = BitConverter.ToInt32(srcBuf, pos); // ICONDIRENTRY.dwBytesInRes
pos += 4;
int imgOffset = BitConverter.ToInt32(srcBuf, pos); // ICONDIRENTRY.dwImageOffset
if (imgOffset + imgSize > srcBuf.Length)
throw new ArgumentException("ugh");
writer.Write(srcBuf, imgOffset, imgSize);
writer.Flush();

// Create new icon.
destStream.Seek(0, SeekOrigin.Begin);
splitIcons.Add(new sd.Icon(destStream));
}
}
}

frames = splitIcons.Select(r => IconFrame.FromControlObject(1, r)).ToList();
return frames;
_frames = splitIcons.Select(r => IconFrame.FromControlObject(1, r)).ToList();
return _frames;
}

protected override void Dispose(bool disposing)
{
if (_destroyIcon && Control != null)
{
Win32.DestroyIcon(Control.Handle);
}
base.Dispose(disposing);
if (disposing)
{
if (frames != null)
if (_frames != null)
{
foreach (var frame in frames)
foreach (var frame in _frames)
{
((sd.Icon)frame.ControlObject).Dispose();
}
frames = null;
_frames = null;
}
}
}
Expand All @@ -150,15 +169,15 @@ public sd.Image GetImageWithSize(int? size)
{
if (size != null)
{
if (cachedImages == null)
cachedImages = new Dictionary<int, sd.Image>();
if (_cachedImages == null)
_cachedImages = new Dictionary<int, sd.Image>();

if (cachedImages.TryGetValue(size.Value, out var bmp))
if (_cachedImages.TryGetValue(size.Value, out var bmp))
return bmp;

var icon = GetIconClosestToSize(size.Value);
bmp = icon.ToBitmap();
cachedImages[size.Value] = bmp;
_cachedImages[size.Value] = bmp;
return bmp;
}
return GetIdealIcon().Bitmap.ToSD();
Expand Down Expand Up @@ -203,7 +222,7 @@ public sd.Icon GetIcon()

public void Create(IEnumerable<IconFrame> frames)
{
this.frames = frames.ToList();
this._frames = frames.ToList();
var frame = GetIdealIcon();
size = frame.Size;
Control = (sd.Icon)frame.ControlObject;
Expand Down
6 changes: 6 additions & 0 deletions src/Eto.WinForms/Eto.WinForms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ You do not need to use any of the classes of this assembly (unless customizing t
<Compile Include="..\Shared\HttpClientExtensions.cs">
<Link>HttpClientExtensions.cs</Link>
</Compile>
<Compile Include="..\Eto.Wpf\Drawing\SystemIconsHandler.cs">
<Link>Drawing\SystemIconsHandler</Link>
</Compile>
<Compile Include="..\Eto.Wpf\ShellIcon.cs">
<Link>ShellIcon.cs</Link>
</Compile>
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit b3c72c2

Please sign in to comment.