Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add drag-and-drop support for YTD form #276

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions CodeWalker.Core/GameFiles/Resources/Texture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace CodeWalker.GameFiles
{


[TypeConverter(typeof(ExpandableObjectConverter))] public class TextureDictionary : ResourceFileBase
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TextureDictionary : ResourceFileBase
{
public override long BlockLength
{
Expand Down Expand Up @@ -172,7 +171,7 @@ private void BuildDict()
public void BuildFromTextureList(List<Texture> textures)
{
textures.Sort((a, b) => a.NameHash.CompareTo(b.NameHash));

var texturehashes = new List<uint>();
foreach (var tex in textures)
{
Expand All @@ -188,7 +187,8 @@ public void BuildFromTextureList(List<Texture> textures)

}

[TypeConverter(typeof(ExpandableObjectConverter))] public class TextureBase : ResourceSystemBlock
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TextureBase : ResourceSystemBlock
{
public override long BlockLength
{
Expand Down Expand Up @@ -430,7 +430,8 @@ public override string ToString()
}
}

[TypeConverter(typeof(ExpandableObjectConverter))] public class Texture : TextureBase
[TypeConverter(typeof(ExpandableObjectConverter))]
public class Texture : TextureBase
{
public override long BlockLength
{
Expand Down Expand Up @@ -475,6 +476,23 @@ public long MemoryUsage
}
}

/// <summary>
/// Checks if the <see cref="Texture.Width"/> and <see cref="Texture.Height"/> are powers of two.
/// </summary>
/// <remarks>
/// It is not necessary for the <see cref="Texture.Width"/> and <see cref="Texture.Height"/> to be the same.
/// </remarks>
/// <value>
/// <see langword="true"/> if the <see cref="Texture.Width"/> and <see cref="Texture.Height"/> are powers of two; otherwise, <see langword="false"/>.
/// </value>
public bool IsPowerOf2
{
get
{
return (Width & (Width - 1)) == 0 && (Height & (Height - 1)) == 0;
}
}

public override void Read(ResourceDataReader reader, params object[] parameters)
{
base.Read(reader, parameters);
Expand Down Expand Up @@ -612,7 +630,8 @@ public override string ToString()
}
}

[TypeConverter(typeof(ExpandableObjectConverter))] public class TextureData : ResourceGraphicsBlock
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TextureData : ResourceGraphicsBlock
{
public override long BlockLength
{
Expand Down
3 changes: 3 additions & 0 deletions CodeWalker/Forms/YtdForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

130 changes: 128 additions & 2 deletions CodeWalker/Forms/YtdForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,13 @@ private void AddTexture()
var tex = OpenDDSFile();
if (tex == null) return;

var textures = new List<Texture>();
textures.AddRange(TexDict.Textures.data_items);
var textures = new List<Texture>(TexDict.Textures.data_items);
if (textures.Any(t => t.Name.Equals(tex.Name, StringComparison.InvariantCultureIgnoreCase)))
{
MessageBox.Show($"A texture with the name {tex.Name} already exists in this YTD.\nAll textures must have unique names in a YTD.");
return;
}

textures.Add(tex);

TexDict.BuildFromTextureList(textures);
Expand Down Expand Up @@ -322,6 +327,12 @@ private Texture OpenDDSFile()
{
var dds = File.ReadAllBytes(fn);
var tex = DDSIO.GetTexture(dds);
if (!tex.IsPowerOf2)
{
MessageBox.Show($"The texture is not a power of two texture.\nThe texture must have a width and height equal to a power of two e.g. 256, 512, 1024, etc...");
return null;
}

tex.Name = Path.GetFileNameWithoutExtension(fn);
tex.NameHash = JenkHash.GenHash(tex.Name?.ToLowerInvariant());
JenkIndex.Ensure(tex.Name?.ToLowerInvariant());
Expand Down Expand Up @@ -649,5 +660,120 @@ private void SelTextureNameTextBox_TextChanged(object sender, EventArgs e)
{
RenameTexture(SelTextureNameTextBox.Text);
}

/// <summary>
/// Add one or more textures to the YTD by dragging and dropping them into the YTD.
/// </summary>
/// <param name="sender">
/// The source of the event.
/// </param>
/// <param name="e">
/// The <see cref="DragEventArgs"/> that contains the event data.
/// </param>
private void TexturesListView_DragDrop(object sender, DragEventArgs e)
{
if (TexDict.Textures?.data_items == null)
{
return;
}

if (!e.Data.GetDataPresent(DataFormats.FileDrop))
{
return;
}

string[] filePaths = e.Data.GetData(DataFormats.FileDrop) as string[];
if (filePaths == null)
{
// Couldn't get files paths?
return;
}

List<Texture> newTextures = new List<Texture>(TexDict.Textures.data_items);
foreach (string filePath in filePaths)
{
if (!filePath.EndsWith(".dds", StringComparison.InvariantCultureIgnoreCase))
{
// Not a DDS file?
MessageBox.Show("You can only drag and drop DDS files into an YTD.");
return;
}

if (!File.Exists(filePath))
{
// Couldn't find file?
MessageBox.Show($"Couldn't find file {filePath}.");
return;
}

// Check if a texture with the same name already exists in the YTD.
string textureName = Path.GetFileNameWithoutExtension(filePath);
if(newTextures.Any(t => t.Name.Equals(textureName, StringComparison.InvariantCultureIgnoreCase)))
{
MessageBox.Show($"A texture with the name {textureName} already exists in this YTD.\nAll textures must have unique names in a YTD.");
return;
}

byte[] dds = File.ReadAllBytes(filePath);
try
{
Texture texture = DDSIO.GetTexture(dds);
if(texture == null)
{
throw new Exception("Something went wrong while loading the texture.");
}

if(!texture.IsPowerOf2)
{
MessageBox.Show($"The texture {filePath} is not a power of two texture.\nThe texture must have a width and height equal to a power of two e.g. 256, 512, 1024, etc...");
return;
}

texture.Name = textureName;
texture.NameHash = JenkHash.GenHash(texture.Name?.ToLowerInvariant());
JenkIndex.Ensure(texture.Name?.ToLowerInvariant());
newTextures.Add(texture);
}
catch
{
MessageBox.Show($"Unable to load {filePath}.\nAre you sure it's a valid .dds file?");
}
}

TexDict.BuildFromTextureList(newTextures);

Modified = true;

LoadTexDict(TexDict, FileName);

UpdateModelFormTextures();
}

/// <summary>
/// Checks if the files can be dropped into the YTD.
/// </summary>
/// <param name="sender">
/// The source of the event.
/// </param>
/// <param name="e">
/// The <see cref="DragEventArgs"/> that contains the event data.
/// </param>
private void TexturesListView_DragEnter(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.None;
return;
}

string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files == null)
{
e.Effect = DragDropEffects.None;
return;
}

e.Effect = DragDropEffects.Copy;
}
}
}