#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

315 lines
9.3 KiB

// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
namespace ICSharpCode.IconEditor
{
public partial class IconPanel
{
Size iconSize;
int colorDepth;
IconEntry entry;
Bitmap maskBitmap;
Bitmap bitmap;
public Size IconSize {
get { return iconSize; }
}
public int ColorDepth {
get { return colorDepth; }
}
public IconEntry Entry {
get {
return entry;
}
set {
if (maskBitmap != null) {
maskBitmap.Dispose();
maskBitmap = null;
}
if (bitmap != null) {
bitmap.Dispose();
bitmap = null;
}
entry = value;
if (entry != null) {
bitmap = entry.GetImage();
if (entry.Type == IconEntryType.Classic) {
maskBitmap = FixBitmap(entry.GetMaskImage());
bitmap = FixBitmap(bitmap);
}
exportANDMaskToolStripMenuItem.Visible = entry.Type == IconEntryType.Classic;
exportXORMaskToolStripMenuItem.Visible = entry.Type == IconEntryType.Classic;
compressedToolStripMenuItem.Checked = entry.IsCompressed;
compressedToolStripMenuItem.Enabled = entry.IsCompressed || entry.ColorDepth == 32;
}
this.ContextMenuStrip = (entry != null) ? contextMenuStrip : emptyContextMenuStrip;
UpdateSize();
Invalidate();
}
}
public event EventHandler EntryChanged = delegate {};
Bitmap FixBitmap(Bitmap src)
{
if (src == null)
return src;
Bitmap dest = new Bitmap(src.Width, src.Height);
using (Graphics g = Graphics.FromImage(dest)) {
g.DrawImageUnscaled(src, 0, 0);
}
src.Dispose();
return dest;
}
public IconPanel(Size size, int colorDepth)
{
this.iconSize = size;
this.colorDepth = colorDepth;
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
UpdateSize();
}
void UpdateSize()
{
Size newClientSize = new Size(LimitSizeIfNoEntry(iconSize.Width) + 2, LimitSizeIfNoEntry(iconSize.Height) + 2);
if (this.ClientSize != newClientSize)
this.ClientSize = newClientSize;
}
int LimitSizeIfNoEntry(int size)
{
if (entry != null)
return size;
else
return Math.Min(size, 32);
}
void IconPanelPaint(object sender, PaintEventArgs e)
{
const int drawOffset = 1;
if (maskBitmap != null) {
IntPtr destDC = e.Graphics.GetHdc();
{ // AND blitting
IntPtr memDC = Gdi32.CreateCompatibleDC(destDC);
IntPtr srcHBitmap = maskBitmap.GetHbitmap();
IntPtr oldHBitmap = Gdi32.SelectObject(memDC, srcHBitmap);
Gdi32.BitBlt(destDC, drawOffset, drawOffset, iconSize.Width, iconSize.Height, memDC, 0, 0, Gdi32.SRCAND);
// TODO: review if the objects get destroyed correctly
Gdi32.SelectObject(memDC, oldHBitmap);
Gdi32.DeleteObject(srcHBitmap);
Gdi32.DeleteDC(memDC);
Gdi32.DeleteDC(oldHBitmap);
}
{ // XOR blitting
IntPtr memDC = Gdi32.CreateCompatibleDC(destDC);
IntPtr srcHBitmap = bitmap.GetHbitmap();
IntPtr oldHBitmap = Gdi32.SelectObject(memDC, srcHBitmap);
Gdi32.BitBlt(destDC, drawOffset, drawOffset, iconSize.Width, iconSize.Height, memDC, 0, 0, Gdi32.SRCINVERT);
Gdi32.SelectObject(memDC, oldHBitmap);
Gdi32.DeleteObject(srcHBitmap);
Gdi32.DeleteDC(memDC);
Gdi32.DeleteDC(oldHBitmap);
}
Gdi32.DeleteDC(destDC);
} else if (bitmap != null) {
e.Graphics.DrawImageUnscaled(bitmap, drawOffset, drawOffset);
}
}
/// <summary>
/// Helper class containing Gdi32 API functions
/// </summary>
private static class Gdi32
{
/// <summary>dest = source AND dest</summary>
public const int SRCAND = 0x008800C6;
/// <summary>dest = source XOR dest</summary>
public const int SRCINVERT = 0x00660046;
/// <summary>dest = source</summary>
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject,int nXDest,int nYDest,
int nWidth,int nHeight,IntPtr hObjectSource,
int nXSrc,int nYSrc,int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC,int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC,IntPtr hObject);
}
void ExportToolStripMenuItemClick(object sender, EventArgs e)
{
using (SaveFileDialog dlg = new SaveFileDialog()) {
dlg.DefaultExt = "png";
dlg.Filter = "PNG images|*.png|All files|*.*";
if (dlg.ShowDialog() == DialogResult.OK) {
entry.ExportArgbBitmap().Save(dlg.FileName, ImageFormat.Png);
}
}
}
void ExportANDMaskToolStripMenuItemClick(object sender, EventArgs e)
{
using (SaveFileDialog dlg = new SaveFileDialog()) {
dlg.DefaultExt = "bmp";
dlg.Filter = "BMP images|*.bmp|All files|*.*";
if (dlg.ShowDialog() == DialogResult.OK) {
using (var stream = dlg.OpenFile()) {
entry.GetMaskImageData().CopyTo(stream);
}
}
}
}
void ExportXORMaskToolStripMenuItemClick(object sender, EventArgs e)
{
using (SaveFileDialog dlg = new SaveFileDialog()) {
dlg.DefaultExt = "bmp";
dlg.Filter = "BMP images|*.bmp|All files|*.*";
if (dlg.ShowDialog() == DialogResult.OK) {
using (var stream = dlg.OpenFile()) {
entry.GetImageData().CopyTo(stream);
}
}
}
}
void DeleteToolStripMenuItemClick(object sender, EventArgs e)
{
this.Entry = null;
EntryChanged(this, e);
}
void ReplaceWithImageToolStripMenuItemClick(object sender, EventArgs e)
{
using (OpenFileDialog dlg = new OpenFileDialog()) {
dlg.Filter = "Images|*.png;*.bmp;*.gif;*.jpg|All files|*.*";
if (dlg.ShowDialog() == DialogResult.OK) {
try {
Bitmap newBitmap = new Bitmap(dlg.FileName);
SetImage(newBitmap);
} catch (Exception ex) {
MessageService.ShowHandledException(ex);
}
}
}
}
void CompressedToolStripMenuItemClick(object sender, EventArgs e)
{
// Toggle compression
this.Entry = new IconEntry(iconSize.Width, iconSize.Height, colorDepth, entry.ExportArgbBitmap(), !entry.IsCompressed);
EntryChanged(this, EventArgs.Empty);
}
void SetImage(Bitmap newBitmap)
{
// scale to correct size and make it ARGB
if (iconSize != newBitmap.Size) {
int r = MessageService.ShowCustomDialog(
"Import Image",
string.Format("The image has size {0}x{1}, but size {2}x{3} is expected.", newBitmap.Width, newBitmap.Height, iconSize.Width, iconSize.Height),
0, 1, "Convert", "Cancel");
if (r != 0) {
return;
}
}
bool? compress = entry != null ? entry.IsCompressed : (bool?)null;
this.Entry = new IconEntry(iconSize.Width, iconSize.Height, colorDepth, newBitmap, compress);
EntryChanged(this, EventArgs.Empty);
}
Point mouseDownLocation;
void IconPanelMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
mouseDownLocation = e.Location;
}
}
void IconPanelMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
if (mouseDownLocation.IsEmpty == false && entry != null) {
int dx = Math.Abs(e.X - mouseDownLocation.X);
int dy = Math.Abs(e.Y - mouseDownLocation.Y);
if (dx > SystemInformation.DragSize.Width || dy > SystemInformation.DragSize.Height)
{
mouseDownLocation = Point.Empty;
this.DoDragDrop(entry.ExportArgbBitmap(), DragDropEffects.Copy);
}
}
}
}
void IconPanelDragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Bitmap)) {
e.Effect = DragDropEffects.Copy;
} else if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
e.Effect = DragDropEffects.None;
string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files != null && files.Length == 1) {
string ext = Path.GetExtension(files[0]);
if (ext.Equals(".png", StringComparison.OrdinalIgnoreCase) || ext.Equals(".bmp", StringComparison.OrdinalIgnoreCase)
|| ext.Equals(".gif", StringComparison.OrdinalIgnoreCase) || ext.Equals(".jpg", StringComparison.OrdinalIgnoreCase))
{
e.Effect = DragDropEffects.Copy;
}
}
} else {
e.Effect = DragDropEffects.None;
}
}
void IconPanelDragDrop(object sender, DragEventArgs e)
{
try {
Bitmap bmp = null;
if (e.Data.GetDataPresent(DataFormats.Bitmap)) {
bmp = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
} else if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files != null && files.Length == 1) {
bmp = new Bitmap(files[0]);
}
}
if (bmp != null) {
SetImage(bmp);
}
} catch (Exception ex) {
MessageService.ShowHandledException(ex);
}
}
}
}