pk3DS/pk3DS.WinForms/Tools/Icon.cs
2024-06-02 18:30:56 -05:00

221 lines
6.3 KiB
C#

using pk3DS.Core.CTR;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
namespace pk3DS.WinForms;
public sealed partial class Icon : Form
{
private SMDH SMDH;
public Icon()
{
InitializeComponent();
SMDH = Main.SMDH;
if (SMDH?.AppSettings == null || SMDH.LargeIcon.Bytes == null)
{
byte[] data = new byte[0x3C0]; // Feed a blank SMDH
Array.Copy(BitConverter.GetBytes(0x48444D53), data, 4); // SMDH header
SMDH = new SMDH(data);
B_Save.Enabled = false;
}
for (int i = 0; i < 16; i++)
CB_AppInfo.Items.Add(i);
LoadSMDH();
AllowDrop = true;
DragEnter += TC_Main_DragEnter;
DragDrop += TC_Main_DragDrop;
}
private void TC_Main_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
private void TC_Main_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
string path = files[0]; // open first D&D
OpenFile(path, true);
}
private void LoadSMDH()
{
PB_Large.Image = SMDH.LargeIcon.Icon;
PB_Small.Image = SMDH.SmallIcon.Icon;
CB_AppInfo.SelectedIndex = 0;
CB_AppInfo_SelectedIndexChanged(null, null);
}
private void SaveSMDH()
{
Main.SMDH = SMDH;
File.WriteAllBytes(Path.Combine(Main.ExeFSPath, "icon.bin"), Main.SMDH.Write());
}
private void OpenFile(string path, bool drop = false)
{
var fi = new FileInfo(path);
if (fi.Length > 1024 * 1024 * 5)
return;
byte[] data = File.ReadAllBytes(path);
if (data.Length == 0x36C0) // SMDH
ImportSMDH(data, true);
else ImportIcon(data, drop);
}
private void B_Save_Click(object sender, EventArgs e)
{
CB_AppInfo_SelectedIndexChanged(null, null); // Force re-save
if (DialogResult.Yes == WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Save changes?"))
{
SaveSMDH();
Close();
}
}
private void B_Cancel_Click(object sender, EventArgs e)
{
Close();
}
private void B_ExportSMDH_Click(object sender, EventArgs e)
{
ExportSMDH();
}
private void B_ExportSmallIcon_Click(object sender, EventArgs e)
{
ExportIcon(false);
}
private void B_ExportLargeIcon_Click(object sender, EventArgs e)
{
ExportIcon(true);
}
private void ExportSMDH()
{
var sfd = new SaveFileDialog
{
FileName = "icon.bin",
Filter = "System Menu Data Header|*.*",
};
if (sfd.ShowDialog() != DialogResult.Yes) return;
CB_AppInfo_SelectedIndexChanged(null, null); // Force re-save
File.WriteAllBytes(sfd.FileName, SMDH.Write());
}
private void ExportIcon(bool large)
{
var sfd = new SaveFileDialog
{
FileName = large ? "Large Icon.png" : "Small Icon.png",
Filter = "Icon Image " + (large ? "48x48" : "24x24") + "|*.png",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
using var ms = new MemoryStream();
//error will throw from here
(large ? SMDH.LargeIcon.Icon : SMDH.SmallIcon.Icon).Save(ms, ImageFormat.Png);
byte[] data = ms.ToArray();
File.WriteAllBytes(sfd.FileName, data);
}
private void B_ImportSMDH_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog
{
FileName = "icon.bin",
Filter = "System Menu Data Header|*.*",
};
if (ofd.ShowDialog() != DialogResult.OK) return;
OpenFile(ofd.FileName);
}
private void B_ImportSmallIcon_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog
{
FileName = "small.png",
Filter = "Small Icon Image|*.png",
};
if (ofd.ShowDialog() != DialogResult.OK) return;
OpenFile(ofd.FileName);
}
private void B_ImportLargeIcon_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog
{
FileName = "large.png",
Filter = "Large Icon Image|*.png",
};
if (ofd.ShowDialog() != DialogResult.OK) return;
OpenFile(ofd.FileName);
}
private void ImportSMDH(byte[] data, bool prompt = false)
{
if (prompt && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Replace SMDH?"))
return;
var newSMDH = new SMDH(data);
if (newSMDH.LargeIcon.Icon == null) return;
SMDH = newSMDH;
entry = -1; // allow proper refreshing
LoadSMDH();
}
private void ImportIcon(byte[] data, bool prompt = false)
{
try
{
using Stream BitmapStream = new MemoryStream(data);
var img = Image.FromStream(BitmapStream);
var mBitmap = new Bitmap(img);
bool small = img.Width == 24 && img.Height == 24;
bool large = img.Width == 48 && img.Height == 48;
if (!small && !large)
WinFormsUtil.Alert("Image size is not correct.", $"Width: {img.Width}\nHeight: {img.Height}", "Expected Dimensions (24x24 or 48x48)");
if (prompt && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Import image?", small ? "Small Icon" : "Large Icon"))
return;
if (small)
SMDH.SmallIcon.ChangeIcon(mBitmap);
if (large)
SMDH.LargeIcon.ChangeIcon(mBitmap);
}
catch
{ WinFormsUtil.Error("Invalid image format?"); }
}
private int entry = -1;
private void CB_AppInfo_SelectedIndexChanged(object sender, EventArgs e)
{
if (entry > -1)
{
SMDH.AppInfo[entry].ShortDescription = TB_Short.Text;
SMDH.AppInfo[entry].LongDescription = TB_Long.Text;
SMDH.AppInfo[entry].Publisher = TB_Publisher.Text;
}
entry = CB_AppInfo.SelectedIndex;
TB_Short.Text = SMDH.AppInfo[entry].ShortDescription;
TB_Long.Text = SMDH.AppInfo[entry].LongDescription;
TB_Publisher.Text = SMDH.AppInfo[entry].Publisher;
}
}