Refactored Animation Editor

This commit is contained in:
miku-666
2022-08-20 20:05:45 +02:00
parent e881a42502
commit 885677d33d
21 changed files with 1452 additions and 1602 deletions

View File

@@ -1,4 +1,4 @@
namespace PckStudio.Forms.Utilities.AnimationEditor
namespace PckStudio.Forms.Additional_Popups.Animation
{
partial class ChangeTile
{
@@ -30,8 +30,8 @@
{
this.acceptBtn = new System.Windows.Forms.Button();
this.CancelBtn = new System.Windows.Forms.Button();
this.treeView1 = new System.Windows.Forms.TreeView();
this.treeView2 = new System.Windows.Forms.TreeView();
this.treeViewBlocks = new System.Windows.Forms.TreeView();
this.treeViewItems = new System.Windows.Forms.TreeView();
this.metroLabel1 = new MetroFramework.Controls.MetroLabel();
this.metroLabel2 = new MetroFramework.Controls.MetroLabel();
this.metroTextBox1 = new MetroFramework.Controls.MetroTextBox();
@@ -54,7 +54,7 @@
this.acceptBtn.TabIndex = 7;
this.acceptBtn.Text = "Save";
this.acceptBtn.UseVisualStyleBackColor = true;
this.acceptBtn.Click += new System.EventHandler(this.button1_Click);
this.acceptBtn.Click += new System.EventHandler(this.AcceptBtn_Click);
//
// CancelBtn
//
@@ -68,29 +68,29 @@
this.CancelBtn.TabIndex = 13;
this.CancelBtn.Text = "Cancel";
this.CancelBtn.UseVisualStyleBackColor = true;
this.CancelBtn.Click += new System.EventHandler(this.button2_Click);
this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click);
//
// treeView1
//
this.treeView1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeView1.ForeColor = System.Drawing.Color.White;
this.treeView1.Location = new System.Drawing.Point(0, 0);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(184, 125);
this.treeView1.TabIndex = 14;
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViews_AfterSelect);
this.treeViewBlocks.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.treeViewBlocks.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeViewBlocks.ForeColor = System.Drawing.Color.White;
this.treeViewBlocks.Location = new System.Drawing.Point(0, 0);
this.treeViewBlocks.Name = "treeView1";
this.treeViewBlocks.Size = new System.Drawing.Size(184, 125);
this.treeViewBlocks.TabIndex = 14;
this.treeViewBlocks.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViews_AfterSelect);
//
// treeView2
//
this.treeView2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.treeView2.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeView2.ForeColor = System.Drawing.Color.White;
this.treeView2.Location = new System.Drawing.Point(0, 0);
this.treeView2.Name = "treeView2";
this.treeView2.Size = new System.Drawing.Size(184, 125);
this.treeView2.TabIndex = 14;
this.treeView2.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViews_AfterSelect);
this.treeViewItems.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.treeViewItems.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeViewItems.ForeColor = System.Drawing.Color.White;
this.treeViewItems.Location = new System.Drawing.Point(0, 0);
this.treeViewItems.Name = "treeView2";
this.treeViewItems.Size = new System.Drawing.Size(184, 125);
this.treeViewItems.TabIndex = 14;
this.treeViewItems.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViews_AfterSelect);
//
// metroLabel1
//
@@ -159,7 +159,7 @@
// Blocks
//
this.Blocks.BackColor = System.Drawing.SystemColors.WindowFrame;
this.Blocks.Controls.Add(this.treeView1);
this.Blocks.Controls.Add(this.treeViewBlocks);
this.Blocks.Location = new System.Drawing.Point(4, 38);
this.Blocks.Name = "Blocks";
this.Blocks.Size = new System.Drawing.Size(184, 125);
@@ -169,7 +169,7 @@
// Items
//
this.Items.BackColor = System.Drawing.SystemColors.WindowFrame;
this.Items.Controls.Add(this.treeView2);
this.Items.Controls.Add(this.treeViewItems);
this.Items.Location = new System.Drawing.Point(4, 38);
this.Items.Name = "Items";
this.Items.Size = new System.Drawing.Size(184, 125);
@@ -213,8 +213,8 @@
#endregion
private System.Windows.Forms.Button acceptBtn;
private System.Windows.Forms.Button CancelBtn;
private System.Windows.Forms.TreeView treeView1;
private System.Windows.Forms.TreeView treeView2;
private System.Windows.Forms.TreeView treeViewBlocks;
private System.Windows.Forms.TreeView treeViewItems;
private MetroFramework.Controls.MetroLabel metroLabel1;
private MetroFramework.Controls.MetroLabel metroLabel2;
private MetroFramework.Controls.MetroTextBox metroTextBox1;

View File

@@ -0,0 +1,158 @@
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.IO;
using System.Windows.Forms;
using MetroFramework.Forms;
using System.Drawing.Drawing2D;
using Newtonsoft.Json.Linq;
using PckStudio.Forms.Utilities;
namespace PckStudio.Forms.Additional_Popups.Animation
{
public partial class ChangeTile : MetroForm
{
string selectedTile = "";
bool isItem = false;
public string SelectedTile => selectedTile;
public bool IsItem => isItem;
List<TreeNode> treeViewBlockCache = new List<TreeNode>();
List<TreeNode> treeViewItemCache = new List<TreeNode>();
public ChangeTile()
{
InitializeComponent();
ImageList tiles = new ImageList();
tiles.ColorDepth = ColorDepth.Depth32Bit;
tiles.Images.AddRange(AnimationUtil.tileImages);
treeViewBlocks.ImageList = tiles;
treeViewItems.ImageList = tiles;
try
{
int i = 0;
if (AnimationUtil.tileData["blocks"] != null)
{
foreach (JObject content in AnimationUtil.tileData["blocks"].Children())
{
foreach (JProperty prop in content.Properties())
{
if (!string.IsNullOrEmpty((string)prop.Value))
{
TreeNode tileNode = new TreeNode((string)prop.Value)
{
Tag = prop.Name,
ImageIndex = i,
SelectedImageIndex = i,
};
treeViewBlocks.Nodes.Add(tileNode);
treeViewBlockCache.Add(tileNode);
}
i++;
}
}
}
if (AnimationUtil.tileData["items"] != null)
{
foreach (JObject content in AnimationUtil.tileData["items"].Children())
{
foreach (JProperty prop in content.Properties())
{
if (!string.IsNullOrEmpty((string)prop.Value))
{
TreeNode tileNode = new TreeNode((string)prop.Value)
{
Tag = prop.Name,
ImageIndex = i,
SelectedImageIndex = i,
};
treeViewItems.Nodes.Add(tileNode);
treeViewItemCache.Add(tileNode);
}
i++;
}
}
}
}
catch (Newtonsoft.Json.JsonException j_ex)
{
MessageBox.Show(j_ex.Message, "Error");
return;
}
}
private void treeViews_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Tag is string tileData)
{
selectedTile = tileData;
Console.WriteLine(selectedTile);
isItem = e.Node.TreeView == treeViewItems;
}
}
void filter_TextChanged(object sender, EventArgs e)
{
// Some code in this function is modified code from this StackOverflow answer - MattNL
//https://stackoverflow.com/questions/8260322/filter-a-treeview-with-a-textbox-in-a-c-sharp-winforms-app
//blocks repainting tree until all objects loaded
treeViewBlocks.BeginUpdate();
treeViewBlocks.Nodes.Clear();
treeViewItems.BeginUpdate();
treeViewItems.Nodes.Clear();
if (!string.IsNullOrEmpty(metroTextBox1.Text))
{
foreach (TreeNode _node in treeViewBlockCache)
{
if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
treeViewBlocks.Nodes.Add((TreeNode)_node.Clone());
}
}
foreach (TreeNode _node in treeViewItemCache)
{
if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
treeViewItems.Nodes.Add((TreeNode)_node.Clone());
}
}
}
else
{
foreach (TreeNode _node in treeViewBlockCache)
{
treeViewBlocks.Nodes.Add((TreeNode)_node.Clone());
}
foreach (TreeNode _node in treeViewItemCache)
{
treeViewItems.Nodes.Add((TreeNode)_node.Clone());
}
}
//enables redrawing tree after all objects have been added
treeViewBlocks.EndUpdate();
treeViewItems.EndUpdate();
}
private void CancelBtn_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void AcceptBtn_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(selectedTile)) CancelBtn_Click(sender, e);
DialogResult = DialogResult.OK;
Close();
}
}
}

View File

@@ -0,0 +1,175 @@

namespace PckStudio.Forms.Additional_Popups.Animation
{
partial class FrameEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SaveBtn = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.CancelBtn = new System.Windows.Forms.Button();
this.FrameIndexUpDown = new System.Windows.Forms.NumericUpDown();
this.FrameTimeUpDown = new System.Windows.Forms.NumericUpDown();
((System.ComponentModel.ISupportInitialize)(this.FrameIndexUpDown)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.FrameTimeUpDown)).BeginInit();
this.SuspendLayout();
//
// SaveBtn
//
this.SaveBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.SaveBtn.ForeColor = System.Drawing.Color.White;
this.SaveBtn.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.SaveBtn.Location = new System.Drawing.Point(55, 111);
this.SaveBtn.Name = "SaveBtn";
this.SaveBtn.Size = new System.Drawing.Size(75, 23);
this.SaveBtn.TabIndex = 7;
this.SaveBtn.Text = "Save";
this.SaveBtn.UseVisualStyleBackColor = true;
this.SaveBtn.Click += new System.EventHandler(this.SaveBtn_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.label2.Location = new System.Drawing.Point(9, 54);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(65, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Frame Index";
//
// label1
//
this.label1.AutoSize = true;
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.label1.Location = new System.Drawing.Point(9, 83);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(62, 13);
this.label1.TabIndex = 10;
this.label1.Text = "Frame Time";
//
// label3
//
this.label3.AutoSize = true;
this.label3.ForeColor = System.Drawing.Color.White;
this.label3.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.label3.Location = new System.Drawing.Point(47, 13);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(109, 13);
this.label3.TabIndex = 12;
this.label3.Text = "may/matt was here :3";
//
// CancelBtn
//
this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.CancelBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.CancelBtn.ForeColor = System.Drawing.Color.White;
this.CancelBtn.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.CancelBtn.Location = new System.Drawing.Point(135, 111);
this.CancelBtn.Name = "CancelBtn";
this.CancelBtn.Size = new System.Drawing.Size(75, 23);
this.CancelBtn.TabIndex = 13;
this.CancelBtn.Text = "Cancel";
this.CancelBtn.UseVisualStyleBackColor = true;
this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click);
//
// FrameIndexUpDown
//
this.FrameIndexUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
this.FrameIndexUpDown.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.FrameIndexUpDown.ForeColor = System.Drawing.SystemColors.Window;
this.FrameIndexUpDown.Location = new System.Drawing.Point(77, 54);
this.FrameIndexUpDown.Maximum = new decimal(new int[] {
1,
0,
0,
0});
this.FrameIndexUpDown.Name = "FrameIndexUpDown";
this.FrameIndexUpDown.Size = new System.Drawing.Size(179, 20);
this.FrameIndexUpDown.TabIndex = 14;
this.FrameIndexUpDown.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// FrameTimeUpDown
//
this.FrameTimeUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
this.FrameTimeUpDown.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.FrameTimeUpDown.ForeColor = System.Drawing.SystemColors.Window;
this.FrameTimeUpDown.Location = new System.Drawing.Point(77, 81);
this.FrameTimeUpDown.Maximum = new decimal(new int[] {
10000,
0,
0,
0});
this.FrameTimeUpDown.Name = "FrameTimeUpDown";
this.FrameTimeUpDown.Size = new System.Drawing.Size(179, 20);
this.FrameTimeUpDown.TabIndex = 15;
this.FrameTimeUpDown.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// FrameEditor
//
this.AcceptButton = this.SaveBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.CancelBtn;
this.ClientSize = new System.Drawing.Size(264, 140);
this.ControlBox = false;
this.Controls.Add(this.FrameTimeUpDown);
this.Controls.Add(this.FrameIndexUpDown);
this.Controls.Add(this.CancelBtn);
this.Controls.Add(this.label3);
this.Controls.Add(this.label1);
this.Controls.Add(this.SaveBtn);
this.Controls.Add(this.label2);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(266, 142);
this.Name = "FrameEditor";
this.Resizable = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Theme = MetroFramework.MetroThemeStyle.Dark;
((System.ComponentModel.ISupportInitialize)(this.FrameIndexUpDown)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.FrameTimeUpDown)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button SaveBtn;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button CancelBtn;
private System.Windows.Forms.NumericUpDown FrameIndexUpDown;
private System.Windows.Forms.NumericUpDown FrameTimeUpDown;
}
}

View File

