DS-Pokemon-Rom-Editor/Ekona/Images/ImageControl.cs
AdAstra-LD 73ca3d06a9 Added Ekona and NImages file support
More progress with the Trainer Editor
2021-07-21 23:04:53 +02:00

592 lines
22 KiB
C#

/*
* Copyright (C) 2011 pleoNeX
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* By: pleoNeX
*
*/
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Xml.Linq;
using Ekona.Images.Formats;
namespace Ekona.Images
{
public partial class ImageControl : UserControl
{
IPluginHost pluginHost;
ImageBase image;
PaletteBase palette;
bool isMap;
MapBase map;
bool stop;
public ImageControl()
{
InitializeComponent();
}
public ImageControl(IPluginHost pluginHost, bool isMap)
{
InitializeComponent();
this.pluginHost = pluginHost;
this.isMap = isMap;
this.palette = pluginHost.Get_Palette();
this.image = pluginHost.Get_Image();
if (isMap)
this.map = pluginHost.Get_Map();
Update_Info();
this.comboDepth.SelectedIndexChanged += new EventHandler(comboDepth_SelectedIndexChanged);
this.numericWidth.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericHeight.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericStart.ValueChanged += new EventHandler(numericStart_ValueChanged);
ReadLanguage();
Update_Image();
}
public ImageControl(IPluginHost pluginHost, ImageBase image, PaletteBase palette)
{
InitializeComponent();
isMap = false;
this.image = image;
this.palette = palette;
this.pluginHost = pluginHost;
Update_Info();
this.comboDepth.SelectedIndexChanged += new EventHandler(comboDepth_SelectedIndexChanged);
this.numericWidth.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericHeight.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericStart.ValueChanged += new EventHandler(numericStart_ValueChanged);
ReadLanguage();
Update_Image();
}
public ImageControl(IPluginHost pluginHost, ImageBase image, PaletteBase palette, MapBase map)
{
InitializeComponent();
this.pluginHost = pluginHost;
this.isMap = true;
this.palette = palette;
this.image = image;
this.map = map;
Update_Info();
this.comboDepth.SelectedIndexChanged += new EventHandler(comboDepth_SelectedIndexChanged);
this.numericWidth.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericHeight.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericStart.ValueChanged += new EventHandler(numericStart_ValueChanged);
ReadLanguage();
Update_Image();
}
public ImageControl(XElement lang, ImageBase image, PaletteBase palette, MapBase map)
{
InitializeComponent();
this.isMap = true;
this.palette = palette;
this.image = image;
this.map = map;
Update_Info();
btnImport.Enabled = false;
groupBox2.Enabled = false;
this.comboDepth.SelectedIndexChanged += new EventHandler(comboDepth_SelectedIndexChanged);
this.numericWidth.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericHeight.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericStart.ValueChanged += new EventHandler(numericStart_ValueChanged);
ReadLanguage(lang);
Update_Image();
}
public ImageControl(XElement lang, ImageBase image, PaletteBase palette)
{
InitializeComponent();
isMap = false;
this.image = image;
this.palette = palette;
Update_Info();
btnImport.Enabled = false;
groupBox2.Enabled = false;
this.comboDepth.SelectedIndexChanged += new EventHandler(comboDepth_SelectedIndexChanged);
this.numericWidth.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericHeight.ValueChanged += new EventHandler(numericSize_ValueChanged);
this.numericStart.ValueChanged += new EventHandler(numericStart_ValueChanged);
ReadLanguage(lang);
Update_Image();
}
private void ReadLanguage()
{
XElement xml = XElement.Load(pluginHost.Get_LangXML());
xml = xml.Element("Ekona").Element("ImageControl");
ReadLanguage(xml);
}
private void ReadLanguage(XElement xml)
{
try
{
label5.Text = xml.Element("S01").Value;
groupProp.Text = xml.Element("S02").Value;
label3.Text = xml.Element("S03").Value;
checkHex.Text = xml.Element("S04").Value;
label1.Text = xml.Element("S05").Value;
label2.Text = xml.Element("S06").Value;
label6.Text = xml.Element("S07").Value;
label10.Text = xml.Element("S08").Value;
label9.Text = xml.Element("S09").Value;
checkTransparency.Text = xml.Element("S0A").Value;
btnSetTrans.Text = xml.Element("S0B").Value;
btnBgd.Text = xml.Element("S0C").Value;
btnBgdRem.Text = xml.Element("S0D").Value;
radioOriginalPal.Text = xml.Element("S0E").Value;
checkMapCmp.Text = xml.Element("S0F").Value;
btnExport.Text = xml.Element("S10").Value;
btnImport.Text = xml.Element("S11").Value;
comboBox1.Items[0] = xml.Element("S12").Value;
comboBox1.Items[1] = xml.Element("S13").Value;
groupBox2.Text = xml.Element("S16").Value;
radioSwapPal.Text = xml.Element("S17").Value;
radioReplacePal.Text = xml.Element("S18").Value;
label7.Text = xml.Element("S19").Value;
}
catch { throw new Exception("There was an error reading the XML file of language."); }
}
private void Update_Info()
{
stop = true;
switch (image.FormatColor)
{
case ColorFormat.A3I5: comboDepth.SelectedIndex = 4; break;
case ColorFormat.A5I3: comboDepth.SelectedIndex = 5; break;
case ColorFormat.colors4: comboDepth.SelectedIndex = 6; break;
case ColorFormat.colors16: comboDepth.SelectedIndex = 0; break;
case ColorFormat.colors256: comboDepth.SelectedIndex = 1; break;
case ColorFormat.direct: comboDepth.SelectedIndex = 3; break;
case ColorFormat.colors2: comboDepth.SelectedIndex = 2; break;
}
if (isMap)
{
btnImport.Enabled = (map.CanEdit && image.CanEdit && palette.CanEdit ? true : false);
this.comboBox1.Enabled = false;
this.numericWidth.Value = (map.Width != 0 ? map.Width : image.Width);
this.numericHeight.Value = (map.Height != 0 ? map.Height : image.Height);
comboBox1.SelectedIndex = 1;
numericHeight.Minimum = image.TileSize;
numericWidth.Minimum = image.TileSize;
numericWidth.Increment = image.TileSize;
numericHeight.Increment = image.TileSize;
}
else
{
btnImport.Enabled = (image.CanEdit && palette.CanEdit ? true : false);
this.numericWidth.Value = image.Width;
this.numericHeight.Value = image.Height;
switch (image.FormTile)
{
case TileForm.Lineal:
comboBox1.SelectedIndex = 0;
numericHeight.Minimum = 1;
numericWidth.Minimum = 1;
numericWidth.Increment = 1;
numericHeight.Increment = 1;
break;
case TileForm.Horizontal:
comboBox1.SelectedIndex = 1;
numericHeight.Minimum = image.TileSize;
numericWidth.Minimum = image.TileSize;
numericWidth.Increment = image.TileSize;
numericHeight.Increment = image.TileSize;
break;
}
}
this.numTileSize.Value = image.TileSize;
this.numPal.Maximum = palette.NumberOfPalettes - 1;
this.numericStart.Maximum = image.Original.Length - 1;
this.checkMapCmp.Enabled = isMap;
stop = false;
}
private void Update_Image()
{
Bitmap bitmap;
if (!isMap)
bitmap = (Bitmap)image.Get_Image(palette);
else
bitmap = (Bitmap)map.Get_Image(image, palette);
if (checkTransparency.Checked)
bitmap.MakeTransparent(palette.Palette[(int)numPal.Value][0]);
Clipboard.SetImage(bitmap);
pic.Image = bitmap;
if (bitmap.Width == 512)
pic.BorderStyle = System.Windows.Forms.BorderStyle.None;
else
pic.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
}
private void numericStart_ValueChanged(object sender, EventArgs e)
{
if (stop)
return;
if (!isMap)
image.StartByte = (int)numericStart.Value;
else
map.StartByte = (int)numericStart.Value;
Update_Image();
}
private void numTileSize_ValueChanged(object sender, EventArgs e)
{
if (stop)
return;
image.TileSize = (int)numTileSize.Value;
Update_Image();
}
private void numericSize_ValueChanged(object sender, EventArgs e)
{
if (stop)
return;
if (!isMap)
{
image.Height = (int)numericHeight.Value;
image.Width = (int)numericWidth.Value;
}
else
{
map.Width = (int)numericWidth.Value;
map.Height = (int)numericHeight.Value;
}
Update_Image();
}
private void comboDepth_SelectedIndexChanged(object sender, EventArgs e)
{
if (stop)
return;
switch (comboDepth.SelectedIndex)
{
case 0: image.FormatColor = ColorFormat.colors16; break;
case 1: image.FormatColor = ColorFormat.colors256; break;
case 2: image.FormatColor = ColorFormat.colors2; break;
case 3: image.FormatColor = ColorFormat.direct; break;
case 4: image.FormatColor = ColorFormat.A3I5; break;
case 5: image.FormatColor = ColorFormat.A5I3; break;
case 6: image.FormatColor = ColorFormat.colors4; break;
case 7: image.FormatColor = ColorFormat.A4I4; break;
case 8: image.FormatColor = ColorFormat.BGRA32; break;
case 9: image.FormatColor = ColorFormat.ABGR32; break;
}
Update_Image();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (stop)
return;
switch (comboBox1.SelectedIndex)
{
case 0:
image.FormTile = TileForm.Lineal;
numericHeight.Minimum = 1;
numericWidth.Minimum = 1;
numericWidth.Increment = 1;
numericHeight.Increment = 1;
break;
case 1:
image.FormTile = TileForm.Horizontal;
numericHeight.Minimum = image.TileSize;
numericWidth.Minimum = image.TileSize;
numericWidth.Increment = image.TileSize;
numericHeight.Increment = image.TileSize;
break;
}
Update_Image();
}
private void numPal_ValueChanged(object sender, EventArgs e)
{
for (int j = 0; j < image.TilesPalette.Length; j++)
image.TilesPalette[j] = (byte)numPal.Value;
Update_Image();
}
private void checkTransparency_CheckedChanged(object sender, EventArgs e)
{
if (checkTransparency.Checked)
{
Bitmap imageT = (Bitmap)pic.Image;
imageT.MakeTransparent(palette.Palette[(int)numPal.Value][0]);
pic.Image = imageT;
}
else
Update_Image();
}
private void checkHex_CheckedChanged(object sender, EventArgs e)
{
numericStart.Hexadecimal = checkHex.Checked;
}
private void btnSetTrans_Click(object sender, EventArgs e)
{
int pal_index = (int)numPal.Value;
Color[] pal = palette.Palette[pal_index];
byte[] tiles = image.Tiles;
int index = -1;
if ((palette.Depth == ColorFormat.colors256 && palette.NumberOfColors == 256) ||
(palette.Depth == ColorFormat.colors16 && palette.NumberOfColors == 16))
{
index = Actions.Remove_DuplicatedColors(ref pal, ref tiles);
if (index == -1)
{
index = Actions.Remove_NotUsedColors(ref pal, ref tiles);
}
}
else
{
index = palette.NumberOfColors; // First empty place
Color[] newPal = new Color[pal.Length + 1];
Array.Copy(pal, newPal, pal.Length);
pal = newPal;
}
if (index == -1)
{
MessageBox.Show("No space in the palette found");
return;
}
pal[index] = Color.FromArgb(248, 0, 248); // Usually used as transparent color
Actions.Swap_Color(ref tiles, ref pal, index, 0, image.FormatColor);
Color[][] new_pal = palette.Palette;
new_pal[pal_index] = pal;
if (image.ID > 0)
image.Set_Tiles(tiles);
if (palette.ID > 0)
palette.Set_Palette(new_pal);
Save_Files();
}
private void btnExport_Click(object sender, EventArgs e)
{
SaveFileDialog o = new SaveFileDialog();
o.AddExtension = true;
o.DefaultExt = ".png";
o.Filter = "Portable Network Graphic (*.png)|*.png|" +
"BitMaP (*.bmp)|*.bmp|" +
"JPEG (*.jpg)|*.jpg;*.jpeg|" +
"Tagged Image File Format (*.tiff)|*.tiff;*.tif|" +
"Graphic Interchange Format (*.gif)|*.gif|" +
"Icon (*.ico)|*.ico;*.icon";
o.OverwritePrompt = true;
if (isMap)
o.FileName = map.FileName + ".png";
else
o.FileName = image.FileName + ".png";
if (o.ShowDialog() == DialogResult.OK)
{
if (o.FilterIndex == 2)
pic.Image.Save(o.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
else if (o.FilterIndex == 1)
pic.Image.Save(o.FileName, System.Drawing.Imaging.ImageFormat.Png);
else if (o.FilterIndex == 3)
pic.Image.Save(o.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
else if (o.FilterIndex == 4)
pic.Image.Save(o.FileName, System.Drawing.Imaging.ImageFormat.Tiff);
else if (o.FilterIndex == 5)
pic.Image.Save(o.FileName, System.Drawing.Imaging.ImageFormat.Gif);
else if (o.FilterIndex == 6)
pic.Image.Save(o.FileName, System.Drawing.Imaging.ImageFormat.Icon);
}
o.Dispose();
}
private void btnImport_Click(object sender, EventArgs e)
{
OpenFileDialog o = new OpenFileDialog();
o.CheckFileExists = true;
o.Filter = "Supported images |*.png;*.bmp;*.jpg;*.jpeg;*.tif;*.tiff;*.gif;*.ico;*.icon|" +
"BitMaP (*.bmp)|*.bmp|" +
"Portable Network Graphic (*.png)|*.png|" +
"JPEG (*.jpg)|*.jpg;*.jpeg|" +
"Tagged Image File Format (*.tiff)|*.tiff;*.tif|" +
"Graphic Interchange Format (*.gif)|*.gif|" +
"Icon (*.ico)|*.ico;*.icon";
o.Multiselect = false;
if (o.ShowDialog() != DialogResult.OK)
return;
Bitmap bitmap = (Bitmap)Image.FromFile(o.FileName);
// Get tiles + palette from the current image
byte[] tiles = new byte[0];
Color[] pal = new Color[0];
if (radioOriginalPal.Checked)
{
BMP bmp = new BMP(o.FileName);
tiles = bmp.Tiles;
pal = bmp.Palette.Palette[0];
}
else
{
try { Actions.Indexed_Image(bitmap, image.FormatColor, out tiles, out pal); }
catch (Exception ex) { MessageBox.Show(ex.Message); Console.WriteLine(ex.Message); return; }
}
// Swap palettes if "Swap palette" is checked. Try to change the colors to the old palette
if (radioSwapPal.Checked)
{
try { Actions.Swap_Palette(ref tiles, palette.Palette[(int)numPal.Value], pal, image.FormatColor); }
catch (Exception ex) { MessageBox.Show(ex.Message); Console.WriteLine(ex.Message); return; }
}
// If the tile form is horizontal convert to it
if (image.FormTile == TileForm.Horizontal || isMap)
{
tiles = Actions.HorizontalToLineal(tiles, bitmap.Width, bitmap.Height, image.BPP, 8);
image.FormTile = TileForm.Horizontal;
}
// Create a map file // MetLob edition 19/05/2015
if (isMap && checkMapCmp.Checked)
map.Set_Map(Actions.Create_Map(ref tiles, image.BPP, image.TileSize, (byte)numPal.Value), map.CanEdit, bitmap.Width, bitmap.Height);
else if (isMap)
{
int num_tiles = (tiles.Length * 8 / image.BPP) / (image.TileSize * image.TileSize);
map.Set_Map(Actions.Create_BasicMap(num_tiles, 0, (byte)numPal.Value), map.CanEdit);
}
// Set the data
image.Set_Tiles(tiles, bitmap.Width, bitmap.Height, image.FormatColor, image.FormTile, image.CanEdit, 8);
if (radioReplacePal.Checked)
palette.Set_Palette(pal, (int)numPal.Value);
Save_Files();
Update_Image();
Update_Info();
}
private void Save_Files()
{
if (image.ID >= 0)
{
try
{
string imageFile = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + Path.GetRandomFileName() + image.FileName;
image.Write(imageFile, palette);
pluginHost.ChangeFile(image.ID, imageFile);
}
catch (Exception e) { MessageBox.Show("Error writing new image:\n" + e.Message); };
}
if (palette.ID >= 0 && radioReplacePal.Checked)
{
try
{
string paletteFile = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + Path.GetRandomFileName() + palette.FileName;
palette.Write(paletteFile);
pluginHost.ChangeFile(palette.ID, paletteFile);
}
catch (Exception e) { MessageBox.Show("Error writing new palette:\n" + e.Message); };
}
if (isMap && map.ID >= 0)
{
try
{
string mapFile = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + Path.GetRandomFileName() + map.FileName;
map.Write(mapFile, image, palette);
pluginHost.ChangeFile(map.ID, mapFile);
}
catch (Exception e) { MessageBox.Show("Error writing new map:\n" + e.Message); };
}
}
private void pic_DoubleClick(object sender, EventArgs e)
{
XElement xml = XElement.Load(pluginHost.Get_LangXML());
xml = xml.Element("Ekona").Element("ImageControl");
Form ven = new Form();
PictureBox pcBox = new PictureBox();
pcBox.Image = pic.Image;
pcBox.SizeMode = PictureBoxSizeMode.AutoSize;
ven.Controls.Add(pcBox);
ven.BackColor = SystemColors.GradientInactiveCaption;
ven.Text = xml.Element("S15").Value;
ven.AutoScroll = true;
ven.MaximumSize = new Size(1024, 700);
ven.ShowIcon = false;
ven.AutoSize = true;
ven.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
ven.MaximizeBox = false;
ven.Show();
}
private void btnBgd_Click(object sender, EventArgs e)
{
ColorDialog o = new ColorDialog();
o.AllowFullOpen = true;
o.AnyColor = true;
if (o.ShowDialog() == DialogResult.OK)
{
pic.BackColor = o.Color;
btnBgdRem.Enabled = true;
}
}
private void btnBgdTrans_Click(object sender, EventArgs e)
{
btnBgdRem.Enabled = false;
pic.BackColor = Color.Transparent;
}
}
}