Skip to content

Commit

Permalink
Merge pull request #2627 from cwensley/curtis/improve-themed-messagebox
Browse files Browse the repository at this point in the history
Improve ThemedMessageBox with wrapping logic and default system icons.
  • Loading branch information
cwensley authored Mar 1, 2024
2 parents da62e2c + b3c72c2 commit e529eb9
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 e529eb9

Please sign in to comment.