@@ -0,0 +1,45 @@
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 MetroFramework.Forms;
using System.Windows.Forms;
using PckStudio.Forms.Editor;
namespace PckStudio.Forms.Additional_Popups.Animation
{
public partial class FrameEditor : MetroForm
{
public int FrameTextureIndex => (int)FrameIndexUpDown.Value;
public int FrameTime => (int)FrameTimeUpDown.Value;
public FrameEditor(int indexLimit)
{
InitializeComponent();
label3.Text = "Frame must be within 0 and " + indexLimit + ".";
FrameIndexUpDown.Maximum = indexLimit;
FrameTimeUpDown.Minimum = 1;
}
public FrameEditor(int frameTime, int frameTextureIndex, int indexLimit) : this(indexLimit)
{
FrameIndexUpDown.Value = frameTextureIndex;
FrameTimeUpDown.Value = frameTime;
}
private void SaveBtn_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void CancelBtn_Click(object sender, EventArgs e)
{
Close();
}
}
}

View File

@@ -1,5 +1,5 @@

namespace PckStudio.Forms.Utilities.AnimationEditor
namespace PckStudio.Forms.Additional_Popups.Animation
{
partial class SetBulkSpeed
{

View File

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
using MetroFramework.Forms;
using System.Windows.Forms;
namespace PckStudio.Forms.Utilities.AnimationEditor
namespace PckStudio.Forms.Additional_Popups.Animation
{
public partial class SetBulkSpeed : MetroForm
{
@@ -23,16 +23,12 @@ namespace PckStudio.Forms.Utilities.AnimationEditor
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
e.Handled = !char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar);
}
private void button1_Click(object sender, EventArgs e)
{
if(metroTextBox2.Text == "") {}
else if(Int16.Parse(metroTextBox2.Text) < 0) {}
if (metroTextBox2.Text == "" || short.Parse(metroTextBox2.Text) < 0) return;
else
{
int i = 0;
@@ -47,14 +43,13 @@ namespace PckStudio.Forms.Utilities.AnimationEditor
tv.Nodes.Insert(i, frameNode);
i++;
}
this.Close();
Close();
}
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
Close();
}
}
}

View File

@@ -0,0 +1,344 @@
namespace PckStudio.Forms.Editor
{
partial class AnimationEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AnimationEditor));
this.frameTreeView = new System.Windows.Forms.TreeView();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.addFrameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeFrameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.bulkAnimationSpeedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.importJavaAnimationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.changeTileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.InterpolationCheckbox = new MetroFramework.Controls.MetroCheckBox();
this.AnimationPlayBtn = new MetroFramework.Controls.MetroButton();
this.AnimationStopBtn = new MetroFramework.Controls.MetroButton();
this.tileLabel = new MetroFramework.Controls.MetroLabel();
this.MipMapCheckbox = new MetroFramework.Controls.MetroCheckBox();
this.MipMapLabel = new MetroFramework.Controls.MetroLabel();
this.MipMapNumericUpDown = new System.Windows.Forms.NumericUpDown();
this.pictureBoxWithInterpolationMode1 = new PckStudio.PictureBoxWithInterpolationMode();
this.contextMenuStrip1.SuspendLayout();
this.menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.MipMapNumericUpDown)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxWithInterpolationMode1)).BeginInit();
this.SuspendLayout();
//
// treeView1
//
this.frameTreeView.AllowDrop = true;
this.frameTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.frameTreeView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.frameTreeView.ContextMenuStrip = this.contextMenuStrip1;
this.frameTreeView.ForeColor = System.Drawing.Color.White;
this.frameTreeView.Location = new System.Drawing.Point(20, 88);
this.frameTreeView.Margin = new System.Windows.Forms.Padding(0);
this.frameTreeView.Name = "treeView1";
this.frameTreeView.Size = new System.Drawing.Size(165, 198);
this.frameTreeView.TabIndex = 15;
this.frameTreeView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.frameTreeView_ItemDrag);
this.frameTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.frameTreeView_AfterSelect);
this.frameTreeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_doubleClick);
this.frameTreeView.DragDrop += new System.Windows.Forms.DragEventHandler(this.frameTreeView_DragDrop);
this.frameTreeView.DragEnter += new System.Windows.Forms.DragEventHandler(this.frameTreeView_DragEnter);
this.frameTreeView.DragOver += new System.Windows.Forms.DragEventHandler(this.frameTreeView_DragOver);
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.addFrameToolStripMenuItem,
this.removeFrameToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(154, 48);
//
// addFrameToolStripMenuItem
//
this.addFrameToolStripMenuItem.Image = global::PckStudio.Properties.Resources.ExportFile;
this.addFrameToolStripMenuItem.Name = "addFrameToolStripMenuItem";
this.addFrameToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
this.addFrameToolStripMenuItem.Text = "Add Frame";
this.addFrameToolStripMenuItem.Click += new System.EventHandler(this.addFrameToolStripMenuItem_Click);
//
// removeFrameToolStripMenuItem
//
this.removeFrameToolStripMenuItem.Image = global::PckStudio.Properties.Resources.Del;
this.removeFrameToolStripMenuItem.Name = "removeFrameToolStripMenuItem";
this.removeFrameToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
this.removeFrameToolStripMenuItem.Text = "Remove Frame";
this.removeFrameToolStripMenuItem.Click += new System.EventHandler(this.removeFrameToolStripMenuItem_Click);
//
// menuStrip
//
this.menuStrip.AutoSize = false;
this.menuStrip.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.editToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(20, 60);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(372, 24);
this.menuStrip.TabIndex = 14;
this.menuStrip.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.saveToolStripMenuItem1});
this.fileToolStripMenuItem.ForeColor = System.Drawing.Color.White;
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
//
// saveToolStripMenuItem1
//
this.saveToolStripMenuItem1.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem1.Image")));
this.saveToolStripMenuItem1.Name = "saveToolStripMenuItem1";
this.saveToolStripMenuItem1.Size = new System.Drawing.Size(98, 22);
this.saveToolStripMenuItem1.Text = "Save";
this.saveToolStripMenuItem1.Click += new System.EventHandler(this.saveToolStripMenuItem1_Click);
//
// editToolStripMenuItem
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.bulkAnimationSpeedToolStripMenuItem,
this.importJavaAnimationToolStripMenuItem,
this.changeTileToolStripMenuItem});
this.editToolStripMenuItem.ForeColor = System.Drawing.Color.White;
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(46, 20);
this.editToolStripMenuItem.Text = "Tools";
//
// bulkAnimationSpeedToolStripMenuItem
//
this.bulkAnimationSpeedToolStripMenuItem.Image = global::PckStudio.Properties.Resources.clock;
this.bulkAnimationSpeedToolStripMenuItem.Name = "bulkAnimationSpeedToolStripMenuItem";
this.bulkAnimationSpeedToolStripMenuItem.Size = new System.Drawing.Size(210, 22);
this.bulkAnimationSpeedToolStripMenuItem.Text = "Set Bulk Animation Speed";
this.bulkAnimationSpeedToolStripMenuItem.Click += new System.EventHandler(this.bulkAnimationSpeedToolStripMenuItem_Click);
//
// importJavaAnimationToolStripMenuItem
//
this.importJavaAnimationToolStripMenuItem.Image = global::PckStudio.Properties.Resources.ExportFile;
this.importJavaAnimationToolStripMenuItem.Name = "importJavaAnimationToolStripMenuItem";
this.importJavaAnimationToolStripMenuItem.Size = new System.Drawing.Size(210, 22);
this.importJavaAnimationToolStripMenuItem.Text = "Import Java Animation";
this.importJavaAnimationToolStripMenuItem.Click += new System.EventHandler(this.importJavaAnimationToolStripMenuItem_Click);
//
// changeTileToolStripMenuItem
//
this.changeTileToolStripMenuItem.Image = global::PckStudio.Properties.Resources.changeTile;
this.changeTileToolStripMenuItem.Name = "changeTileToolStripMenuItem";
this.changeTileToolStripMenuItem.Size = new System.Drawing.Size(210, 22);
this.changeTileToolStripMenuItem.Text = "Change Tile";
this.changeTileToolStripMenuItem.Click += new System.EventHandler(this.changeTileToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.ForeColor = System.Drawing.Color.White;
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "Help";
this.helpToolStripMenuItem.Click += new System.EventHandler(this.helpToolStripMenuItem_Click);
//
// InterpolationCheckbox
//
this.InterpolationCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.InterpolationCheckbox.AutoSize = true;
this.InterpolationCheckbox.Location = new System.Drawing.Point(188, 317);
this.InterpolationCheckbox.Name = "InterpolationCheckbox";
this.InterpolationCheckbox.Size = new System.Drawing.Size(204, 15);
this.InterpolationCheckbox.TabIndex = 17;
this.InterpolationCheckbox.Text = "Interpolates (not simulated above)";
this.InterpolationCheckbox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.InterpolationCheckbox.UseSelectable = true;
//
// AnimationPlayBtn
//
this.AnimationPlayBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.AnimationPlayBtn.Location = new System.Drawing.Point(188, 291);
this.AnimationPlayBtn.Name = "AnimationPlayBtn";
this.AnimationPlayBtn.Size = new System.Drawing.Size(99, 24);
this.AnimationPlayBtn.TabIndex = 18;
this.AnimationPlayBtn.Text = "Play Animation";
this.AnimationPlayBtn.Theme = MetroFramework.MetroThemeStyle.Dark;
this.AnimationPlayBtn.UseSelectable = true;
this.AnimationPlayBtn.Click += new System.EventHandler(this.StartAnimationBtn_Click);
//
// AnimationStopBtn
//
this.AnimationStopBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.AnimationStopBtn.Enabled = false;
this.AnimationStopBtn.Location = new System.Drawing.Point(293, 291);
this.AnimationStopBtn.Name = "AnimationStopBtn";
this.AnimationStopBtn.Size = new System.Drawing.Size(99, 24);
this.AnimationStopBtn.TabIndex = 19;
this.AnimationStopBtn.Text = "Stop Animation";
this.AnimationStopBtn.Theme = MetroFramework.MetroThemeStyle.Dark;
this.AnimationStopBtn.UseSelectable = true;
this.AnimationStopBtn.Click += new System.EventHandler(this.StopAnimationBtn_Click);
//
// tileLabel
//
this.tileLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.tileLabel.AutoSize = true;
this.tileLabel.Location = new System.Drawing.Point(20, 290);
this.tileLabel.MinimumSize = new System.Drawing.Size(170, 19);
this.tileLabel.Name = "tileLabel";
this.tileLabel.Size = new System.Drawing.Size(57, 19);
this.tileLabel.TabIndex = 20;
this.tileLabel.Text = "tileLabel";
this.tileLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// MipMapCheckbox
//
this.MipMapCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.MipMapCheckbox.AutoSize = true;
this.MipMapCheckbox.Location = new System.Drawing.Point(20, 312);
this.MipMapCheckbox.Name = "MipMapCheckbox";
this.MipMapCheckbox.Size = new System.Drawing.Size(128, 15);
this.MipMapCheckbox.TabIndex = 21;
this.MipMapCheckbox.Text = "Is Mip Map Texture?";
this.MipMapCheckbox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.MipMapCheckbox.UseSelectable = true;
this.MipMapCheckbox.CheckedChanged += new System.EventHandler(this.MipMapCheckBox_CheckedChanged);
//
// MipMapLabel
//
this.MipMapLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.MipMapLabel.AutoSize = true;
this.MipMapLabel.Location = new System.Drawing.Point(21, 330);
this.MipMapLabel.Name = "MipMapLabel";
this.MipMapLabel.Size = new System.Drawing.Size(99, 19);
this.MipMapLabel.TabIndex = 22;
this.MipMapLabel.Text = "Mip Map Level:";
this.MipMapLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
this.MipMapLabel.Visible = false;
//
// MipMapNumericUpDown
//
this.MipMapNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.MipMapNumericUpDown.BackColor = System.Drawing.Color.Black;
this.MipMapNumericUpDown.ForeColor = System.Drawing.SystemColors.Window;
this.MipMapNumericUpDown.Location = new System.Drawing.Point(127, 330);
this.MipMapNumericUpDown.Maximum = new decimal(new int[] {
5,
0,
0,
0});
this.MipMapNumericUpDown.Minimum = new decimal(new int[] {
2,
0,
0,
0});
this.MipMapNumericUpDown.Name = "MipMapNumericUpDown";
this.MipMapNumericUpDown.Size = new System.Drawing.Size(44, 20);
this.MipMapNumericUpDown.TabIndex = 23;
this.MipMapNumericUpDown.Value = new decimal(new int[] {
2,
0,
0,
0});
this.MipMapNumericUpDown.Visible = false;
//
// pictureBoxWithInterpolationMode1
//
this.pictureBoxWithInterpolationMode1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBoxWithInterpolationMode1.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.pictureBoxWithInterpolationMode1.Location = new System.Drawing.Point(188, 88);
this.pictureBoxWithInterpolationMode1.Name = "pictureBoxWithInterpolationMode1";
this.pictureBoxWithInterpolationMode1.Size = new System.Drawing.Size(204, 198);
this.pictureBoxWithInterpolationMode1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBoxWithInterpolationMode1.TabIndex = 16;
this.pictureBoxWithInterpolationMode1.TabStop = false;
//
// AnimationEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(412, 362);
this.Controls.Add(this.AnimationStopBtn);
this.Controls.Add(this.AnimationPlayBtn);
this.Controls.Add(this.MipMapNumericUpDown);
this.Controls.Add(this.MipMapLabel);
this.Controls.Add(this.MipMapCheckbox);
this.Controls.Add(this.tileLabel);
this.Controls.Add(this.InterpolationCheckbox);
this.Controls.Add(this.pictureBoxWithInterpolationMode1);
this.Controls.Add(this.frameTreeView);
this.Controls.Add(this.menuStrip);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MinimumSize = new System.Drawing.Size(412, 362);
this.Name = "AnimationEditor";
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Text = "Animation Editor";
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.contextMenuStrip1.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.MipMapNumericUpDown)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxWithInterpolationMode1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TreeView frameTreeView;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem1;
private PictureBoxWithInterpolationMode pictureBoxWithInterpolationMode1;
private MetroFramework.Controls.MetroCheckBox InterpolationCheckbox;
private MetroFramework.Controls.MetroButton AnimationPlayBtn;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem addFrameToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem removeFrameToolStripMenuItem;
private MetroFramework.Controls.MetroButton AnimationStopBtn;
private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem bulkAnimationSpeedToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem importJavaAnimationToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem changeTileToolStripMenuItem;
private MetroFramework.Controls.MetroLabel tileLabel;
private MetroFramework.Controls.MetroCheckBox MipMapCheckbox;
private MetroFramework.Controls.MetroLabel MipMapLabel;
private System.Windows.Forms.NumericUpDown MipMapNumericUpDown;
}
}

View File

@@ -0,0 +1,591 @@
using MetroFramework.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using PckStudio.Classes.FileTypes;
using PckStudio.Forms.Additional_Popups.Animation;
using PckStudio.Properties;
using PckStudio.Forms.Utilities;
namespace PckStudio.Forms.Editor
{
public partial class AnimationEditor : MetroForm
{
PCKFile.FileData animationFile;
Animation currentAnimation;
AnimationPlayer player;
bool isItem = false;
string animationSection => AnimationUtil.GetAnimationSection(isItem);
string TileName = string.Empty;
//int frameCounter = 0; // ported directly from Java Edition code -MattNL
sealed class Animation
{
public const int MinimumFrameTime = 1;
private readonly List<Image> frameTextures;
private readonly List<Frame> frames = new List<Frame>();
public Frame this[int frameIndex] => frames[frameIndex];
// not implemented rn...
public bool Interpolate { get; set; } = false;
public Animation(Image image)
{
frameTextures = new List<Image>(SplitImageToFrameTextures(image));
}
public Animation(Image image, string ANIM) : this(image)
{
ParseAnim(ANIM);
}
public struct Frame
{
public readonly Image Texture;
public int Ticks;
public static implicit operator Image(Frame f) => f.Texture;
public Frame(Image texture) : this(texture, MinimumFrameTime)
{}
public Frame(Image texture, int frameTime)
{
Texture = texture;
Ticks = frameTime;
}
}
public void ParseAnim(string ANIM)
{
_ = ANIM ?? throw new ArgumentNullException(nameof(ANIM));
ANIM = (Interpolate = ANIM.StartsWith("#")) ? ANIM.Substring(1) : ANIM;
string[] animData = ANIM.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
int lastFrameTime = MinimumFrameTime;
foreach (string frameInfo in animData)
{
string[] frameData = frameInfo.Split('*');
//if (frameData.Length < 2)
// continue; // shouldn't happen
int currentFrameIndex = int.TryParse(frameData[0], out currentFrameIndex) ? currentFrameIndex : 0;
// Some textures like the Halloween 2015's Lava texture don't have a
// frame time parameter for certain frames.
// This will detect that and place the last frame time in its place.
// This is accurate to console edition behavior.
// - MattNL
int currentFrameTime = string.IsNullOrEmpty(frameData[1]) ? lastFrameTime : int.Parse(frameData[1]);
AddFrame(currentFrameIndex, currentFrameTime);
lastFrameTime = currentFrameTime;
}
}
public Frame AddFrame(int frameTextureIndex) => AddFrame(frameTextureIndex, MinimumFrameTime);
public Frame AddFrame(int frameTextureIndex, int frameTime)
{
if (frameTextureIndex < 0 || frameTextureIndex >= frameTextures.Count)
throw new ArgumentOutOfRangeException(nameof(frameTextureIndex));
Frame f = new Frame(frameTextures[frameTextureIndex], frameTime);
frames.Add(f);
return f;
}
public bool RemoveFrame(int frameIndex)
{
frames.RemoveAt(frameIndex);
return true;
}
private static IEnumerable<Image> SplitImageToFrameTextures(Image source)
{
for (int i = 0; i < source.Height / source.Width; i++)
{
Rectangle tileArea = new Rectangle(0, i * source.Width, source.Width, source.Width);
Bitmap tileImage = new Bitmap(source.Width, source.Width);
using (Graphics gfx = Graphics.FromImage(tileImage))
{
gfx.SmoothingMode = SmoothingMode.None;
gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(source, new Rectangle(0, 0, source.Width, source.Width), tileArea, GraphicsUnit.Pixel);
}
yield return tileImage;
}
yield break;
}
public Frame GetFrame(int index) => frames[index];
public List<Frame> GetFrames()
{
return frames;
}
public int GetFrameIndex(Image frameTexture)
{
_ = frameTexture ?? throw new ArgumentNullException(nameof(frameTexture));
return frameTextures.IndexOf(frameTexture);
}
public int FrameCount => frames.Count;
public int FrameTextureCount => frameTextures.Count;
public void SetFrame(Frame frame, int frameTextureIndex, int frameTime = MinimumFrameTime)
=> SetFrame(frames.IndexOf(frame), frameTextureIndex, frameTime);
public void SetFrame(int frameIndex, int frameTextureIndex, int frameTime = MinimumFrameTime)
{
frames[frameIndex] = new Frame(frameTextures[frameTextureIndex], frameTime);
}
public string BuildAnim()
{
string animationData = Interpolate ? "#" : string.Empty;
frames.ForEach(frame => animationData += $"{GetFrameIndex(frame)}*{frame.Ticks},");
return animationData.TrimEnd(',');
}
public Image BuildTexture()
{
int width = frameTextures[0].Width;
int height = frameTextures[0].Height;
if (width != height) throw new Exception("Invalid size");
var img = new Bitmap(width, height * FrameTextureCount);
int pos_y = 0;
using (var g = Graphics.FromImage(img))
frameTextures.ForEach(texture =>
{
g.DrawImage(texture, 0, pos_y);
pos_y += height;
});
return img;
}
//public static Animation FromJson(string json, Image texture)
//{
// _ = json ?? throw new ArgumentNullException(nameof(json));
// _ = texture ?? throw new ArgumentNullException(nameof(texture));
// var _animation = new Animation(texture);
// JObject mcmeta = JObject.Parse(json);
// if (mcmeta["animation"] is JToken animation)
// {
// int frameTime = 1;
// // Some if statements to ensure that the animation is valid.
// if (animation["frametime"] is JToken frametime_token && frametime_token.Type == JTokenType.Integer)
// frameTime = (int)frametime_token;
// if (animation["interpolate"] is JToken interpolate_token && interpolate_token.Type == JTokenType.Boolean)
// _animation.Interpolate = (bool)interpolate_token;
// if (animation["frames"] is JToken frames_token &&
// frames_token.Type == JTokenType.Array)
// {
// foreach (JToken frame in frames_token.Children())
// {
// if (frame.Type == JTokenType.Object)
// {
// if (frame["index"] is JToken frame_index && frame_index.Type == JTokenType.Integer &&
// frame["time"] is JToken frame_time && frame_time.Type == JTokenType.Integer)
// {
// Console.WriteLine("{0}*{1}", (int)frame["index"], (int)frame["time"]);
// _animation.AddFrame((int)frame["index"], (int)frame["time"]);
// }
// }
// else if (frame.Type == JTokenType.Integer)
// {
// Console.WriteLine("{0}*{1}", (int)frame, frameTime);
// _animation.AddFrame((int)frame, frameTime);
// }
// }
// }
// }
// return _animation;
//}
}
sealed class AnimationPlayer
{
public const int BaseTickSpeed = 24;
public bool IsPlaying { get; private set; } = false;
private int currentAnimationFrameIndex = 0;
private PictureBox display;
private Animation _animation;
private CancellationTokenSource cts = new CancellationTokenSource();
public AnimationPlayer(PictureBox display)
{
SetContext(display);
}
private async void DoAnimate()
{
_ = display ?? throw new ArgumentNullException(nameof(display));
_ = _animation ?? throw new ArgumentNullException(nameof(_animation));
IsPlaying = true;
while (!cts.IsCancellationRequested)
{
if (currentAnimationFrameIndex >= _animation.FrameCount)
currentAnimationFrameIndex = 0;
Animation.Frame frame = SetFrameDisplayed(currentAnimationFrameIndex++);
await Task.Delay(BaseTickSpeed * frame.Ticks);
}
IsPlaying = false;
}
public void Start(Animation animation)
{
_animation = animation;
cts = new CancellationTokenSource();
Task.Run(DoAnimate, cts.Token);
}
public void Stop() => cts.Cancel();
public Animation.Frame GetCurrentFrame() => _animation[currentAnimationFrameIndex];
public void SetContext(PictureBox display) => this.display = display;
public void SelectFrame(Animation animation, int index)
{
_animation = animation;
if (IsPlaying) Stop();
SetFrameDisplayed(index);
currentAnimationFrameIndex = index;
}
private Animation.Frame SetFrameDisplayed(int i)
{
Monitor.Enter(_animation);
Animation.Frame frame = _animation[i];
display.Image = frame;
Monitor.Exit(_animation);
return frame;
}
}
public AnimationEditor(PCKFile.FileData file)
{
InitializeComponent();
isItem = file.filepath.Split('/').Contains("items");
TileName = Path.GetFileNameWithoutExtension(file.filepath);
animationFile = file;
// sanity check
if (TileName.EndsWith("MipMapLevel2") || TileName.EndsWith("MipMapLevel3"))
{
string mipMapLvl = TileName.Last().ToString();
TileName = TileName.Substring(0, TileName.Length - 12);
MipMapCheckbox.Checked = true;
MipMapNumericUpDown.Value = short.Parse(mipMapLvl);
}
using MemoryStream textureMem = new MemoryStream(animationFile.data);
var texture = new Bitmap(textureMem);
currentAnimation = animationFile.properties.HasProperty("ANIM")
? new Animation(texture, animationFile.properties.GetProperty("ANIM").Item2)
: new Animation(texture);
InterpolationCheckbox.Checked = currentAnimation.Interpolate;
player = new AnimationPlayer(pictureBoxWithInterpolationMode1);
foreach (JObject content in AnimationUtil.tileData[animationSection].Children())
{
var prop = content.Properties().FirstOrDefault(prop => prop.Name == TileName);
if (prop is JProperty)
{
tileLabel.Text = (string)prop.Value;
break;
}
}
LoadAnimationTreeView();
}
private void LoadAnimationTreeView()
{
frameTreeView.Nodes.Clear();
// $"Frame: {i}, Frame Time: {Animation.MinimumFrameTime}"
currentAnimation.GetFrames().ForEach(f => frameTreeView.Nodes.Add($"Frame: {currentAnimation.GetFrameIndex(f.Texture)}, Frame Time: {f.Ticks}"));
}
private void frameTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
if (player.IsPlaying && !AnimationPlayBtn.Enabled)
AnimationPlayBtn.Enabled = !(AnimationStopBtn.Enabled = !AnimationStopBtn.Enabled);
player.SelectFrame(currentAnimation, frameTreeView.SelectedNode.Index);
}
private int mix(double ratio, int val1, int val2) // Ported from Java Edition code
{
return (int)(ratio * val1 + (1.0D - ratio) * val2);
}
private void StartAnimationBtn_Click(object sender, EventArgs e)
{
AnimationPlayBtn.Enabled = !(AnimationStopBtn.Enabled = !AnimationStopBtn.Enabled);
if (currentAnimation.FrameCount > 1)
{
player.SetContext(pictureBoxWithInterpolationMode1);
player.Start(currentAnimation);
}
}
private void StopAnimationBtn_Click(object sender, EventArgs e)
{
AnimationPlayBtn.Enabled = !(AnimationStopBtn.Enabled = !AnimationStopBtn.Enabled);
player.Stop();
}
private void frameTreeView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Delete)
removeFrameToolStripMenuItem_Click(sender, e);
}
private TreeNode FindNodeByName(TreeNode treeNode, string name)
{
foreach (TreeNode node in treeNode.Nodes)
{
if (node.Text.ToLower() == name.ToLower()) return node;
return FindNodeByName(node, name);
}
return null;
}
private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
{
string anim = currentAnimation.BuildAnim();
animationFile.properties.SetProperty("ANIM", anim);
using (var stream = new MemoryStream())
{
currentAnimation.BuildTexture().Save(stream, ImageFormat.Png);
animationFile.SetData(stream.ToArray());
}
DialogResult = DialogResult.OK;
}
// Most of the code below is modified code from this link: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.itemdrag?view=windowsdesktop-6.0
// - MattNL
private void frameTreeView_ItemDrag(object sender, ItemDragEventArgs e)
{
// Move the dragged node when the left mouse button is used.
if (e.Button == MouseButtons.Left)
{
DoDragDrop(e.Item, DragDropEffects.Move);
}
}
// Set the target drop effect to the effect
// specified in the ItemDrag event handler.
private void frameTreeView_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
}
// Select the node under the mouse pointer to indicate the
// expected drop location.
private void frameTreeView_DragOver(object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the mouse position.
Point targetPoint = frameTreeView.PointToClient(new Point(e.X, e.Y));
// Select the node at the mouse position.
frameTreeView.SelectedNode = frameTreeView.GetNodeAt(targetPoint);
}
private void frameTreeView_DragDrop(object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the drop location.
Point targetPoint = frameTreeView.PointToClient(new Point(e.X, e.Y));
// Retrieve the node at the drop location.
TreeNode targetNode = frameTreeView.GetNodeAt(targetPoint);
// Retrieve the node that was dragged.
TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
// Confirm that the node at the drop location is not
// the dragged node or a descendant of the dragged node.
if (targetNode == null)
{
draggedNode.Remove();
frameTreeView.Nodes.Add(draggedNode);
}
else if (!draggedNode.Equals(targetNode) && !ContainsNode(draggedNode, targetNode))
{
// If it is a move operation, remove the node from its current
// location and add it to the node at the drop location.
if (e.Effect == DragDropEffects.Move)
{
int draggedIndex = draggedNode.Index;
int targetIndex = targetNode.Index;
currentAnimation.GetFrames().Swap(draggedIndex, targetIndex);
LoadAnimationTreeView();
}
}
}
// Determine whether one node is a parent
// or ancestor of a second node.
private bool ContainsNode(TreeNode node1, TreeNode node2)
{
// Check the parent node of the second node.
if (node2.Parent == null) return false;
if (node2.Parent.Equals(node1)) return true;
// If the parent node is not null or equal to the first node,
// call the ContainsNode method recursively using the parent of
// the second node.
return ContainsNode(node1, node2.Parent);
}
private void treeView1_doubleClick(object sender, EventArgs e)
{
var frame = currentAnimation.GetFrame(frameTreeView.SelectedNode.Index);
using FrameEditor diag = new FrameEditor(frame.Ticks, currentAnimation.GetFrameIndex(frame.Texture), currentAnimation.FrameTextureCount-1);
if (diag.ShowDialog(this) == DialogResult.OK)
{
currentAnimation.SetFrame(frame, diag.FrameTextureIndex, diag.FrameTime);
LoadAnimationTreeView();
}
}
private void addFrameToolStripMenuItem_Click(object sender, EventArgs e)
{
using FrameEditor diag = new FrameEditor(currentAnimation.FrameTextureCount-1);
if (diag.ShowDialog(this) == DialogResult.OK)
{
currentAnimation.AddFrame(diag.FrameTextureIndex, diag.FrameTime);
LoadAnimationTreeView();
}
}
private void removeFrameToolStripMenuItem_Click(object sender, EventArgs e)
{
if (frameTreeView.SelectedNode is TreeNode t &&
currentAnimation.RemoveFrame(t.Index))
frameTreeView.SelectedNode.Remove();
}
private void bulkAnimationSpeedToolStripMenuItem_Click(object sender, EventArgs e)
{
SetBulkSpeed diag = new SetBulkSpeed(frameTreeView);
diag.ShowDialog(this);
diag.Dispose();
}
private void importJavaAnimationToolStripMenuItem_Click(object sender, EventArgs e)
{
DialogResult query = MessageBox.Show("This feature will replace the existing animation data. It might fail if the selected animation script is invalid. Are you sure that you want to continue?", "Warning", MessageBoxButtons.YesNo);
if (query == DialogResult.No) return;
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Multiselect = false;
fileDialog.Title = "Please select a valid Minecaft: Java Edition animation script";
// It's marked as .png.mcmeta just in case
// some weirdo tries to pass a pack.mcmeta or something
// -MattNL
fileDialog.Filter = "Animation Scripts (*.mcmeta)|*.png.mcmeta";
fileDialog.CheckPathExists = true;
fileDialog.CheckFileExists = true;
if (fileDialog.ShowDialog(this) != DialogResult.OK) return;
Console.WriteLine("Selected Animation Script: " + fileDialog.FileName);
string textureFile = fileDialog.FileName.Substring(0, fileDialog.FileName.Length - ".mcmeta".Length);
if (!File.Exists(textureFile))
{
MessageBox.Show(textureFile + " was not found", "Texture not found");
return;
}
using MemoryStream textureMem = new MemoryStream(File.ReadAllBytes(textureFile));
var new_animation = new Animation(Image.FromStream(textureMem));
try
{
JObject mcmeta = JObject.Parse(File.ReadAllText(fileDialog.FileName));
if (mcmeta["animation"] is JToken animation)
{
int frameTime = Animation.MinimumFrameTime;
// Some if statements to ensure that the animation is valid.
if (animation["frametime"] is JToken frametime_token && frametime_token.Type == JTokenType.Integer)
frameTime = (int)frametime_token;
if (animation["interpolate"] is JToken interpolate_token && interpolate_token.Type == JTokenType.Boolean)
new_animation.Interpolate = (bool)interpolate_token;
if (animation["frames"] is JToken frames_token &&
frames_token.Type == JTokenType.Array)
{
foreach (JToken frame in frames_token.Children())
{
if (frame.Type == JTokenType.Object)
{
if (frame["index"] is JToken frame_index && frame_index.Type == JTokenType.Integer &&
frame["time"] is JToken frame_time && frame_time.Type == JTokenType.Integer)
{
Console.WriteLine((int)frame["index"] + "*" + (int)frame["time"]);
new_animation.AddFrame((int)frame["index"], (int)frame["time"]);
}
}
else if (frame.Type == JTokenType.Integer)
{
Console.WriteLine((int)frame + "*" + frameTime);
new_animation.AddFrame((int)frame);
}
}
}
}
currentAnimation = new_animation;
LoadAnimationTreeView();
}
catch (JsonException j_ex)
{
MessageBox.Show(j_ex.Message, "Invalid animation");
return;
}
}
private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Simply drag and drop frames in the tree to rearrange your animation.\n\n" +
"The \"Interpolates\" checkbox enables the blending animation seen with some textures in the game, such as Prismarine.\n\n" +
"You can preview your animation at any time by simply pressing the \"Play Animation\" button!\n\n" +
"You can edit the frame and its speed by double clicking a frame in the tree. If you'd like to change the entire animation's speed, you can do so with the \"Set Bulk Animation Speed\" button in the \"Tools\" tab.\n\n" +
"Porting animations from Java packs are made simple with the \"Import Java Animation\" button found in the \"Tools\" tab!", "Help");
}
private void changeTileToolStripMenuItem_Click(object sender, EventArgs e)
{
using (ChangeTile diag = new ChangeTile())
if (diag.ShowDialog(this) == DialogResult.OK)
{
Console.WriteLine(diag.SelectedTile);
if (TileName != diag.SelectedTile) isItem = diag.IsItem;
TileName = diag.SelectedTile;
foreach (JObject content in AnimationUtil.tileData[animationSection].Children())
{
var first = content.Properties().FirstOrDefault(p => p.Name == TileName);
if (first is JProperty p) tileLabel.Text = (string)p.Value;
}
}
}
private void MipMapCheckBox_CheckedChanged(object sender, EventArgs e)
{
MipMapNumericUpDown.Visible = MipMapLabel.Visible = MipMapCheckbox.Checked;
}
}
}

View File

@@ -134,9 +134,6 @@
38gYasBfqDYE0K7dOn/Wvut/sfkdGYPUgJI9VNuAAwYGAGn6yvdevWgPAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>280, 17</value>
</metadata>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAA0AAAAAAAEAIAD7NAAA1gAAAICAAAABACAAKAgBANE1AACAgAAAAQAIAChMAAD5PQEAQEAAAAEA

View File

@@ -1,350 +0,0 @@
namespace PckStudio
{
partial class AnimationEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AnimationEditor));
this.treeView1 = new System.Windows.Forms.TreeView();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.addFrameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeFrameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.bulkAnimationSpeedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.importJavaAnimationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.changeTileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.InterpolationCheckbox = new MetroFramework.Controls.MetroCheckBox();
this.AnimationPlayBtn = new MetroFramework.Controls.MetroButton();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.AnimationStopBtn = new MetroFramework.Controls.MetroButton();
this.tileLabel = new MetroFramework.Controls.MetroLabel();
this.MipMapCheckbox = new MetroFramework.Controls.MetroCheckBox();
this.metroLabel1 = new MetroFramework.Controls.MetroLabel();
this.MipMapNumericUpDown = new System.Windows.Forms.NumericUpDown();
this.pictureBoxWithInterpolationMode1 = new PckStudio.PictureBoxWithInterpolationMode();
this.contextMenuStrip1.SuspendLayout();
this.menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.MipMapNumericUpDown)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxWithInterpolationMode1)).BeginInit();
this.SuspendLayout();
//
// treeView1
//
this.treeView1.AllowDrop = true;
this.treeView1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.treeView1.ContextMenuStrip = this.contextMenuStrip1;
this.treeView1.ForeColor = System.Drawing.Color.White;
this.treeView1.Location = new System.Drawing.Point(20, 84);
this.treeView1.Margin = new System.Windows.Forms.Padding(0);
this.treeView1.MaximumSize = new System.Drawing.Size(205, 350);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(165, 202);
this.treeView1.TabIndex = 15;
this.treeView1.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.treeView1_ItemDrag);
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
this.treeView1.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_doubleClick);
this.treeView1.DragDrop += new System.Windows.Forms.DragEventHandler(this.treeView1_DragDrop);
this.treeView1.DragEnter += new System.Windows.Forms.DragEventHandler(this.treeView1_DragEnter);
this.treeView1.DragOver += new System.Windows.Forms.DragEventHandler(this.treeView1_DragOver);
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.addFrameToolStripMenuItem,
this.removeFrameToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(154, 48);
//
// addFrameToolStripMenuItem
//
this.addFrameToolStripMenuItem.Image = global::PckStudio.Properties.Resources.ExportFile;
this.addFrameToolStripMenuItem.Name = "addFrameToolStripMenuItem";
this.addFrameToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
this.addFrameToolStripMenuItem.Text = "Add Frame";
this.addFrameToolStripMenuItem.Click += new System.EventHandler(this.addFrameToolStripMenuItem_Click);
//
// removeFrameToolStripMenuItem
//
this.removeFrameToolStripMenuItem.Image = global::PckStudio.Properties.Resources.Del;
this.removeFrameToolStripMenuItem.Name = "removeFrameToolStripMenuItem";
this.removeFrameToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
this.removeFrameToolStripMenuItem.Text = "Remove Frame";
this.removeFrameToolStripMenuItem.Click += new System.EventHandler(this.removeFrameToolStripMenuItem_Click);
//
// menuStrip
//
this.menuStrip.AutoSize = false;
this.menuStrip.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.editToolStripMenuItem,
this.helpToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(20, 60);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(372, 24);
this.menuStrip.TabIndex = 14;
this.menuStrip.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.saveToolStripMenuItem1});
this.fileToolStripMenuItem.ForeColor = System.Drawing.Color.White;
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
//
// saveToolStripMenuItem1
//
this.saveToolStripMenuItem1.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem1.Image")));
this.saveToolStripMenuItem1.Name = "saveToolStripMenuItem1";
this.saveToolStripMenuItem1.Size = new System.Drawing.Size(98, 22);
this.saveToolStripMenuItem1.Text = "Save";
this.saveToolStripMenuItem1.Click += new System.EventHandler(this.saveToolStripMenuItem1_Click);
//
// editToolStripMenuItem
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.bulkAnimationSpeedToolStripMenuItem,
this.importJavaAnimationToolStripMenuItem,
this.changeTileToolStripMenuItem});
this.editToolStripMenuItem.ForeColor = System.Drawing.Color.White;
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(46, 20);
this.editToolStripMenuItem.Text = "Tools";
//
// bulkAnimationSpeedToolStripMenuItem
//
this.bulkAnimationSpeedToolStripMenuItem.Image = global::PckStudio.Properties.Resources.clock;
this.bulkAnimationSpeedToolStripMenuItem.Name = "bulkAnimationSpeedToolStripMenuItem";
this.bulkAnimationSpeedToolStripMenuItem.Size = new System.Drawing.Size(210, 22);
this.bulkAnimationSpeedToolStripMenuItem.Text = "Set Bulk Animation Speed";
this.bulkAnimationSpeedToolStripMenuItem.Click += new System.EventHandler(this.bulkAnimationSpeedToolStripMenuItem_Click);
//
// importJavaAnimationToolStripMenuItem
//
this.importJavaAnimationToolStripMenuItem.Image = global::PckStudio.Properties.Resources.ExportFile;
this.importJavaAnimationToolStripMenuItem.Name = "importJavaAnimationToolStripMenuItem";
this.importJavaAnimationToolStripMenuItem.Size = new System.Drawing.Size(210, 22);
this.importJavaAnimationToolStripMenuItem.Text = "Import Java Animation";
this.importJavaAnimationToolStripMenuItem.Click += new System.EventHandler(this.importJavaAnimationToolStripMenuItem_Click);
//
// changeTileToolStripMenuItem
//
this.changeTileToolStripMenuItem.Image = global::PckStudio.Properties.Resources.changeTile;
this.changeTileToolStripMenuItem.Name = "changeTileToolStripMenuItem";
this.changeTileToolStripMenuItem.Size = new System.Drawing.Size(210, 22);
this.changeTileToolStripMenuItem.Text = "Change Tile";
this.changeTileToolStripMenuItem.Click += new System.EventHandler(this.changeTileToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.ForeColor = System.Drawing.Color.White;
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "Help";
this.helpToolStripMenuItem.Click += new System.EventHandler(this.helpToolStripMenuItem_Click);
//
// InterpolationCheckbox
//
this.InterpolationCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.InterpolationCheckbox.AutoSize = true;
this.InterpolationCheckbox.Location = new System.Drawing.Point(188, 317);
this.InterpolationCheckbox.Name = "InterpolationCheckbox";
this.InterpolationCheckbox.Size = new System.Drawing.Size(204, 15);
this.InterpolationCheckbox.TabIndex = 17;
this.InterpolationCheckbox.Text = "Interpolates (not simulated above)";
this.InterpolationCheckbox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.InterpolationCheckbox.UseSelectable = true;
//
// AnimationPlayBtn
//
this.AnimationPlayBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.AnimationPlayBtn.Location = new System.Drawing.Point(188, 291);
this.AnimationPlayBtn.Name = "AnimationPlayBtn";
this.AnimationPlayBtn.Size = new System.Drawing.Size(99, 24);
this.AnimationPlayBtn.TabIndex = 18;
this.AnimationPlayBtn.Text = "Play Animation";
this.AnimationPlayBtn.Theme = MetroFramework.MetroThemeStyle.Dark;
this.AnimationPlayBtn.UseSelectable = true;
this.AnimationPlayBtn.Click += new System.EventHandler(this.StartAnimationBtn_Click);
//
// timer1
//
this.timer1.Interval = 1;
this.timer1.Tick += new System.EventHandler(this.animate);
//
// AnimationStopBtn
//
this.AnimationStopBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.AnimationStopBtn.Enabled = false;
this.AnimationStopBtn.Location = new System.Drawing.Point(293, 291);
this.AnimationStopBtn.Name = "AnimationStopBtn";
this.AnimationStopBtn.Size = new System.Drawing.Size(99, 24);
this.AnimationStopBtn.TabIndex = 19;
this.AnimationStopBtn.Text = "Stop Animation";
this.AnimationStopBtn.Theme = MetroFramework.MetroThemeStyle.Dark;
this.AnimationStopBtn.UseSelectable = true;
this.AnimationStopBtn.Click += new System.EventHandler(this.StopAnimationBtn_Click);
//
// tileLabel
//
this.tileLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.tileLabel.AutoSize = true;
this.tileLabel.Location = new System.Drawing.Point(20, 290);
this.tileLabel.MinimumSize = new System.Drawing.Size(170, 19);
this.tileLabel.Name = "tileLabel";
this.tileLabel.Size = new System.Drawing.Size(57, 19);
this.tileLabel.TabIndex = 20;
this.tileLabel.Text = "tileLabel";
this.tileLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// MipMapCheckbox
//
this.MipMapCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.MipMapCheckbox.AutoSize = true;
this.MipMapCheckbox.Location = new System.Drawing.Point(20, 312);
this.MipMapCheckbox.Name = "MipMapCheckbox";
this.MipMapCheckbox.Size = new System.Drawing.Size(128, 15);
this.MipMapCheckbox.TabIndex = 21;
this.MipMapCheckbox.Text = "Is Mip Map Texture?";
this.MipMapCheckbox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.MipMapCheckbox.UseSelectable = true;
this.MipMapCheckbox.CheckedChanged += new System.EventHandler(this.metroCheckBox2_CheckedChanged);
//
// metroLabel1
//
this.metroLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.metroLabel1.AutoSize = true;
this.metroLabel1.Location = new System.Drawing.Point(21, 330);
this.metroLabel1.Name = "metroLabel1";
this.metroLabel1.Size = new System.Drawing.Size(99, 19);
this.metroLabel1.TabIndex = 22;
this.metroLabel1.Text = "Mip Map Level:";
this.metroLabel1.Theme = MetroFramework.MetroThemeStyle.Dark;
this.metroLabel1.Visible = false;
//
// MipMapNumericUpDown
//
this.MipMapNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.MipMapNumericUpDown.BackColor = System.Drawing.Color.Black;
this.MipMapNumericUpDown.ForeColor = System.Drawing.SystemColors.Window;
this.MipMapNumericUpDown.Location = new System.Drawing.Point(127, 330);
this.MipMapNumericUpDown.Maximum = new decimal(new int[] {
5,
0,
0,
0});
this.MipMapNumericUpDown.Minimum = new decimal(new int[] {
2,
0,
0,
0});
this.MipMapNumericUpDown.Name = "MipMapNumericUpDown";
this.MipMapNumericUpDown.Size = new System.Drawing.Size(44, 20);
this.MipMapNumericUpDown.TabIndex = 23;
this.MipMapNumericUpDown.Value = new decimal(new int[] {
2,
0,
0,
0});
this.MipMapNumericUpDown.Visible = false;
//
// pictureBoxWithInterpolationMode1
//
this.pictureBoxWithInterpolationMode1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBoxWithInterpolationMode1.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.pictureBoxWithInterpolationMode1.Location = new System.Drawing.Point(188, 88);
this.pictureBoxWithInterpolationMode1.Name = "pictureBoxWithInterpolationMode1";
this.pictureBoxWithInterpolationMode1.Size = new System.Drawing.Size(204, 198);
this.pictureBoxWithInterpolationMode1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBoxWithInterpolationMode1.TabIndex = 16;
this.pictureBoxWithInterpolationMode1.TabStop = false;
//
// AnimationEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(412, 362);
this.Controls.Add(this.AnimationStopBtn);
this.Controls.Add(this.AnimationPlayBtn);
this.Controls.Add(this.MipMapNumericUpDown);
this.Controls.Add(this.metroLabel1);
this.Controls.Add(this.MipMapCheckbox);
this.Controls.Add(this.tileLabel);
this.Controls.Add(this.InterpolationCheckbox);
this.Controls.Add(this.pictureBoxWithInterpolationMode1);
this.Controls.Add(this.treeView1);
this.Controls.Add(this.menuStrip);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MinimumSize = new System.Drawing.Size(412, 362);
this.Name = "AnimationEditor";
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Text = "Animation Editor";
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.contextMenuStrip1.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.MipMapNumericUpDown)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxWithInterpolationMode1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TreeView treeView1;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem1;
private PictureBoxWithInterpolationMode pictureBoxWithInterpolationMode1;
private MetroFramework.Controls.MetroCheckBox InterpolationCheckbox;
private MetroFramework.Controls.MetroButton AnimationPlayBtn;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem addFrameToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem removeFrameToolStripMenuItem;
private System.Windows.Forms.Timer timer1;
private MetroFramework.Controls.MetroButton AnimationStopBtn;
private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem bulkAnimationSpeedToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem importJavaAnimationToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem changeTileToolStripMenuItem;
private MetroFramework.Controls.MetroLabel tileLabel;
private MetroFramework.Controls.MetroCheckBox MipMapCheckbox;
private MetroFramework.Controls.MetroLabel metroLabel1;
private System.Windows.Forms.NumericUpDown MipMapNumericUpDown;
}
}

View File

@@ -1,672 +0,0 @@
using MetroFramework.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PckStudio.Classes.FileTypes;
using PckStudio.Forms.Utilities.AnimationEditor;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PckStudio
{
public partial class AnimationEditor : MetroForm
{
PCKFile.FileData animationFile = null;
List<Image> frames = new List<Image>();
int frameCount => frames.Count;
static JObject tileData = JObject.Parse(Properties.Resources.tileData);
Image texture = null;
bool isItem = false;
int minimumFrameTime = 1;
string TileName = "";
int animCurrentFrame = 0;
Tuple<int, int> currentFrameData = new Tuple<int, int>(0, 1);
Image img = null;
Image imgB = null;
int nextFrame;
//int frameCounter = 0; // ported directly from Java Edition code -MattNL
public AnimationEditor(Image imgage, string tileName, bool isItem)
{
InitializeComponent();
this.isItem = isItem;
TileName = tileName;
string filePath = $"res/textures/{(isItem ? "items" : "blocks")}/{tileName}.png";
animationFile = CreateNewAnimationFile(imgage, filePath);
CreateFrameList(imgage);
}
public AnimationEditor(PCKFile.FileData file)
{
InitializeComponent();
isItem = file.filepath.Split('/').Contains("items");
TileName = Path.GetFileNameWithoutExtension(file.filepath);
animationFile = file;
if (TileName.EndsWith("MipMapLevel2") || TileName.EndsWith("MipMapLevel3"))
{
string mipMapLvl = TileName.Last().ToString();
TileName = TileName.Substring(0, TileName.Length - 12);
MipMapCheckbox.Checked = true;
MipMapNumericUpDown.Value = short.Parse(mipMapLvl);
}
string anim = string.Empty;
animationFile.properties.FirstOrDefault(x => x.Item1.Equals("ANIM"));
MemoryStream textureMem = new MemoryStream(animationFile.data);
texture = new Bitmap(textureMem);
CreateFrameList(texture);
Console.WriteLine(TileName);
foreach (JObject content in tileData[isItem ? "Items" : "Blocks"].Children())
{
foreach (JProperty prop in content.Properties())
{
if (prop.Name == TileName) tileLabel.Text = (string)prop.Value;
}
}
if (!string.IsNullOrEmpty(anim))
{
string[] animData = anim.Split(',');
if (string.IsNullOrEmpty(animData.Last())) animData = animData.Take(animData.Length - 1).ToArray();
int lastFrameTime = 0;
foreach (string frame in animData)
{
string[] frameData = frame.Split('*');
if (frameData.Length < 2)
continue; // shouldn't happen
int currentFrame = 0;
int currentFrameTime = 1;
if (string.IsNullOrEmpty(frameData[0])) throw new Exception("Invalid animation data");
currentFrame = int.Parse(frameData[0]);
// Some textures like the Halloween 2015's Lava texture don't have a
// frame time parameter for certain frames.
// This will detect that and place the last frame time in its place.
// This is accurate to console edition behavior.
// - MattNL
currentFrameTime = string.IsNullOrEmpty(frameData[1]) ? lastFrameTime : int.Parse(frameData[1]);
string label = $"Frame: {currentFrame}, Frame Time: {currentFrameTime}";
Console.WriteLine(label);
TreeNode frameNode = new TreeNode(label);
var finalFrameData = new Tuple<int, int>(currentFrame, currentFrameTime);
frameNode.Tag = finalFrameData;
treeView1.Nodes.Add(frameNode);
lastFrameTime = currentFrameTime;
}
}
else
{
for (int i = 0; i < frameCount; i++)
{
TreeNode frameNode = new TreeNode($"Frame: {i}, Frame Time: {minimumFrameTime}");
var finalFrameData = new Tuple<int, int>(i, minimumFrameTime);
frameNode.Tag = finalFrameData;
treeView1.Nodes.Add(frameNode);
}
}
pictureBoxWithInterpolationMode1.Image = frames[0]; //Sets image preview to the first frame of animation (0 for now)
Console.WriteLine("Animation Frame Count: " + frameCount);
}
private PCKFile.FileData CreateNewAnimationFile(Image imgageFile, string name = "")
{
PCKFile.FileData file = new PCKFile.FileData(name, 2);
file.properties.Add(("ANIM", ""));
using (var stream = new MemoryStream())
{
imgageFile.Save(stream, ImageFormat.Png);
file.SetData(stream.ToArray());
}
return file;
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
var frameData = e.Node.Tag as Tuple<int, int>;
Console.WriteLine(frameData.Item1 + " --- " + frameData.Item2);
if (AnimationPlayBtn.Enabled)
{
pictureBoxWithInterpolationMode1.Image = frames[frameData.Item1];
}
}
void CreateFrameList(Image texture)
{
frames.Clear();
frames.AddRange(SplitImageToFrames(texture));
}
private IEnumerable<Image> SplitImageToFrames(Image source)
{
for (int i = 0; i < source.Height / source.Width; i++)
{
Rectangle tileArea = new Rectangle(new Point(0, i * source.Width), new Size(source.Width, source.Width));
Bitmap tileImage = new Bitmap(source.Width, source.Width);
using (Graphics gfx = Graphics.FromImage(tileImage))
{
gfx.SmoothingMode = SmoothingMode.None;
gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(source, new Rectangle(0, 0, source.Width, source.Width), tileArea, GraphicsUnit.Pixel);
}
yield return tileImage;
}
yield break;
}
private int mix(double ratio, int val1, int val2) // Ported from Java Edition code
{
return (int)(ratio * val1 + (1.0D - ratio) * val2);
}
void animate(object sender, EventArgs e)
{
//Console.WriteLine(frameCounter + " $$$ " + frameCount);
//frameCounter = (frameCounter + 1) % frameCount;
if (animCurrentFrame > (treeView1.Nodes.Count - 1)) animCurrentFrame = 0;
currentFrameData = treeView1.Nodes[animCurrentFrame].Tag as Tuple<int, int>;
pictureBoxWithInterpolationMode1.Image = frames[currentFrameData.Item1];
//animCurrentTotalFrameTime = Int16.Parse(currentFrameData.Item2);
timer1.Interval = currentFrameData.Item2 * 50;
animCurrentFrame++;
if (InterpolationCheckbox.Checked)
{
img = frames[currentFrameData.Item1];
nextFrame = animCurrentFrame + 1;
if (nextFrame > frameCount - 1) nextFrame = 0;
Console.WriteLine(nextFrame);
imgB = frames[nextFrame];
}
#region interpolation code (unoptimized and unused at the moment)
// Interpolation Code (Very slow, messy, and resource heavy depending on the resolution!!!)
else if (InterpolationCheckbox.Checked && (img != null && imgB != null))
{
double d0 = 1.0D - animCurrentFrame / frameCount;
int i = animCurrentFrame;
int j = frameCount;
int k = (frameCount + 1) % j;
for (int l = 0; l < (frameCount - 1); ++l)
{
int i1 = img.Width;
int j1 = img.Width;
Bitmap finalInterpolation = new Bitmap(pictureBoxWithInterpolationMode1.Image);
// pictureBoxWithInterpolationMode1.Image.Dispose();
// pictureBoxWithInterpolationMode1.Image = null;
for (int k1 = 0; k1 < j1; ++k1)
{
for (int l1 = 0; l1 < i1; ++l1)
{
//Get Both Colours at the pixel point
Bitmap imgC = new Bitmap(img);
Bitmap imgBC = new Bitmap(imgB);
Color col1 = imgC.GetPixel(l1, k1);
Color col2 = imgBC.GetPixel(l1, k1);
imgC.Dispose();
imgC = null;
imgBC.Dispose();
imgBC = null;
int i2 = 0;
i2 |= col1.A << 24;
i2 |= col1.R << 16;
i2 |= col1.G << 8;
i2 |= col1.B;
int j2 = 0;
j2 |= col2.A << 24;
j2 |= col2.R << 16;
j2 |= col2.G << 8;
j2 |= col2.B;
int k2 = this.mix(d0, i2 >> 16 & 255, j2 >> 16 & 255);
int l2 = this.mix(d0, i2 >> 8 & 255, j2 >> 8 & 255);
int i3 = this.mix(d0, i2 & 255, j2 & 255);
// Create new grayscale RGB colour
uint finalColor = (uint)(i2 & -16777216 | k2 << 16 | l2 << 8 | i3);
byte[] values = BitConverter.GetBytes(finalColor);
int a = values[3];
int b = values[0];
int g = values[1];
int r = values[2];
Color newcol = Color.FromArgb(a, r, g, b);
finalInterpolation.SetPixel(l1, k1, newcol);
}
}
pictureBoxWithInterpolationMode1.Image = finalInterpolation;
//finalInterpolation.Dispose();
}
}
#endregion
//Console.WriteLine(animCurrentFrame + " - " + animCurrentFrameTime + " - " + animCurrentTotalFrameTime + " - " + (treeView1.Nodes.Count - 1));
}
private void StartAnimationBtn_Click(object sender, EventArgs e)
{
animCurrentFrame = 0;
//animCurrentFrameTime = 0;
//animCurrentTotalFrameTime = -1;
//frameCounter = 0;
AnimationPlayBtn.Enabled = !(AnimationStopBtn.Enabled = !AnimationStopBtn.Enabled);
timer1.Start();
}
private void StopAnimationBtn_Click(object sender, EventArgs e)
{
AnimationPlayBtn.Enabled = !(AnimationStopBtn.Enabled = !AnimationStopBtn.Enabled);
timer1.Stop();
}
private void treeView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Delete) treeView1.Nodes.Remove(treeView1.SelectedNode);
}
private TreeNode FindNodeByName(TreeNode treeNode, string name)
{
foreach (TreeNode node in treeNode.Nodes)
{
if (node.Text.ToLower() == name.ToLower()) return node;
return FindNodeByName(node, name);
}
return null;
}
private void addNodeToAnimationsFolder(TreeNode newNode)
{
//TreeNode parent = FindNodeByName(treeViewMain, isItem ? "items" : "blocks");
//if (parent != null)
//{
// Console.WriteLine("ParentNotNULL");
// TreeNode check = FindNodeByName(treeViewMain, newNode.Text);
// parent.Nodes.Add(newNode);
//}
//else
//{
// TreeNode texturesParent = FindNodeByName(treeViewMain, "textures");
// if (texturesParent != null)
// {
// Console.WriteLine("TextureNotNULL");
// TreeNode newFolder = new TreeNode(isItem ? "items" : "blocks");
// texturesParent.Nodes.Add(newFolder);
// newFolder.Nodes.Add(newNode);
// }
// else
// {
// TreeNode resParent = FindNodeByName(treeViewMain, "res");
// if (resParent != null)
// {
// Console.WriteLine("ResNotNULL");
// TreeNode newFolder = new TreeNode("textures");
// resParent.Nodes.Add(newFolder);
// TreeNode newFolderB = new TreeNode(isItem ? "items" : "blocks");
// newFolder.Nodes.Add(newFolderB);
// newFolderB.Nodes.Add(newNode);
// }
// else
// {
// Console.WriteLine("ResNULL");
// TreeNode newFolder = new TreeNode("res");
// treeViewMain.Nodes.Add(newFolder);
// TreeNode newFolderB = new TreeNode("textures");
// newFolder.Nodes.Add(newFolderB);
// TreeNode newFolderC = new TreeNode(isItem ? "items" : "blocks");
// newFolderB.Nodes.Add(newFolderC);
// newFolderC.Nodes.Add(newNode);
// }
// }
//}
}
private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
{
using (var stream = new MemoryStream())
{
texture.Save(stream, ImageFormat.Png);
animationFile.SetData(stream.ToArray());
}
animationFile.filepath = $"res/textures/{(isItem ? "items" : "blocks")}/{TileName}{(MipMapCheckbox.Checked ? $"MipMapLevel{MipMapNumericUpDown.Value}" : string.Empty)}.png";
string animationData = InterpolationCheckbox.Checked ? "#" : "";
foreach (TreeNode node in treeView1.Nodes)
{
var frameData = node.Tag as Tuple<int, int>;
animationData += $"{frameData.Item1}*{frameData.Item2},";
}
animationData.TrimEnd(',');
foreach (var pair in animationFile.properties)
{
if (pair.Item1 == "ANIM")
{
animationFile.properties[animationFile.properties.IndexOf(pair)] = ("ANIM", animationData);
break;
}
else
{
animationFile.properties.Add(("ANIM", animationData));
break;
}
};
//if (create)
//{
// mf.name = "res/textures/" + (isItem ? "items" : "blocks");
// TreeNode newNode = new TreeNode(newTileName + ".png") { Tag = mf };//creates node for minefile
// newNode.ImageIndex = 2;
// newNode.SelectedImageIndex = 2;
// addNodeToAnimationsFolder(newNode);
// treeViewMain.SelectedNode = newNode;
// create = false;
//}
//else if (isItem && treeViewMain.SelectedNode.Parent.Text == "blocks")
//{
// Console.WriteLine("block: " + treeViewMain.SelectedNode.Parent.Text);
// TreeNode newNode = treeViewMain.SelectedNode;
// newNode.ImageIndex = 2;
// newNode.SelectedImageIndex = 2;
// treeViewMain.SelectedNode.Remove();
// addNodeToAnimationsFolder(newNode);
//}
//else if (treeViewMain.SelectedNode.Parent.Text == "items")
//{
// Console.WriteLine("item: " + treeViewMain.SelectedNode.Parent.Text);
// TreeNode newNode = treeViewMain.SelectedNode;
// newNode.ImageIndex = 2;
// newNode.SelectedImageIndex = 2;
// treeViewMain.SelectedNode.Remove();
// addNodeToAnimationsFolder(newNode);
//}
if(MipMapCheckbox.Checked) TileName = TileName.Substring(0, TileName.Length - 12);
}
// Most of the code below is modified code from this link: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.itemdrag?view=windowsdesktop-6.0
// - MattNL
private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
{
// Move the dragged node when the left mouse button is used.
if (e.Button == MouseButtons.Left)
{
DoDragDrop(e.Item, DragDropEffects.Move);
}
}
// Set the target drop effect to the effect
// specified in the ItemDrag event handler.
private void treeView1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
}
// Select the node under the mouse pointer to indicate the
// expected drop location.
private void treeView1_DragOver(object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the mouse position.
Point targetPoint = treeView1.PointToClient(new Point(e.X, e.Y));
// Select the node at the mouse position.
treeView1.SelectedNode = treeView1.GetNodeAt(targetPoint);
}
private void treeView1_DragDrop(object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the drop location.
Point targetPoint = treeView1.PointToClient(new Point(e.X, e.Y));
// Retrieve the node at the drop location.
TreeNode targetNode = treeView1.GetNodeAt(targetPoint);
// Retrieve the node that was dragged.
TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
// Confirm that the node at the drop location is not
// the dragged node or a descendant of the dragged node.
if (targetNode == null)
{
draggedNode.Remove();
treeView1.Nodes.Add(draggedNode);
}
else if (!draggedNode.Equals(targetNode) && !ContainsNode(draggedNode, targetNode))
{
// If it is a move operation, remove the node from its current
// location and add it to the node at the drop location.
if (e.Effect == DragDropEffects.Move)
{
int draggedIndex = draggedNode.Index;
int targetIndex = targetNode.Index;
draggedNode.Remove();
if (targetNode.Tag == null) // Add to folder
{
targetNode.Nodes.Add(draggedNode);
}
else // Move file aside
{
if (targetNode.Parent != null)
{
targetNode.Parent.Nodes.Insert(targetIndex, draggedNode);
}
else
{
treeView1.Nodes.Insert(targetIndex, draggedNode);
}
}
}
// Expand the node at the location
// to show the dropped node.
targetNode.Expand();
}
}
// Determine whether one node is a parent
// or ancestor of a second node.
private bool ContainsNode(TreeNode node1, TreeNode node2)
{
// Check the parent node of the second node.
if (node2.Parent == null) return false;
if (node2.Parent.Equals(node1)) return true;
// If the parent node is not null or equal to the first node,
// call the ContainsNode method recursively using the parent of
// the second node.
return ContainsNode(node1, node2.Parent);
}
private void treeView1_doubleClick(object sender, EventArgs e)
{
FrameEditor diag = new FrameEditor(
treeView1, // animation editor tree
treeView1.SelectedNode.Tag as Tuple<string, string>, // the current selected frame data
frameCount - 1, // frame limit
false, // create new frame?
treeView1.SelectedNode // the current frame selected
);
diag.ShowDialog(this);
diag.Dispose();
}
private void addFrameToolStripMenuItem_Click(object sender, EventArgs e)
{
FrameEditor diag = new FrameEditor(
treeView1,
new Tuple<string, string>("", ""),
frameCount - 1,
true,
new TreeNode());
diag.ShowDialog(this);
diag.Dispose();
}
private void removeFrameToolStripMenuItem_Click(object sender, EventArgs e)
{
treeView1.SelectedNode.Remove();
}
private void bulkAnimationSpeedToolStripMenuItem_Click(object sender, EventArgs e)
{
SetBulkSpeed diag = new SetBulkSpeed(treeView1);
diag.ShowDialog(this);
diag.Dispose();
}
private void importJavaAnimationToolStripMenuItem_Click(object sender, EventArgs e)
{
DialogResult query = MessageBox.Show("This feature will replace the existing animation data. It might fail if the selected animation script is invalid. Are you sure that you want to continue?", "Warning", MessageBoxButtons.YesNo);
if (query == DialogResult.No) return;
// In case the import fails, the user won't lose any data - MattNL
Image oldImage = texture;
int oldFrameCount = frameCount;
List<Image> oldFrames = frames;
TreeNodeCollection oldAnimData = treeView1.Nodes;
OpenFileDialog diag = new OpenFileDialog();
diag.Multiselect = false;
diag.Filter = "Animation Scripts (*.mcmeta)|*.png.mcmeta"; /* It's marked as .png.mcmeta just in case
some weirdo tries to pass a pack.mcmeta or something
-MattNL */
diag.Title = "Please select a valid Minecaft: Java Edition animation script";
diag.ShowDialog(this);
diag.Dispose();
if (String.IsNullOrEmpty(diag.FileName)) return; // Return if name is null or if the user cancels
Console.WriteLine("Selected Animation Script: " + diag.FileName);
treeView1.Nodes.Clear();
MemoryStream textureMem = new MemoryStream(File.ReadAllBytes(Path.GetDirectoryName(diag.FileName) + "\\/" + Path.GetFileNameWithoutExtension(diag.FileName)));
texture = Image.FromStream(textureMem);
CreateFrameList(texture);
try
{
JObject mcmeta = JObject.Parse(File.ReadAllText(diag.FileName));
if (mcmeta["animation"] != null)
{
int frameTime = 1;
// Some if statements to ensure that the animation is valid.
if (mcmeta["animation"]["frametime"] != null &&
mcmeta["animation"]["frametime"].Type == JTokenType.Integer) frameTime = (int)mcmeta["animation"]["frametime"];
if (mcmeta["animation"]["interpolate"] != null &&
mcmeta["animation"]["interpolate"].Type == JTokenType.Boolean && (Boolean)mcmeta["animation"]["interpolate"] == true) InterpolationCheckbox.Checked = true;
if (mcmeta["animation"]["frames"] != null &&
mcmeta["animation"]["frames"].Type == JTokenType.Array)
{
foreach (JToken frame in mcmeta["animation"]["frames"].Children())
{
if (frame.Type == JTokenType.Object)
{
if (frame["index"] != null && frame["index"].Type == JTokenType.Integer &&
frame["time"] != null && frame["time"].Type == JTokenType.Integer)
{
Console.WriteLine((int)frame["index"] + "*" + (int)frame["time"]);
TreeNode frameNode = new TreeNode();
var finalFrameData = new Tuple<int, int>(((int)frame["index"]), ((int)frame["time"]));
frameNode.Text = "Frame: " + ((int)frame["index"]).ToString() + ", Frame Time: " + ((int)frame["time"]).ToString();
frameNode.Tag = finalFrameData;
treeView1.Nodes.Add(frameNode);
}
}
else if (frame.Type == JTokenType.Integer)
{
Console.WriteLine((int)frame + "*" + frameTime);
TreeNode frameNode = new TreeNode();
var finalFrameData = new Tuple<int, int>(((int)frame), frameTime);
frameNode.Text = "Frame: " + ((int)frame).ToString() + ", Frame Time: " + frameTime.ToString();
frameNode.Tag = finalFrameData;
treeView1.Nodes.Add(frameNode);
}
}
}
else
{
for (int i = 0; i < frameCount; i++)
{
TreeNode frameNode = new TreeNode();
var finalFrameData = new Tuple<int, int>(i, frameTime);
frameNode.Text = "Frame: " + i.ToString() + ", Frame Time: " + frameTime.ToString();
frameNode.Tag = finalFrameData;
treeView1.Nodes.Add(frameNode);
}
}
}
}
catch (JsonException j_ex)
{
MessageBox.Show(j_ex.Message, "Invalid animation");
texture = oldImage;
frames = oldFrames;
foreach (TreeNode node in oldAnimData)
{
treeView1.Nodes.Add(node);
}
return;
}
pictureBoxWithInterpolationMode1.Image = frames[(treeView1.Nodes[0].Tag as Tuple<int, int>).Item1];
}
private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Simply drag and drop frames in the tree to rearrange your animation.\n\n" +
"The \"Interpolates\" checkbox enables the blending animation seen with some textures in the game, such as Prismarine.\n\n" +
"You can preview your animation at any time by simply pressing the \"Play Animation\" button!\n\n" +
"You can edit the frame and its speed by double clicking a frame in the tree. If you'd like to change the entire animation's speed, you can do so with the \"Set Bulk Animation Speed\" button in the \"Tools\" tab.\n\n" +
"Porting animations from Java packs are made simple with the \"Import Java Animation\" button found in the \"Tools\" tab!", "Help");
}
private void changeTileToolStripMenuItem_Click(object sender, EventArgs e)
{
using (ChangeTile diag = new ChangeTile(TileName))
if (diag.ShowDialog(this) == DialogResult.OK)
{
Console.WriteLine(diag.SelectedTile);
if (TileName != diag.SelectedTile) isItem = diag.IsItem;
TileName = diag.SelectedTile;
foreach (JObject content in tileData[isItem ? "Items" : "Blocks"].Children())
{
foreach (JProperty prop in content.Properties())
{
if (prop.Name == TileName) tileLabel.Text = (string)prop.Value;
}
}
}
}
private void metroCheckBox2_CheckedChanged(object sender, EventArgs e)
{
MipMapNumericUpDown.Visible = metroLabel1.Visible = MipMapCheckbox.Checked;
}
}
}

View File

@@ -1,227 +0,0 @@
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.IO;
using System.Windows.Forms;
using MetroFramework.Forms;
using System.Drawing.Drawing2D;
using Newtonsoft.Json.Linq;
using PckStudio.Properties;
namespace PckStudio.Forms.Utilities.AnimationEditor
{
public partial class ChangeTile : MetroForm
{
string selectedTile = "";
string oldTileName = "";
bool isItem = false;
public string SelectedTile => selectedTile;
public bool IsItem => isItem;
List<TreeNode> treeView1Cache = new List<TreeNode>();
List<TreeNode> treeView2Cache = new List<TreeNode>();
public ChangeTile(string oldName = "")
{
oldTileName = oldName;
InitializeComponent();
ImageList tiles = new ImageList();
tiles.ColorDepth = ColorDepth.Depth32Bit;
//for (int i = 0; i < 545; i++)
//{
// int row = i / 16;
// int column = i % 16;
// Rectangle tileArea = new Rectangle(new Point(column * 16, row * 16), new Size(16, 16));
// Bitmap tileImage = new Bitmap(16, 16);
// using (Graphics gfx = Graphics.FromImage(tileImage))
// {
// gfx.SmoothingMode = SmoothingMode.None;
// gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
// gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
// gfx.DrawImage(Resources.terrain_sheet, new Rectangle(0, 0, 16, 16), tileArea, GraphicsUnit.Pixel);
// }
// tiles.Images.Add(tileImage);
//}
//for (int i = 0; i < 273; i++)
//{
// int row = i / 16;
// int column = i % 16;
// Rectangle tileArea = new Rectangle(new Point(column * 16, row * 16), new Size(16, 16));
// Bitmap tileImage = new Bitmap(16, 16);
// using (Graphics gfx = Graphics.FromImage(tileImage))
// {
// gfx.SmoothingMode = SmoothingMode.None;
// gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
// gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
// gfx.DrawImage(Resources.items_sheet, new Rectangle(0, 0, 16, 16), tileArea, GraphicsUnit.Pixel);
// }
// tiles.Images.Add(tileImage);
//}
tiles.Images.AddRange(CreateImageList(Resources.terrain_sheet, 16, 16).ToArray());
tiles.Images.AddRange(CreateImageList(Resources.items_sheet, 16, 16).ToArray());
treeView1.ImageList = tiles;
treeView2.ImageList = tiles;
try
{
JObject tileData = JObject.Parse(Resources.tileData);
int i = 0;
if (tileData["Blocks"] != null)
{
foreach (JObject content in tileData["Blocks"].Children())
{
foreach (JProperty prop in content.Properties())
{
if (!string.IsNullOrEmpty((string)prop.Value))
{
TreeNode tileNode = new TreeNode();
tileNode.Text = (string)prop.Value;
Tuple<string, int> finalTileData = new Tuple<string, int>(prop.Name, i);
tileNode.Tag = finalTileData;
tileNode.ImageIndex = i;
tileNode.SelectedImageIndex = i;
treeView1.Nodes.Add(tileNode);
treeView1Cache.Add(tileNode);
}
i++;
}
}
}
if (tileData["Items"] != null)
{
foreach (JObject content in tileData["Items"].Children())
{
foreach (JProperty prop in content.Properties())
{
if (!string.IsNullOrEmpty((string)prop.Value))
{
TreeNode tileNode = new TreeNode();
tileNode.Text = (string)prop.Value;
Tuple<string, int> finalTileData = new Tuple<string, int>(prop.Name, i);
tileNode.Tag = finalTileData;
tileNode.ImageIndex = i;
tileNode.SelectedImageIndex = i;
treeView2.Nodes.Add(tileNode);
treeView2Cache.Add(tileNode);
}
i++;
}
}
}
//Blocks.Controls.Add(treeView1);
//Items.Controls.Add(treeView2);
}
catch (Newtonsoft.Json.JsonException j_ex)
{
MessageBox.Show(j_ex.Message, "Error");
return;
}
}
private IEnumerable<Image> CreateImageList(Image source, int width, int height)
{
int img_row_count = source.Width / width;
int img_column_count = source.Height / height;
for (int i = 0; i < img_column_count * img_row_count; i++)
{
int row = i / width;
int column = i % height;
Rectangle tileArea = new Rectangle(new Point(column * width, row * height), new Size(16, 16));
Bitmap tileImage = new Bitmap(width, height);
using (Graphics gfx = Graphics.FromImage(tileImage))
{
gfx.SmoothingMode = SmoothingMode.None;
gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(source, new Rectangle(0, 0, width, height), tileArea, GraphicsUnit.Pixel);
}
yield return tileImage;
}
yield break;
}
private void treeViews_AfterSelect(object sender, TreeViewEventArgs e)
{
Tuple<string, int> tileData = e.Node.Tag as Tuple<string, int>;
Console.WriteLine(tileData.Item1 + " - " + tileData.Item2);
selectedTile = tileData.Item1;
Console.WriteLine(selectedTile);
isItem = e.Node.TreeView == treeView2;
}
void filter_TextChanged(object sender, EventArgs e)
{
// Some code in this function is modified code from this StackOverflow answer - MattNL
//https://stackoverflow.com/questions/8260322/filter-a-treeview-with-a-textbox-in-a-c-sharp-winforms-app
//blocks repainting tree until all objects loaded
treeView1.BeginUpdate();
treeView1.Nodes.Clear();
treeView2.BeginUpdate();
treeView2.Nodes.Clear();
if (metroTextBox1.Text != string.Empty)
{
foreach (TreeNode _node in treeView1Cache)
{
if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
treeView1.Nodes.Add((TreeNode)_node.Clone());
}
}
foreach (TreeNode _node in treeView2Cache)
{
if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
treeView2.Nodes.Add((TreeNode)_node.Clone());
}
}
}
else
{
foreach (TreeNode _node in treeView1Cache)
{
treeView1.Nodes.Add((TreeNode)_node.Clone());
}
foreach (TreeNode _node in treeView2Cache)
{
treeView2.Nodes.Add((TreeNode)_node.Clone());
}
}
//enables redrawing tree after all objects have been added
treeView1.EndUpdate();
treeView2.EndUpdate();
}
private void button2_Click(object sender, EventArgs e)
{
selectedTile = oldTileName;
Close();
}
private void button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(selectedTile)) button2_Click(sender, e);
DialogResult = DialogResult.OK;
Close();
}
}
}

View File

@@ -1,200 +0,0 @@

namespace PckStudio.Forms.Utilities.AnimationEditor
{
partial class FrameEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.metroTextBox1 = new MetroFramework.Controls.MetroTextBox();
this.label1 = new System.Windows.Forms.Label();
this.metroTextBox2 = new MetroFramework.Controls.MetroTextBox();
this.label3 = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button1.ForeColor = System.Drawing.Color.White;
this.button1.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.button1.Location = new System.Drawing.Point(55, 111);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 7;
this.button1.Text = "Save";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.label2.Location = new System.Drawing.Point(9, 54);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(36, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Frame";
//
// metroTextBox1
//
//
//
//
this.metroTextBox1.CustomButton.Image = null;
this.metroTextBox1.CustomButton.Location = new System.Drawing.Point(157, 1);
this.metroTextBox1.CustomButton.Name = "";
this.metroTextBox1.CustomButton.Size = new System.Drawing.Size(21, 21);
this.metroTextBox1.CustomButton.Style = MetroFramework.MetroColorStyle.Blue;
this.metroTextBox1.CustomButton.TabIndex = 1;
this.metroTextBox1.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light;
this.metroTextBox1.CustomButton.UseSelectable = true;
this.metroTextBox1.CustomButton.Visible = false;
this.metroTextBox1.Lines = new string[0];
this.metroTextBox1.Location = new System.Drawing.Point(77, 51);
this.metroTextBox1.MaxLength = 4;
this.metroTextBox1.Name = "metroTextBox1";
this.metroTextBox1.PasswordChar = '\0';
this.metroTextBox1.ScrollBars = System.Windows.Forms.ScrollBars.None;
this.metroTextBox1.SelectedText = "";
this.metroTextBox1.SelectionLength = 0;
this.metroTextBox1.SelectionStart = 0;
this.metroTextBox1.ShortcutsEnabled = true;
this.metroTextBox1.Size = new System.Drawing.Size(179, 23);
this.metroTextBox1.TabIndex = 9;
this.metroTextBox1.Theme = MetroFramework.MetroThemeStyle.Dark;
this.metroTextBox1.UseSelectable = true;
this.metroTextBox1.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));
this.metroTextBox1.WaterMarkFont = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Pixel);
this.metroTextBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
//
// label1
//
this.label1.AutoSize = true;
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.label1.Location = new System.Drawing.Point(9, 83);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(62, 13);
this.label1.TabIndex = 10;
this.label1.Text = "Frame Time";
//
// metroTextBox2
//
//
//
//
this.metroTextBox2.CustomButton.Image = null;
this.metroTextBox2.CustomButton.Location = new System.Drawing.Point(157, 1);
this.metroTextBox2.CustomButton.Name = "";
this.metroTextBox2.CustomButton.Size = new System.Drawing.Size(21, 21);
this.metroTextBox2.CustomButton.Style = MetroFramework.MetroColorStyle.Blue;
this.metroTextBox2.CustomButton.TabIndex = 1;
this.metroTextBox2.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light;
this.metroTextBox2.CustomButton.UseSelectable = true;
this.metroTextBox2.CustomButton.Visible = false;
this.metroTextBox2.Lines = new string[0];
this.metroTextBox2.Location = new System.Drawing.Point(77, 80);
this.metroTextBox2.MaxLength = 4;
this.metroTextBox2.Name = "metroTextBox2";
this.metroTextBox2.PasswordChar = '\0';
this.metroTextBox2.ScrollBars = System.Windows.Forms.ScrollBars.None;
this.metroTextBox2.SelectedText = "";
this.metroTextBox2.SelectionLength = 0;
this.metroTextBox2.SelectionStart = 0;
this.metroTextBox2.ShortcutsEnabled = true;
this.metroTextBox2.Size = new System.Drawing.Size(179, 23);
this.metroTextBox2.TabIndex = 11;
this.metroTextBox2.Theme = MetroFramework.MetroThemeStyle.Dark;
this.metroTextBox2.UseSelectable = true;
this.metroTextBox2.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));
this.metroTextBox2.WaterMarkFont = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Pixel);
this.metroTextBox2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
//
// label3
//
this.label3.AutoSize = true;
this.label3.ForeColor = System.Drawing.Color.White;
this.label3.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.label3.Location = new System.Drawing.Point(47, 13);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(109, 13);
this.label3.TabIndex = 12;
this.label3.Text = "may/matt was here :3";
//
// button2
//
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button2.ForeColor = System.Drawing.Color.White;
this.button2.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.button2.Location = new System.Drawing.Point(135, 111);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 13;
this.button2.Text = "Cancel";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// FrameEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(264, 140);
this.ControlBox = false;
this.Controls.Add(this.button2);
this.Controls.Add(this.label3);
this.Controls.Add(this.label1);
this.Controls.Add(this.metroTextBox2);
this.Controls.Add(this.button1);
this.Controls.Add(this.label2);
this.Controls.Add(this.metroTextBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(266, 142);
this.Name = "FrameEditor";
this.Resizable = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label2;
private MetroFramework.Controls.MetroTextBox metroTextBox1;
private System.Windows.Forms.Label label1;
private MetroFramework.Controls.MetroTextBox metroTextBox2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button button2;
}
}

