Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ThemedMessageBox with wrapping logic and default system icons. #2627

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading