SpriteLibrary/SpriteLibrary/SpriteEntryForm.cs

436 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Resources;
using System.Windows.Forms;
using System.Collections;
using System.Drawing.Drawing2D;
namespace SpriteLibrary
{
internal partial class SpriteEntryForm : Form
{
SpriteController MyController;
ResourceManager myResources = null;
List<SpriteInfo> SpriteInformation = new List<SpriteInfo>();
SpriteInfo TempInformation = null;
Size SnapGridSize = new Size(5,5);
SpriteDatabase myDatabase = null;
int CurrentSIIndex = -1; //The information item we are editing. -1 means it is a new one.
int CurrentSIAnimation = -1;
bool WeAreDragging = false;
Point DragStart = new Point(-1, -1);
Rectangle ChosenArea = new Rectangle(1,1,100,100);
ToolTip myToolTip = new ToolTip();
internal SpriteEntryForm(SpriteDatabase theDatabase, List<SpriteInfo> ListToWorkOn, Size GridSize)
{
InitializeComponent();
myDatabase = theDatabase;
myResources = myDatabase.GetResourceManager();
SnapGridSize = GridSize;
LocalSetup();
SpriteInformation.AddRange(ListToWorkOn);
if (SpriteInformation.Count > 0)
{
SelectNewIndex(0);
}
}
private void LocalSetup()
{
pbImageField.BackgroundImageLayout = ImageLayout.Stretch;
pbImageField.BackgroundImage = new Bitmap(600, 800);
MyController = new SpriteController(pbImageField);
myToolTip.AutoPopDelay = 5000;
myToolTip.AutomaticDelay = 500;
PopulateMenu();
UpdateMenu();
SpriteInformationToForm();
UpdateMenu();
myToolTip.SetToolTip(btnNewAnimation, "Create another animation for the current sprite.");
}
internal List<SpriteInfo> GetUpdatedList()
{
return SpriteInformation;
}
private void PopulateMenu()
{
ResourceManager rm = myResources;
PopulateMenu(rm);
}
private void PopulateMenu(ResourceManager rm)
{
if (myResources == null) myResources = rm;
ResourceSet RS = rm.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true);
cbStartingImage.Items.Clear();
foreach (DictionaryEntry entry in RS)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;
if (resource is Image)
{
cbStartingImage.Items.Add(resourceKey);
}
}
cbStartingImage.SelectedIndex = 0;
}
private void UpdateMenu()
{
SuspendLayout();
lblCountSprites.Text = CurrentSIIndex+":"+CurrentSIAnimation+" of " + SpriteInformation.Count.ToString();
if (TempInformation == null) SetUpEmptyInfo();
//Put in numbers into the combo-box of which frame to base ourselves off of
cbAnimation.Items.Clear();
for(int i =0; i < TempInformation.Animations.Count; i++)
{
cbAnimation.Items.Add(i.ToString());
}
if (CurrentSIAnimation == 0)
{
rbFromImage.Checked = true;
panelRadioButtons.Visible = false;
}
else
panelRadioButtons.Visible = true;
if(TempInformation.Animations.Count >1)
{
btnAnimBack.Enabled = true;
btnAnimFwd.Enabled = true;
}
else
{
btnAnimBack.Enabled = false;
btnAnimFwd.Enabled = false;
}
if (rbFromImage.Checked)
{
if(!TCTabPages.TabPages.Contains(tpFromImage))
TCTabPages.TabPages.Add(tpFromImage);
if (TCTabPages.TabPages.Contains(tpMirrorRotate))
TCTabPages.TabPages.Remove(tpMirrorRotate);
}
else
{
if (TCTabPages.TabPages.Contains(tpFromImage))
TCTabPages.TabPages.Remove(tpFromImage);
if (!TCTabPages.TabPages.Contains(tpMirrorRotate))
TCTabPages.TabPages.Add(tpMirrorRotate);
}
UpdateChosenAreaLabel();
ResumeLayout();
}
private void UpdateChosenAreaLabel()
{
lblChosenArea.Text = ChosenArea.X + "," + ChosenArea.Y + "," + ChosenArea.Width + "," + ChosenArea.Height;
UpdateHighlightBox();
}
private void UpdateHighlightBox()
{
int transparency = 50;
Image NewFrontImage = new Bitmap(pbImageField.BackgroundImage.Width, pbImageField.BackgroundImage.Height);
Color FillColor = Color.Green;
Brush brush = new SolidBrush(Color.FromArgb(transparency, FillColor.R, FillColor.G, FillColor.B));
Brush nobrush = new SolidBrush(Color.FromArgb(0,0,0,0));
using (Graphics G = Graphics.FromImage(NewFrontImage))
{
G.FillRectangle(brush, 0,0,NewFrontImage.Width,NewFrontImage.Height);
GraphicsPath path = new GraphicsPath();
path.AddRectangle(ChosenArea);
G.SetClip(path);
G.Clear(Color.Transparent);
G.ResetClip();
// G.FillRectangle(nobrush, ChosenArea);
}
pbImageField.Image = NewFrontImage;
pbImageField.SizeMode = PictureBoxSizeMode.StretchImage;
pbImageField.Invalidate();
}
private void SetUpEmptyInfo()
{
TempInformation = new SpriteInfo();
TempInformation.SpriteName = "";
TempInformation.ViewPercent = 100;
AnimationInfo AI = new AnimationInfo();
AI.AnimSpeed = 200;
AI.FieldsToUse = AnimationType.SpriteDefinition;
AI.Height = 100;
AI.Width = 100;
AI.StartPoint = new Point(0, 0);
TempInformation.Animations.Add(AI);
}
private void cbStartingImage_SelectedIndexChanged(object sender, EventArgs e)
{
ResourceManager rm;
if (myResources != null) rm = myResources;
else rm = Properties.Resources.ResourceManager;
//We have a selected item
if (cbStartingImage.SelectedIndex >= 0)
{
//Load in a new image into our background
Image NewImage = (Bitmap)rm.GetObject(cbStartingImage.SelectedItem.ToString());
if (NewImage != null)
{
MyController.ReplaceOriginalImage(new Bitmap(NewImage));
pbImageField.BackgroundImage = new Bitmap(NewImage);
pbImageField.Invalidate();
}
}
}
/// <summary>
/// Take the values stored in TempInformation and push it out to our form
/// </summary>
private void SpriteInformationToForm()
{
if (TempInformation == null) return;
//For the main sprite information
tbSpriteName.Text = TempInformation.SpriteName;
tbDefaultSize.Text = TempInformation.ViewPercent.ToString();
//From the current animation
AnimationInfo AI = null;
if (CurrentSIAnimation < 0) CurrentSIAnimation = 0;
if (CurrentSIAnimation >= TempInformation.Animations.Count) CurrentSIAnimation = TempInformation.Animations.Count -1;
if (CurrentSIAnimation < TempInformation.Animations.Count)
{
if (CurrentSIAnimation >= TempInformation.Animations.Count)
TempInformation.Animations.Add(new AnimationInfo());
AI = TempInformation.Animations[CurrentSIAnimation];
tbAmimationSpeed.Text = AI.AnimSpeed.ToString();
cbStartingImage.Text = AI.ImageName;
cbMirrorH.Checked = AI.MirrorHorizontally;
cbMirrorV.Checked = AI.MirrorVertically;
cbAnimation.Text = AI.AnimationToUse.ToString();
tbNumFrames.Text = AI.NumFrames.ToString();
//lblChosenArea.Text = AI.Width + "x" + AI.Height;
ChosenArea = new Rectangle(AI.StartPoint.X, AI.StartPoint.Y, AI.Width, AI.Height);
UpdateChosenAreaLabel();
//Radio buttons
if (AI.FieldsToUse == AnimationType.SpriteDefinition) rbFromImage.Checked = true;
if (AI.FieldsToUse == AnimationType.Mirror) rbMirror.Checked = true;
if (AI.FieldsToUse == AnimationType.Rotation) rbRotation.Checked = true;
}
}
/// <summary>
/// Take the values stored in TempInformation and push it out to our form
/// </summary>
private void FormToSpriteInformation()
{
if (TempInformation == null) return;
//For the main sprite information
TempInformation.SpriteName = tbSpriteName.Text;
int.TryParse(tbDefaultSize.Text, out TempInformation.ViewPercent);
//From the current animation
AnimationInfo AI = null;
if (CurrentSIAnimation < 0) CurrentSIAnimation = 0;
if (CurrentSIAnimation >= TempInformation.Animations.Count) CurrentSIAnimation = TempInformation.Animations.Count - 1;
if (CurrentSIAnimation < TempInformation.Animations.Count)
{
AI = TempInformation.Animations[CurrentSIAnimation];
int.TryParse(tbAmimationSpeed.Text, out AI.AnimSpeed);
AI.ImageName = cbStartingImage.Text;
AI.MirrorHorizontally = cbMirrorH.Checked;
AI.MirrorVertically = cbMirrorV.Checked;
int.TryParse(cbAnimation.Text, out AI.AnimationToUse);
int.TryParse(tbNumFrames.Text, out AI.NumFrames);
AI.StartPoint = ChosenArea.Location;
AI.Width = ChosenArea.Width;
AI.Height = ChosenArea.Height;
if (rbFromImage.Checked) AI.FieldsToUse = AnimationType.SpriteDefinition;
if (rbMirror.Checked) AI.FieldsToUse = AnimationType.Mirror;
if (rbRotation.Checked) AI.FieldsToUse = AnimationType.Rotation;
}
}
/// <summary>
/// Given two locations that we have clicked on, find the area we have selected
/// </summary>
/// <param name="Start"></param>
/// <param name="End"></param>
/// <returns></returns>
private Rectangle AreaFromGridPoints(Point Start, Point End)
{
//Get the points translated from locations on the picturebox
Point OneImagePoint = MyController.ReturnPointAdjustedForImage(Start);
Point TwoImagePoint = MyController.ReturnPointAdjustedForImage(End);
//Now, shrink them to figure out which grid points we have chosen
Point OneGridPoint = new Point(OneImagePoint.X / SnapGridSize.Width, OneImagePoint.Y / SnapGridSize.Height);
Point TwoGridPoint = new Point(TwoImagePoint.X / SnapGridSize.Width, TwoImagePoint.Y / SnapGridSize.Height);
//Find the top-left point and the bottom-right point
Point StartGridPoint = new Point(Math.Min(OneGridPoint.X, TwoGridPoint.X), Math.Min(OneGridPoint.Y, TwoGridPoint.Y));
Point EndGridPoint = new Point(Math.Max(OneGridPoint.X, TwoGridPoint.X), Math.Max(OneGridPoint.Y, TwoGridPoint.Y));
//Translate them back into points on the image
Point ReturnSPoint = new Point(StartGridPoint.X * SnapGridSize.Width, StartGridPoint.Y * SnapGridSize.Height);
Point ReturnEPoint = new Point((EndGridPoint.X +1) * SnapGridSize.Width, (EndGridPoint.Y +1) * SnapGridSize.Height);
//Change it into a rectangle and return it
Rectangle ReturnRec = new Rectangle(ReturnSPoint.X, ReturnSPoint.Y, ReturnEPoint.X - ReturnSPoint.X, ReturnEPoint.Y - ReturnSPoint.Y);
return ReturnRec;
}
private void SpriteEntryForm_FormClosing(object sender, FormClosingEventArgs e)
{
myDatabase.Save(); //try saving the file
}
private void pbImageField_MouseMove(object sender, MouseEventArgs e)
{
//If we are dragging, process the dragging
if (WeAreDragging)
{
ChosenArea = AreaFromGridPoints(DragStart, e.Location);
UpdateChosenAreaLabel();
}
}
private void pbImageField_MouseDown(object sender, MouseEventArgs e)
{
//When the mouse goes down, we note that we are trying to drag
WeAreDragging = true;
DragStart = e.Location;
}
private void pbImageField_MouseUp(object sender, MouseEventArgs e)
{
//When the mouse goes up, stop dragging and update
if(WeAreDragging)
{
ChosenArea = AreaFromGridPoints(DragStart, e.Location);
UpdateChosenAreaLabel();
}
WeAreDragging = false;
}
void ApplyChanges()
{
FormToSpriteInformation();
if (CurrentSIIndex > 0 && CurrentSIIndex < SpriteInformation.Count)
{
SpriteInformation[CurrentSIIndex].CopyFrom(TempInformation);
}
else
{
SpriteInformation.Add(TempInformation.Clone());
CurrentSIIndex = SpriteInformation.IndexOf(TempInformation);
}
UpdateMenu();
}
private void btnApply_Click(object sender, EventArgs e)
{
ApplyChanges();
}
private void WeHaveNewItem()
{
TempInformation.CopyFrom(SpriteInformation[CurrentSIIndex]);
SpriteInformationToForm();
UpdateMenu();
}
private void SelectNewIndex(int nindex)
{
if (nindex < 0) return;
if (nindex >= SpriteInformation.Count) return;
CurrentSIIndex = nindex;
TempInformation = SpriteInformation[nindex].Clone();
WeHaveNewItem();
UpdateMenu();
}
private void btnFwd_Click(object sender, EventArgs e)
{
if (SpriteInformation.Count == 0) return; //nothing to do
CurrentSIIndex++;
if (CurrentSIIndex >= SpriteInformation.Count) CurrentSIIndex = 0;
if (TempInformation == null) TempInformation = new SpriteInfo();
WeHaveNewItem();
}
private void btnBack_Click(object sender, EventArgs e)
{
if (SpriteInformation.Count == 0) return; //nothing to do
CurrentSIIndex--;
if (CurrentSIIndex < 0) CurrentSIIndex = SpriteInformation.Count - 1;
if (TempInformation == null) TempInformation = new SpriteInfo();
WeHaveNewItem();
}
private void btnNewSprite_Click(object sender, EventArgs e)
{
TempInformation = null;
CurrentSIIndex = -1;
SetUpEmptyInfo();
SpriteInformationToForm();
UpdateMenu();
}
private void btnNewAnimation_Click(object sender, EventArgs e)
{
ApplyChanges();
AnimationInfo AI = TempInformation.Animations[CurrentSIAnimation].Clone();
TempInformation.Animations.Add(AI);
CurrentSIAnimation++;
SpriteInformationToForm();
UpdateMenu();
}
private void btnAnimBack_Click(object sender, EventArgs e)
{
ApplyChanges();
CurrentSIAnimation--;
if (CurrentSIAnimation < 0)
CurrentSIAnimation = TempInformation.Animations.Count - 1;
SpriteInformationToForm();
UpdateMenu();
}
private void btnAnimFwd_Click(object sender, EventArgs e)
{
ApplyChanges();
CurrentSIAnimation++;
if (CurrentSIAnimation >=TempInformation.Animations.Count)
CurrentSIAnimation = 0;
SpriteInformationToForm();
UpdateMenu();
}
}
}