View File

@@ -1,71 +0,0 @@
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 MetroFramework.Forms;
using System.Windows.Forms;
namespace PckStudio.Forms.Utilities.AnimationEditor
{
public partial class FrameEditor : MetroForm
{
bool newF;
TreeView tv;
TreeNode node;
int limit;
Tuple<string, string> data = new Tuple<string, string>("","");
public FrameEditor(TreeView treeView, Tuple<string, string> frameData, int frameLimit, bool newFrame, TreeNode nodeToEdit)
{
limit = frameLimit;
node = nodeToEdit;
data = frameData;
tv = treeView;
newF = newFrame;
InitializeComponent();
label3.Text = "Frame must be within 0 and " + frameLimit + ".\nFrame Time must be greater than 0.";
metroTextBox1.Text = data.Item1;
metroTextBox2.Text = data.Item2;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
private void button1_Click(object sender, EventArgs e)
{
if(metroTextBox1.Text == "" || metroTextBox2.Text == "") {}
else if(Int16.Parse(metroTextBox1.Text) > limit || Int16.Parse(metroTextBox1.Text) < 0 || Int16.Parse(metroTextBox2.Text) < 0) {}
else
{
if(newF)
{
TreeNode frameNode = new TreeNode();
Tuple<string, string> finalFrameData = new Tuple<string, string>(metroTextBox1.Text, metroTextBox2.Text);
frameNode.Tag = finalFrameData;
frameNode.Text = "Frame: " + metroTextBox1.Text + ", Frame Time: " + metroTextBox2.Text;
tv.Nodes.Add(frameNode);
}
else if(!String.IsNullOrEmpty(data.Item1))
{
Tuple<string, string> finalFrameData = new Tuple<string, string>(metroTextBox1.Text, metroTextBox2.Text);
node.Tag = finalFrameData;
node.Text = "Frame: " + metroTextBox1.Text + ", Frame Time: " + metroTextBox2.Text;
}
this.Close();
}
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}

View File

@@ -0,0 +1,68 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using System.Drawing.Imaging;
using System.IO;
namespace PckStudio.Forms.Utilities
{
public static class AnimationUtil
{
public static string GetAnimationSection(bool isItem) => isItem ? "items" : "blocks";
public static readonly JObject tileData = JObject.Parse(Resources.tileData);
private static Image[] _tileImages;
public static Image[] tileImages
{
get {
if (_tileImages == null)
_tileImages = CreateImageList(Resources.terrain_sheet, 16, 16).Concat(CreateImageList(Resources.items_sheet, 16, 16)).ToArray();
return _tileImages;
}
}
public static PCKFile.FileData CreateNewAnimationFile(Image source, string tileName, bool isItem)
{
PCKFile.FileData file = new PCKFile.FileData($"res/textures/{GetAnimationSection(isItem)}/{tileName}.png", 2);
file.properties.Add(("ANIM", string.Empty));
using (var stream = new MemoryStream())
{
source.Save(stream, ImageFormat.Png);
file.SetData(stream.ToArray());
}
return file;
}
private static IEnumerable<Image> CreateImageList(Image source, int width, int height)
{
int img_row_count = source.Width / width;
int img_column_count = source.Height / height;
for (int i = 0; i < img_column_count * img_row_count; i++)
{
int row = i / width;
int column = i % height;
Rectangle tileArea = new Rectangle(new Point(column * width, row * height), new Size(width, height));
Bitmap tileImage = new Bitmap(width, height);
using (Graphics gfx = Graphics.FromImage(tileImage))
{
gfx.SmoothingMode = SmoothingMode.None;
gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(source, new Rectangle(0, 0, width, height), tileArea, GraphicsUnit.Pixel);
}
yield return tileImage;
}
yield break;
}
}
}

View File

@@ -6,10 +6,10 @@ using System.Linq;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using PckStudio.Properties;
using Ohana3DS_Rebirth.Ohana;
using System.Drawing.Imaging;
using RichPresenceClient;
using Ohana3DS_Rebirth.Ohana;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO;
using PckStudio.Classes.IO.LOC;
@@ -17,6 +17,7 @@ using PckStudio.Classes.IO.GRF;
using PckStudio.Forms;
using PckStudio.Forms.Utilities;
using PckStudio.Forms.Editor;
using PckStudio.Forms.Additional_Popups.Animation;
namespace PckStudio
{
@@ -526,7 +527,6 @@ namespace PckStudio
diag.Dispose();
}
private void createAnimatedTextureToolStripMenuItem_Click(object sender, EventArgs e)
{
using (var ofd = new OpenFileDialog())
@@ -535,30 +535,22 @@ namespace PckStudio
ofd.Title = "Select a PNG File";
if (ofd.ShowDialog() == DialogResult.OK)
{
try
{
using (Forms.Utilities.AnimationEditor.ChangeTile diag = new Forms.Utilities.AnimationEditor.ChangeTile())
using ChangeTile diag = new ChangeTile();
if (diag.ShowDialog(this) == DialogResult.OK)
{
Console.WriteLine(diag.SelectedTile);
using (Image img = new Bitmap(ofd.FileName))
using (AnimationEditor animationEditor = new AnimationEditor(img, diag.SelectedTile, diag.IsItem))
{
using Image img = new Bitmap(ofd.FileName);
var file = AnimationUtil.CreateNewAnimationFile(img, diag.SelectedTile, diag.IsItem);
currentPCK.Files.Add(file);
using AnimationEditor animationEditor = new AnimationEditor(file);
if (animationEditor.ShowDialog() == DialogResult.OK)
{
treeMeta.Nodes.Clear();
ReloadMetaTreeView();
BuildMainTreeView();
saved = false;
}
}
}
}
catch
{
MessageBox.Show("Invalid animation data.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
}
private void treeViewMain_DoubleClick(object sender, EventArgs e)
@@ -590,6 +582,15 @@ namespace PckStudio
}
break;
case 2 when file.filepath.StartsWith("res/textures/blocks/") || file.filepath.StartsWith("res/textures/items/"):
using (AnimationEditor animationEditor = new AnimationEditor(file))
{
if (animationEditor.ShowDialog(this) == DialogResult.OK)
ReloadMetaTreeView();
}
break;
case 7:
case 10 when (Path.GetExtension(file.filepath) == ".grf" && file.type == 7) ||
(Path.GetExtension(file.filepath) == ".grh" && file.type == 10):
@@ -2626,19 +2627,14 @@ namespace PckStudio
//Check for Animated Texture
if (file.filepath.StartsWith("res/textures/blocks/") || file.filepath.StartsWith("res/textures/items/"))
{
try
{
AnimationEditor diag = new AnimationEditor(file);
diag.ShowDialog(this);
diag.Dispose();
string filename = Path.GetFileNameWithoutExtension(file.filepath);
if ((filename.EndsWith("MipMapLevel2") ||filename.EndsWith("MipMapLevel3")) &&
currentPCK.TryGetFile(file.filepath.Substring(0, file.filepath.Length - 4 - 12) + ".png", 2, out var baseAnimationFile))
file = baseAnimationFile;
using AnimationEditor diag = new AnimationEditor(file);
if (diag.ShowDialog(this) == DialogResult.OK)
ReloadMetaTreeView();
}
catch
{
MessageBox.Show("Invalid animation data.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
if (Path.GetFileName(file.filepath) == "audio.pck")
{

View File

@@ -225,16 +225,16 @@
<Compile Include="Forms\Editor\LOCEditor.Designer.cs">
<DependentUpon>LOCEditor.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Utilities\Animation\ChangeTile.cs">
<Compile Include="Forms\Additional-Popups\Animation\ChangeTile.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Utilities\Animation\ChangeTile.Designer.cs">
<Compile Include="Forms\Additional-Popups\Animation\ChangeTile.Designer.cs">
<DependentUpon>ChangeTile.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Utilities\Animation\SetBulkSpeed.cs">
<Compile Include="Forms\Additional-Popups\Animation\SetBulkSpeed.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Utilities\Animation\SetBulkSpeed.Designer.cs">
<Compile Include="Forms\Additional-Popups\Animation\SetBulkSpeed.Designer.cs">
<DependentUpon>SetBulkSpeed.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Additional-Popups\Audio\creditsEditor.cs">
@@ -291,6 +291,7 @@
<Compile Include="Forms\Additional-Popups\Audio\pleaseWait.Designer.cs">
<DependentUpon>pleaseWait.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Utilities\AnimationUtil.cs" />
<Compile Include="Forms\Utilities\Skins\ANIMEditor.cs">
<SubType>Form</SubType>
</Compile>
@@ -321,16 +322,16 @@
<Compile Include="Forms\Skins-And-Textures\SkinPreview.Designer.cs">
<DependentUpon>SkinPreview.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Utilities\Animation\AnimationEditor.cs">
<Compile Include="Forms\Editor\AnimationEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Utilities\Animation\AnimationEditor.Designer.cs">
<Compile Include="Forms\Editor\AnimationEditor.Designer.cs">
<DependentUpon>AnimationEditor.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Utilities\Animation\FrameEditor.cs">
<Compile Include="Forms\Additional-Popups\Animation\FrameEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Utilities\Animation\FrameEditor.Designer.cs">
<Compile Include="Forms\Additional-Popups\Animation\FrameEditor.Designer.cs">
<DependentUpon>FrameEditor.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Editor\AudioEditor.cs">
@@ -456,10 +457,10 @@
<EmbeddedResource Include="Forms\Editor\LOCEditor.resx">
<DependentUpon>LOCEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Utilities\Animation\ChangeTile.resx">
<EmbeddedResource Include="Forms\Additional-Popups\Animation\ChangeTile.resx">
<DependentUpon>ChangeTile.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Utilities\Animation\SetBulkSpeed.resx">
<EmbeddedResource Include="Forms\Additional-Popups\Animation\SetBulkSpeed.resx">
<DependentUpon>SetBulkSpeed.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Additional-Popups\Audio\creditsEditor.resx">
@@ -527,10 +528,10 @@
<EmbeddedResource Include="Forms\Skins-And-Textures\SkinPreview.resx">
<DependentUpon>SkinPreview.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Utilities\Animation\AnimationEditor.resx">
<EmbeddedResource Include="Forms\Editor\AnimationEditor.resx">
<DependentUpon>AnimationEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Utilities\Animation\FrameEditor.resx">
<EmbeddedResource Include="Forms\Additional-Popups\Animation\FrameEditor.resx">
<DependentUpon>FrameEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Editor\AudioEditor.resx">

View File

@@ -1,7 +1,7 @@
{
"COMMENT_1": "Tile data research by MattNL",
"COMMENT_2": "JSON conversion by PhoenixARC",
"Blocks": [
"blocks": [
{ "grass_top": "Grass Block (Top)" },
{ "stone": "Stone" },
{ "dirt": "Dirt" },
@@ -547,7 +547,7 @@
{ "dark_oak_trapdoor": "Dark Oak Trapdoor" },
{ "jungle_trapdoor": "Jungle Trapdoor" }
],
"Items": [
"items": [
{ "helmetCloth": "Leather Helmet" },
{ "helmetChain": "Chain Helmet" },
{ "helmetIron": "Iron Helmet" },