initial commit

This commit is contained in:
Darrin Massena 2014-07-06 17:47:28 -07:00
commit f4c0203914
2604 changed files with 277246 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*.pidb
*.userprefs
*/bin/
*/*/bin/
/game/wi.xcodeproj/project.xcworkspace/
/game/wi.xcodeproj/xcuserdata/
/DerivedData/

1
AniMax/.cvsignore Normal file
View File

@ -0,0 +1 @@
bin

204
AniMax/AboutForm.cs Normal file
View File

@ -0,0 +1,204 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace SpiffCode
{
/// <summary>
/// Summary description for AboutForm.
/// </summary>
public class AboutForm : Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnSystemInfo;
private System.Windows.Forms.PictureBox pictureBox1;
private SpiffCode.ScBorder scBorder1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public AboutForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
// SetBitmap(new Bitmap(@"c:\code\ht\animax\shp.png"));
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(AboutForm));
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.btnOK = new System.Windows.Forms.Button();
this.btnSystemInfo = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.scBorder1 = new SpiffCode.ScBorder();
this.panel2.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(112, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(200, 16);
this.label1.TabIndex = 1;
this.label1.Text = "SpiffCode AniMax 2002 (Version 0.31)";
//
// label2
//
this.label2.Location = new System.Drawing.Point(112, 24);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(336, 16);
this.label2.TabIndex = 2;
this.label2.Text = "Copyright © 2002 SpiffCode Incorporated. All Rights Reserved.";
//
// label3
//
this.label3.Location = new System.Drawing.Point(112, 56);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(168, 16);
this.label3.TabIndex = 3;
this.label3.Text = "This program is licensed to:";
//
// label4
//
this.label4.Location = new System.Drawing.Point(8, 8);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(100, 16);
this.label4.TabIndex = 0;
this.label4.Text = "Mark Soderwall";
//
// label5
//
this.label5.Location = new System.Drawing.Point(8, 24);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(128, 16);
this.label5.TabIndex = 1;
this.label5.Text = "Extreme Illustrations";
//
// label6
//
this.label6.Location = new System.Drawing.Point(16, 200);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(352, 64);
this.label6.TabIndex = 5;
this.label6.Text = @"Warning: This computer program is protected by copyright law and international treaties. Unauthorized reproduction or distribution of this program, or any portion of it, may result in severe civil and criminal penalties, and will be prosecuted to the maximum extent possible under the law.";
this.label6.UseMnemonic = false;
//
// panel2
//
this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.panel2.Controls.AddRange(new System.Windows.Forms.Control[] {
this.label5,
this.label4});
this.panel2.Location = new System.Drawing.Point(112, 72);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(352, 48);
this.panel2.TabIndex = 4;
//
// btnOK
//
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnOK.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnOK.Location = new System.Drawing.Point(376, 203);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(88, 23);
this.btnOK.TabIndex = 6;
this.btnOK.Text = "OK";
//
// btnSystemInfo
//
this.btnSystemInfo.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnSystemInfo.Location = new System.Drawing.Point(376, 234);
this.btnSystemInfo.Name = "btnSystemInfo";
this.btnSystemInfo.Size = new System.Drawing.Size(88, 23);
this.btnSystemInfo.TabIndex = 7;
this.btnSystemInfo.Text = "&System Info...";
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Bitmap)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(-24, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(168, 192);
this.pictureBox1.TabIndex = 8;
this.pictureBox1.TabStop = false;
//
// scBorder1
//
this.scBorder1.Location = new System.Drawing.Point(16, 190);
this.scBorder1.Name = "scBorder1";
this.scBorder1.Size = new System.Drawing.Size(448, 3);
this.scBorder1.TabIndex = 9;
this.scBorder1.Text = "scBorder1";
//
// AboutForm
//
this.AcceptButton = this.btnOK;
this.AutoScale = false;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(200)), ((System.Byte)(204)), ((System.Byte)(206)));
this.CancelButton = this.btnOK;
this.ClientSize = new System.Drawing.Size(480, 272);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.scBorder1,
this.btnSystemInfo,
this.btnOK,
this.label6,
this.panel2,
this.label3,
this.label2,
this.label1,
this.pictureBox1});
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "AboutForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "About SpiffCode AniMax";
this.panel2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
}
}

BIN
AniMax/AboutForm.resources Normal file

Binary file not shown.

879
AniMax/AboutForm.resx Normal file
View File

@ -0,0 +1,879 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
qi3/9z+lH/h/MtLZz1XXTuUAAAAASUVORK5CYII=
</value>
</data>
<data name="$this.Name">
<value>AboutForm</value>
</data>
</root>

39
AniMax/AniMax.cs Normal file
View File

@ -0,0 +1,39 @@
using System;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for AniMax.
/// </summary>
public class AniMax
{
private static Form s_frmMain;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] astrArgs) {
string strOpenFileName = null;
if (astrArgs.Length != 0)
strOpenFileName = astrArgs[0];
Globals.NullDocument = new AnimDoc(Globals.TileSize,
Globals.FrameRate);
Globals.NullDocument.Dirty = false;
Globals.ActiveDocument = Globals.NullDocument;
s_frmMain = new MainForm(strOpenFileName);
#if true
Application.Run(s_frmMain);
#else
try {
Application.Run(s_frmMain);
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
}
#endif
}
}
}

161
AniMax/AniMax.csproj Normal file
View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FBB48F3B-5FB4-4D87-AD16-E17C2FB9FEFA}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>SpiffCode</RootNamespace>
<AssemblyName>AniMax</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunWithWarnings>false</RunWithWarnings>
<additionalargs>-unsafe</additionalargs>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunWithWarnings>false</RunWithWarnings>
<additionalargs>-unsafe</additionalargs>
</PropertyGroup>
<ItemGroup>
<Compile Include="AboutForm.cs" />
<Compile Include="AniMax.cs" />
<Compile Include="AnimDoc.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="BitmapsForm.cs" />
<Compile Include="CombinerForm.cs" />
<Compile Include="Frame.cs" />
<Compile Include="FrameControl.cs" />
<Compile Include="Globals.cs" />
<Compile Include="MainForm.cs" />
<Compile Include="MiscControls.cs" />
<Compile Include="OptionsForm.cs" />
<Compile Include="PerPixelAlphaForm.cs" />
<Compile Include="PreviewControl.cs" />
<Compile Include="PreviewPanel.cs" />
<Compile Include="ReplaceColorsForm.cs" />
<Compile Include="Strip.cs" />
<Compile Include="StripControl.cs" />
<Compile Include="StripForm.cs" />
<Compile Include="StripProperties.cs" />
<Compile Include="StripSet.cs" />
<Compile Include="StripsForm.cs" />
<Compile Include="UndoManager.cs" />
<Compile Include="WallPreviewForm.cs" />
<Compile Include="XBitmap.cs" />
<Compile Include="XBitmapSet.cs" />
<Compile Include="..\SpiffLib\misc.cs">
<Link>misc.cs</Link>
</Compile>
<Compile Include="..\SpiffLib\palette.cs">
<Link>palette.cs</Link>
</Compile>
<Compile Include="..\SpiffLib\tbitmap.cs">
<Link>tbitmap.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="AboutForm.resx">
<DependentUpon>AboutForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="BitmapsForm.resx">
<DependentUpon>BitmapsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="CombinerForm.resx">
<DependentUpon>CombinerForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FrameControl.resx">
<DependentUpon>FrameControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MiscControls.resx">
<DependentUpon>MiscControls.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="OptionsForm.resx">
<DependentUpon>OptionsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="PerPixelAlphaForm.resx">
<DependentUpon>PerPixelAlphaForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="PreviewControl.resx">
<DependentUpon>PreviewControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="PreviewPanel.resx">
<DependentUpon>PreviewPanel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ReplaceColorsForm.resx">
<DependentUpon>ReplaceColorsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="StripControl.resx">
<DependentUpon>StripControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="StripForm.resx">
<DependentUpon>StripForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="StripProperties.resx">
<DependentUpon>StripProperties.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="StripsForm.resx">
<DependentUpon>StripsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="WallPreviewForm.resx">
<DependentUpon>WallPreviewForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Resources\about graphic.png" />
<EmbeddedResource Include="Resources\grab.cur" />
<EmbeddedResource Include="Resources\grid icon.png" />
<EmbeddedResource Include="Resources\hand.cur" />
<EmbeddedResource Include="Resources\hires toggle icon.png" />
<EmbeddedResource Include="Resources\loop forward icon.png" />
<EmbeddedResource Include="Resources\origin point toggle icon.png" />
<EmbeddedResource Include="Resources\play icon.png" />
<EmbeddedResource Include="Resources\play toggle icon.png" />
<EmbeddedResource Include="Resources\properties icon.png" />
<EmbeddedResource Include="Resources\set special point icon.png" />
<EmbeddedResource Include="Resources\side color toggle icon.png" />
<EmbeddedResource Include="Resources\stop icon.png" />
</ItemGroup>
<ItemGroup>
<None Include="AniMax.exe.manifest" />
</ItemGroup>
<ItemGroup>
<Content Include="App.ico" />
<Content Include="licenses.licx" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Runtime.Serialization.Formatters.Soap" />
<Reference Include="MagicLibrary, Version=1.5.0.0, Culture=neutral, PublicKeyToken=null">
<SpecificVersion>False</SpecificVersion>
<HintPath>MagicLibrary.dll</HintPath>
</Reference>
<Reference Include="SharpZipLib, Version=0.31.0.0, Culture=neutral, PublicKeyToken=1b03e6acf1164f73">
<SpecificVersion>False</SpecificVersion>
<HintPath>SharpZipLib.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<MonoDevelop>
<Properties InternalTargetFrameworkVersion="3.5" />
</MonoDevelop>
</ProjectExtensions>
</Project>

BIN
AniMax/AniMax.doc Normal file

Binary file not shown.

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="SpiffCode.HostileTakeover.AniMax"
type="win32"
/>
<description>Animation Editor</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

20
AniMax/AniMax.sln Normal file
View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AniMax", "AniMax.csproj", "{FBB48F3B-5FB4-4D87-AD16-E17C2FB9FEFA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FBB48F3B-5FB4-4D87-AD16-E17C2FB9FEFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FBB48F3B-5FB4-4D87-AD16-E17C2FB9FEFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FBB48F3B-5FB4-4D87-AD16-E17C2FB9FEFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FBB48F3B-5FB4-4D87-AD16-E17C2FB9FEFA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = AniMax.csproj
EndGlobalSection
EndGlobal

690
AniMax/AnimDoc.cs Normal file
View File

@ -0,0 +1,690 @@
using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
using System.IO;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using System.Text; // For ASCIIEncoding
using SpiffLib;
using ICSharpCode.SharpZipLib.Zip;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Diagnostics;
namespace SpiffCode
{
/// <summary>
/// Summary description for AnimDoc.
/// </summary>
[Serializable]
public class AnimDoc : ISerializable
{
// Persistable state
private int m_nTileSize;
private XBitmapSet m_xbms;
private StripSet m_stps;
private int m_msFrameRate;
//
private bool m_fDirty = false;
private bool m_fHires = false;
private string m_strFileName = "untitled.amx";
private Strip m_stpActive;
// Public properties
public XBitmapSet XBitmapSet {
get {
return m_xbms;
}
}
public StripSet StripSet {
get {
return m_stps;
}
}
public bool Hires {
get {
return m_fHires;
}
set {
m_fHires = value;
}
}
// Exposed for anyone who wants to keep track of this AnimDoc's ActiveStrip
public event EventHandler ActiveStripChanged;
public Strip ActiveStrip {
get {
return m_stpActive;
}
set {
m_stpActive = value;
if (ActiveStripChanged != null)
ActiveStripChanged(this, EventArgs.Empty);
}
}
public bool Dirty {
get {
return m_fDirty;
}
set {
m_fDirty = value;
}
}
public string FileName {
get {
return m_strFileName;
}
set {
m_strFileName = value;
Dirty = true;
}
}
public int FrameRate {
get {
return m_msFrameRate;
}
set {
m_msFrameRate = value;
}
}
public int TileSize {
get {
return m_nTileSize;
}
set {
m_nTileSize = value;
Dirty = true;
}
}
//
public AnimDoc(int nTileSize, int cmsFrameRate) {
m_nTileSize = nTileSize;
m_msFrameRate = cmsFrameRate;
m_xbms = new XBitmapSet();
m_stps = new StripSet();
m_fDirty = true;
}
public static AnimDoc Load(string strFileName) {
if (!File.Exists(strFileName))
throw new FileNotFoundException("File Not found", strFileName);
return Load(strFileName, null);
}
public static AnimDoc Load(string strFileName, Stream stmZamx) {
string strFileNameOrig = strFileName;
string strExt = Path.GetExtension(strFileName).ToLower();
bool fZip = strExt == ".zip" || strExt == ".zamx";
string strCurrentDirSav = null;
string strTempDir = null;
// Remember current dir
strCurrentDirSav = Directory.GetCurrentDirectory();
if (fZip) {
// Change current dir to temp dir
strTempDir = Path.Combine(Path.GetTempPath(), "AniMax_temp_extract_dir");
Directory.CreateDirectory(strTempDir);
Directory.SetCurrentDirectory(strTempDir);
// Extract the .zip to the temp dir
ZipInputStream zipi = new ZipInputStream(stmZamx != null ? stmZamx : File.OpenRead(strFileName));
ZipEntry zipe;
while ((zipe = zipi.GetNextEntry()) != null) {
string strDir = Path.GetDirectoryName(zipe.Name);
if (Path.GetExtension(zipe.Name).ToLower() == ".amx")
strFileName = zipe.Name;
if (strDir != null && strDir != "") {
if (!Directory.Exists(strDir))
Directory.CreateDirectory(strDir);
}
FileStream stm = File.Create(zipe.Name);
byte[] abT = new byte[zipe.Size];
// For some reason due to its implementation, ZipInputStream.Read can return
// fewer than the requested number of bytes. Loop until we have them all.
while (true) {
int cbRead = zipi.Read(abT, 0, abT.Length);
if (cbRead <= 0)
break;
stm.Write(abT, 0, cbRead);
}
stm.Close();
}
zipi.Close();
// Convert filename from, say, c:\ht\data\foo.zip or foo.zamx to foo.amx
strFileName = Path.GetFileNameWithoutExtension(strFileName) + ".amx";
}
FileStream stmAmx = File.Open(strFileName, FileMode.Open, FileAccess.Read);
SoapFormatter spfmt = new SoapFormatter();
spfmt.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
spfmt.Binder = new RelaxedSerializationBinder();
if (!fZip) {
// If .amx being loaded is in a directory other than the current one,
// change to it so deserialization will find the contained bitmaps in
// their proper place.
string strPath = Path.GetDirectoryName(strFileName);
if (strPath != null && strPath != "")
Directory.SetCurrentDirectory(strPath);
}
AnimDoc doc = null;
try {
doc = (AnimDoc)spfmt.Deserialize(stmAmx);
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
Console.WriteLine(ex);
}
stmAmx.Close();
// Restore current dir (NOTE: can't delete temp dir until it isn't current)
Directory.SetCurrentDirectory(strCurrentDirSav);
if (fZip) {
// Delete temp extraction dir and its contents
Directory.Delete(strTempDir, true);
}
if (doc == null)
return null;
doc.m_strFileName = strFileNameOrig;
return doc;
}
public void Save(string strFileName) {
string strExt = Path.GetExtension(strFileName).ToLower();
bool fZip = strExt == ".zip" || strExt == ".zamx";
// Update the XBitmaps to have paths relative to the specified file
// in a subdirectory named after the file.
m_strFileName = strFileName;
// Create a sub-directory for all the Bitmaps
// UNDONE: clean it out?
string strName = Path.GetFileNameWithoutExtension(strFileName);
string strBitmapDir = Path.Combine(Path.GetDirectoryName(strFileName), strName);
foreach (XBitmap xbm in XBitmapSet)
xbm.FileName = Path.Combine(strName, Path.GetFileName(xbm.FileName));
string strAmxFileName = fZip ? strFileName + ".temporary_file" : strFileName;
FileStream stm = File.Open(strAmxFileName, FileMode.Create, FileAccess.Write);
SoapFormatter spfmt = new SoapFormatter();
// This cuts down on the verbosity of the generated XML file
spfmt.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
spfmt.Serialize(stm, this);
stm.Close();
if (fZip) {
ZipOutputStream zipo = null;
zipo = new ZipOutputStream(File.Create(strFileName));
zipo.SetLevel(9); // maximum compression
// Read temporary .amx file
stm = File.OpenRead(strAmxFileName);
byte[] abT = new byte[stm.Length];
stm.Read(abT, 0, abT.Length);
stm.Close();
// Delete temporary .amx file
File.Delete(strAmxFileName);
// Write .amx file to .zip
ZipEntry zipe = new ZipEntry(strName + ".amx");
zipo.PutNextEntry(zipe);
zipo.Write(abT, 0, abT.Length);
// Write the bitmaps too
foreach (XBitmap xbm in m_xbms) {
// Write temporary bitmap file
xbm.Save(strAmxFileName);
// Read temporary bitmap file
stm = File.OpenRead(strAmxFileName);
abT = new byte[stm.Length];
stm.Read(abT, 0, abT.Length);
stm.Close();
// Delete the temporary bitmap file
File.Delete(strAmxFileName);
// Write bitmap to .zip
zipe = new ZipEntry(Path.Combine(strName, Path.GetFileName(xbm.FileName)));
zipo.PutNextEntry(zipe);
zipo.Write(abT, 0, abT.Length);
}
zipo.Finish();
zipo.Close();
} else {
// Save the Bitmaps too
Directory.CreateDirectory(strBitmapDir);
foreach (XBitmap xbm in m_xbms)
xbm.Save(Path.Combine(strBitmapDir, Path.GetFileName(xbm.FileName)));
}
m_fDirty = false;
}
public static bool ParseNameValueString(string str, out string strName, out string strValue) {
int ichEquals = str.IndexOf('=');
if (ichEquals == -1) {
strName = null;
strValue = null;
return false;
}
strName = str.Substring(0, ichEquals).Trim();
strValue = str.Substring(ichEquals + 1);
return true;
}
public bool Import(string[] astrFileNames) {
// Is this a SideWinder framedata.txt file?
if (astrFileNames.Length == 1 && Path.GetFileName(astrFileNames[0]).ToLower() == "framedata.txt") {
// Yep, open it up and parse it
StreamReader stmr = new StreamReader(astrFileNames[0]);
int iLine = 0;
string str;
do {
iLine++;
str = stmr.ReadLine();
} while (str == ""); // skip blank lines
if (str == null) {
MessageBox.Show(null, "Reached the end of the file before it was expected", "Error");
return false;
}
string strName, strValue;
if (!ParseNameValueString(str, out strName, out strValue)) {
MessageBox.Show(null, String.Format("Syntax error on line %d: %s", iLine, str), "Error");
return false;
}
if (strName != "cfrm") {
MessageBox.Show(null, "Expected a 'cfrm =' statement but didn't find it", "Error");
return false;
}
// Find a unique name for this strip
int iStrip = 0;
while (StripSet["strip" + iStrip] != null)
iStrip++;
Strip stp = new Strip("strip" + iStrip);
StripSet.Add(stp);
int cfr = int.Parse(strValue);
for (int ifr = 0; ifr < cfr; ifr++) {
// 1. Read the bitmap from it and add it to the Document's XBitmapSet
XBitmap xbm;
string strBitmap = "frame" + ifr + ".bmp";
try {
xbm = new XBitmap(strBitmap, true);
} catch {
MessageBox.Show(null, String.Format("Can't load \"{0}\"", strBitmap), "Error");
return false;
}
XBitmapSet.Add(xbm);
// 2. Create a Frame to go with the Bitmap and add it to the appropriate
// Strip. If no strip exists, create one.
Frame fr = new Frame();
fr.BitmapPlacers.Add(new BitmapPlacer());
fr.BitmapPlacers[0].XBitmap = xbm;
stp[ifr] = fr;
bool fDone = false;
while (!fDone) {
do {
iLine++;
str = stmr.ReadLine();
} while (str == ""); // skip blank lines
if (!ParseNameValueString(str, out strName, out strValue)) {
MessageBox.Show(null, String.Format("Syntax error on line %d: %s", iLine, str), "Error");
return false;
}
switch (strName) {
case "flags":
Debug.Assert(strValue.Trim() == "0");
break;
case "xCenter":
fr.BitmapPlacers[0].X = int.Parse(strValue);
break;
case "yCenter":
fr.BitmapPlacers[0].Y = int.Parse(strValue);
break;
case "xGrab":
fr.SpecialPoint = new Point(int.Parse(strValue) - fr.BitmapPlacers[0].X, fr.SpecialPoint.Y);
break;
case "yGrab":
fr.SpecialPoint = new Point(fr.SpecialPoint.X, int.Parse(strValue) - fr.BitmapPlacers[0].Y);
break;
case "xWidth":
Debug.Assert(int.Parse(strValue.Trim()) == xbm.Width);
break;
case "yHeight":
Debug.Assert(int.Parse(strValue.Trim()) == xbm.Height);
fDone = true;
break;
}
}
}
} else {
// XBitmap encapsulates special filename rules
astrFileNames = XBitmap.FilterFileNames(astrFileNames);
// By sorting the filenames we introduce a useful bit of
// determinism.
Array.Sort(astrFileNames);
// Enumerate all the filenames and for each one:
foreach (string strFile in astrFileNames) {
// 0. Verify the filename fits the pattern we're expecting
string[] astr = strFile.Substring(strFile.LastIndexOf('\\') + 1).Split('_', '.');
if (astr.Length != 5) {
MessageBox.Show(null, String.Format("File {0} does not match the requisite naming pattern. Skipping and continuing.",
strFile), "Error");
continue;
}
string strAnimDoc = astr[0];
string strStripA = astr[1];
string strStripB = astr[2];
int ifr = Convert.ToInt32(astr[3]);
// 1. Read the bitmap from it and add it to the Document's XBitmapSet
XBitmap xbm;
try {
xbm = new XBitmap(strFile);
} catch {
MessageBox.Show(null, String.Format("Can't load \"{0}\"", strFile), "Error");
return false;
}
XBitmapSet.Add(xbm);
// 2. Create a Frame to go with the Bitmap and add it to the appropriate
// Strip. If no strip exists, create one.
Frame fr = new Frame();
fr.BitmapPlacers.Add(new BitmapPlacer());
fr.BitmapPlacers[0].XBitmap = xbm;
fr.BitmapPlacers[0].X = xbm.Width / 2;
fr.BitmapPlacers[0].Y = xbm.Height / 2;
string strStripName = strStripA + " " + strStripB;
Strip stp = StripSet[strStripName];
if (stp == null) {
stp = new Strip(strStripName);
StripSet.Add(stp);
}
stp[ifr] = fr;
}
}
Dirty = true;
return true;
}
public bool WriteAnir(Palette pal, string strExportPath, string strAnimName) {
Color clrTransparent = Color.FromArgb(0xff, 0, 0xff);
SolidBrush brTransparent = new SolidBrush(clrTransparent);
ASCIIEncoding enc = new ASCIIEncoding();
FileStream stm = new FileStream(strExportPath + Path.DirectorySeparatorChar + strAnimName + ".anir", FileMode.Create, FileAccess.Write);
BinaryWriter stmw = new BinaryWriter(stm);
// Count the number of Strips
ushort cstpd = (ushort)StripSet.Count;
// Write AnimationFileHeader.cstpd
stmw.Write(Misc.SwapUShort(cstpd));
// Write array of offsets to StripDatas (AnimationFileHeader.aoffStpd)
ushort offStpd = (ushort)(2 + (2 * cstpd));
ArrayList albm = new ArrayList();
foreach (Strip stp in StripSet) {
stmw.Write(Misc.SwapUShort(offStpd));
// Advance offset to where the next StripData will be
offStpd += (ushort)((26+1+1+2) /* sizeof(StripData) - sizeof(FrameData) */ +
((1+1+1+1+1+1+1+1+1) /* sizeof(FrameData) */ * stp.Count));
// Force word alignment of StripDatas
if ((offStpd & 1) == 1)
offStpd++;
}
// Write array of StripDatas
foreach (Strip stp in StripSet) {
// Write StripData.Name
byte[] abT = new byte[26];
enc.GetBytes(stp.Name, 0, Math.Min(stp.Name.Length, 25), abT, 0);
abT[25] = 0;
stmw.Write(abT);
// Write StripData.cHold
stmw.Write((byte)stp.DefHoldCount);
// Write StripData.bfFlags
stmw.Write((byte)0);
// Write StripData.cfrmd
ushort cfrmd = (ushort)stp.Count;
stmw.Write(Misc.SwapUShort(cfrmd));
// Write array of FrameDatas
foreach (Frame fr in stp) {
// Add the Frame's Bitmap for output
int ibm = -1;
Bitmap bm;
if (fr.BitmapPlacers.Count > 0) {
bm = fr.BitmapPlacers[0].XBitmap.Bitmap;
ibm = albm.IndexOf(bm);
if (ibm == -1)
ibm = albm.Add(bm);
}
// Write FrameData.ibm (the index of the Bitmap as it will be in the Bitmap array)
stmw.Write((byte)ibm);
ibm = -1;
if (fr.BitmapPlacers.Count > 1) {
// Add the Frame's Bitmap for output
bm = fr.BitmapPlacers[1].XBitmap.Bitmap;
ibm = albm.IndexOf(bm);
if (ibm == -1)
ibm = albm.Add(bm);
}
// Write FrameData.ibm2 (the index of the Bitmap as it will be in the Bitmap array)
stmw.Write((byte)ibm);
// Write FrameData.cHold
stmw.Write((byte)fr.HoldCount);
// Write FrameData.xOrigin, FrameData.yOrigin
if (fr.BitmapPlacers.Count > 0) {
stmw.Write((byte)fr.BitmapPlacers[0].X);
stmw.Write((byte)fr.BitmapPlacers[0].Y);
} else {
stmw.Write((byte)0);
stmw.Write((byte)0);
}
if (fr.BitmapPlacers.Count > 1) {
stmw.Write((byte)fr.BitmapPlacers[1].X);
stmw.Write((byte)fr.BitmapPlacers[1].Y);
} else {
stmw.Write((byte)0);
stmw.Write((byte)0);
}
// Write FrameData.bCustomData1, FrameData.bCustomData2
stmw.Write((byte)fr.SpecialPoint.X);
stmw.Write((byte)fr.SpecialPoint.Y);
#if false
// Write FrameData.bCustomData3
stmw.Write((byte)0);
#endif
}
// Force word alignment of StripDatas given that FrameDatas are an odd
// number of bytes long and there may be an odd number of frames.
if ((cfrmd & 1) == 1)
stmw.Write((byte)0);
}
stmw.Close();
// Write out .tbm
if (albm.Count != 0) {
string strFileName = strExportPath + Path.DirectorySeparatorChar + strAnimName + ".tbm";
// if (gfSuperVerbose)
// Console.WriteLine("Crunching and writing " + strFileName);
TBitmap.Save((Bitmap[])albm.ToArray(typeof(Bitmap)), pal, strFileName);
}
return true;
}
// ISerializable interface implementation
private AnimDoc(SerializationInfo seri, StreamingContext stmc) {
m_xbms = (XBitmapSet)seri.GetValue("Bitmaps", typeof(XBitmapSet));
m_stps = (StripSet)seri.GetValue("Strips", typeof(StripSet));
m_msFrameRate = seri.GetInt32("FrameRate");
try {
bool fHires = seri.GetBoolean("Hires");
if (fHires) {
m_nTileSize = 24;
} else {
m_nTileSize = 16;
}
} catch {
m_nTileSize = -1;
}
if (m_nTileSize == -1) {
m_nTileSize = seri.GetInt32("TileSize");
}
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
seri.AddValue("Bitmaps", m_xbms);
seri.AddValue("Strips", m_stps);
seri.AddValue("FrameRate", m_msFrameRate);
seri.AddValue("TileSize", m_nTileSize);
}
}
// This class is implemented to allow one Assembly read a .amx file written by a
// different Assembly -- what a concept!
public class RelaxedSerializationBinder : SerializationBinder {
public override Type BindToType(string strAssemblyName, string strTypeName) {
return Type.GetType(strTypeName);
}
}
}

BIN
AniMax/App.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

58
AniMax/AssemblyInfo.cs Normal file
View File

@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

394
AniMax/BitmapsForm.cs Normal file
View File

@ -0,0 +1,394 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
namespace SpiffCode
{
/// <summary>
/// Summary description for BitmapsForm.
/// </summary>
public class BitmapsForm : System.Windows.Forms.Form
{
private AnimDoc m_doc;
private XBitmapSet m_xbms;
private System.Windows.Forms.ListView lstv;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader columnHeader3;
private System.Windows.Forms.ColumnHeader columnHeader4;
private System.Windows.Forms.ColumnHeader columnHeader5;
private System.Windows.Forms.ContextMenu mnuListView;
private System.Windows.Forms.MenuItem mniViewList;
private System.Windows.Forms.MenuItem mniViewDetails;
private System.Windows.Forms.MenuItem mniViewThumbnails;
private System.Windows.Forms.MenuItem mniView;
private System.Windows.Forms.MenuItem mniAddBitmap;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.OpenFileDialog openFileDialog;
private System.Windows.Forms.MenuItem mniDelete;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem mniRename;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public BitmapsForm(AnimDoc doc)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
// My constructor code
Globals.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged);
m_doc = doc;
if (m_doc != null)
m_xbms = doc.XBitmapSet;
RefreshView();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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.openFileDialog = new System.Windows.Forms.OpenFileDialog();
this.mniViewList = new System.Windows.Forms.MenuItem();
this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
this.mniView = new System.Windows.Forms.MenuItem();
this.mniViewThumbnails = new System.Windows.Forms.MenuItem();
this.mniViewDetails = new System.Windows.Forms.MenuItem();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.columnHeader5 = new System.Windows.Forms.ColumnHeader();
this.columnHeader4 = new System.Windows.Forms.ColumnHeader();
this.mnuListView = new System.Windows.Forms.ContextMenu();
this.mniAddBitmap = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.mniDelete = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.lstv = new System.Windows.Forms.ListView();
this.mniRename = new System.Windows.Forms.MenuItem();
this.SuspendLayout();
//
// openFileDialog
//
this.openFileDialog.DefaultExt = "png";
this.openFileDialog.Filter = "All bitmaps (*.bmp,*.jpg,*.png,*.gif,*.tif)|*.png;*.tif;*.gif;*.jpg;*.bmp|All fil" +
"es|*.*";
this.openFileDialog.Multiselect = true;
this.openFileDialog.Title = "Add Bitmaps";
//
// mniViewList
//
this.mniViewList.Index = 0;
this.mniViewList.Text = "List";
this.mniViewList.Click += new System.EventHandler(this.mniViewList_Click);
//
// columnHeader3
//
this.columnHeader3.Text = "Height";
this.columnHeader3.Width = 44;
//
// columnHeader2
//
this.columnHeader2.Text = "Width";
this.columnHeader2.Width = 40;
//
// mniView
//
this.mniView.Index = 5;
this.mniView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniViewList,
this.mniViewThumbnails,
this.mniViewDetails});
this.mniView.Text = "View";
this.mniView.Popup += new System.EventHandler(this.mniView_Popup);
//
// mniViewThumbnails
//
this.mniViewThumbnails.Index = 1;
this.mniViewThumbnails.Text = "Thumbnails";
this.mniViewThumbnails.Click += new System.EventHandler(this.mniViewThumbnails_Click);
//
// mniViewDetails
//
this.mniViewDetails.Index = 2;
this.mniViewDetails.Text = "Details";
this.mniViewDetails.Click += new System.EventHandler(this.mniViewDetails_Click);
//
// columnHeader1
//
this.columnHeader1.Text = "Name";
this.columnHeader1.Width = 125;
//
// columnHeader5
//
this.columnHeader5.Text = "Date Modified";
this.columnHeader5.Width = 120;
//
// columnHeader4
//
this.columnHeader4.Text = "Size";
this.columnHeader4.Width = 46;
//
// mnuListView
//
this.mnuListView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniAddBitmap,
this.menuItem3,
this.mniDelete,
this.mniRename,
this.menuItem2,
this.mniView});
this.mnuListView.Popup += new System.EventHandler(this.mnuListView_Popup);
//
// mniAddBitmap
//
this.mniAddBitmap.Index = 0;
this.mniAddBitmap.Text = "Add Bitmap...";
this.mniAddBitmap.Click += new System.EventHandler(this.mniAddBitmap_Click);
//
// menuItem3
//
this.menuItem3.Index = 1;
this.menuItem3.Text = "-";
//
// mniDelete
//
this.mniDelete.Index = 2;
this.mniDelete.Shortcut = System.Windows.Forms.Shortcut.Del;
this.mniDelete.Text = "Delete";
this.mniDelete.Click += new System.EventHandler(this.mniDelete_Click);
//
// menuItem2
//
this.menuItem2.Index = 4;
this.menuItem2.Text = "-";
//
// lstv
//
this.lstv.AllowColumnReorder = true;
this.lstv.AllowDrop = true;
this.lstv.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2,
this.columnHeader3,
this.columnHeader4,
this.columnHeader5});
this.lstv.ContextMenu = this.mnuListView;
this.lstv.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstv.FullRowSelect = true;
this.lstv.LabelEdit = true;
this.lstv.Name = "lstv";
this.lstv.Size = new System.Drawing.Size(312, 389);
this.lstv.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.lstv.TabIndex = 0;
this.lstv.View = System.Windows.Forms.View.Details;
this.lstv.DragDrop += new System.Windows.Forms.DragEventHandler(this.lstv_DragDrop);
this.lstv.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lstv_AfterLabelEdit);
this.lstv.DragEnter += new System.Windows.Forms.DragEventHandler(this.lstv_DragEnter);
this.lstv.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.lstv_ItemDrag);
this.lstv.BeforeLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lstv_BeforeLabelEdit);
//
// mniRename
//
this.mniRename.Index = 3;
this.mniRename.Text = "Rename";
//
// BitmapsForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(312, 389);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.lstv});
this.Name = "BitmapsForm";
this.ShowInTaskbar = false;
this.Text = "Bitmaps";
this.ResumeLayout(false);
}
#endregion
private void OnActiveDocumentChanged(object obSender, EventArgs e) {
m_doc = Globals.ActiveDocument;
m_xbms = m_doc != null ? m_doc.XBitmapSet : null;
RefreshView();
}
private void mnuListView_Popup(object sender, System.EventArgs e) {
mniDelete.Enabled = lstv.SelectedItems.Count != 0;
}
private void mniViewDetails_Click(object sender, System.EventArgs e) {
lstv.View = View.Details;
}
private void mniViewThumbnails_Click(object sender, System.EventArgs e) {
lstv.View = View.LargeIcon;
}
private void mniViewList_Click(object sender, System.EventArgs e) {
lstv.View = View.List;
}
private void mniView_Popup(object sender, System.EventArgs e) {
mniViewList.Checked = false;
mniViewThumbnails.Checked = false;
mniViewDetails.Checked = false;
switch (lstv.View) {
case View.List:
mniViewList.Checked = true;
break;
case View.LargeIcon:
mniViewThumbnails.Checked = true;
break;
case View.Details:
mniViewDetails.Checked = true;
break;
}
}
private void lstv_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
bool fFileNamePresent = e.Data.GetDataPresent(DataFormats.FileDrop);
if (fFileNamePresent)
e.Effect = DragDropEffects.All;
else
e.Effect = DragDropEffects.None;
}
private void lstv_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
bool fFileNamePresent = e.Data.GetDataPresent(DataFormats.FileDrop);
if (fFileNamePresent) {
string[] astr = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string strT in astr) {
m_xbms.Add(strT);
}
m_doc.Dirty = true;
}
RefreshView();
}
private void RefreshView() {
lstv.Items.Clear();
// Prep LargeImageList
if (lstv.LargeImageList != null)
lstv.LargeImageList.Dispose();
lstv.LargeImageList = new ImageList();
lstv.LargeImageList.ColorDepth = ColorDepth.Depth32Bit;
lstv.LargeImageList.ImageSize = new Size(64, 64);
// Prep SmallImageList
if (lstv.SmallImageList != null)
lstv.SmallImageList.Dispose();
lstv.SmallImageList = new ImageList();
lstv.SmallImageList.ColorDepth = ColorDepth.Depth32Bit;
lstv.SmallImageList.ImageSize = new Size(16, 16);
int i = 0;
foreach (XBitmap xbm in m_xbms) {
ListViewItem lvi = lstv.Items.Add(Path.GetFileName(xbm.FileName));
lvi.Tag = xbm;
lvi.SubItems.Add(xbm.Width.ToString());
lvi.SubItems.Add(xbm.Height.ToString());
try {
FileInfo fili = new FileInfo(xbm.FileName);
lvi.SubItems.Add(fili.Length.ToString("#,##0"));
lvi.SubItems.Add(fili.LastWriteTime.ToShortDateString() + " " + fili.LastWriteTime.ToShortTimeString());
} catch (FileNotFoundException) {
// UNDONE: deal with this!
}
// Make a better thumbnail
Bitmap bmLarge = xbm.MakeThumbnail(64, 64, false);
lstv.LargeImageList.Images.Add(bmLarge);
lstv.SmallImageList.Images.Add(bmLarge);
lvi.ImageIndex = i++;
}
}
private void mniAddBitmap_Click(object sender, System.EventArgs e) {
if (openFileDialog.ShowDialog() != DialogResult.OK)
return;
foreach (string strFileName in openFileDialog.FileNames) {
m_xbms.Add(strFileName);
}
m_doc.Dirty = true;
RefreshView();
}
private void mniDelete_Click(object sender, System.EventArgs e) {
XBitmap xbm = (XBitmap)lstv.SelectedItems[0].Tag;
int i = m_xbms.IndexOf(xbm);
// UNDONE: undo
m_xbms.RemoveAt(i);
lstv.Items.Remove(lstv.SelectedItems[0]);
m_doc.Dirty = true;
}
private void lstv_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e) {
XBitmap[] axbm = new XBitmap[lstv.SelectedItems.Count];
for (int i = 0; i < lstv.SelectedItems.Count; i++)
axbm[i] = (XBitmap)lstv.SelectedItems[i].Tag;
DoDragDrop(axbm, DragDropEffects.All);
}
private void lstv_BeforeLabelEdit(object sender, System.Windows.Forms.LabelEditEventArgs e) {
// We do this so the user can press the del key while in label editing mode
// without it being intercepted by the context menu and used to delete the
// entire Strip
lstv.ContextMenu = null;
}
private void lstv_AfterLabelEdit(object sender, System.Windows.Forms.LabelEditEventArgs e) {
// Restore the context menu so the command keys, etc will work again
lstv.ContextMenu = mnuListView;
XBitmap xbm = (XBitmap)lstv.Items[e.Item].Tag;
// No change or an invalid change
if (e.Label == null || e.Label == "") {
e.CancelEdit = true;
return;
}
xbm.FileName = e.Label;
m_doc.Dirty = true;
}
}
}

Binary file not shown.

108
AniMax/BitmapsForm.resx Normal file
View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="openFileDialog.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>131, 17</value>
</data>
<data name="mnuListView.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="$this.Name">
<value>BitmapsForm</value>
</data>
</root>

282
AniMax/CombinerForm.cs Normal file
View File

@ -0,0 +1,282 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for CombinerForm.
/// </summary>
public class CombinerForm : System.Windows.Forms.Form
{
private Point m_ptOffset;
private FrameControl[] m_afrc = new FrameControl[20];
private Label[] m_albl = new Label[20];
private Strip[] m_astp = new Strip[20];
private int[] m_aifr = new int[20];
private int m_iSelected = 0;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private SpiffCode.FrameControl frc2;
private SpiffCode.FrameControl frc1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public CombinerForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
m_afrc[0] = frc1;
m_afrc[1] = frc2;
m_albl[0] = label1;
m_albl[1] = label2;
Globals.ActiveDocumentChanged += new EventHandler(OnInvalidatingChange);
Globals.ActiveFrameChanged += new EventHandler(OnInvalidatingChange);
Globals.PreviewScaleChanged += new EventHandler(OnInvalidatingChange);
Globals.GridChanged += new EventHandler(OnInvalidatingChange);
Globals.SideColorMappingOnChanged += new EventHandler(OnInvalidatingChange);
Globals.ShowOriginPointChanged += new EventHandler(OnInvalidatingChange);
Globals.ShowSpecialPointChanged += new EventHandler(OnInvalidatingChange);
((StripControl)Globals.StripControl).FrameOffsetChanged +=
new FrameOffsetEventHandler(OnFrameOffsetChanged);
Globals.FrameContentChanged += new EventHandler(OnInvalidatingChange);
m_ptOffset = new Point(0, 0);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.frc2 = new SpiffCode.FrameControl();
this.frc1 = new SpiffCode.FrameControl();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 80);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(80, 24);
this.label1.TabIndex = 2;
this.label1.Text = "<empty>";
this.label1.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// label2
//
this.label2.Location = new System.Drawing.Point(96, 80);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(80, 24);
this.label2.TabIndex = 3;
this.label2.Text = "<empty>";
this.label2.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// frc2
//
this.frc2.AllowDrop = true;
this.frc2.BorderColor = System.Drawing.Color.Black;
this.frc2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.frc2.Frame = null;
this.frc2.FrameIndex = 0;
this.frc2.Location = new System.Drawing.Point(96, 8);
this.frc2.Name = "frc2";
this.frc2.OffsetPoint = new System.Drawing.Point(0, 0);
this.frc2.Size = new System.Drawing.Size(80, 72);
this.frc2.Strip = null;
this.frc2.TabIndex = 4;
this.frc2.Text = "frameControl1";
this.frc2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.frc2_MouseDown);
//
// frc1
//
this.frc1.AllowDrop = true;
this.frc1.BorderColor = System.Drawing.Color.Black;
this.frc1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.frc1.Frame = null;
this.frc1.FrameIndex = 0;
this.frc1.Location = new System.Drawing.Point(8, 8);
this.frc1.Name = "frc1";
this.frc1.OffsetPoint = new System.Drawing.Point(0, 0);
this.frc1.Size = new System.Drawing.Size(80, 72);
this.frc1.Strip = null;
this.frc1.TabIndex = 5;
this.frc1.Text = "frameControl1";
this.frc1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.frc1_MouseDown);
//
// CombinerForm
//
this.AutoScale = false;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(172)), ((System.Byte)(235)), ((System.Byte)(172)));
this.ClientSize = new System.Drawing.Size(280, 302);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.frc1,
this.frc2,
this.label2,
this.label1});
this.Name = "CombinerForm";
this.Text = "Combiner";
this.ResumeLayout(false);
}
#endregion
private void OnInvalidatingChange(object obSender, EventArgs e) {
SelectStrip(m_iSelected, Globals.ActiveStrip, Globals.ActiveFrame);
if (Globals.ActiveStrip != null && Globals.ActiveStrip.Count != 0)
m_afrc[m_iSelected].Frame = Globals.ActiveStrip[Globals.ActiveFrame];
}
public void OnFrameOffsetChanged(object obSender, FrameOffsetEventArgs e) {
m_ptOffset.X = e.X;
m_ptOffset.Y = e.Y;
frc1.OffsetPoint = m_ptOffset;
frc2.OffsetPoint = m_ptOffset;
Invalidate();
}
private void RefreshView() {
Invalidate();
}
override protected void OnResize(EventArgs e) {
Invalidate();
base.OnResize(e);
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) {
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
if (Globals.ActiveStrip == null || Globals.ActiveStrip.Count == 0) {
e.Graphics.FillRectangle(new SolidBrush(BackColor), e.ClipRectangle);
return;
}
Frame.DrawArgs drwa = new Frame.DrawArgs();
drwa.clrBackground = BackColor;
drwa.fDrawBackground = true;
drwa.fMapSideColors = Globals.SideColorMappingOn;
drwa.fShowGrid = Globals.GridOn;
drwa.cxGrid = Globals.GridWidth;
drwa.cyGrid = Globals.GridHeight;
drwa.fShowOrigin = Globals.ShowOriginPoint;
drwa.fShowSpecialPoint = Globals.ShowSpecialPoint;
drwa.nScale = Globals.PreviewScale;
Rectangle rcClient = new Rectangle(0, 0, ClientRectangle.Width, ClientRectangle.Height);
Graphics g = e.Graphics;
int xCenter = rcClient.Width / 2;
int yCenter = rcClient.Height / 2;
int cxT = ((rcClient.Width + drwa.nScale - 1) / drwa.nScale) + 2;
int cyT = ((rcClient.Height + drwa.nScale - 1) / drwa.nScale) + 2;
int xCenterT = cxT / 2;
int yCenterT = cyT / 2;
// Create a temporary bitmap for compositing the grid, frames, origin indicator, etc into
using (Bitmap bmT = new Bitmap(cxT, cyT)) {
Point ptSpecial = new Point(0, 0);
for (int i = 0; i < m_astp.Length; i++) {
// Draw the frame and its indicators (grid, center point, special point, etc)
Strip stp = m_astp[i];
if (stp == null)
continue;
Frame fr = stp[m_aifr[i]];
Point ptOffset = new Point(m_ptOffset.X + ptSpecial.X, m_ptOffset.Y + ptSpecial.Y);
fr.DrawUnscaled(bmT, cxT, cyT, drwa, ptOffset);
drwa.fDrawBackground = false;
drwa.fShowGrid = false;
ptSpecial = fr.SpecialPoint;
}
// Force a nice simple fast old-school stretchblt
InterpolationMode imOld = g.InterpolationMode;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
// NOTE: _without_ this the first row and column are only scaled by half!
PixelOffsetMode pomOld = g.PixelOffsetMode;
g.PixelOffsetMode = PixelOffsetMode.Half;
// StretchBlt the temporary composite to the passed-in Graphic
g.DrawImage(bmT, rcClient.Left - ((xCenterT * drwa.nScale) - xCenter),
rcClient.Top - ((yCenterT * drwa.nScale) - yCenter),
cxT * drwa.nScale, cyT * drwa.nScale);
// Restore the Graphics' state
g.PixelOffsetMode = pomOld;
g.InterpolationMode = imOld;
}
}
private void SelectStrip(int i, Strip stp, int ifr) {
// Deselect any selected strip's FrameControl
for (int j = 0; j < m_astp.Length; j++) {
if (m_afrc[j] != null)
m_afrc[j].BorderColor = Color.Black;
}
m_iSelected = i;
m_afrc[m_iSelected].BorderColor = Color.Red;
m_astp[m_iSelected] = stp;
m_aifr[m_iSelected] = stp == null ? 0 : stp.ActiveFrame;
m_afrc[m_iSelected].Frame = stp == null ? null : stp.Count == 0 ? null : stp[stp.ActiveFrame];
m_albl[m_iSelected].Text = stp == null ? "<empty>" : stp.Name;
Invalidate();
}
private void frc1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
SelectStrip(0, m_astp[0], m_aifr[0]);
Globals.ActiveStrip = m_astp[m_iSelected];
Globals.ActiveFrame = m_aifr[m_iSelected];
}
private void frc2_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
SelectStrip(1, m_astp[1], m_aifr[1]);
Globals.ActiveStrip = m_astp[m_iSelected];
Globals.ActiveFrame = m_aifr[m_iSelected];
}
}
}

Binary file not shown.

102
AniMax/CombinerForm.resx Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.Name">
<value>CombinerForm</value>
</data>
</root>

348
AniMax/Frame.cs Normal file
View File

@ -0,0 +1,348 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
using System.Collections;
namespace SpiffCode
{
/// <summary>
/// Summary description for Frame.
/// </summary>
[Serializable]
public class Frame : ISerializable, ICloneable
{
private int m_cHold = 0;
private Point m_ptSpecial;
private BitmapPlacerList m_plcl;
public Frame() {
m_plcl = new BitmapPlacerList();
}
public int HoldCount {
set {
m_cHold = value;
}
get {
return m_cHold;
}
}
public Point SpecialPoint {
set {
m_ptSpecial = value;
}
get {
return m_ptSpecial;
}
}
public BitmapPlacerList BitmapPlacers {
get {
return m_plcl;
}
}
// Deep copy
public object Clone() {
Frame fr = new Frame();
fr.m_cHold = m_cHold;
fr.m_ptSpecial = new Point(m_ptSpecial.X, m_ptSpecial.Y);
fr.m_plcl = (BitmapPlacerList)m_plcl.Clone();
return fr;
}
public struct DrawArgs { // drwa
public int nScale;
public bool fShowGrid;
public bool fShowOrigin;
public bool fShowSpecialPoint;
public bool fMapSideColors;
public bool fDrawBackground;
public Color clrBackground;
public int cxGrid;
public int cyGrid;
}
public void Draw(Graphics g, Rectangle rcClient, DrawArgs drwa, Point ptOffset) {
int xCenter = rcClient.Width / 2;
int yCenter = rcClient.Height / 2;
int cxT = ((rcClient.Width + drwa.nScale - 1) / drwa.nScale) + 2;
int cyT = ((rcClient.Height + drwa.nScale - 1) / drwa.nScale) + 2;
int xCenterT = cxT / 2;
int yCenterT = cyT / 2;
// NOTE: these 'using' statements (a 'shortcut' for calling .Dispose()) are
// absolutely necessary or we chew up all virtual memory while animating
// Create a temporary bitmap for compositing the grid, frames, origin indicator, etc into
using (Bitmap bmT = new Bitmap(cxT, cyT)) {
// Draw the frame and its indicators (grid, center point, special point, etc)
DrawUnscaled(bmT, cxT, cyT, drwa, ptOffset);
// Force a nice simple fast old-school stretchblt
InterpolationMode imOld = g.InterpolationMode;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
// NOTE: _without_ this the first row and column are only scaled by half!
PixelOffsetMode pomOld = g.PixelOffsetMode;
g.PixelOffsetMode = PixelOffsetMode.Half;
// StretchBlt the temporary composite to the passed-in Graphic
g.DrawImage(bmT, rcClient.Left - ((xCenterT * drwa.nScale) - xCenter),
rcClient.Top - ((yCenterT * drwa.nScale) - yCenter),
cxT * drwa.nScale, cyT * drwa.nScale);
g.PixelOffsetMode = pomOld;
g.InterpolationMode = imOld;
}
}
public void DrawUnscaled(Bitmap bmDst, int cx, int cy, DrawArgs drwa, Point ptOffset) {
Graphics gDst = Graphics.FromImage(bmDst);
int xCenter = cx / 2;
int yCenter = cy / 2;
// Draw background (if enabled)
if (drwa.fDrawBackground)
gDst.Clear(drwa.clrBackground);
#if false
// Draw background bitmap, if any
if (m_bmBackground != null)
gT.DrawImage(m_bmBackground, xCenter - (m_bmBackground.Width / 2) + m_ptBackgroundOffset.X,
yCenter - (m_bmBackground.Height / 2) + m_ptBackgroundOffset.Y,
m_bmBackground.Width, m_bmBackground.Height);
#endif
// Draw grid (if enabled)
// UNDONE: use alpha to draw grid (e.g., brighten or darken)
if (drwa.fShowGrid) {
int cxGrid = drwa.cxGrid;
int cyGrid = drwa.cyGrid;
// Brush br = new SolidBrush(Color.FromKnownColor(KnownColor.LightGray));
Brush br = new SolidBrush(Color.FromArgb(256 / 3, 255, 255, 255));
for (int x = (xCenter + ptOffset.X) % cxGrid; x < cx; x += cxGrid)
gDst.FillRectangle(br, x, 0, 1, cy);
for (int y = (yCenter + ptOffset.Y) % cyGrid; y < cy; y += cyGrid)
gDst.FillRectangle(br, 0, y, cx, 1);
}
BitmapData bmdDst = bmDst.LockBits(
new Rectangle(0, 0, bmDst.Width, bmDst.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
// Draw bitmaps from bottom up
for (int i = BitmapPlacers.Count - 1; i >= 0; i--) {
BitmapPlacer plc = BitmapPlacers[i];
XBitmap xbm = plc.XBitmap;
xbm.SuperBlt(0, 0, bmdDst,
xCenter - plc.X + ptOffset.X,
yCenter - plc.Y + ptOffset.Y,
xbm.Bitmap.Width, xbm.Bitmap.Height,
drwa.fMapSideColors);
}
bmDst.UnlockBits(bmdDst);
// Draw origin point (if enabled)
if (drwa.fShowOrigin) {
// This is really weird but if we don't do our own clipping then SetPixel will
// raise an exception!
int x = xCenter + ptOffset.X;
int y = yCenter + ptOffset.Y;
if (x >= 0 && y >= 0 && x < bmDst.Width && y < bmDst.Height)
bmDst.SetPixel(x, y, Color.FromKnownColor(KnownColor.Orange));
}
// Draw special point (if enabled)
if (drwa.fShowSpecialPoint) {
// This is really weird but if we don't do our own clipping then SetPixel will
// raise an exception!
int x = xCenter + ptOffset.X + m_ptSpecial.X;
int y = yCenter + ptOffset.Y + m_ptSpecial.Y;
if (x >= 0 && y >= 0 && x < bmDst.Width && y < bmDst.Height)
bmDst.SetPixel(x, y, Color.FromArgb(0, 255, 0));
}
gDst.Dispose();
}
// ISerializable interface implementation
private Frame(SerializationInfo seri, StreamingContext stmc) : this() {
try {
m_plcl = (BitmapPlacerList)seri.GetValue("BitmapPlacers", typeof(BitmapPlacerList));
} catch {
m_plcl = new BitmapPlacerList();
m_plcl.Add(new BitmapPlacer());
m_plcl[0].X = seri.GetInt32("BitmapX");
m_plcl[0].Y = seri.GetInt32("BitmapY");
m_plcl[0].XBitmap = (XBitmap)seri.GetValue("XBitmap", typeof(XBitmap));
}
try {
m_cHold = seri.GetInt32("HoldCount");
} catch {}
try {
m_ptSpecial = (Point)seri.GetValue("SpecialPoint", typeof(Point));
} catch {}
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
seri.AddValue("BitmapPlacers", m_plcl);
seri.AddValue("HoldCount", m_cHold);
seri.AddValue("SpecialPoint", m_ptSpecial);
}
}
[Serializable]
public class BitmapPlacerList : CollectionBase, ISerializable, ICloneable {
public BitmapPlacerList() {
}
// Automatically expand the collection to include as many
// elements as the caller is expecting.
public BitmapPlacer this[int i] {
get {
// while (i >= InnerList.Count)
// InnerList.Add(new BitmapPlacer());
return (BitmapPlacer)InnerList[i];
}
set {
// while (i >= InnerList.Count)
// InnerList.Add(new BitmapPlacer());
InnerList[i] = value;
}
}
public int Add(BitmapPlacer plc) {
return ((IList)this).Add(plc);
}
public void Insert(int iplc, BitmapPlacer plc) {
InnerList.Insert(iplc, plc);
}
public int Index(BitmapPlacer plc) {
for (int i = 0; i < InnerList.Count; i++) {
if (plc == (BitmapPlacer)InnerList[i]) {
return i;
}
}
return -1;
}
// Deep copy
public object Clone() {
BitmapPlacerList plcl = new BitmapPlacerList();
for (int i = 0; i < InnerList.Count; i++) {
plcl.Add((BitmapPlacer)((BitmapPlacer)InnerList[i]).Clone());
}
return plcl;
}
// ISerializable interface implementation
private BitmapPlacerList(SerializationInfo seri, StreamingContext stmc) : this() {
for (int i = 0; i < seri.MemberCount; i++) {
BitmapPlacer plc = (BitmapPlacer)seri.GetValue(i.ToString(), typeof(BitmapPlacer));
InnerList.Add(plc);
}
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
int i = 0;
foreach (BitmapPlacer plc in InnerList) {
seri.AddValue(i.ToString(), plc);
i++;
}
}
}
[Serializable]
public class BitmapPlacer : ISerializable, ICloneable {
private Point m_pt;
private XBitmap m_xbm;
public BitmapPlacer() {
}
public Point Point {
get {
return m_pt;
}
set {
m_pt = value;
}
}
public int X {
get {
return m_pt.X;
}
set {
m_pt.X = value;
}
}
public int Y {
get {
return m_pt.Y;
}
set {
m_pt.Y = value;
}
}
public XBitmap XBitmap {
get {
return m_xbm;
}
set {
m_xbm = value;
}
}
public object Clone() {
BitmapPlacer plc = new BitmapPlacer();
plc.m_pt = new Point(m_pt.X, m_pt.Y);
plc.m_xbm = m_xbm.Clone();
return plc;
}
private BitmapPlacer(SerializationInfo seri, StreamingContext stmc) : this() {
m_pt = (Point)seri.GetValue("Point", typeof(Point));
m_xbm = (XBitmap)seri.GetValue("XBitmap", typeof(XBitmap));
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
seri.AddValue("Point", m_pt);
seri.AddValue("XBitmap", XBitmap);
}
}
}

129
AniMax/FrameControl.cs Normal file
View File

@ -0,0 +1,129 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for FrameControl.
/// </summary>
public class FrameControl : System.Windows.Forms.Control
{
private Point m_ptOffset;
private Strip m_stp;
private Frame m_fr;
private int m_ifr;
private int m_nScale = 2;
private BorderStyle m_bdrs = BorderStyle.None;
private Color m_clrBorder = Color.Black;
public FrameControl()
{
m_ptOffset = new Point(0, 0);
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) {
}
protected override void OnPaint(PaintEventArgs pe)
{
if (m_fr == null) {
pe.Graphics.FillRectangle(new SolidBrush(BackColor), pe.ClipRectangle);
} else {
Frame.DrawArgs drwa = new Frame.DrawArgs();
drwa.clrBackground = BackColor;
drwa.fDrawBackground = true;
drwa.fMapSideColors = Globals.SideColorMappingOn;
drwa.fShowGrid = false;
drwa.fShowOrigin = Globals.ShowOriginPoint;
drwa.fShowSpecialPoint = Globals.ShowSpecialPoint;
drwa.nScale = m_nScale;
m_fr.Draw(pe.Graphics, ClientRectangle, drwa, m_ptOffset);
}
switch (m_bdrs) {
case BorderStyle.FixedSingle:
Rectangle rc = ClientRectangle;
rc.Width--;
rc.Height--;
pe.Graphics.DrawRectangle(new Pen(m_clrBorder), rc);
break;
case BorderStyle.Fixed3D:
ControlPaint.DrawBorder3D(pe.Graphics, ClientRectangle, Border3DStyle.Raised);
break;
}
// Calling the base class OnPaint
// base.OnPaint(pe);
}
public Strip Strip {
get {
return m_stp;
}
set {
m_stp = value;
Invalidate();
}
}
public Frame Frame {
get {
return m_fr;
}
set {
m_fr = value;
Invalidate();
}
}
public BorderStyle BorderStyle {
get {
return m_bdrs;
}
set {
m_bdrs = value;
Invalidate();
}
}
public Color BorderColor {
get {
return m_clrBorder;
}
set {
m_clrBorder = value;
if (m_bdrs != BorderStyle.None)
Invalidate();
}
}
public int FrameIndex {
get {
return m_ifr;
}
set {
m_ifr = value;
if (m_stp != null) {
m_fr = m_stp[m_ifr];
Invalidate();
}
}
}
public Point OffsetPoint {
get {
return m_ptOffset;
}
set {
m_ptOffset = value;
Invalidate();
}
}
}
}

Binary file not shown.

42
AniMax/FrameControl.resx Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

365
AniMax/Globals.cs Normal file
View File

@ -0,0 +1,365 @@
using System;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
namespace SpiffCode
{
/// <summary>
/// Summary description for Globals.
/// </summary>
public class Globals
{
private static AnimDoc s_doc;
private static Strip s_stpActive = null;
private static int s_ifrActive = 0;
private static int s_cfrActive = 1;
private static int s_msFrameRate = 80;
private static int s_nPreviewScale = 4;
private static int s_nStripScale = 1;
private static bool s_fSideColorMappingOn = true;
private static bool s_fGridOn = true;
private static bool s_fShowOriginPoint = false;
private static bool s_fShowSpecialPoint = false;
private static AnimDoc s_docNull;
private static Control s_ctlStrip;
private static Control s_ctlPreview;
private static Form s_frmStrips;
private static Form s_frmStrip;
private static Form s_frmMain;
private static Cursor s_crsrHand;
private static Cursor s_crsrGrab;
private static int s_nTileSize = 32;
private static int s_cxGrid = 32;
private static int s_cyGrid = 32;
public static event EventHandler ActiveDocumentChanged;
public static AnimDoc ActiveDocument {
get {
return s_doc;
}
set {
// Keep track of the ActiveDoc's ActiveStrip
if (s_doc != null)
s_doc.ActiveStripChanged -= new EventHandler(OnActiveStripChanged);
s_doc = value;
if (ActiveDocumentChanged != null)
ActiveDocumentChanged(null, EventArgs.Empty);
ActiveStrip = s_doc == null ? null : s_doc.ActiveStrip;
if (s_doc != null)
s_doc.ActiveStripChanged += new EventHandler(OnActiveStripChanged);
}
}
private static void OnActiveStripChanged(object obSender, EventArgs e) {
ActiveStrip = s_doc.ActiveStrip;
}
public static event EventHandler ActiveStripChanged;
public static Strip ActiveStrip {
get {
return s_stpActive;
}
set {
// Keep track of the ActiveStrip's ActiveFrame
if (s_stpActive != null) {
s_stpActive.ActiveFrameChanged -= new EventHandler(OnActiveFrameChanged);
s_stpActive.ActiveFrameCountChanged -= new EventHandler(OnActiveFrameCountChanged);
}
s_stpActive = value;
if (ActiveStripChanged != null)
ActiveStripChanged(null, EventArgs.Empty);
ActiveFrame = s_stpActive == null ? 0 : s_stpActive.ActiveFrame;
if (s_stpActive != null) {
s_stpActive.ActiveFrameChanged += new EventHandler(OnActiveFrameChanged);
s_stpActive.ActiveFrameCountChanged += new EventHandler(OnActiveFrameCountChanged);
}
}
}
private static void OnActiveFrameChanged(object obSender, EventArgs e) {
ActiveFrame = s_stpActive.ActiveFrame;
}
private static void OnActiveFrameCountChanged(object obSender, EventArgs e) {
ActiveFrameCount = s_stpActive.ActiveFrameCount;
}
public static event EventHandler ActiveFrameChanged;
public static int ActiveFrame {
get {
return s_ifrActive;
}
set {
s_ifrActive = value;
if (ActiveFrameChanged != null)
ActiveFrameChanged(null, EventArgs.Empty);
}
}
public static event EventHandler ActiveFrameCountChanged;
public static int ActiveFrameCount {
get {
return s_cfrActive;
}
set {
s_cfrActive = value;
if (ActiveFrameCountChanged != null)
ActiveFrameCountChanged(null, EventArgs.Empty);
}
}
public static int FrameRate {
get {
return s_msFrameRate;
}
set {
s_msFrameRate = value;
}
}
public static event EventHandler GridChanged;
public static bool GridOn {
get {
return s_fGridOn;
}
set {
s_fGridOn = value;
if (GridChanged != null)
GridChanged(null, EventArgs.Empty);
}
}
public static int GridWidth {
get {
return s_cxGrid;
}
set {
s_cxGrid = value;
if (GridChanged != null)
GridChanged(null, EventArgs.Empty);
}
}
public static int GridHeight {
get {
return s_cyGrid;
}
set {
s_cyGrid = value;
if (GridChanged != null)
GridChanged(null, EventArgs.Empty);
}
}
public static event EventHandler TileSizeChanged;
public static int TileSize {
set {
s_nTileSize = value;
GridWidth = s_nTileSize;
GridHeight = s_nTileSize;
if (s_nTileSize < 24) {
StripScale = 2;
} else {
StripScale = 1;
}
if (TileSizeChanged != null)
TileSizeChanged(null, EventArgs.Empty);
}
get {
return s_nTileSize;
}
}
public static Cursor HandCursor {
get {
if (s_crsrHand == null) {
Assembly ass = Assembly.GetAssembly(typeof(Globals));
// string[] astr = ass.GetManifestResourceNames();
Stream stm = ass.GetManifestResourceStream("SpiffCode.Resources.hand.cur");
s_crsrHand = new Cursor(stm);
stm.Close();
}
return s_crsrHand;
}
}
public static Cursor GrabCursor {
get {
if (s_crsrGrab == null) {
Assembly ass = Assembly.GetAssembly(typeof(Globals));
Stream stm = ass.GetManifestResourceStream("SpiffCode.Resources.grab.cur");
s_crsrGrab = new Cursor(stm);
stm.Close();
}
return s_crsrGrab;
}
}
public static event EventHandler SideColorMappingOnChanged;
public static bool SideColorMappingOn {
get {
return s_fSideColorMappingOn;
}
set {
s_fSideColorMappingOn = value;
if (SideColorMappingOnChanged != null)
SideColorMappingOnChanged(null, EventArgs.Empty);
}
}
public static event EventHandler ShowOriginPointChanged;
public static bool ShowOriginPoint {
get {
return s_fShowOriginPoint;
}
set {
s_fShowOriginPoint = value;
if (ShowOriginPointChanged != null)
ShowOriginPointChanged(null, EventArgs.Empty);
}
}
public static event EventHandler ShowSpecialPointChanged;
public static bool ShowSpecialPoint {
get {
return s_fShowSpecialPoint;
}
set {
s_fShowSpecialPoint = value;
if (ShowSpecialPointChanged != null)
ShowSpecialPointChanged(null, EventArgs.Empty);
}
}
public static event EventHandler PreviewScaleChanged;
public static int PreviewScale {
get {
return s_nPreviewScale;
}
set {
s_nPreviewScale = value;
if (PreviewScaleChanged != null)
PreviewScaleChanged(null, EventArgs.Empty);
}
}
public static event EventHandler StripScaleChanged;
public static int StripScale {
get {
return s_nStripScale;
}
set {
s_nStripScale = value;
if (StripScaleChanged != null)
StripScaleChanged(null, EventArgs.Empty);
}
}
public static AnimDoc NullDocument {
get {
return s_docNull;
}
set {
s_docNull = value;
}
}
public static Control StripControl {
get {
return s_ctlStrip;
}
set {
s_ctlStrip = value;
}
}
public static Control PreviewControl {
get {
return s_ctlPreview;
}
set {
s_ctlPreview = value;
}
}
public static Form StripsForm {
get {
return s_frmStrips;
}
set {
s_frmStrips = value;
}
}
public static Form StripForm {
get {
return s_frmStrip;
}
set {
s_frmStrip = value;
}
}
public static Form MainForm {
get {
return s_frmMain;
}
set {
s_frmMain = value;
}
}
public static event KeyPressEventHandler KeyPress;
// UNDONE: this will send to every handler even after one has handled
// the event.
public static void OnKeyPress(Object sender, KeyPressEventArgs e) {
if (KeyPress != null)
KeyPress(sender, e);
}
public static event KeyEventHandler KeyDown;
public static void OnKeyDown(Object sender, KeyEventArgs e) {
if (KeyDown != null)
KeyDown(sender, e);
}
public static event KeyEventHandler KeyUp;
public static void OnKeyUp(Object sender, KeyEventArgs e) {
if (KeyUp != null)
KeyUp(sender, e);
}
public static event EventHandler FrameContentChanged;
// UNDONE: this will send to every handler even after one has handled
// the event.
public static void OnFrameContentChanged(Object sender, EventArgs e) {
if (FrameContentChanged != null)
FrameContentChanged(sender, e);
}
}
}

814
AniMax/MainForm.cs Normal file
View File

@ -0,0 +1,814 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Crownwood.Magic.Docking;
using Crownwood.Magic.Common;
using System.Diagnostics;
using System.IO;
using System.Drawing.Imaging;
namespace SpiffCode
{
/// <summary>
/// Summary description for MainForm.
/// </summary>
public class MainForm : System.Windows.Forms.Form
{
private string gstrAniMax = "AniMax";
private PreviewPanel m_ctlPreviewPanel;
private Form m_frmStrips;
private Content m_tntStrips;
private Form m_frmBitmaps;
private Content m_tntBitmaps;
private StripForm m_frmFrames;
private Content m_tntFrames;
private Form m_frmCombiner;
private Content m_tntCombiner;
private DockingManager m_dkm;
private AnimDoc m_doc;
private WindowContent m_wcStrips;
private System.Windows.Forms.MenuItem mniFile;
private System.Windows.Forms.MenuItem menuItem9;
private System.Windows.Forms.MenuItem menuItem10;
private System.Windows.Forms.MenuItem menuItem11;
private System.Windows.Forms.MenuItem menuItem12;
private System.Windows.Forms.MenuItem menuItem13;
private System.Windows.Forms.MenuItem menuItem14;
private System.Windows.Forms.MenuItem mniNew;
private System.Windows.Forms.MenuItem mniOpen;
private System.Windows.Forms.MenuItem mniSave;
private System.Windows.Forms.MenuItem mniExit;
private System.Windows.Forms.MenuItem mniSaveAs;
private System.Windows.Forms.MenuItem mniClose;
private System.Windows.Forms.MenuItem mniImport;
private System.Windows.Forms.MenuItem mniExport;
private System.Windows.Forms.MainMenu mnuMain;
private System.Windows.Forms.SaveFileDialog saveFileDialog;
private System.Windows.Forms.OpenFileDialog openFileDialog;
private System.Windows.Forms.MenuItem mniViewBitmaps;
private System.Windows.Forms.MenuItem mniView;
private System.Windows.Forms.MenuItem mniViewStrips;
private System.Windows.Forms.MenuItem mniViewTracks;
private System.Windows.Forms.MenuItem mniTools;
private System.Windows.Forms.MenuItem mniOptions;
private System.Windows.Forms.OpenFileDialog importFileDialog;
private System.Windows.Forms.MenuItem mniRepairSideColors;
private System.Windows.Forms.MenuItem mniNormalizeBitmaps;
private System.Windows.Forms.MenuItem mniUndo;
private System.Windows.Forms.MenuItem mniEdit;
private System.Windows.Forms.MenuItem mniHelp;
private System.Windows.Forms.MenuItem mniViewCombiner;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem mniHelpAbout;
private System.Windows.Forms.MenuItem mniWallPreview;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem mniReplaceColors;
private System.ComponentModel.IContainer components = null;
public MainForm(string strOpenFileName)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
m_dkm = new DockingManager(this, VisualStyle.IDE);
Globals.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged);
m_doc = Globals.ActiveDocument;
Globals.MainForm = this;
// Create all the "Contents" used to display the various animation components
m_ctlPreviewPanel = new PreviewPanel(m_doc);
Globals.PreviewControl = m_ctlPreviewPanel.PreviewControl;
m_ctlPreviewPanel.Dock = DockStyle.Fill;
Controls.Add(m_ctlPreviewPanel);
m_dkm.InnerControl = m_ctlPreviewPanel;
m_frmStrips = new StripsForm(m_doc);
Globals.StripsForm = m_frmStrips;
m_tntStrips = m_dkm.Contents.Add(m_frmStrips, m_frmStrips.Text);
m_tntStrips.DisplaySize = new Size(ClientSize.Width / 4, ClientSize.Height / 2);
m_wcStrips = m_dkm.AddContentWithState(m_tntStrips, State.DockLeft);
m_frmBitmaps = new BitmapsForm(m_doc);
m_tntBitmaps = m_dkm.Contents.Add(m_frmBitmaps, m_frmBitmaps.Text);
m_tntBitmaps.DisplaySize = new Size(ClientSize.Width / 4, ClientSize.Height / 2);
m_dkm.AddContentWithState(m_tntBitmaps, State.DockTop);
// Add the Bitmaps form to the StripForm's Zone
m_dkm.AddContentToZone(m_tntBitmaps, m_wcStrips.ParentZone, 1);
m_frmFrames = new StripForm(m_doc);
Globals.StripForm = m_frmFrames;
m_tntFrames = m_dkm.Contents.Add(m_frmFrames, m_frmFrames.Text);
m_frmFrames.Content = m_tntFrames;
int cx = ClientSize.Width - (ClientSize.Width / 4);
int cy = ClientSize.Height / 3;
m_tntFrames.DisplaySize = new Size(cx, cy);
m_dkm.AddContentWithState(m_tntFrames, State.DockBottom);
m_frmCombiner = new CombinerForm();
m_tntCombiner = m_dkm.Contents.Add(m_frmCombiner, m_frmCombiner.Text);
m_tntCombiner.DisplaySize = new Size(ClientSize.Width / 2, ClientSize.Height / 2);
// m_dkm.AddContentWithState(m_tntCombiner, State.Floating);
// m_dkm.HideContent(m_tntCombiner);
// Do a little wiring
((StripControl)Globals.StripControl).FrameOffsetChanged +=
new FrameOffsetEventHandler(((PreviewControl)Globals.PreviewControl).OnFrameOffsetChanged);
((PreviewControl)Globals.PreviewControl).FrameOffsetChanged +=
new FrameOffsetEventHandler(((StripControl)Globals.StripControl).OnFrameOffsetChanged);
// We always have a document around
if (strOpenFileName == null)
NewDocument();
else
OpenDocument(strOpenFileName);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (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()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(MainForm));
this.mniFile = new System.Windows.Forms.MenuItem();
this.mniNew = new System.Windows.Forms.MenuItem();
this.mniOpen = new System.Windows.Forms.MenuItem();
this.mniClose = new System.Windows.Forms.MenuItem();
this.menuItem9 = new System.Windows.Forms.MenuItem();
this.mniSave = new System.Windows.Forms.MenuItem();
this.mniSaveAs = new System.Windows.Forms.MenuItem();
this.menuItem10 = new System.Windows.Forms.MenuItem();
this.mniImport = new System.Windows.Forms.MenuItem();
this.mniExport = new System.Windows.Forms.MenuItem();
this.menuItem14 = new System.Windows.Forms.MenuItem();
this.menuItem13 = new System.Windows.Forms.MenuItem();
this.menuItem12 = new System.Windows.Forms.MenuItem();
this.menuItem11 = new System.Windows.Forms.MenuItem();
this.mniExit = new System.Windows.Forms.MenuItem();
this.mniOptions = new System.Windows.Forms.MenuItem();
this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
this.mniViewTracks = new System.Windows.Forms.MenuItem();
this.mniViewBitmaps = new System.Windows.Forms.MenuItem();
this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
this.mniViewStrips = new System.Windows.Forms.MenuItem();
this.mnuMain = new System.Windows.Forms.MainMenu();
this.mniEdit = new System.Windows.Forms.MenuItem();
this.mniUndo = new System.Windows.Forms.MenuItem();
this.mniView = new System.Windows.Forms.MenuItem();
this.mniViewCombiner = new System.Windows.Forms.MenuItem();
this.mniTools = new System.Windows.Forms.MenuItem();
this.mniNormalizeBitmaps = new System.Windows.Forms.MenuItem();
this.mniRepairSideColors = new System.Windows.Forms.MenuItem();
this.mniWallPreview = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.mniHelp = new System.Windows.Forms.MenuItem();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.mniHelpAbout = new System.Windows.Forms.MenuItem();
this.importFileDialog = new System.Windows.Forms.OpenFileDialog();
this.mniReplaceColors = new System.Windows.Forms.MenuItem();
//
// mniFile
//
this.mniFile.Index = 0;
this.mniFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniNew,
this.mniOpen,
this.mniClose,
this.menuItem9,
this.mniSave,
this.mniSaveAs,
this.menuItem10,
this.mniImport,
this.mniExport,
this.menuItem14,
this.menuItem13,
this.menuItem12,
this.menuItem11,
this.mniExit});
this.mniFile.Text = "&File";
this.mniFile.Popup += new System.EventHandler(this.mniFile_Popup);
//
// mniNew
//
this.mniNew.Index = 0;
this.mniNew.Shortcut = System.Windows.Forms.Shortcut.CtrlN;
this.mniNew.Text = "&New";
this.mniNew.Click += new System.EventHandler(this.mniNew_Click);
//
// mniOpen
//
this.mniOpen.Index = 1;
this.mniOpen.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
this.mniOpen.Text = "&Open...";
this.mniOpen.Click += new System.EventHandler(this.mniOpen_Click);
//
// mniClose
//
this.mniClose.Index = 2;
this.mniClose.Text = "&Close";
this.mniClose.Click += new System.EventHandler(this.mniClose_Click);
//
// menuItem9
//
this.menuItem9.Index = 3;
this.menuItem9.Text = "-";
//
// mniSave
//
this.mniSave.Index = 4;
this.mniSave.Shortcut = System.Windows.Forms.Shortcut.CtrlS;
this.mniSave.Text = "&Save";
this.mniSave.Click += new System.EventHandler(this.mniSave_Click);
//
// mniSaveAs
//
this.mniSaveAs.Index = 5;
this.mniSaveAs.Text = "Save &As...";
this.mniSaveAs.Click += new System.EventHandler(this.mniSaveAs_Click);
//
// menuItem10
//
this.menuItem10.Index = 6;
this.menuItem10.Text = "-";
//
// mniImport
//
this.mniImport.Index = 7;
this.mniImport.Text = "&Import...";
this.mniImport.Click += new System.EventHandler(this.mniImport_Click);
//
// mniExport
//
this.mniExport.Enabled = false;
this.mniExport.Index = 8;
this.mniExport.Text = "&Export...";
//
// menuItem14
//
this.menuItem14.Index = 9;
this.menuItem14.Text = "-";
//
// menuItem13
//
this.menuItem13.Enabled = false;
this.menuItem13.Index = 10;
this.menuItem13.Text = "Recent Strips";
//
// menuItem12
//
this.menuItem12.Enabled = false;
this.menuItem12.Index = 11;
this.menuItem12.Text = "Recent Files";
//
// menuItem11
//
this.menuItem11.Index = 12;
this.menuItem11.Text = "-";
//
// mniExit
//
this.mniExit.Index = 13;
this.mniExit.Text = "E&xit";
//
// mniOptions
//
this.mniOptions.Index = 5;
this.mniOptions.Text = "&Options...";
this.mniOptions.Click += new System.EventHandler(this.mniOptions_Click);
//
// saveFileDialog
//
this.saveFileDialog.DefaultExt = "amx";
this.saveFileDialog.FileName = "untitled.amx";
this.saveFileDialog.Filter = "AniMax files (*.amx)|*.amx|Zipped AniMax files (*.zamx)|*.zamx|All files|*.*";
this.saveFileDialog.Title = "Save AniMax File";
//
// mniViewTracks
//
this.mniViewTracks.Index = 2;
this.mniViewTracks.Text = "&Frames Window";
this.mniViewTracks.Click += new System.EventHandler(this.mniViewTracks_Click);
//
// mniViewBitmaps
//
this.mniViewBitmaps.Index = 0;
this.mniViewBitmaps.Text = "&Bitmaps Window";
this.mniViewBitmaps.Click += new System.EventHandler(this.mniViewBitmaps_Click);
//
// openFileDialog
//
this.openFileDialog.DefaultExt = "amx";
this.openFileDialog.Filter = "AniMax files (*.amx)|*.amx|Zipped AniMax files (*.zamx)|*.zamx|All files|*.*";
this.openFileDialog.Title = "Open AniMax File";
//
// mniViewStrips
//
this.mniViewStrips.Index = 1;
this.mniViewStrips.Text = "&Strips Window";
this.mniViewStrips.Click += new System.EventHandler(this.mniViewStrips_Click);
//
// mnuMain
//
this.mnuMain.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniFile,
this.mniEdit,
this.mniView,
this.mniTools,
this.mniHelp});
//
// mniEdit
//
this.mniEdit.Index = 1;
this.mniEdit.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniUndo});
this.mniEdit.Text = "&Edit";
this.mniEdit.Popup += new System.EventHandler(this.mniEdit_Popup);
//
// mniUndo
//
this.mniUndo.Index = 0;
this.mniUndo.Shortcut = System.Windows.Forms.Shortcut.CtrlZ;
this.mniUndo.Text = "&Undo";
this.mniUndo.Click += new System.EventHandler(this.mniUndo_Click);
//
// mniView
//
this.mniView.Index = 2;
this.mniView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniViewBitmaps,
this.mniViewStrips,
this.mniViewTracks,
this.mniViewCombiner});
this.mniView.Text = "&View";
this.mniView.Popup += new System.EventHandler(this.mniView_Popup);
//
// mniViewCombiner
//
this.mniViewCombiner.Index = 3;
this.mniViewCombiner.Text = "&Combiner Window";
this.mniViewCombiner.Click += new System.EventHandler(this.mniViewCombiner_Click);
//
// mniTools
//
this.mniTools.Index = 3;
this.mniTools.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniNormalizeBitmaps,
this.mniRepairSideColors,
this.mniWallPreview,
this.mniReplaceColors,
this.menuItem3,
this.mniOptions});
this.mniTools.Text = "&Tools";
//
// mniNormalizeBitmaps
//
this.mniNormalizeBitmaps.Enabled = false;
this.mniNormalizeBitmaps.Index = 0;
this.mniNormalizeBitmaps.Text = "Normalize Bitmaps";
//
// mniRepairSideColors
//
this.mniRepairSideColors.Index = 1;
this.mniRepairSideColors.Text = "Repair Side Colors";
this.mniRepairSideColors.Click += new System.EventHandler(this.mniRepairSideColors_Click);
//
// mniWallPreview
//
this.mniWallPreview.Index = 2;
this.mniWallPreview.Text = "&Wall Preview";
this.mniWallPreview.Click += new System.EventHandler(this.mniWallPreview_Click);
//
// menuItem3
//
this.menuItem3.Index = 4;
this.menuItem3.Text = "-";
//
// mniHelp
//
this.mniHelp.Index = 4;
this.mniHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.mniHelpAbout});
this.mniHelp.Text = "&Help";
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.Shortcut = System.Windows.Forms.Shortcut.F1;
this.menuItem1.Text = "&Help";
this.menuItem1.Click += new System.EventHandler(this.mniHelp_Click);
//
// mniHelpAbout
//
this.mniHelpAbout.Index = 1;
this.mniHelpAbout.Text = "&About SpiffCode AniMax...";
this.mniHelpAbout.Click += new System.EventHandler(this.mniHelpAbout_Click);
//
// importFileDialog
//
this.importFileDialog.Filter = "Bitmap files (*.bmp,*.png,*.gif,*.jpg,*.exif,*.tif)|*.bmp;*.png;*.gif;*.exif;*.jp" +
"g|Framedata files|*.txt";
this.importFileDialog.Multiselect = true;
this.importFileDialog.Title = "Import";
//
// mniReplaceColors
//
this.mniReplaceColors.Index = 3;
this.mniReplaceColors.Text = "Replace Colors...";
this.mniReplaceColors.Click += new System.EventHandler(this.mniReplaceColors_Click);
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(712, 478);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.KeyPreview = true;
this.Menu = this.mnuMain;
this.Name = "MainForm";
this.Text = "AniMax";
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown);
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.MainForm_KeyPress);
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp);
}
#endregion
private void OnActiveDocumentChanged(object obSender, EventArgs e) {
m_doc = Globals.ActiveDocument;
if (m_doc.FileName == null)
Text = gstrAniMax;
else
Text = gstrAniMax + " - " + m_doc.FileName;
}
private void mniNew_Click(object sender, System.EventArgs e) {
NewDocument();
}
private void NewDocument() {
// First close the open document (if any)
if (!CloseDocument())
return;
// Create a new one and show its views
Globals.ActiveDocument = new AnimDoc(Globals.TileSize,
Globals.FrameRate);
ShowViews();
// I'm tired of being asked if I want to save untitled on exit even though I
// haven't done anything to it.
m_doc.Dirty = false;
}
private void mniSave_Click(object sender, System.EventArgs e) {
SaveDocument();
}
private void mniSaveAs_Click(object sender, System.EventArgs e) {
SaveAsDocument();
}
private void mniOpen_Click(object sender, System.EventArgs e) {
// If the current doc is dirty give the user a chance to save it
// before loading the new doc.
if (!GiveUserChanceToSaveChangesOrCancel())
return;
if (openFileDialog.ShowDialog() != DialogResult.OK)
return;
OpenDocument(openFileDialog.FileName);
}
public void CloseAndOpenDocument(string strFileName) {
if (!GiveUserChanceToSaveChangesOrCancel())
return;
OpenDocument(strFileName);
}
private void OpenDocument(string strFileName) {
//
Cursor.Current = Cursors.WaitCursor;
Directory.SetCurrentDirectory(Path.GetDirectoryName(strFileName));
AnimDoc doc = AnimDoc.Load(strFileName);
Cursor.Current = Cursors.Arrow;
if (doc == null) {
MessageBox.Show(this, String.Format("Unexpected error loading {0} " +
"or one of the bitmap files it depends on. Sorry.", strFileName), "AniMax");
return;
}
Globals.ActiveDocument = doc;
Globals.TileSize = doc.TileSize;
Globals.ActiveStrip = doc.StripSet[0];
ShowViews();
}
private void mniClose_Click(object sender, System.EventArgs e) {
CloseDocument();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) {
if (!CloseDocument())
e.Cancel = true;
}
private bool SaveDocument() {
if (m_doc.FileName == null) {
return SaveAsDocument();
} else {
Cursor.Current = Cursors.WaitCursor;
m_doc.Save(m_doc.FileName);
Cursor.Current = Cursors.Arrow;
return true;
}
}
private bool SaveAsDocument() {
saveFileDialog.FileName = m_doc.FileName;
if (saveFileDialog.ShowDialog() != DialogResult.OK)
return false;
Cursor.Current = Cursors.WaitCursor;
m_doc.Save(saveFileDialog.FileName);
Cursor.Current = Cursors.Arrow;
Text = "AniMax - " + m_doc.FileName;
return true;
}
private bool GiveUserChanceToSaveChangesOrCancel() {
if (m_doc.Dirty) {
DialogResult dlgr = MessageBox.Show(this,
String.Format("Do you want to save the changes to {0}?", m_doc.FileName),
"AniMax", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
if (dlgr == DialogResult.Cancel)
return false;
else if (dlgr == DialogResult.Yes)
return SaveDocument();
}
return true;
}
private bool CloseDocument() {
if (!GiveUserChanceToSaveChangesOrCancel())
return false;
Globals.ActiveDocument = Globals.NullDocument;
return true;
}
private void mniViewBitmaps_Click(object sender, System.EventArgs e) {
ShowContent(m_tntBitmaps);
}
private void mniViewStrips_Click(object sender, System.EventArgs e) {
ShowContent(m_tntStrips);
}
private void mniViewTracks_Click(object sender, System.EventArgs e) {
ShowContent(m_tntFrames);
}
private void mniViewCombiner_Click(object sender, System.EventArgs e) {
ShowContent(m_tntCombiner);
}
private void ShowViews() {
ShowContent(m_tntStrips);
ShowContent(m_tntBitmaps);
ShowContent(m_tntFrames);
}
private void ShowContent(Content tnt) {
if (!tnt.Visible)
m_dkm.ShowContent(tnt);
}
private void mniView_Popup(object sender, System.EventArgs e) {
bool fDocExists = m_doc != null;
mniViewBitmaps.Enabled = fDocExists;
mniViewStrips.Enabled = fDocExists;
mniViewTracks.Enabled = fDocExists;
}
private void mniFile_Popup(object sender, System.EventArgs e) {
bool fDocExists = m_doc != null;
mniClose.Enabled = fDocExists;
mniSave.Enabled = fDocExists;
mniSaveAs.Enabled = fDocExists;
mniExport.Enabled = fDocExists;
}
private void mniOptions_Click(object sender, System.EventArgs e) {
// UNDONE: the options form includes a mishmash of items, some of which are
// scoped to the application, some to the current document. Document options
// should be moved to a properties dialog or something.
// CONSIDER: ye olde PropertyGrid?
OptionsForm frm = new OptionsForm();
frm.FrameRate = m_doc != null ? m_doc.FrameRate : Globals.FrameRate;
frm.GridWidth = Globals.GridWidth;
frm.GridHeight = Globals.GridHeight;
if (frm.ShowDialog(this) != DialogResult.OK)
return;
if (m_doc != null)
m_doc.FrameRate = frm.FrameRate;
else
Globals.FrameRate = frm.FrameRate;
Globals.GridWidth = frm.GridWidth;
Globals.GridHeight = frm.GridHeight;
frm.Dispose();
}
private void mniImport_Click(object sender, System.EventArgs e) {
if (importFileDialog.ShowDialog() != DialogResult.OK)
return;
string[] astrFileNames = importFileDialog.FileNames;
// If a document doesn't already exist create a new one and show its views
if (m_doc == Globals.NullDocument) {
m_doc = new AnimDoc(Globals.TileSize, Globals.FrameRate);
ShowViews();
}
Cursor.Current = Cursors.WaitCursor;
bool fSuccess = m_doc.Import(astrFileNames);
Cursor.Current = Cursors.Arrow;
if (!fSuccess)
return;
Globals.ActiveDocument = m_doc;
Globals.ActiveStrip = m_doc.StripSet[0];
}
// We have a universal key handler that any control or child form can register
// with to take a crack at processing the key press.
private void MainForm_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) {
Globals.OnKeyPress(sender, e);
}
private void MainForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {
Globals.OnKeyDown(sender, e);
}
private void MainForm_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e) {
Globals.OnKeyUp(sender, e);
}
private void mniRepairSideColors_Click(object sender, System.EventArgs e) {
if (m_doc.XBitmapSet.Count == 0) {
MessageBox.Show(this, "Hey dork, no Bitmaps have been loaded yet.", "Error");
return;
}
foreach (XBitmap xbm in m_doc.XBitmapSet) {
bool fDirty = ReplaceColor(xbm.Bitmap, Color.FromArgb(0, 114, 232), Color.FromArgb(0, 116, 232), true);
fDirty |= ReplaceColor(xbm.Bitmap, Color.FromArgb(0, 112, 232), Color.FromArgb(0, 116, 232), true);
fDirty |= ReplaceColor(xbm.Bitmap, Color.FromArgb(0, 96, 192), Color.FromArgb(0, 96, 196), true);
fDirty |= ReplaceColor(xbm.Bitmap, Color.FromArgb(0, 48, 88), Color.FromArgb(0, 48, 92), true);
if (fDirty) {
xbm.Dirty = fDirty;
m_doc.Dirty = true;
}
}
// UNDONE: this is a hack. Decide on the right way to force selective refreshes
Globals.StripControl.Invalidate();
Globals.PreviewControl.Invalidate();
}
#region Handy Helpers
static public bool ReplaceColor(Bitmap bm, Color clrOld, Color clrNew, bool f6bit) {
bool fFound = false;
if (f6bit) {
clrOld = Color.FromArgb(clrOld.R & 0xfc, clrOld.G & 0xfc, clrOld.B & 0xfc);
clrNew = Color.FromArgb(clrNew.R & 0xfc, clrNew.G & 0xfc, clrNew.B & 0xfc);
}
for (int y = 0; y < bm.Height; y++) {
for (int x = 0; x < bm.Width; x++) {
Color clr = bm.GetPixel(x, y);
if (f6bit)
clr = Color.FromArgb(clr.R & 0xfc, clr.G & 0xfc, clr.B & 0xfc);
if (clr == clrOld) {
fFound = true;
bm.SetPixel(x, y, clrNew);
}
}
}
return fFound;
}
#endregion
private void mniUndo_Click(object sender, System.EventArgs e) {
UndoManager.Undo();
}
private void mniEdit_Popup(object sender, System.EventArgs e) {
mniUndo.Enabled = UndoManager.AnyUndos();
}
private void mniHelp_Click(object sender, System.EventArgs e) {
Process.Start("http://www.tinybit.org/AniMax");
}
private void mniToolsHack_Click(object sender, System.EventArgs e) {
foreach (Strip stp in Globals.ActiveDocument.StripSet) {
if (!stp.Name.ToLower().StartsWith("turret"))
continue;
foreach (Frame fr in stp) {
Point pt = new Point(fr.SpecialPoint.X - 7, fr.SpecialPoint.Y - 3);
fr.SpecialPoint = pt;
foreach (BitmapPlacer plc in fr.BitmapPlacers) {
plc.X += 7;
plc.Y += 3;
}
}
}
// Force a redraw of everything
Globals.ActiveDocument = Globals.ActiveDocument;
}
private void mniHelpAbout_Click(object sender, System.EventArgs e) {
new AboutForm().ShowDialog(this);
}
private void mniWallPreview_Click(object sender, System.EventArgs e) {
new WallPreviewForm().ShowDialog(this);
}
private void mniGenerateCompass_Click(object sender, System.EventArgs e) {
Bitmap bm = new Bitmap(200, 200);
Graphics g = Graphics.FromImage(bm);
Pen pen = new Pen(Color.White);
int xC = 100;
int yC = 100;
for (int i = 0; i < 16; i++) {
double nAngle = (Math.PI * 2) * (i / 16.0);
int xE = (int)(Math.Sin(nAngle) * 100);
int yE = (int)(Math.Cos(nAngle) * 100);
g.DrawLine(pen, xC, yC, xC + xE, yC + yE);
}
g.Dispose();
bm.Save(@"c:\compass.png", ImageFormat.Png);
}
private void mniReplaceColors_Click(object sender, System.EventArgs e) {
if (m_doc.XBitmapSet.Count == 0) {
MessageBox.Show(this, "Hey dork, no Bitmaps have been loaded yet.", "Error");
return;
}
new ReplaceColorsForm(m_doc).ShowDialog(this);
}
}
}

BIN
AniMax/MainForm.resources Normal file

Binary file not shown.

136
AniMax/MainForm.resx Normal file
View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="saveFileDialog.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>114, 17</value>
</data>
<data name="openFileDialog.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>236, 17</value>
</data>
<data name="mnuMain.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="importFileDialog.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>360, 17</value>
</data>
<data name="$this.Name">
<value>MainForm</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAIAEBAQAAAAAAAoAQAAJgAAACAgEAAAAAAA6AIAAE4BAAAoAAAAEAAAACAAAAABAAQAAAAAAMAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/
AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAH//j/j/jwAAf/+P+P+PAAB4iIiIiIgAAH93h3h3
jwAAf3eHeHePAAB4iIiIiIgAAH93h3h3jwAAf3eHeHePAAB4iIiIiIgAAH93h3h3jwAAf3eHeHePAAB4
iIiIgAAAAH//j/j39wAAf/+P+PdwAAB3d3d3dwAAwAEAAMABAADAAQAAwAEAAMABAADAAQAAwAEAAMAB
AADAAQAAwAEAAMABAADAAQAAwAEAAMADAADABwAAwA8AACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD/
/wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAHiIiIiIiIiIiIiIiIAAAAB/////j///j/
//j/+AAAAAf////4///4///4//gAAAAH////+P//+P//+P/4AAAAB/////j///j///j/+AAAAAf////4
///4///4//gAAAAHiIiIiIiIiIiIiIiIAAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH
/3h4eHh4eHh4eP/4AAAAB/+Hh4iHh4iHh4j/+AAAAAf/eHh4eHh4eHh4//gAAAAHiIiIiIiIiIiIiIiI
AAAAB/94eHh4eHh4eHj/+AAAAAf/h4eIh4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4AAAAB/+Hh4iHh4iH
h4j/+AAAAAf/eHh4eHh4eHh4//gAAAAHiIiIiIiIiIiIiIiIAAAAB/94eHh4eHh4eHj/+AAAAAf/h4eI
h4eIh4eI//gAAAAH/3h4eHh4eHh4eP/4AAAAB/+Hh4iHh4iHh4j/+AAAAAf/eHh4eHh4eHh4//gAAAAH
iIiIiIiIiIiIcAAAAAAAB/////j///j//3/4cAAAAAf////4///4//9/hwAAAAAH////+P//+P//eHAA
AAAAB/////j///j//3cAAAAAAAf////4///4//9wAAAAAAAHd3d3d3d3d3d3cAAAAADgAAAH4AAAB+AA
AAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AA
AAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAH4AAAB+AAAA/gAAAf4AAAP+AAAH/gAAD/4AAB/w==
</value>
</data>
</root>

38
AniMax/MiscControls.cs Normal file
View File

@ -0,0 +1,38 @@
using System.Windows.Forms;
using System.Drawing;
namespace SpiffCode {
public class ScToggleButton : CheckBox {
new public bool CanFocus {
get {
return false;
}
}
override protected bool ShowFocusCues {
get {
return false;
}
}
new public bool IsDefault {
get {
base.IsDefault = false;
return false;
}
set {
base.IsDefault = false;
}
}
}
public class ScBorder : Control {
override protected void OnPaint(PaintEventArgs e) {
ControlPaint.DrawBorder(e.Graphics, ClientRectangle,
Color.Black, 0, ButtonBorderStyle.None,
SystemColors.ControlDark, 1, ButtonBorderStyle.Solid,
Color.Black, 0, ButtonBorderStyle.None,
SystemColors.ControlLight, 1, ButtonBorderStyle.Solid);
}
}
}

Binary file not shown.

42
AniMax/MiscControls.resx Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

198
AniMax/OptionsForm.cs Normal file
View File

@ -0,0 +1,198 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for OptionsForm.
/// </summary>
public class OptionsForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox tbFrameRate;
private System.Windows.Forms.TextBox tbGridWidth;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox tbGridHeight;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public OptionsForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.btnOK = new System.Windows.Forms.Button();
this.tbFrameRate = new System.Windows.Forms.TextBox();
this.btnCancel = new System.Windows.Forms.Button();
this.tbGridWidth = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.tbGridHeight = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(72, 16);
this.label1.TabIndex = 4;
this.label1.Text = "Frame Rate:";
//
// label2
//
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 7F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label2.Location = new System.Drawing.Point(136, 16);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(80, 16);
this.label2.TabIndex = 5;
this.label2.Text = "(in milliseconds)";
//
// btnOK
//
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(79, 112);
this.btnOK.Name = "btnOK";
this.btnOK.TabIndex = 1;
this.btnOK.Text = "OK";
//
// tbFrameRate
//
this.tbFrameRate.Location = new System.Drawing.Point(80, 13);
this.tbFrameRate.Name = "tbFrameRate";
this.tbFrameRate.Size = new System.Drawing.Size(48, 20);
this.tbFrameRate.TabIndex = 6;
this.tbFrameRate.Text = "";
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(207, 112);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 3;
this.btnCancel.Text = "Cancel";
//
// tbGridWidth
//
this.tbGridWidth.Location = new System.Drawing.Point(80, 40);
this.tbGridWidth.Name = "tbGridWidth";
this.tbGridWidth.Size = new System.Drawing.Size(48, 20);
this.tbGridWidth.TabIndex = 7;
this.tbGridWidth.Text = "";
//
// label3
//
this.label3.Location = new System.Drawing.Point(8, 44);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(64, 16);
this.label3.TabIndex = 8;
this.label3.Text = "Grid Width:";
//
// label4
//
this.label4.Location = new System.Drawing.Point(8, 68);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(72, 16);
this.label4.TabIndex = 9;
this.label4.Text = "Grid Height:";
//
// tbGridHeight
//
this.tbGridHeight.Location = new System.Drawing.Point(80, 64);
this.tbGridHeight.Name = "tbGridHeight";
this.tbGridHeight.Size = new System.Drawing.Size(48, 20);
this.tbGridHeight.TabIndex = 10;
this.tbGridHeight.Text = "";
//
// OptionsForm
//
this.AcceptButton = this.btnOK;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(362, 143);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.tbGridHeight,
this.label4,
this.label3,
this.tbGridWidth,
this.tbFrameRate,
this.label2,
this.label1,
this.btnCancel,
this.btnOK});
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "OptionsForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Options";
this.ResumeLayout(false);
}
#endregion
public int FrameRate {
get {
return Convert.ToInt32(tbFrameRate.Text);
}
set {
tbFrameRate.Text = value.ToString();
}
}
public int GridWidth {
get {
return Convert.ToInt32(tbGridWidth.Text);
}
set {
tbGridWidth.Text = value.ToString();
}
}
public int GridHeight {
get {
return Convert.ToInt32(tbGridHeight.Text);
}
set {
tbGridHeight.Text = value.ToString();
}
}
}
}

Binary file not shown.

102
AniMax/OptionsForm.resx Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.Name">
<value>OptionsForm</value>
</data>
</root>

241
AniMax/PerPixelAlphaForm.cs Normal file
View File

@ -0,0 +1,241 @@
//
// Copyright © 2002 Rui Godinho Lopes <rui@ruilopes.com>
// All rights reserved.
//
// This source file(s) may be redistributed unmodified by any means
// PROVIDING they are not sold for profit without the authors expressed
// written consent, and providing that this notice and the authors name
// and all copyright notices remain intact.
//
// Any use of the software in source or binary forms, with or without
// modification, must include, in the user documentation ("About" box and
// printed documentation) and internal comments to the code, notices to
// the end user as follows:
//
// "Portions Copyright © 2002 Rui Godinho Lopes"
//
// An email letting me know that you are using it would be nice as well.
// That's not much to ask considering the amount of work that went into
// this.
//
// THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED. USE IT AT YOUT OWN RISK. THE AUTHOR ACCEPTS NO
// LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
//
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SpiffCode {
// a static class to expose needed win32 gdi functions.
class Win32 {
public enum Bool {
False= 0,
True
};
[StructLayout(LayoutKind.Sequential)]
public struct Point {
public Int32 x;
public Int32 y;
public Point(Int32 x, Int32 y) { this.x= x; this.y= y; }
}
[StructLayout(LayoutKind.Sequential)]
public struct Size {
public Int32 cx;
public Int32 cy;
public Size(Int32 cx, Int32 cy) { this.cx= cx; this.cy= cy; }
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct ARGB {
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct BLENDFUNCTION {
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
public const Int32 ULW_COLORKEY = 0x00000001;
public const Int32 ULW_ALPHA = 0x00000002;
public const Int32 ULW_OPAQUE = 0x00000004;
public const byte AC_SRC_OVER = 0x00;
public const byte AC_SRC_ALPHA = 0x01;
[DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
[DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling=true)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll", ExactSpelling=true)]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool DeleteObject(IntPtr hObject);
[DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, UInt32 fl);
[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool MoveToEx(IntPtr hdc, Int32 x, Int32 y, IntPtr lpPoint);
[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool LineTo(IntPtr hdc, Int32 x, Int32 y);
[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Bool GdiFlush();
[DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Int32 SetWindowLong(IntPtr hwnd, Int32 index, Int32 value);
}
/// <para>PerPixel forms should derive from this base class</para>
/// <author><name>Rui Godinho Lopes</name><email>rui@ruilopes.com</email></author>
public class PerPixelAlphaForm : Form {
/// <para>Changes the current bitmap.</para>
public void SetBitmap(Bitmap bitmap) {
SetBitmap(bitmap, 255);
}
#if false
/// <para>Changes the current bitmap with a custom opacity level. Here is where all happens!</para>
public void SetBitmap(Bitmap bitmap, byte opacity) {
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException("The bitmap must be 32bpp with alpha-channel.");
Bitmap bmWindow = new Bitmap(Width, Height, PixelFormat.Format32bppArgb); // NEW:
// Bitmap bmWindow = bitmap;
Graphics g = Graphics.FromImage(bmWindow);
g.Clear(Color.FromArgb(0, 0, 0, 0));
g.DrawImage(bitmap, 0, 0, bmWindow.Width, bmWindow.Height);
g.Flush();
IntPtr memDc = g.GetHdc();
// Win32.Bool fSuccess = Win32.PrintWindow(Handle, memDc, 0); // NEW:
int err = Marshal.GetLastWin32Error();
if (err != 1400) {
Win32.Size size = new Win32.Size(bmWindow.Width, bmWindow.Height);
Win32.Point pointSource = new Win32.Point(0, 0);
Win32.Point topPos = new Win32.Point(Left, Top);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = opacity;
blend.AlphaFormat = Win32.AC_SRC_ALPHA;
Win32.GdiFlush();
// BackgroundImage = bmWindow;
IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
Win32.ReleaseDC(IntPtr.Zero, screenDc);
}
g.ReleaseHdc(memDc);
g.Dispose();
}
#else
public void SetBitmap(Bitmap bitmap, byte opacity) {
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException("The bitmap must be 32bpp with alpha-channel.");
IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero;
try {
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap
oldBitmap = Win32.SelectObject(memDc, hBitmap);
Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
Win32.Point pointSource = new Win32.Point(0, 0);
Win32.Point topPos = new Win32.Point(Left, Top);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = opacity;
blend.AlphaFormat = Win32.AC_SRC_ALPHA;
Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
}
finally {
Win32.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero) {
Win32.SelectObject(memDc, oldBitmap);
//Windows.DeleteObject(hBitmap); // The documentation says that we have to use the Windows.DeleteObject... but since there is no such method I use the normal DeleteObject from Win32 GDI and it's working fine without any resource leak.
Win32.DeleteObject(hBitmap);
}
Win32.DeleteDC(memDc);
}
}
#endif
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
return cp;
}
}
public Bitmap SnapshotWindow() {
Bitmap bm = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
#if false
IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero;
hBitmap = bm.GetHbitmap(); // grab a GDI handle from this GDI+ bitmap
oldBitmap = Win32.SelectObject(memDc, hBitmap);
Win32.PrintWindow(Handle, memDc, 0);
Win32.ReleaseDC(IntPtr.Zero, screenDc);
Win32.SelectObject(memDc, oldBitmap);
// Win32.DeleteObject(hBitmap);
Win32.DeleteDC(memDc);
bm = Bitmap.FromHbitmap(hBitmap);
#else
Graphics g = Graphics.FromImage(bm);
IntPtr hdcMem = g.GetHdc();
Win32.PrintWindow(Handle, hdcMem, 0);
g.ReleaseHdc(hdcMem);
g.Dispose();
#endif
return bm;
}
protected override void OnPaint(PaintEventArgs e) {
// base.OnPaint(e);
}
protected override void OnPaintBackground(PaintEventArgs e) {
// base.OnPaintBackground(e);
}
}
}

Binary file not shown.

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

452
AniMax/PreviewControl.cs Normal file
View File

@ -0,0 +1,452 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for PreviewControl.
/// </summary>
public class PreviewControl : System.Windows.Forms.UserControl
{
private bool m_fFrameRecentering = false;
private bool m_fSpaceDown = false;
private bool m_fAllFrames;
private bool m_fRepositionBitmaps = false;
private BitmapPlacer m_plcSelected = null;
private Point m_ptPreSetSpecialPoint;
private bool m_fSetSpecialPoint = false;
private PreviewControlMode m_mode = PreviewControlMode.RepositionBitmap;
#if false
private bool m_fOnionSkin = true;
#endif
private bool m_fDragging = false;
private Point m_ptDragStart;
private Point[] m_aptPreDragBitmap;
private Point m_ptOffset;
private Point m_ptInitialOffset;
private System.Windows.Forms.Label label1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public PreviewControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// My initialization
ResizeRedraw = true;
Globals.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged);
Globals.ActiveFrameChanged += new EventHandler(OnInvalidatingChange);
Globals.GridChanged += new EventHandler(OnInvalidatingChange);
Globals.SideColorMappingOnChanged += new EventHandler(OnInvalidatingChange);
Globals.ShowOriginPointChanged += new EventHandler(OnInvalidatingChange);
Globals.ShowSpecialPointChanged += new EventHandler(OnInvalidatingChange);
Globals.FrameContentChanged += new EventHandler(OnInvalidatingChange);
Globals.KeyDown += new KeyEventHandler(OnGlobalKeyDown);
Globals.KeyUp += new KeyEventHandler(OnGlobalKeyUp);
m_ptOffset = new Point(0, 0);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component 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.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(56, 16);
this.label1.TabIndex = 1;
this.label1.Text = "Preview";
//
// PreviewControl
//
this.AllowDrop = true;
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.label1});
this.Name = "PreviewControl";
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.PreviewControl_DragEnter);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PreviewControl_MouseUp);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.PreviewControl_DragDrop);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PreviewControl_MouseMove);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PreviewControl_MouseDown);
this.ResumeLayout(false);
}
#endregion
public event FrameOffsetEventHandler FrameOffsetChanged;
public PreviewControlMode Mode {
set {
m_mode = value;
}
get {
return m_mode;
}
}
private void OnGlobalKeyDown(object obSender, KeyEventArgs e) {
if (e.KeyCode == Keys.Space) {
Cursor = m_fFrameRecentering ? Globals.GrabCursor : Globals.HandCursor;
m_fSpaceDown = true;
}
}
private void OnGlobalKeyUp(object obSender, KeyEventArgs e) {
if (e.KeyCode == Keys.Space) {
if (!m_fFrameRecentering)
Cursor = Cursors.Default;
m_fSpaceDown = false;
}
}
private void OnActiveDocumentChanged(object obSender, EventArgs e) {
Invalidate();
}
public void OnFrameOffsetChanged(object obSender, FrameOffsetEventArgs e) {
m_ptOffset.X = e.X;
m_ptOffset.Y = e.Y;
Invalidate();
}
private void OnInvalidatingChange(object obSender, EventArgs e) {
Invalidate();
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
Frame.DrawArgs drwa = new Frame.DrawArgs();
drwa.clrBackground = BackColor;
drwa.fDrawBackground = true;
drwa.fMapSideColors = Globals.SideColorMappingOn;
drwa.fShowGrid = Globals.GridOn;
drwa.cxGrid = Globals.GridWidth;
drwa.cyGrid = Globals.GridHeight;
drwa.fShowOrigin = Globals.ShowOriginPoint;
drwa.fShowSpecialPoint = Globals.ShowSpecialPoint || (m_mode == PreviewControlMode.SetSpecialPoint);
drwa.nScale = Globals.PreviewScale;
if (Globals.ActiveStrip != null && Globals.ActiveStrip.Count != 0) {
Frame fr;
Rectangle rc = new Rectangle(0, 0, ClientRectangle.Width, ClientRectangle.Height);
#if false
if (m_fOnionSkin && Globals.ActiveFrame > 0) {
drwa.fShowGrid = false;
drwa.fShowOrigin = false;
drwa.fShowSpecialPoint = false;
drwa.nAlpha = 128;
fr = Globals.ActiveStrip[Globals.ActiveFrame - 1];
fr.Draw(e.Graphics, rc, drwa, m_ptOffset);
}
#endif
fr = Globals.ActiveStrip[Globals.ActiveFrame];
fr.Draw(e.Graphics, rc, drwa, m_ptOffset);
#if false
if (m_fOnionSkin && Globals.ActiveFrame < Globals.ActiveStrip.Count - 1) {
fr = Globals.ActiveStrip[Globals.ActiveFrame + 1];
fr.Draw(e.Graphics, rc, drwa, m_ptOffset);
}
#endif
#if false
// Draw selection rectangle
if (m_plcSelected != null) {
Point ptUpperLeft = WxyFromFxy(FxyFromBxy(m_plcSelected, new Point(0, 0)));
Point ptLowerRight = WxyFromFxy(FxyFromBxy(m_plcSelected,
new Point(m_plcSelected.XBitmap.Width, m_plcSelected.XBitmap.Height)));
e.Graphics.DrawRectangle(new Pen(Color.Black),
ptUpperLeft.X, ptUpperLeft.Y, ptLowerRight.X - ptUpperLeft.X, ptLowerRight.Y - ptUpperLeft.Y);
}
#endif
} else {
e.Graphics.FillRectangle(new SolidBrush(BackColor), e.ClipRectangle);
}
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) {
if (Globals.ActiveStrip == null)
base.OnPaintBackground(e);
}
private Point WxyFromFxy(Point ptFrame) {
return new Point(((ptFrame.X + m_ptOffset.X) * Globals.PreviewScale) + (ClientRectangle.Width / 2),
((ptFrame.Y + m_ptOffset.Y) * Globals.PreviewScale) + (ClientRectangle.Height / 2));
}
private Point FxyFromBxy(BitmapPlacer plc, Point ptBitmap) {
return new Point(ptBitmap.X - plc.X, ptBitmap.Y - plc.Y);
}
private Point FxyFromWxy(Point ptWindow) {
Rectangle rcClient = ClientRectangle;
int xCenter = rcClient.Width / 2;
int yCenter = rcClient.Height / 2;
int dx = ptWindow.X - xCenter;
if (dx < 0)
dx -= Globals.PreviewScale;
int dy = ptWindow.Y - yCenter;
if (dy < 0)
dy -= Globals.PreviewScale;
return new Point((dx / Globals.PreviewScale) - m_ptOffset.X, (dy / Globals.PreviewScale) - m_ptOffset.Y);
}
private Point BxyFromFxy(BitmapPlacer plc, Point ptFrame) {
return new Point(ptFrame.X + plc.X, ptFrame.Y + plc.Y);
}
private BitmapPlacer HitTest(int wx, int wy) {
Color clrTransparent = Color.FromArgb(0xff, 0, 0xff);
Point fpt = FxyFromWxy(new Point(wx, wy));
foreach (BitmapPlacer plc in Globals.ActiveStrip[Globals.ActiveFrame].BitmapPlacers) {
Point bpt = BxyFromFxy(plc, fpt);
if (bpt.X < 0 || bpt.Y < 0 || bpt.X >= plc.XBitmap.Width || bpt.Y >= plc.XBitmap.Height)
continue;
if (plc.XBitmap.Bitmap.GetPixel(bpt.X, bpt.Y) != clrTransparent)
return plc;
}
return null;
}
private void PreviewControl_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
Strip stp = Globals.ActiveStrip;
if (stp == null)
return;
if (m_fSpaceDown) {
m_fFrameRecentering = true;
m_fDragging = true;
m_ptDragStart = FxyFromWxy(new Point(e.X, e.Y));
m_ptInitialOffset = m_ptOffset;
Cursor = Globals.GrabCursor;
return;
}
switch (m_mode) {
case PreviewControlMode.SetSpecialPoint:
{
m_fDragging = true;
m_fSetSpecialPoint = true;
Point ptT = FxyFromWxy(new Point(e.X, e.Y));
Frame fr = stp[Globals.ActiveFrame];
m_ptPreSetSpecialPoint = fr.SpecialPoint;
fr.SpecialPoint = ptT;
Globals.ActiveDocument.Dirty = true;
Globals.OnFrameContentChanged(this, new EventArgs());
}
break;
case PreviewControlMode.RepositionBitmap:
{
BitmapPlacer plc = HitTest(e.X, e.Y);
if (plc == null)
break;
m_plcSelected = plc;
m_fDragging = true;
m_fAllFrames = (ModifierKeys & Keys.Shift) != 0;
// UNDONE: across frame operations don't really make sense until we have Tracks
m_aptPreDragBitmap = new Point[stp.Count];
for (int ifr = 0; ifr < stp.Count; ifr++) {
Frame fr = stp[ifr];
if (fr.BitmapPlacers.Count > 0) {
m_aptPreDragBitmap[ifr].X = fr.BitmapPlacers[0].X;
m_aptPreDragBitmap[ifr].Y = fr.BitmapPlacers[0].Y;
}
}
// Special handling for active frame
m_aptPreDragBitmap[stp.ActiveFrame].X = m_plcSelected.X;
m_aptPreDragBitmap[stp.ActiveFrame].Y = m_plcSelected.Y;
m_ptDragStart = FxyFromWxy(new Point(e.X, e.Y));
}
break;
}
}
private void PreviewControl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) {
if (!m_fDragging)
return;
Strip stp = Globals.ActiveStrip;
if (stp == null)
return;
if (m_fFrameRecentering) {
m_ptOffset = m_ptInitialOffset;
Point ptNew = FxyFromWxy(new Point(e.X, e.Y));
m_ptOffset.X = m_ptInitialOffset.X + (ptNew.X - m_ptDragStart.X);
m_ptOffset.Y = m_ptInitialOffset.Y + (ptNew.Y - m_ptDragStart.Y);
Invalidate();
Update();
// Notify anyone who cares that we've changed the Frame offset
if (FrameOffsetChanged != null)
FrameOffsetChanged(this, new FrameOffsetEventArgs(m_ptOffset.X, m_ptOffset.Y));
return;
}
switch (m_mode) {
case PreviewControlMode.SetSpecialPoint:
{
Point ptT = FxyFromWxy(new Point(e.X, e.Y));
Frame fr = stp[Globals.ActiveFrame];
fr.SpecialPoint = ptT;
Globals.ActiveDocument.Dirty = true;
Globals.OnFrameContentChanged(this, new EventArgs());
}
break;
case PreviewControlMode.RepositionBitmap:
{
Point ptT = FxyFromWxy(new Point(e.X, e.Y));
int ipl = stp[Globals.ActiveFrame].BitmapPlacers.
Index(m_plcSelected);
int ifr;
int cfr;
if (m_fAllFrames) {
ifr = 0;
cfr = stp.Count;
} else {
ifr = Globals.ActiveFrame;
cfr = Globals.ActiveFrameCount;
}
for (int ifrT = ifr; ifrT < ifr + cfr; ifrT++) {
int iplT = ipl;
if (iplT >= stp[ifrT].BitmapPlacers.Count) {
iplT = 0;
}
BitmapPlacer plc = stp[ifrT].BitmapPlacers[iplT];
plc.X = m_aptPreDragBitmap[ifrT].X + m_ptDragStart.X -
ptT.X;
plc.Y = m_aptPreDragBitmap[ifrT].Y + m_ptDragStart.Y -
ptT.Y;
}
m_fRepositionBitmaps = true;
Globals.ActiveDocument.Dirty = true;
Globals.OnFrameContentChanged(this, new EventArgs());
}
break;
}
}
private void PreviewControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
m_fDragging = false;
if (m_fFrameRecentering) {
Cursor = Cursors.Default;
m_fFrameRecentering = false;
}
if (m_fRepositionBitmaps) {
m_fRepositionBitmaps = false;
Strip stp = Globals.ActiveStrip;
UndoManager.BeginGroup();
for (int ifr = 0; ifr < stp.Count; ifr++) {
if (ifr != stp.ActiveFrame) {
if (stp[ifr].BitmapPlacers.Count > 0) {
UndoManager.AddUndo(new UndoDelegate(UndoSetBitmapPosition),
new Object[] { stp[ifr].BitmapPlacers[0], m_aptPreDragBitmap[ifr].X, m_aptPreDragBitmap[ifr].Y });
}
}
}
UndoManager.AddUndo(new UndoDelegate(UndoSetBitmapPosition),
new Object[] { m_plcSelected, m_aptPreDragBitmap[stp.ActiveFrame].X, m_aptPreDragBitmap[stp.ActiveFrame].Y });
UndoManager.EndGroup();
}
if (m_fSetSpecialPoint) {
m_fSetSpecialPoint = false;
UndoManager.AddUndo(new UndoDelegate(UndoSetSpecialPoint),
new Object[] { Globals.ActiveStrip[Globals.ActiveFrame], m_ptPreSetSpecialPoint.X, m_ptPreSetSpecialPoint.Y });
}
}
private void UndoSetBitmapPosition(object[] aobArgs) {
BitmapPlacer plc = (BitmapPlacer)aobArgs[0];
plc.X = (int)aobArgs[1];
plc.Y = (int)aobArgs[2];
Globals.ActiveDocument.Dirty = true;
Globals.OnFrameContentChanged(this, new EventArgs());
}
private void UndoSetSpecialPoint(object[] aobArgs) {
Frame fr = (Frame)aobArgs[0];
fr.SpecialPoint = new Point((int)aobArgs[1], (int)aobArgs[2]);
Globals.ActiveDocument.Dirty = true;
Globals.OnFrameContentChanged(this, new EventArgs());
}
private void PreviewControl_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
XBitmap[] axbm = (XBitmap[])e.Data.GetData(typeof(XBitmap[]));
if (axbm == null)
e.Effect = DragDropEffects.None;
else
e.Effect = DragDropEffects.Copy;
}
private void PreviewControl_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
XBitmap[] axbm = (XBitmap[])e.Data.GetData(typeof(XBitmap[]));
if (axbm == null)
return;
BitmapPlacerList plcl = Globals.ActiveStrip[Globals.ActiveFrame].BitmapPlacers;
foreach (XBitmap xbm in axbm) {
BitmapPlacer plc = new BitmapPlacer();
plc.X = 0;
plc.Y = 0;
plc.XBitmap = xbm;
plcl.Insert(0, plc);
}
Globals.ActiveDocument.Dirty = true;
Globals.OnFrameContentChanged(this, new EventArgs());
}
}
public enum PreviewControlMode {
SetSpecialPoint,
RepositionBitmap,
}
}

Binary file not shown.

102
AniMax/PreviewControl.resx Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.Name">
<value>PreviewControl</value>
</data>
</root>

64
AniMax/PreviewForm.cs Normal file
View File

@ -0,0 +1,64 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for PreviewForm.
/// </summary>
public class PreviewForm : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public PreviewForm(AnimDoc doc)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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()
{
//
// PreviewForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "PreviewForm";
this.Text = "Preview";
}
#endregion
}
}

102
AniMax/PreviewForm.resx Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.Name">
<value>PreviewForm</value>
</data>
</root>

277
AniMax/PreviewPanel.cs Normal file
View File

@ -0,0 +1,277 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for PreviewPanel.
/// </summary>
public class PreviewPanel : System.Windows.Forms.UserControl
{
private bool m_fLoop = false;
private System.Windows.Forms.NumericUpDown nudHoldCount;
private SpiffCode.PreviewControl ctlPreview;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.CheckBox ckbSpecialPoint;
private System.Windows.Forms.Button btnStop;
private System.Windows.Forms.Button btnPlay;
private System.Windows.Forms.CheckBox ckbTogglePlay;
private System.Windows.Forms.Timer tmrAnim;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.TrackBar trkbScale;
private System.ComponentModel.IContainer components;
public PreviewPanel(AnimDoc doc)
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
Globals.ActiveStripChanged += new EventHandler(OnActiveStripChanged);
Globals.ActiveFrameChanged += new EventHandler(OnActiveFrameChanged);
trkbScale.Value = Globals.PreviewScale - 1;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component 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.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(PreviewPanel));
this.nudHoldCount = new System.Windows.Forms.NumericUpDown();
this.ctlPreview = new SpiffCode.PreviewControl();
this.panel1 = new System.Windows.Forms.Panel();
this.trkbScale = new System.Windows.Forms.TrackBar();
this.ckbSpecialPoint = new System.Windows.Forms.CheckBox();
this.btnStop = new System.Windows.Forms.Button();
this.btnPlay = new System.Windows.Forms.Button();
this.ckbTogglePlay = new System.Windows.Forms.CheckBox();
this.tmrAnim = new System.Windows.Forms.Timer(this.components);
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
((System.ComponentModel.ISupportInitialize)(this.nudHoldCount)).BeginInit();
this.panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trkbScale)).BeginInit();
this.SuspendLayout();
//
// nudHoldCount
//
this.nudHoldCount.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
this.nudHoldCount.BackColor = System.Drawing.SystemColors.Control;
this.nudHoldCount.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.nudHoldCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.nudHoldCount.InterceptArrowKeys = false;
this.nudHoldCount.Location = new System.Drawing.Point(0, 248);
this.nudHoldCount.Name = "nudHoldCount";
this.nudHoldCount.ReadOnly = true;
this.nudHoldCount.Size = new System.Drawing.Size(32, 15);
this.nudHoldCount.TabIndex = 2;
this.nudHoldCount.TabStop = false;
this.nudHoldCount.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.toolTip1.SetToolTip(this.nudHoldCount, "Hold Count");
this.nudHoldCount.ValueChanged += new System.EventHandler(this.nudHoldCount_ValueChanged);
//
// ctlPreview
//
this.ctlPreview.AllowDrop = true;
this.ctlPreview.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctlPreview.Mode = SpiffCode.PreviewControlMode.RepositionBitmap;
this.ctlPreview.Name = "ctlPreview";
this.ctlPreview.Size = new System.Drawing.Size(264, 264);
this.ctlPreview.TabIndex = 3;
//
// panel1
//
this.panel1.BackColor = System.Drawing.SystemColors.Control;
this.panel1.Controls.AddRange(new System.Windows.Forms.Control[] {
this.trkbScale,
this.ckbSpecialPoint,
this.nudHoldCount});
this.panel1.Dock = System.Windows.Forms.DockStyle.Right;
this.panel1.Location = new System.Drawing.Point(264, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(32, 264);
this.panel1.TabIndex = 4;
//
// trkbScale
//
this.trkbScale.Location = new System.Drawing.Point(0, 27);
this.trkbScale.Maximum = 20;
this.trkbScale.Name = "trkbScale";
this.trkbScale.Orientation = System.Windows.Forms.Orientation.Vertical;
this.trkbScale.Size = new System.Drawing.Size(45, 85);
this.trkbScale.TabIndex = 4;
this.trkbScale.TickFrequency = 2;
this.trkbScale.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
this.toolTip1.SetToolTip(this.trkbScale, "Zoom Level");
this.trkbScale.Value = 1;
this.trkbScale.Scroll += new System.EventHandler(this.trkbScale_Scroll);
//
// ckbSpecialPoint
//
this.ckbSpecialPoint.Appearance = System.Windows.Forms.Appearance.Button;
this.ckbSpecialPoint.Image = ((System.Drawing.Bitmap)(resources.GetObject("ckbSpecialPoint.Image")));
this.ckbSpecialPoint.Location = new System.Drawing.Point(4, 1);
this.ckbSpecialPoint.Name = "ckbSpecialPoint";
this.ckbSpecialPoint.Size = new System.Drawing.Size(24, 24);
this.ckbSpecialPoint.TabIndex = 3;
this.toolTip1.SetToolTip(this.ckbSpecialPoint, "Special Point Tool");
this.ckbSpecialPoint.CheckedChanged += new System.EventHandler(this.ckbSpecialPoint_CheckedChanged);
//
// btnStop
//
this.btnStop.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
this.btnStop.Image = ((System.Drawing.Bitmap)(resources.GetObject("btnStop.Image")));
this.btnStop.Location = new System.Drawing.Point(192, 240);
this.btnStop.Name = "btnStop";
this.btnStop.Size = new System.Drawing.Size(24, 24);
this.btnStop.TabIndex = 11;
this.toolTip1.SetToolTip(this.btnStop, "Stop animation");
this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
//
// btnPlay
//
this.btnPlay.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
this.btnPlay.Image = ((System.Drawing.Bitmap)(resources.GetObject("btnPlay.Image")));
this.btnPlay.Location = new System.Drawing.Point(216, 240);
this.btnPlay.Name = "btnPlay";
this.btnPlay.Size = new System.Drawing.Size(24, 24);
this.btnPlay.TabIndex = 10;
this.toolTip1.SetToolTip(this.btnPlay, "Play animation (once through)");
this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
//
// ckbTogglePlay
//
this.ckbTogglePlay.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
this.ckbTogglePlay.Appearance = System.Windows.Forms.Appearance.Button;
this.ckbTogglePlay.Image = ((System.Drawing.Bitmap)(resources.GetObject("ckbTogglePlay.Image")));
this.ckbTogglePlay.Location = new System.Drawing.Point(240, 240);
this.ckbTogglePlay.Name = "ckbTogglePlay";
this.ckbTogglePlay.Size = new System.Drawing.Size(24, 24);
this.ckbTogglePlay.TabIndex = 9;
this.toolTip1.SetToolTip(this.ckbTogglePlay, "Play animation (loop forever)");
this.ckbTogglePlay.Click += new System.EventHandler(this.ckbTogglePlay_CheckedChanged);
//
// tmrAnim
//
this.tmrAnim.Interval = 80;
this.tmrAnim.Tick += new System.EventHandler(this.tmrAnim_Tick);
//
// PreviewPanel
//
this.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(192)), ((System.Byte)(192)), ((System.Byte)(255)));
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.btnStop,
this.btnPlay,
this.ckbTogglePlay,
this.ctlPreview,
this.panel1});
this.Name = "PreviewPanel";
this.Size = new System.Drawing.Size(296, 264);
((System.ComponentModel.ISupportInitialize)(this.nudHoldCount)).EndInit();
this.panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.trkbScale)).EndInit();
this.ResumeLayout(false);
}
#endregion
public Control PreviewControl {
get {
return ctlPreview;
}
}
private void OnActiveStripChanged(object obSender, EventArgs e) {
if (Globals.ActiveStrip != null)
tmrAnim.Interval = 80 * (Globals.ActiveStrip.DefHoldCount + 1);
}
private void OnActiveFrameChanged(object obSender, EventArgs e) {
if (Globals.ActiveStrip != null && Globals.ActiveStrip.Count != 0)
nudHoldCount.Value = Globals.ActiveStrip[Globals.ActiveFrame].HoldCount;
}
private void nudHoldCount_ValueChanged(object sender, System.EventArgs e) {
if (Globals.ActiveStrip == null)
return;
Globals.ActiveStrip[Globals.ActiveFrame].HoldCount = (int)nudHoldCount.Value;
// UNDONE: this is a hack. Determine the best way to do this kind
// of thing.
Globals.StripControl.Invalidate();
}
private void ckbSpecialPoint_CheckedChanged(object sender, System.EventArgs e) {
if (ckbSpecialPoint.Checked)
ctlPreview.Mode = PreviewControlMode.SetSpecialPoint;
else
ctlPreview.Mode = PreviewControlMode.RepositionBitmap;
ctlPreview.Invalidate();
}
private void ckbTogglePlay_CheckedChanged(object sender, System.EventArgs e) {
m_fLoop = !m_fLoop;
if (m_fLoop)
tmrAnim.Start();
else
tmrAnim.Stop();
}
private void btnPlay_Click(object sender, System.EventArgs e) {
Globals.ActiveStrip.ActiveFrame = 0;
m_fLoop = false;
ckbTogglePlay.Checked = false;
tmrAnim.Start();
}
private void btnStop_Click(object sender, System.EventArgs e) {
tmrAnim.Stop();
ckbTogglePlay.Checked = false;
m_fLoop = false;
}
private void tmrAnim_Tick(object sender, System.EventArgs e) {
Strip stp = Globals.ActiveStrip;
if (stp == null)
return;
int ifr = stp.ActiveFrame + 1;
if (ifr >= stp.Count) {
ifr = 0;
if (!m_fLoop) {
tmrAnim.Stop();
}
}
tmrAnim.Interval = (stp[ifr].HoldCount * 80) + (80 * (Globals.ActiveStrip.DefHoldCount + 1));
stp.ActiveFrame = ifr;
}
private void trkbScale_Scroll(object sender, System.EventArgs e) {
Globals.PreviewScale = trkbScale.Value + 1;
ctlPreview.Invalidate();
}
}
}

Binary file not shown.

142
AniMax/PreviewPanel.resx Normal file
View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ckbSpecialPoint.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAADNJREFUOE9j/P//PwNFAGQAJZgizWDXU2L7IDeAARi2MIjPmzjDYOANIDZ2hnM0Dp0w
AAAXu8dW6QvQNwAAAABJRU5ErkJggg==
</value>
</data>
<data name="btnStop.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAADFJREFUOE9j/P//PwNFAGQAJZgizWDXI9sO9ArIPzgxNpeOGjD8ApGcFEndlDg0XQAA
cElQzY1k9AEAAAAASUVORK5CYII=
</value>
</data>
<data name="btnPlay.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAAFtJREFUOE+lk9sKACAIQ+v/P9pUSDC76QLf8jjH7ETUoCcApEIzqxFJQdZpyA3gIFWA
QRCAQlAA9+/NfnkwDYUB0Aqas+oKFtIKwCX8G5CNNXQHeojZiet/GDAAj65E2bBhT7EAAAAASUVORK5C
YII=
</value>
</data>
<data name="ckbTogglePlay.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAAGZJREFUOE/VkjEOACAIA/X/j8ZgAioRqCYOujCAV6BUIiovXkpl4UicASEEBbgQCxBF
L/Ka5lxvX0bIPksXS90OMJuxqBmXeg4F7ByGAd55QIDotlwAskytObXRwoeNQrqNSvoX0ACm8lG+/th5
agAAAABJRU5ErkJggg==
</value>
</data>
<data name="tmrAnim.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>325, 30</value>
</data>
<data name="toolTip1.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="$this.Name">
<value>PreviewPanel</value>
</data>
</root>

296
AniMax/ReplaceColorsForm.cs Normal file
View File

@ -0,0 +1,296 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SpiffCode
{
/// <summary>
/// Summary description for ReplaceColorsForm.
/// </summary>
public class ReplaceColorsForm : System.Windows.Forms.Form
{
private AnimDoc m_doc;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TextBox tbR1;
private System.Windows.Forms.TextBox tbG1;
private System.Windows.Forms.TextBox tbB1;
private System.Windows.Forms.TextBox tbR2;
private System.Windows.Forms.TextBox tbB2;
private System.Windows.Forms.TextBox tbG2;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button button1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public ReplaceColorsForm(AnimDoc doc)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
m_doc = doc;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.tbR1 = new System.Windows.Forms.TextBox();
this.tbG1 = new System.Windows.Forms.TextBox();
this.tbB1 = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.tbR2 = new System.Windows.Forms.TextBox();
this.tbB2 = new System.Windows.Forms.TextBox();
this.tbG2 = new System.Windows.Forms.TextBox();
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 43);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(56, 16);
this.label1.TabIndex = 0;
this.label1.Text = "Replace:";
//
// label2
//
this.label2.Location = new System.Drawing.Point(24, 75);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(32, 16);
this.label2.TabIndex = 1;
this.label2.Text = "With:";
//
// tbR1
//
this.tbR1.Location = new System.Drawing.Point(72, 40);
this.tbR1.Name = "tbR1";
this.tbR1.Size = new System.Drawing.Size(32, 20);
this.tbR1.TabIndex = 0;
this.tbR1.Text = "0";
//
// tbG1
//
this.tbG1.Location = new System.Drawing.Point(120, 40);
this.tbG1.Name = "tbG1";
this.tbG1.Size = new System.Drawing.Size(32, 20);
this.tbG1.TabIndex = 1;
this.tbG1.Text = "0";
//
// tbB1
//
this.tbB1.Location = new System.Drawing.Point(168, 40);
this.tbB1.Name = "tbB1";
this.tbB1.Size = new System.Drawing.Size(32, 20);
this.tbB1.TabIndex = 2;
this.tbB1.Text = "0";
//
// label3
//
this.label3.Location = new System.Drawing.Point(80, 16);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(16, 16);
this.label3.TabIndex = 3;
this.label3.Text = "R";
//
// label4
//
this.label4.Location = new System.Drawing.Point(128, 16);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(16, 16);
this.label4.TabIndex = 3;
this.label4.Text = "G";
//
// label5
//
this.label5.Location = new System.Drawing.Point(176, 16);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(16, 16);
this.label5.TabIndex = 3;
this.label5.Text = "B";
//
// tbR2
//
this.tbR2.Location = new System.Drawing.Point(72, 72);
this.tbR2.Name = "tbR2";
this.tbR2.Size = new System.Drawing.Size(32, 20);
this.tbR2.TabIndex = 3;
this.tbR2.Text = "0";
//
// tbB2
//
this.tbB2.Location = new System.Drawing.Point(168, 72);
this.tbB2.Name = "tbB2";
this.tbB2.Size = new System.Drawing.Size(32, 20);
this.tbB2.TabIndex = 5;
this.tbB2.Text = "0";
//
// tbG2
//
this.tbG2.Location = new System.Drawing.Point(120, 72);
this.tbG2.Name = "tbG2";
this.tbG2.Size = new System.Drawing.Size(32, 20);
this.tbG2.TabIndex = 4;
this.tbG2.Text = "0";
//
// btnOK
//
this.btnOK.Location = new System.Drawing.Point(24, 112);
this.btnOK.Name = "btnOK";
this.btnOK.TabIndex = 6;
this.btnOK.Text = "OK";
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(136, 112);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 7;
this.btnCancel.Text = "Cancel";
//
// button1
//
this.button1.Location = new System.Drawing.Point(16, 10);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(32, 24);
this.button1.TabIndex = 8;
this.button1.Text = "Get";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// ReplaceColorsForm
//
this.AcceptButton = this.btnOK;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(232, 142);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button1,
this.btnOK,
this.label3,
this.tbR1,
this.label2,
this.label1,
this.tbG1,
this.tbB1,
this.label4,
this.label5,
this.tbR2,
this.tbB2,
this.tbG2,
this.btnCancel});
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ReplaceColorsForm";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Replace Colors";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ReplaceColorsForm_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ReplaceColorsForm_MouseMove);
this.ResumeLayout(false);
}
#endregion
private void btnOK_Click(object sender, System.EventArgs e) {
foreach (XBitmap xbm in m_doc.XBitmapSet) {
int nR1 = int.Parse(tbR1.Text);
int nG1 = int.Parse(tbG1.Text);
int nB1 = int.Parse(tbB1.Text);
int nR2 = int.Parse(tbR2.Text);
int nG2 = int.Parse(tbG2.Text);
int nB2 = int.Parse(tbB2.Text);
bool fDirty = MainForm.ReplaceColor(xbm.Bitmap, Color.FromArgb(nR1, nG1, nB1),
Color.FromArgb(nR2, nG2, nB2), true);
if (fDirty) {
xbm.Dirty = fDirty;
m_doc.Dirty = true;
}
}
// UNDONE: this is a hack. Decide on the right way to force selective refreshes
Globals.StripControl.Invalidate();
Globals.PreviewControl.Invalidate();
DialogResult = DialogResult.OK;
}
[DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling=true)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
public static extern Int32 GetPixel(IntPtr hdc, Int32 x, Int32 y);
private void ReplaceColorsForm_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) {
if (!Capture)
return;
IntPtr hdc = GetDC(IntPtr.Zero);
Point ptScreen = PointToScreen(new Point(e.X, e.Y));
Int32 cr = GetPixel(hdc, ptScreen.X, ptScreen.Y);
tbR1.Text = (cr & 0xff).ToString();
tbG1.Text = ((cr >> 8) & 0xff).ToString();
tbB1.Text = ((cr >> 16) & 0xff).ToString();
ReleaseDC(IntPtr.Zero, hdc);
// tbR2.Text = ptScreen.X.ToString();
// tbG2.Text = ptScreen.Y.ToString();
}
private void button1_Click(object sender, System.EventArgs e) {
Capture = true;
}
private void ReplaceColorsForm_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
if (Capture) {
Capture = false;
}
}
}
}

Binary file not shown.

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.Name">
<value>ReplaceColorsForm</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
AniMax/Resources/grab.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

BIN
AniMax/Resources/hand.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

147
AniMax/Strip.cs Normal file
View File

@ -0,0 +1,147 @@
using System;
using System.Collections;
using System.Runtime.Serialization;
namespace SpiffCode
{
/// <summary>
/// Summary description for Strip.
/// </summary>
[Serializable]
public class Strip : CollectionBase, ISerializable, IComparable, ICloneable
{
private string m_strName = null;
private int m_ifrActive = 0;
private int m_cfrActive = 1;
private int m_cHold = 0;
public Strip(string strName)
{
m_strName = strName;
}
public object Clone()
{
Strip stpNew = new Strip(m_strName);
for (int i = 0; i < this.Count; i++) {
stpNew.Add((Frame)this[i].Clone());
}
stpNew.m_ifrActive = m_ifrActive;
stpNew.m_cfrActive = m_cfrActive;
stpNew.m_cHold = m_cHold;
return stpNew;
}
// IComparable implementation
public int CompareTo(object ob) {
return m_strName.CompareTo(((Strip)ob).m_strName);
}
// Public properties
public Frame this[int i] {
get {
return (Frame)InnerList[i];
}
set {
// We allow Frames to be added out-of-range in which case
// we expand the range to include the new Frame.
while (i >= InnerList.Count)
InnerList.Add(null);
InnerList[i] = value;
}
}
public string Name {
get {
return m_strName;
}
set {
m_strName = value;
}
}
// Exposed for anyone who wants to keep track of this Strip's ActiveFrame
public event EventHandler ActiveFrameChanged;
public int ActiveFrame {
get {
return m_ifrActive;
}
set {
m_ifrActive = value;
ActiveFrameCount = 1;
if (ActiveFrameChanged != null)
ActiveFrameChanged(this, EventArgs.Empty);
}
}
public event EventHandler ActiveFrameCountChanged;
public int ActiveFrameCount {
get {
return m_cfrActive;
}
set {
m_cfrActive = value;
if (m_ifrActive + m_cfrActive > Count) {
m_cfrActive = Count - m_ifrActive;
}
if (ActiveFrameCountChanged != null)
ActiveFrameCountChanged(this, EventArgs.Empty);
}
}
public int DefHoldCount {
get {
return m_cHold;
}
set {
m_cHold = value;
}
}
public int Add(Frame fr) {
return ((IList)this).Add(fr);
}
public int IndexOf(Frame fr) {
return ((IList)this).IndexOf(fr);
}
public void Insert(int ifr, Frame fr) {
((IList)this).Insert(ifr, fr);
}
// ISerializable interface implementation
private Strip(SerializationInfo seri, StreamingContext stmc) {
m_strName = seri.GetString("Name");
try {
m_cHold = seri.GetInt32("DefHoldCount");
} catch {}
int cfr = seri.GetInt32("FrameCount");
for (int i = 0; i < cfr; i++) {
Frame fr = (Frame)seri.GetValue(i.ToString(), typeof(Frame));
Add(fr);
}
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
seri.AddValue("Name", m_strName);
seri.AddValue("DefHoldCount", m_cHold);
seri.AddValue("FrameCount", InnerList.Count);
int i = 0;
foreach (Frame fr in InnerList) {
seri.AddValue(i.ToString(), fr);
i++;
}
}
}
}

716
AniMax/StripControl.cs Normal file
View File

@ -0,0 +1,716 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for StripControl.
/// </summary>
public class StripControl : System.Windows.Forms.UserControl
{
private bool m_fSpaceDown = false;
private int m_ifrInsertionPoint = -1;
private bool m_fFrameRecentering = false;
private Point m_ptDown;
private Point m_ptOffset;
private Point m_ptInitialOffset;
private int m_cxFrame = 100;
private bool m_fButtonDown = false;
private bool m_fFrameResizing = false;
private Strip m_stp;
private System.Windows.Forms.HScrollBar sb;
private System.Windows.Forms.ContextMenu mnu;
private System.Windows.Forms.MenuItem mniDelete;
private System.Windows.Forms.MenuItem mniInsert;
private System.Windows.Forms.MenuItem mniCut;
private System.Windows.Forms.MenuItem mniCopy;
private System.Windows.Forms.MenuItem mniPaste;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem mniProperties;
private System.Windows.Forms.Timer tmrScroll;
private System.ComponentModel.IContainer components;
public StripControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// My initialization
ResizeRedraw = true;
SetStyle(ControlStyles.Selectable, true);
m_ptOffset = new Point(0, 0);
Globals.ActiveFrameChanged += new EventHandler(OnInvalidatingChange);
Globals.ActiveFrameCountChanged += new EventHandler(OnInvalidatingChange);
Globals.GridChanged += new EventHandler(OnInvalidatingChange);
Globals.SideColorMappingOnChanged += new EventHandler(OnInvalidatingChange);
Globals.ShowOriginPointChanged += new EventHandler(OnInvalidatingChange);
Globals.ShowSpecialPointChanged += new EventHandler(OnInvalidatingChange);
Globals.KeyPress += new KeyPressEventHandler(StripControl_KeyPress);
Globals.FrameContentChanged += new EventHandler(OnInvalidatingChange);
Globals.KeyDown += new KeyEventHandler(OnGlobalKeyDown);
Globals.KeyUp += new KeyEventHandler(OnGlobalKeyUp);
Globals.StripScaleChanged += new EventHandler(OnInvalidatingChange);
mnu.Popup += new EventHandler(StripControl_Popup);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component 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();
this.sb = new System.Windows.Forms.HScrollBar();
this.mnu = new System.Windows.Forms.ContextMenu();
this.mniCut = new System.Windows.Forms.MenuItem();
this.mniCopy = new System.Windows.Forms.MenuItem();
this.mniPaste = new System.Windows.Forms.MenuItem();
this.mniDelete = new System.Windows.Forms.MenuItem();
this.mniInsert = new System.Windows.Forms.MenuItem();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.mniProperties = new System.Windows.Forms.MenuItem();
this.tmrScroll = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// sb
//
this.sb.Dock = System.Windows.Forms.DockStyle.Bottom;
this.sb.Location = new System.Drawing.Point(0, 79);
this.sb.Name = "sb";
this.sb.Size = new System.Drawing.Size(335, 16);
this.sb.TabIndex = 0;
this.sb.ValueChanged += new System.EventHandler(this.sb_ValueChanged);
//
// mnu
//
this.mnu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniCut,
this.mniCopy,
this.mniPaste,
this.mniDelete,
this.mniInsert,
this.menuItem1,
this.mniProperties});
//
// mniCut
//
this.mniCut.Index = 0;
this.mniCut.Shortcut = System.Windows.Forms.Shortcut.CtrlX;
this.mniCut.Text = "Cu&t";
this.mniCut.Click += new System.EventHandler(this.mniCut_Click);
//
// mniCopy
//
this.mniCopy.Index = 1;
this.mniCopy.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
this.mniCopy.Text = "&Copy";
this.mniCopy.Click += new System.EventHandler(this.mniCopy_Click);
//
// mniPaste
//
this.mniPaste.Index = 2;
this.mniPaste.Shortcut = System.Windows.Forms.Shortcut.CtrlV;
this.mniPaste.Text = "&Paste";
this.mniPaste.Click += new System.EventHandler(this.mniPaste_Click);
//
// mniDelete
//
this.mniDelete.Index = 3;
this.mniDelete.Shortcut = System.Windows.Forms.Shortcut.Del;
this.mniDelete.Text = "&Delete";
this.mniDelete.Click += new System.EventHandler(this.mniDelete_Click);
//
// mniInsert
//
this.mniInsert.Index = 4;
this.mniInsert.Shortcut = System.Windows.Forms.Shortcut.Ins;
this.mniInsert.Text = "&Insert";
this.mniInsert.Click += new System.EventHandler(this.mniInsert_Click);
//
// menuItem1
//
this.menuItem1.Index = 5;
this.menuItem1.Text = "-";
//
// mniProperties
//
this.mniProperties.Index = 6;
this.mniProperties.Text = "Properties";
//
// tmrScroll
//
this.tmrScroll.Interval = 150;
this.tmrScroll.Tick += new System.EventHandler(this.tmrScroll_Tick);
//
// StripControl
//
this.AllowDrop = true;
this.ContextMenu = this.mnu;
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.sb});
this.DockPadding.Bottom = 1;
this.DockPadding.Right = 1;
this.Name = "StripControl";
this.Size = new System.Drawing.Size(336, 96);
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.StripControl_KeyPress);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.StripControl_DragEnter);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.StripControl_DragDrop);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.StripControl_KeyDown);
this.DragOver += new System.Windows.Forms.DragEventHandler(this.StripControl_DragOver);
this.ResumeLayout(false);
}
#endregion
public Strip Strip {
set {
// Our Undo isn't robust enough to be maintained across strip
// activations so we flush it to be sure strip A's undos aren't
// applied to strip B.
UndoManager.Flush();
m_stp = value;
RecalcScrollbar();
Invalidate();
}
get {
return m_stp;
}
}
public int FrameWidth {
set {
m_cxFrame = value;
RecalcScrollbar();
Invalidate();
}
}
public event FrameOffsetEventHandler FrameOffsetChanged;
private void OnInvalidatingChange(object obSender, EventArgs e) {
RecalcScrollbar();
Invalidate();
}
public void OnFrameOffsetChanged(object obSender, FrameOffsetEventArgs e) {
m_ptOffset.X = e.X;
m_ptOffset.Y = e.Y;
Invalidate();
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) {
if (m_stp == null || m_stp.Count == 0)
base.OnPaintBackground(e);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
if (m_stp == null || m_stp.Count == 0)
return;
Frame.DrawArgs drwa = new Frame.DrawArgs();
drwa.clrBackground = this.BackColor;
drwa.fDrawBackground = true;
drwa.fMapSideColors = Globals.SideColorMappingOn;
drwa.fShowGrid = Globals.GridOn;
drwa.cxGrid = Globals.GridWidth;
drwa.cyGrid = Globals.GridHeight;
drwa.fShowOrigin = Globals.ShowOriginPoint;
drwa.fShowSpecialPoint = Globals.ShowSpecialPoint;
drwa.nScale = Globals.StripScale;
Pen penInactive = new Pen(Color.Black);
Pen penActive = new Pen(Color.Red);
Font fnt = new Font("Arial", 8);
Brush brBlack = new SolidBrush(Color.Black);
int cyFrame = sb.Top - 1;
Bitmap bmT = new Bitmap(ClientRectangle.Width, cyFrame + 1);
Graphics gT = Graphics.FromImage(bmT);
gT.Clear(drwa.clrBackground);
int ifr = sb.Value / m_cxFrame;
int x = -(sb.Value % m_cxFrame);
for (; x < ClientRectangle.Width && ifr < m_stp.Count; x += m_cxFrame, ifr++) {
// Draw a frame around the Frame
gT.DrawRectangle(penInactive, x, 0, m_cxFrame, cyFrame);
// Set up a clip box so the scaled frame won't draw anywhere we don't want it to
gT.SetClip(new Rectangle(x + 1, 1, m_cxFrame - 1, cyFrame - 1));
// Draw the scaled Frame
Frame fr = m_stp[ifr];
Rectangle rc = new Rectangle(x, 0, m_cxFrame, cyFrame);
fr.Draw(gT, rc, drwa, m_ptOffset);
// Draw the frame's hold count
if (fr.HoldCount != 0) {
string strT = fr.HoldCount.ToString();
SizeF sizf = e.Graphics.MeasureString(strT, fnt);
gT.DrawString(strT, fnt, brBlack, x + m_cxFrame - sizf.Width - 1, cyFrame - fnt.Height);
}
// Clear out our special clip region
gT.ResetClip();
}
// Draw a special frame around the active Frame
for (int ifrT = m_stp.ActiveFrame; ifrT < m_stp.ActiveFrame +
m_stp.ActiveFrameCount; ifrT++) {
Rectangle rcT = new Rectangle((ifrT * m_cxFrame) - sb.Value, 0, m_cxFrame, cyFrame);
gT.DrawRectangle(penActive, rcT);
rcT.Inflate(-1, -1);
gT.DrawRectangle(penActive, rcT);
}
// Draw the insertion point, if any
if (m_ifrInsertionPoint != -1) {
Brush br = new SolidBrush(Color.Red);
int xT = (m_ifrInsertionPoint * m_cxFrame) - sb.Value;
gT.FillRectangle(br, xT, 0, 1, cyFrame);
gT.FillRectangle(br, xT - 2, 0, 5, 1);
gT.FillRectangle(br, xT - 1, 1, 3, 1);
gT.FillRectangle(br, xT - 1, cyFrame - 2, 3, 1);
gT.FillRectangle(br, xT - 2, cyFrame - 1, 5, 1);
}
// Copy the buffered Strip to the screen
e.Graphics.DrawImageUnscaled(bmT, 0, 0);
gT.Dispose();
bmT.Dispose();
}
protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e) {
if (m_stp == null || m_stp.Count == 0)
return;
if (m_fButtonDown) {
if (m_fFrameResizing) {
Cursor = Cursors.VSplit;
m_cxFrame = Math.Max(4, e.X + sb.Value);
RecalcScrollbar();
Invalidate();
} else if (m_fFrameRecentering) {
m_ptOffset.X = m_ptInitialOffset.X + (e.X - m_ptDown.X) / Globals.StripScale;
m_ptOffset.Y = m_ptInitialOffset.Y + (e.Y - m_ptDown.Y) / Globals.StripScale;
Invalidate();
Update();
// Notify anyone who cares that we've changed the Frame offset
if (FrameOffsetChanged != null)
FrameOffsetChanged(this, new FrameOffsetEventArgs(m_ptOffset.X, m_ptOffset.Y));
} else {
m_fButtonDown = false; // because drag drop will capture the up
DoDragDrop(m_stp[m_stp.ActiveFrame], DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll);
}
} else {
if (e.X >= m_cxFrame - sb.Value - 1 && e.X <= m_cxFrame - sb.Value + 1)
Cursor = Cursors.VSplit;
else
Cursor = m_fSpaceDown ? Globals.HandCursor : Cursors.Default;
}
}
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e) {
Focus();
if (m_stp == null || m_stp.Count == 0)
return;
if (e.Button == MouseButtons.Left) {
m_fButtonDown = true;
// Is user clicking on the frame border?
if (e.X >= m_cxFrame - sb.Value - 1 && e.X <= m_cxFrame - sb.Value + 1) {
m_fFrameResizing = true;
// No, activate the frame they clicked
} else {
int ifr = (e.X + sb.Value) / m_cxFrame;
if (ifr < m_stp.Count) {
if ((ModifierKeys & Keys.Shift) == 0) {
m_stp.ActiveFrame = ifr;
} else {
if (ifr >= m_stp.ActiveFrame) {
m_stp.ActiveFrameCount = ifr -
m_stp.ActiveFrame + 1;
} else {
int cfr = m_stp.ActiveFrame - ifr + 1;
m_stp.ActiveFrame = ifr;
m_stp.ActiveFrameCount = cfr;
}
}
// If spacebar is held down then prepare to recenter the frame.
if (m_fSpaceDown) {
m_fFrameRecentering = true;
m_ptInitialOffset = m_ptOffset;
m_ptDown = new Point(e.X, e.Y);
Cursor = Globals.GrabCursor;
}
}
}
} else if (e.Button == MouseButtons.Right) {
int ifr = (e.X + sb.Value) / m_cxFrame;
if (ifr < m_stp.Count) {
if (m_stp.ActiveFrame != ifr)
m_stp.ActiveFrame = ifr;
mnu.Show(this, new Point(e.X, e.Y));
}
}
}
protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
m_fButtonDown = false;
m_fFrameResizing = false;
m_fFrameRecentering = false;
}
}
protected override void OnResize(EventArgs e) {
base.OnResize(e);
RecalcScrollbar();
}
private void StripControl_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) {
switch (e.KeyChar) {
case '[':
{
int ifr = m_stp.ActiveFrame - 1;
if (ifr < 0)
ifr = m_stp.Count - 1;
m_stp.ActiveFrame = ifr;
e.Handled = true;
}
break;
case ']':
{
int ifr = m_stp.ActiveFrame + 1;
if (ifr >= m_stp.Count)
ifr = 0;
m_stp.ActiveFrame = ifr;
e.Handled = true;
}
break;
}
}
// UNDONE: move _KeyPress handler into this
// UNDONE: this doesn't work for some reason. Somebody is snarfing the arrow keys (but not page up,etc)
private void StripControl_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {
switch (e.KeyCode) {
case Keys.Left:
{
int ifr = m_stp.ActiveFrame - 1;
if (ifr < 0)
ifr = m_stp.Count - 1;
m_stp.ActiveFrame = ifr;
e.Handled = true;
}
break;
case Keys.Right:
{
int ifr = m_stp.ActiveFrame + 1;
if (ifr >= m_stp.Count)
ifr = 0;
m_stp.ActiveFrame = ifr;
e.Handled = true;
}
break;
}
}
private void OnGlobalKeyDown(object obSender, KeyEventArgs e) {
if (e.KeyCode == Keys.Space && !m_fSpaceDown) {
Cursor = Globals.HandCursor;
m_fSpaceDown = true;
}
}
private void OnGlobalKeyUp(object obSender, KeyEventArgs e) {
if (e.KeyCode == Keys.Space) {
Cursor = Cursors.Default;
m_fSpaceDown = false;
}
}
private void StripControl_Popup(object sender, System.EventArgs e) {
mniPaste.Enabled = Clipboard.GetDataObject().GetDataPresent(typeof(Frame));
}
private void StripControl_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
if (e.Data.GetData(typeof(Frame)) == null || (e.KeyState & 8) != 0)
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.Move;
tmrScroll.Start();
}
private void StripControl_DragOver(object sender, System.Windows.Forms.DragEventArgs e) {
if (e.Data.GetData(typeof(Frame)) == null || (e.KeyState & 8) != 0)
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.Move;
// Find the closest between-frames border and draw an insertion cursor there
Point pt = PointToClient(new Point(e.X, e.Y));
SetInsertionPoint(pt.X);
}
private void StripControl_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
tmrScroll.Stop();
Focus();
// Drop from Bitmaps window
XBitmap[] axbm = e.Data.GetData(typeof(XBitmap[])) as XBitmap[];
if (axbm != null) {
if (m_stp == null)
((StripsForm)Globals.StripsForm).NewStrip();
int ifrFirst = m_ifrInsertionPoint;
int ifrInsert = ifrFirst;
UndoManager.BeginGroup();
foreach (XBitmap xbm in axbm) {
Frame frT = new Frame();
frT.BitmapPlacers.Add(new BitmapPlacer());
frT.BitmapPlacers[0].XBitmap = xbm;
frT.BitmapPlacers[0].X = xbm.Width / 2;
frT.BitmapPlacers[0].Y = xbm.Height / 2;
InsertFrame(m_stp, ifrInsert++, frT, true);
}
UndoManager.EndGroup();
m_stp.ActiveFrame = ifrFirst;
}
// Drop from Strip window
// UNDONE: wrap the Frame in a data structure that includes Strip and ifr
// and clean this up
Frame fr = e.Data.GetData(typeof(Frame)) as Frame;
if (fr != null) {
if (m_ifrInsertionPoint != -1) {
if ((ModifierKeys & Keys.Control) == 0) {
// Don't try to move the frame immediately before or after itself
if (m_ifrInsertionPoint == m_stp.ActiveFrame ||
m_ifrInsertionPoint == m_stp.ActiveFrame + 1) {
m_ifrInsertionPoint = -1;
Invalidate();
return;
}
}
UndoManager.BeginGroup();
// Insert at new place
int ifrOld = m_stp.ActiveFrame;
fr = (Frame)m_stp[ifrOld].Clone();
InsertFrame(m_stp, m_ifrInsertionPoint, fr, true);
m_stp.ActiveFrame = m_ifrInsertionPoint;
// If the control key is held the frame is duplicated, not moved
if ((ModifierKeys & Keys.Control) == 0) {
// Remove from old place
if (m_ifrInsertionPoint <= ifrOld)
ifrOld++;
DeleteFrame(m_stp, ifrOld, true);
}
UndoManager.EndGroup();
}
}
m_ifrInsertionPoint = -1;
Invalidate();
}
private void RecalcScrollbar() {
if (m_stp == null) {
sb.Enabled = false;
} else {
int cxScroll = m_stp.Count * m_cxFrame;
if (cxScroll <= ClientRectangle.Width) {
sb.Value = 0;
sb.Enabled = false;
} else {
sb.Enabled = true;
sb.Maximum = cxScroll;
if (sb.Value > cxScroll - ClientRectangle.Width)
sb.Value = cxScroll - ClientRectangle.Width + 1;
sb.LargeChange = ClientRectangle.Width;
sb.SmallChange = m_cxFrame;
}
}
}
private void SetInsertionPoint(int x) {
x += sb.Value;
if (x < 0)
x = 0;
else if (x > m_cxFrame * m_stp.Count)
x = m_cxFrame * m_stp.Count;
int ifr = x / m_cxFrame;
if (x % m_cxFrame >= m_cxFrame / 2)
ifr++;
m_ifrInsertionPoint = ifr;
Invalidate();
}
private void sb_ValueChanged(object sender, System.EventArgs e) {
Invalidate();
}
private void mniInsert_Click(object sender, System.EventArgs e) {
if (m_stp == null)
return;
InsertFrame(m_stp, m_stp.ActiveFrame, new Frame(), true);
m_stp.ActiveFrame = m_stp.ActiveFrame;
}
private void mniDelete_Click(object sender, System.EventArgs e) {
DeleteFrame(m_stp, m_stp.ActiveFrame, true);
}
private void mniCopy_Click(object sender, System.EventArgs e) {
Frame fr = (Frame)m_stp[m_stp.ActiveFrame].Clone();
Clipboard.SetDataObject(fr);
}
private void mniCut_Click(object sender, System.EventArgs e) {
mniCopy_Click(sender, e);
mniDelete_Click(sender, e);
}
private void mniPaste_Click(object sender, System.EventArgs e) {
IDataObject dta = Clipboard.GetDataObject();
if (dta.GetDataPresent(typeof(Frame))) {
Frame fr = (Frame)dta.GetData(typeof(Frame));
InsertFrame(m_stp, m_stp.ActiveFrame, fr, true);
}
}
private void UndoDelete(object[] aobArgs) {
((Strip)aobArgs[0]).Insert((int)aobArgs[1], (Frame)aobArgs[2]);
((Strip)aobArgs[0]).ActiveFrame = (int)aobArgs[3];
Invalidate();
RecalcScrollbar();
}
private void UndoInsert(object[] aobArgs) {
DeleteFrame((Strip)aobArgs[0], (int)aobArgs[1], false);
((Strip)aobArgs[0]).ActiveFrame = (int)aobArgs[2];
Invalidate();
RecalcScrollbar();
}
private void InsertFrame(Strip stp, int ifr, Frame fr, bool fUndoable) {
if (fUndoable)
UndoManager.AddUndo(new UndoDelegate(UndoInsert), new Object [] { stp, ifr, stp.ActiveFrame });
stp.Insert(ifr, fr);
Globals.ActiveDocument.Dirty = true;
Invalidate();
RecalcScrollbar();
}
private void DeleteFrame(Strip stp, int ifr, bool fUndoable) {
if (fUndoable)
UndoManager.AddUndo(new UndoDelegate(UndoDelete), new object[] { stp, ifr, stp[ifr], stp.ActiveFrame});
stp.RemoveAt(ifr);
Globals.ActiveDocument.Dirty = true;
if (stp.ActiveFrame >= stp.Count)
stp.ActiveFrame = stp.Count - 1;
RecalcScrollbar();
}
private void tmrScroll_Tick(object sender, System.EventArgs e) {
if (m_ifrInsertionPoint == -1)
return;
Point ptMouse = PointToClient(Control.MousePosition);
int v;
if (ptMouse.X < 0) {
v = Math.Max(0, sb.Value - m_cxFrame);
} else if (ptMouse.X >= ClientRectangle.Width) {
v = Math.Min((m_cxFrame * m_stp.Count) - ClientRectangle.Width + 1, sb.Value + m_cxFrame);
} else {
return;
}
if (v < sb.Minimum) {
v = sb.Minimum;
}
if (v > sb.Maximum) {
v = sb.Maximum;
}
sb.Value = v;
SetInsertionPoint(ptMouse.X);
}
}
public delegate void FrameOffsetEventHandler(object sender, FrameOffsetEventArgs e);
public class FrameOffsetEventArgs : EventArgs {
public int X;
public int Y;
public FrameOffsetEventArgs(int x, int y) {
X = x;
Y = y;
}
}
}

Binary file not shown.

108
AniMax/StripControl.resx Normal file
View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="mnu.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="tmrScroll.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>90, 17</value>
</data>
<data name="$this.Name">
<value>StripControl</value>
</data>
</root>

267
AniMax/StripForm.cs Normal file
View File

@ -0,0 +1,267 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Crownwood.Magic.Docking;
namespace SpiffCode
{
/// <summary>
/// Summary description for StripForm.
/// </summary>
public class StripForm : System.Windows.Forms.Form
{
private Content m_tnt;
private AnimDoc m_doc;
private SpiffCode.StripControl stpc;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.CheckBox ckbToggleGrid;
private System.Windows.Forms.CheckBox ckbToggleSideColor;
private System.Windows.Forms.CheckBox ckbToggleOriginPoint;
private System.Windows.Forms.CheckBox ckbToggleSpecialPoint;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.Button button1;
private System.ComponentModel.IContainer components;
public StripForm(AnimDoc doc)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
// My constructor code
Globals.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged);
Globals.ActiveStripChanged += new EventHandler(OnActiveStripChanged);
Globals.TileSizeChanged += new EventHandler(OnTileSizeChanged);
Globals.StripControl = stpc;
m_doc = doc;
ckbToggleGrid.Checked = Globals.GridOn;
ckbToggleSideColor.Checked = Globals.SideColorMappingOn;
ckbToggleOriginPoint.Checked = Globals.ShowOriginPoint;
ckbToggleSpecialPoint.Checked = Globals.ShowSpecialPoint;
RefreshView();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(StripForm));
this.stpc = new SpiffCode.StripControl();
this.panel1 = new System.Windows.Forms.Panel();
this.ckbToggleSpecialPoint = new System.Windows.Forms.CheckBox();
this.ckbToggleOriginPoint = new System.Windows.Forms.CheckBox();
this.ckbToggleSideColor = new System.Windows.Forms.CheckBox();
this.ckbToggleGrid = new System.Windows.Forms.CheckBox();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.button1 = new System.Windows.Forms.Button();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// stpc
//
this.stpc.AllowDrop = true;
this.stpc.BackColor = System.Drawing.SystemColors.Control;
this.stpc.Dock = System.Windows.Forms.DockStyle.Fill;
this.stpc.DockPadding.Bottom = 1;
this.stpc.DockPadding.Right = 1;
this.stpc.Location = new System.Drawing.Point(0, 26);
this.stpc.Name = "stpc";
this.stpc.Size = new System.Drawing.Size(648, 100);
this.stpc.Strip = null;
this.stpc.TabIndex = 0;
//
// panel1
//
this.panel1.Controls.Add(this.button1);
this.panel1.Controls.Add(this.ckbToggleSpecialPoint);
this.panel1.Controls.Add(this.ckbToggleOriginPoint);
this.panel1.Controls.Add(this.ckbToggleSideColor);
this.panel1.Controls.Add(this.ckbToggleGrid);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(648, 26);
this.panel1.TabIndex = 1;
//
// ckbToggleSpecialPoint
//
this.ckbToggleSpecialPoint.Appearance = System.Windows.Forms.Appearance.Button;
this.ckbToggleSpecialPoint.Image = ((System.Drawing.Image)(resources.GetObject("ckbToggleSpecialPoint.Image")));
this.ckbToggleSpecialPoint.Location = new System.Drawing.Point(52, 0);
this.ckbToggleSpecialPoint.Name = "ckbToggleSpecialPoint";
this.ckbToggleSpecialPoint.Size = new System.Drawing.Size(24, 24);
this.ckbToggleSpecialPoint.TabIndex = 9;
this.toolTip1.SetToolTip(this.ckbToggleSpecialPoint, "Toggle Special Point on/off");
this.ckbToggleSpecialPoint.CheckedChanged += new System.EventHandler(this.ckbToggleSpecialPoint_CheckedChanged);
//
// ckbToggleOriginPoint
//
this.ckbToggleOriginPoint.Appearance = System.Windows.Forms.Appearance.Button;
this.ckbToggleOriginPoint.Image = ((System.Drawing.Image)(resources.GetObject("ckbToggleOriginPoint.Image")));
this.ckbToggleOriginPoint.Location = new System.Drawing.Point(26, 0);
this.ckbToggleOriginPoint.Name = "ckbToggleOriginPoint";
this.ckbToggleOriginPoint.Size = new System.Drawing.Size(24, 24);
this.ckbToggleOriginPoint.TabIndex = 4;
this.toolTip1.SetToolTip(this.ckbToggleOriginPoint, "Toggle Origin Point on/off");
this.ckbToggleOriginPoint.CheckedChanged += new System.EventHandler(this.ckbToggleOriginPoint_CheckedChanged);
//
// ckbToggleSideColor
//
this.ckbToggleSideColor.Appearance = System.Windows.Forms.Appearance.Button;
this.ckbToggleSideColor.Image = ((System.Drawing.Image)(resources.GetObject("ckbToggleSideColor.Image")));
this.ckbToggleSideColor.Location = new System.Drawing.Point(78, 0);
this.ckbToggleSideColor.Name = "ckbToggleSideColor";
this.ckbToggleSideColor.Size = new System.Drawing.Size(24, 24);
this.ckbToggleSideColor.TabIndex = 1;
this.toolTip1.SetToolTip(this.ckbToggleSideColor, "Toggle side color preview on/off");
this.ckbToggleSideColor.CheckedChanged += new System.EventHandler(this.ckbToggleSideColor_CheckedChanged);
//
// ckbToggleGrid
//
this.ckbToggleGrid.Appearance = System.Windows.Forms.Appearance.Button;
this.ckbToggleGrid.Image = ((System.Drawing.Image)(resources.GetObject("ckbToggleGrid.Image")));
this.ckbToggleGrid.Location = new System.Drawing.Point(0, 0);
this.ckbToggleGrid.Name = "ckbToggleGrid";
this.ckbToggleGrid.Size = new System.Drawing.Size(24, 24);
this.ckbToggleGrid.TabIndex = 0;
this.toolTip1.SetToolTip(this.ckbToggleGrid, "Toggle Grid on/off");
this.ckbToggleGrid.CheckedChanged += new System.EventHandler(this.ckbToggleGrid_CheckedChanged);
//
// button1
//
this.button1.Location = new System.Drawing.Point(104, 0);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(27, 24);
this.button1.TabIndex = 11;
this.button1.Text = "TS";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// StripForm
//
this.AutoScale = false;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(648, 126);
this.Controls.Add(this.stpc);
this.Controls.Add(this.panel1);
this.Name = "StripForm";
this.Text = "Frames";
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
public Content Content {
set {
m_tnt = value;
}
}
private void OnActiveDocumentChanged(object obSender, EventArgs e) {
m_doc = Globals.ActiveDocument;
RefreshView();
}
private void OnActiveStripChanged(object obSender, EventArgs e) {
RefreshView();
}
private void RefreshView() {
stpc.Strip = Globals.ActiveStrip;
string strT = Globals.ActiveStrip == null ? "(none)" : Globals.ActiveStrip.Name;
Text = "Frames - " + strT;
if (m_tnt != null)
m_tnt.Title = Text;
}
private void ckbToggleGrid_CheckedChanged(object sender, System.EventArgs e) {
Globals.GridOn = ckbToggleGrid.Checked;
}
private void ckbToggleSideColor_CheckedChanged(object sender, System.EventArgs e) {
Globals.SideColorMappingOn = ckbToggleSideColor.Checked;
}
private void ckbToggleOriginPoint_CheckedChanged(object sender, System.EventArgs e) {
Globals.ShowOriginPoint = ckbToggleOriginPoint.Checked;
}
private void ckbToggleSpecialPoint_CheckedChanged(object sender, System.EventArgs e) {
Globals.ShowSpecialPoint = ckbToggleSpecialPoint.Checked;
}
#if false
private void ckbToggleHires_CheckedChanged(object sender, System.EventArgs e) {
bool fHires = ckbToggleHires.Checked;
if (Globals.Hires != fHires)
Globals.Hires = fHires;
if (Globals.ActiveDocument.Hires != fHires)
Globals.ActiveDocument.Hires = fHires;
}
#endif
private void OnTileSizeChanged(object obSender, EventArgs e) {
#if false
ckbToggleHires.Checked = Globals.Hires;
#endif
}
private void btnProperties_Click(object sender, System.EventArgs e) {
ShowStripProperties(stpc.Strip);
}
public void ShowStripProperties(Strip stp) {
Form frm = new StripProperties(stp);
if (frm.ShowDialog(this) == DialogResult.Cancel)
return;
// UNDONE: animation interval must be updated if Strip.DefHoldCount changes
// if (stp == stpc.Strip)
// tmrAnim.Interval = 80 + (80 * stpc.Strip.DefHoldCount);
}
private void button1_Click(object sender, System.EventArgs e) {
int nTSNew = 32;
switch (Globals.TileSize) {
case 16:
nTSNew = 24;
break;
case 24:
nTSNew = 32;
break;
case 32:
nTSNew = 16;
break;
}
if (Globals.TileSize != nTSNew) {
Globals.TileSize = nTSNew;
}
if (Globals.ActiveDocument.TileSize != nTSNew) {
Globals.ActiveDocument.TileSize = nTSNew;
}
}
}
}

BIN
AniMax/StripForm.resources Normal file

Binary file not shown.

243
AniMax/StripForm.resx Normal file
View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used forserialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="stpc.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="stpc.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="stpc.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="panel1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="panel1.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="panel1.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="panel1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="panel1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="panel1.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="ckbToggleSpecialPoint.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ckbToggleSpecialPoint.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleSpecialPoint.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleSpecialPoint.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAADNJREFUOE9j/P//PwNFAGQAJZgizWDXU2L7IDeAARi2MIjPmzjDYOANIDZ2hnM0Dp0w
AAAXu8dW6QvQNwAAAABJRU5ErkJggg==
</value>
</data>
<data name="ckbToggleOriginPoint.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ckbToggleOriginPoint.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleOriginPoint.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleOriginPoint.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAADRJREFUOE9j/P//PwNFAGQAJZgizWDXU2L7IDfga4PCfxjG502cYTDwBhAbO8M5GodO
GAAAjp/MnENk/sEAAAAASUVORK5CYII=
</value>
</data>
<data name="ckbToggleSideColor.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ckbToggleSideColor.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleSideColor.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleSideColor.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAAFdJREFUOE9j/P//PwNFAGQAJZgizWDXU2I7xPslL/6jY1yGvlBg+I+O8RoANB5oFiKM
SDYAGkNwQ0gyAGQ7MgYZRpIBMKcje4NkA6gSBgQDkeJ0MGoAAwAGCYiV2rv9ugAAAABJRU5ErkJggg==
</value>
</data>
<data name="ckbToggleGrid.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="ckbToggleGrid.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleGrid.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="ckbToggleGrid.Image" type="System.Drawing.Bitmap, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALEwAA
CxMBAJqcGAAAAD1JREFUOE9j+P//PwMML1++CshE8NHZ2OThmkGKB8YAkK3kYpCrB4EXhkEsDLwXyE0D
sFQ73NIBvqyMSw4AfNj7z9qm0egAAAAASUVORK5CYII=
</value>
</data>
<data name="toolTip1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="toolTip1.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>138, 23</value>
</data>
<data name="toolTip1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="button1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="button1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="button1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>(Default)</value>
</data>
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Name">
<value>StripForm</value>
</data>
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>80</value>
</data>
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
</root>

120
AniMax/StripProperties.cs Normal file
View File

@ -0,0 +1,120 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for StripProperties.
/// </summary>
public class StripProperties : System.Windows.Forms.Form
{
private System.Windows.Forms.PropertyGrid prgStrip;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOK;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public StripProperties(Strip stp)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
prgStrip.SelectedObject = stp;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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.prgStrip = new System.Windows.Forms.PropertyGrid();
this.panel1 = new System.Windows.Forms.Panel();
this.btnCancel = new System.Windows.Forms.Button();
this.btnOK = new System.Windows.Forms.Button();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// prgStrip
//
this.prgStrip.CommandsVisibleIfAvailable = true;
this.prgStrip.Dock = System.Windows.Forms.DockStyle.Fill;
this.prgStrip.HelpVisible = false;
this.prgStrip.LargeButtons = false;
this.prgStrip.LineColor = System.Drawing.SystemColors.ScrollBar;
this.prgStrip.Name = "prgStrip";
this.prgStrip.Size = new System.Drawing.Size(292, 294);
this.prgStrip.TabIndex = 0;
this.prgStrip.Text = "Strip Properties";
this.prgStrip.ViewBackColor = System.Drawing.SystemColors.Window;
this.prgStrip.ViewForeColor = System.Drawing.SystemColors.WindowText;
//
// panel1
//
this.panel1.Controls.AddRange(new System.Windows.Forms.Control[] {
this.btnCancel,
this.btnOK});
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panel1.Location = new System.Drawing.Point(0, 294);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(292, 40);
this.panel1.TabIndex = 1;
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(169, 8);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
//
// btnOK
//
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnOK.Location = new System.Drawing.Point(49, 8);
this.btnOK.Name = "btnOK";
this.btnOK.TabIndex = 0;
this.btnOK.Text = "OK";
//
// StripProperties
//
this.AcceptButton = this.btnOK;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(292, 334);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.prgStrip,
this.panel1});
this.Name = "StripProperties";
this.Text = "Strip Properties";
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
}
}

Binary file not shown.

102
AniMax/StripProperties.resx Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.Name">
<value>StripProperties</value>
</data>
</root>

69
AniMax/StripSet.cs Normal file
View File

@ -0,0 +1,69 @@
using System;
using System.Collections;
using System.Runtime.Serialization;
namespace SpiffCode
{
/// <summary>
/// Summary description for StripSet.
/// </summary>
[Serializable]
public class StripSet : CollectionBase, ISerializable
{
public StripSet() {
}
public Strip this[int i] {
get {
return (Strip)InnerList[i];
}
set {
InnerList[i] = value;
}
}
public Strip this[string strStripName] {
get {
foreach (Strip stp in InnerList) {
if (stp.Name == strStripName)
return stp;
}
return null;
}
}
// For whatever reason the designers of CollectionBase decided to implement
// IList.Add as 'explicit' which means it is effectively hidden from users
// of derived classes. So we must add our own Add method which does have the
// benefit of being type-safe (possibly why they hid IList.Add in the first place)
public int Add(Strip stp) {
return ((IList)this).Add(stp);
}
public int IndexOf(Strip stp) {
return ((IList)this).IndexOf(stp);
}
public void Sort() {
InnerList.Sort();
}
// ISerializable interface implementation
private StripSet(SerializationInfo seri, StreamingContext stmc) {
for (int i = 0; i < seri.MemberCount; i++) {
Strip stp = (Strip)seri.GetValue(i.ToString(), typeof(Strip));
Add(stp);
}
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
int i = 0;
foreach (Strip stp in InnerList) {
seri.AddValue(i.ToString(), stp);
i++;
}
}
}
}

490
AniMax/StripsForm.cs Normal file
View File

@ -0,0 +1,490 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for StripsForm.
/// </summary>
public class StripsForm : System.Windows.Forms.Form
{
private AnimDoc m_doc;
private StripSet m_stps;
private Strip m_stpActive;
private System.Windows.Forms.ListView lstv;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.MenuItem mniView;
private System.Windows.Forms.MenuItem mniViewDetails;
private System.Windows.Forms.MenuItem mniViewList;
private System.Windows.Forms.MenuItem mniViewThumbnails;
private System.Windows.Forms.ContextMenu mnuListView;
private System.Windows.Forms.MenuItem mniNewStrip;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem mniDelete;
private System.Windows.Forms.MenuItem mniRename;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem mniProperties;
private System.Windows.Forms.MenuItem mniStripsSort;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public StripsForm(AnimDoc doc)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
// My constructor code
Globals.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged);
Globals.ActiveStripChanged += new EventHandler(OnActiveStripChanged);
m_doc = doc;
m_stps = m_doc.StripSet;
RefreshView();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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.mniViewList = new System.Windows.Forms.MenuItem();
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
this.mniView = new System.Windows.Forms.MenuItem();
this.mniViewThumbnails = new System.Windows.Forms.MenuItem();
this.mniViewDetails = new System.Windows.Forms.MenuItem();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.mniRename = new System.Windows.Forms.MenuItem();
this.mnuListView = new System.Windows.Forms.ContextMenu();
this.mniNewStrip = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.mniDelete = new System.Windows.Forms.MenuItem();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.mniProperties = new System.Windows.Forms.MenuItem();
this.lstv = new System.Windows.Forms.ListView();
this.mniStripsSort = new System.Windows.Forms.MenuItem();
this.SuspendLayout();
//
// mniViewList
//
this.mniViewList.Index = 0;
this.mniViewList.Text = "List";
this.mniViewList.Click += new System.EventHandler(this.mniViewList_Click);
//
// columnHeader2
//
this.columnHeader2.Text = "# frames";
//
// mniView
//
this.mniView.Index = 5;
this.mniView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniViewList,
this.mniViewThumbnails,
this.mniViewDetails});
this.mniView.Text = "View";
this.mniView.Popup += new System.EventHandler(this.mniView_Popup);
//
// mniViewThumbnails
//
this.mniViewThumbnails.Index = 1;
this.mniViewThumbnails.Text = "Thumbnails";
this.mniViewThumbnails.Click += new System.EventHandler(this.mniViewThumbnails_Click);
//
// mniViewDetails
//
this.mniViewDetails.Index = 2;
this.mniViewDetails.Text = "Details";
this.mniViewDetails.Click += new System.EventHandler(this.mniViewDetails_Click);
//
// columnHeader1
//
this.columnHeader1.Text = "Name";
this.columnHeader1.Width = 90;
//
// mniRename
//
this.mniRename.Index = 3;
this.mniRename.Text = "Rename";
this.mniRename.Click += new System.EventHandler(this.mniRename_Click);
//
// mnuListView
//
this.mnuListView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mniNewStrip,
this.menuItem2,
this.mniDelete,
this.mniRename,
this.menuItem1,
this.mniView,
this.mniStripsSort,
this.menuItem3,
this.mniProperties});
this.mnuListView.Popup += new System.EventHandler(this.mnuListView_Popup);
//
// mniNewStrip
//
this.mniNewStrip.Index = 0;
this.mniNewStrip.Text = "New Strip";
this.mniNewStrip.Click += new System.EventHandler(this.mniNewStrip_Click);
//
// menuItem2
//
this.menuItem2.Index = 1;
this.menuItem2.Text = "-";
//
// mniDelete
//
this.mniDelete.Index = 2;
this.mniDelete.Shortcut = System.Windows.Forms.Shortcut.Del;
this.mniDelete.Text = "Delete";
this.mniDelete.Click += new System.EventHandler(this.mniDelete_Click);
//
// menuItem1
//
this.menuItem1.Index = 4;
this.menuItem1.Text = "-";
//
// menuItem3
//
this.menuItem3.Index = 7;
this.menuItem3.Text = "-";
//
// mniProperties
//
this.mniProperties.Index = 8;
this.mniProperties.Text = "&Properties";
this.mniProperties.Click += new System.EventHandler(this.mniProperties_Click);
//
// lstv
//
this.lstv.AllowColumnReorder = true;
this.lstv.AllowDrop = true;
this.lstv.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2});
this.lstv.ContextMenu = this.mnuListView;
this.lstv.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstv.FullRowSelect = true;
this.lstv.HideSelection = false;
this.lstv.LabelEdit = true;
this.lstv.MultiSelect = false;
this.lstv.Name = "lstv";
this.lstv.Size = new System.Drawing.Size(320, 309);
this.lstv.TabIndex = 0;
this.lstv.View = System.Windows.Forms.View.Details;
this.lstv.ItemActivate += new System.EventHandler(this.lstv_ItemActivate);
this.lstv.DoubleClick += new System.EventHandler(this.lstv_DoubleClick);
this.lstv.DragDrop += new System.Windows.Forms.DragEventHandler(this.lstv_DragDrop);
this.lstv.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lstv_AfterLabelEdit);
this.lstv.DragEnter += new System.Windows.Forms.DragEventHandler(this.lstv_DragEnter);
this.lstv.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.lstv_ItemDrag);
this.lstv.BeforeLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.lstv_BeforeLabelEdit);
this.lstv.SelectedIndexChanged += new System.EventHandler(this.lstv_SelectedIndexChanged);
//
// mniStripsSort
//
this.mniStripsSort.Index = 6;
this.mniStripsSort.Text = "&Sort";
this.mniStripsSort.Click += new System.EventHandler(this.mniStripsSort_Click);
//
// StripsForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(320, 309);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.lstv});
this.Name = "StripsForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "Strips";
this.ResumeLayout(false);
}
#endregion
private void OnActiveDocumentChanged(object obSender, EventArgs e) {
m_doc = Globals.ActiveDocument;
m_stps = m_doc.StripSet;
RefreshView();
}
private void OnActiveStripChanged(object obSender, EventArgs e) {
if (m_stpActive == Globals.ActiveStrip)
return;
m_stpActive = Globals.ActiveStrip;
foreach (ListViewItem lvi in lstv.Items) {
if (lvi.Tag == Globals.ActiveStrip) {
lvi.Selected = true;
break;
}
}
}
private void mniView_Popup(object sender, System.EventArgs e) {
mniViewList.Checked = false;
mniViewThumbnails.Checked = false;
mniViewDetails.Checked = false;
switch (lstv.View) {
case View.List:
mniViewList.Checked = true;
break;
case View.LargeIcon:
mniViewThumbnails.Checked = true;
break;
case View.Details:
mniViewDetails.Checked = true;
break;
}
}
private void mniViewDetails_Click(object sender, System.EventArgs e) {
lstv.View = View.Details;
}
private void mniViewThumbnails_Click(object sender, System.EventArgs e) {
lstv.View = View.LargeIcon;
}
private void mniViewList_Click(object sender, System.EventArgs e) {
lstv.View = View.List;
}
private void RefreshView() {
lstv.Items.Clear();
if (m_stps == null)
return;
// Prep LargeImageList
if (lstv.LargeImageList != null)
lstv.LargeImageList.Dispose();
lstv.LargeImageList = new ImageList();
lstv.LargeImageList.ColorDepth = ColorDepth.Depth32Bit;
lstv.LargeImageList.ImageSize = new Size(64, 64);
// Prep SmallImageList
if (lstv.SmallImageList != null)
lstv.SmallImageList.Dispose();
lstv.SmallImageList = new ImageList();
lstv.SmallImageList.ColorDepth = ColorDepth.Depth32Bit;
lstv.SmallImageList.ImageSize = new Size(16, 16);
int i = 0;
foreach (Strip stp in m_stps) {
ListViewItem lvi = lstv.Items.Add(stp.Name);
lvi.Tag = stp;
if (stp == Globals.ActiveStrip)
lvi.Selected = true;
lvi.SubItems.Add(stp.Count.ToString());
// UNDONE: cook up better thumbnails
// UNDONE: have a 'blank' thumbnail for empty Strips
if (stp.Count > 0) {
if (stp[0].BitmapPlacers.Count > 0) {
XBitmap xbm = stp[0].BitmapPlacers[0].XBitmap;
Bitmap bmThumb = xbm.MakeThumbnail(64, 64, false);
lstv.LargeImageList.Images.Add(bmThumb);
bmThumb = xbm.MakeThumbnail(16, 16, false);
lstv.SmallImageList.Images.Add(bmThumb);
lvi.ImageIndex = i++;
}
}
}
}
private void mniNewStrip_Click(object sender, System.EventArgs e) {
NewStrip();
}
public void NewStrip() {
Strip stp = new Strip("untitled " + (m_stps.Count + 1).ToString());
// UNDONE: undo
m_stps.Add(stp);
Globals.ActiveStrip = stp;
m_doc.Dirty = true;
RefreshView();
}
private void lstv_BeforeLabelEdit(object sender, System.Windows.Forms.LabelEditEventArgs e) {
// We do this so the user can press the del key while in label editing mode
// without it being intercepted by the context menu and used to delete the
// entire Strip
lstv.ContextMenu = null;
}
private void lstv_AfterLabelEdit(object sender, System.Windows.Forms.LabelEditEventArgs e) {
// Restore the context menu so the command keys, etc will work again
lstv.ContextMenu = mnuListView;
Strip stp = (Strip)lstv.Items[e.Item].Tag;
// No change or an invalid change
if (e.Label == null || e.Label == "") {
e.CancelEdit = true;
return;
}
stp.Name = e.Label;
m_doc.Dirty = true;
}
private void mnuListView_Popup(object sender, System.EventArgs e) {
bool fAnySelected = lstv.SelectedItems.Count != 0;
mniDelete.Enabled = fAnySelected;
mniRename.Enabled = fAnySelected;
mniProperties.Enabled = fAnySelected;
}
private void mniDelete_Click(object sender, System.EventArgs e) {
Strip stp = (Strip)lstv.SelectedItems[0].Tag;
int i = m_stps.IndexOf(stp);
// UNDONE: undo
m_stps.RemoveAt(i);
lstv.Items.Remove(lstv.SelectedItems[0]);
m_doc.Dirty = true;
// Select a new Strip to be active
i = Math.Min(i, m_stps.Count - 1);
if (i >= 0)
Globals.ActiveStrip = m_stps[i];
else
Globals.ActiveStrip = null;
}
private void mniRename_Click(object sender, System.EventArgs e) {
MessageBox.Show(this, "Click on the name of the strip to select it then edit it in place.",
"AniMax");
}
private void lstv_ItemActivate(object sender, System.EventArgs e) {
// m_doc.ActiveStrip = (Strip)lstv.SelectedItems[0].Tag;
}
private void lstv_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
}
private void lstv_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
string[] astrFiles = e.Data.GetData(DataFormats.FileDrop) as string[];
if (astrFiles != null) {
if (astrFiles.Length == 1)
((MainForm)Globals.MainForm).CloseAndOpenDocument(astrFiles[0]);
else
MessageBox.Show(this, "Please, only drop one animation file.", "Too many files dropped", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
#if false
XBitmap[] axbm = e.Data.GetData(typeof(XBitmap[])) as XBitmap[];
if (axbm == null)
return;
// Use the standard file naming convention to break the bitmaps down into
// animations (e.g., *_fire_*_*), a single track (e.g., track 1), and a set
// of TSprite keys (e.g., *_*_d_n)
foreach (XBitmap xbm in axbm) {
string strFile = xbm.FileName;
string[] astr = strFile.Substring(strFile.LastIndexOf('\\') + 1).Split('_', '.');
if (astr.Length != 5) {
MessageBox.Show(this, String.Format("Warning: file {0} does not match the requisite naming pattern", strFile),
"AniMax");
continue;
}
// Find the appropriate animation
Strip stp = null;
Frame fr = null;
string strName = astr[1] + " " + astr[2];
foreach (Strip stpT in m_stps) {
if (stpT.Name == strName) {
stp = stpT;
fr = stp[0];
break;
}
}
// If one isn't found, create a new stpmation and empty track
if (stp == null) {
stp = new Strip(strName);
m_stps.Add(stp);
tspr = new TSprite("track 1");
stp.Add(tspr);
}
Sprite spr = new Sprite(xbm, 0, 0);
Time t = 0;
if (tspr.End != Time.tUndefined)
t = tspr.End + m_doc.FrameRate;
tspr.SetValue(t, spr);
}
m_doc.Dirty = true;
RefreshView();
#endif
}
private void lstv_SelectedIndexChanged(object sender, System.EventArgs e) {
if (lstv.SelectedItems.Count == 0)
return;
Globals.ActiveStrip = (Strip)lstv.SelectedItems[0].Tag;
}
private void lstv_DoubleClick(object sender, System.EventArgs e) {
((StripForm)Globals.StripForm).ShowStripProperties((Strip)lstv.SelectedItems[0].Tag);
}
private void mniProperties_Click(object sender, System.EventArgs e) {
((StripForm)Globals.StripForm).ShowStripProperties((Strip)lstv.SelectedItems[0].Tag);
}
private void lstv_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e) {
DoDragDrop(lstv.SelectedItems[0].Tag, DragDropEffects.All);
}
private void mniStripsSort_Click(object sender, System.EventArgs e) {
m_stps.Sort();
RefreshView();
}
}
}

BIN
AniMax/StripsForm.resources Normal file

Binary file not shown.

105
AniMax/StripsForm.resx Normal file
View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="mnuListView.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="$this.Name">
<value>StripsForm</value>
</data>
</root>

69
AniMax/UndoManager.cs Normal file
View File

@ -0,0 +1,69 @@
using System;
using System.Collections;
using System.Diagnostics;
namespace SpiffCode {
public delegate void UndoDelegate(object[] aobArgs);
public class UndoManager {
private static Stack s_stk = new Stack();
private static int s_cElements;
private static bool s_fGrouping = false;
public static void AddUndo(UndoDelegate dgtUndo, object[] aobArgs) {
if (s_fGrouping)
s_cElements++;
s_stk.Push(aobArgs);
s_stk.Push(dgtUndo);
}
public static void Flush() {
s_stk.Clear();
}
public static void Undo() {
if (s_stk.Count == 0)
return;
UndoDelegate dgtUndo;
object[] aobArgs;
object ob = s_stk.Pop();
if (ob is int) {
int cElements = (int)ob;
for (int i = 0; i < cElements; i++) {
dgtUndo = (UndoDelegate)s_stk.Pop();
aobArgs = (object[])s_stk.Pop();
dgtUndo(aobArgs);
}
return;
}
dgtUndo = (UndoDelegate)ob;
aobArgs = (object[])s_stk.Pop();
dgtUndo(aobArgs);
}
public static void Redo() {
// UNDONE:
}
public static bool AnyUndos() {
return s_stk.Count != 0;
}
// WARNING: can't do nested groups
public static void BeginGroup() {
Debug.Assert(!s_fGrouping);
s_fGrouping = true;
s_cElements = 0;
}
public static void EndGroup() {
s_fGrouping = false;
s_stk.Push(s_cElements);
}
}
}

178
AniMax/WallPreviewForm.cs Normal file
View File

@ -0,0 +1,178 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace SpiffCode
{
/// <summary>
/// Summary description for WallPreviewForm.
/// </summary>
public class WallPreviewForm : System.Windows.Forms.Form
{
private const int kctxMap = 64;
private const int kctyMap = 64;
private bool m_fMouseDown = false;
private bool m_fSet;
private bool[,] m_mpfWall = new bool[kctxMap, kctyMap];
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public WallPreviewForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
m_mpfWall[5, 5] = true;
m_mpfWall[6, 5] = true;
m_mpfWall[6, 6] = true;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(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()
{
//
// WallPreviewForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(368, 334);
this.Name = "WallPreviewForm";
this.Text = "Wall Preview";
}
#endregion
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
Graphics g = e.Graphics;
int nScale = Globals.PreviewScale;
Bitmap bmDst = new Bitmap(Width, Height);
Graphics gDst = Graphics.FromImage(bmDst);
// Draw background (if enabled)
// if (drwa.fDrawBackground)
gDst.Clear(BackColor);
// Draw grid (if enabled)
if (true) {
Brush br = new SolidBrush(Color.FromArgb(256 / 3, 255, 255, 255));
for (int x = 0; x < bmDst.Width; x += Globals.GridWidth)
gDst.FillRectangle(br, x, 0, 1, bmDst.Height);
for (int y = 0; y < bmDst.Height; y += Globals.GridHeight)
gDst.FillRectangle(br, 0, y, bmDst.Width, 1);
}
BitmapData bmdDst = bmDst.LockBits(new Rectangle(0, 0, bmDst.Width, bmDst.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
for (int ty = 0; ty < Height / Globals.GridHeight; ty++) {
for (int tx = 0; tx < Width / Globals.GridWidth; tx++) {
if (m_mpfWall[tx, ty]) {
int ifrm = 0;
if (ty > 0)
ifrm |= m_mpfWall[tx, ty - 1] ? 1 : 0;
if (tx < kctxMap - 1)
ifrm |= m_mpfWall[tx + 1, ty] ? 2 : 0;
if (ty < kctyMap - 1)
ifrm |= m_mpfWall[tx, ty + 1] ? 4 : 0;
if (tx > 0)
ifrm |= m_mpfWall[tx - 1, ty] ? 8 : 0;
XBitmap xbm = Globals.ActiveStrip[ifrm].BitmapPlacers[0].XBitmap;
xbm.SuperBlt(0, 0, bmdDst,
tx * Globals.GridWidth, ty * Globals.GridHeight,
xbm.Bitmap.Width, xbm.Bitmap.Height,
Globals.SideColorMappingOn);
}
}
}
bmDst.UnlockBits(bmdDst);
// Force a nice simple fast old-school stretchblt
InterpolationMode imOld = g.InterpolationMode;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
// NOTE: _without_ this the first row and column are only scaled by half!
PixelOffsetMode pomOld = g.PixelOffsetMode;
g.PixelOffsetMode = PixelOffsetMode.Half;
// StretchBlt the temporary composite to the passed-in Graphic
g.DrawImage(bmDst, 0, 0, bmDst.Width * nScale, bmDst.Height * nScale);
g.PixelOffsetMode = pomOld;
g.InterpolationMode = imOld;
// e.Graphics.DrawImage(bmDst, 0, 0, Width, Height);
bmDst.Dispose();
gDst.Dispose();
}
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e) {
int nScale = Globals.PreviewScale;
m_fMouseDown = true;
int tx = e.X / (Globals.GridWidth * nScale);
int ty = e.Y / (Globals.GridHeight * nScale);
m_fSet = !m_mpfWall[tx, ty];
m_mpfWall[tx, ty] = m_fSet;
Invalidate();
}
protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e) {
if (!m_fMouseDown)
return;
int nScale = Globals.PreviewScale;
int tx = e.X / (Globals.GridWidth * nScale);
int ty = e.Y / (Globals.GridHeight * nScale);
m_mpfWall[tx, ty] = m_fSet;
Invalidate();
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent) {
}
protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e) {
m_fMouseDown = false;
}
}
}

Binary file not shown.

102
AniMax/WallPreviewForm.resx Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.Name">
<value>WallPreviewForm</value>
</data>
</root>

610
AniMax/XBitmap.cs Normal file
View File

@ -0,0 +1,610 @@
using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
namespace SpiffCode
{
/// <summary>
/// Summary description for XBitmap.
/// </summary>
// UNDONE: implement IDisposable and m_bm.Dispose()
[Serializable]
public class XBitmap : ISerializable {
private Bitmap m_bm;
private Bitmap m_bmBlack;
private string m_strFileName;
private bool m_fDirty = false;
public XBitmap(string strFileName) {
Load(strFileName, false);
}
public XBitmap(string strFileName, bool fFrame) {
Load(strFileName, true);
}
private XBitmap(Bitmap bm, Bitmap bmBlack, string strFileName,
bool fDirty) {
m_bm = bm;
m_bmBlack = bmBlack;
m_strFileName = strFileName;
m_fDirty = fDirty;
}
public XBitmap Clone() {
return new XBitmap((Bitmap)m_bm.Clone(),
m_bmBlack == null ? null : (Bitmap)m_bmBlack.Clone(),
(string)m_strFileName.Clone(), m_fDirty);
}
public static string[] FilterFileNames(string[] astrFileNames) {
ArrayList alFilenames = new ArrayList();
foreach (string strFile in astrFileNames) {
try {
HasBlackCompanion(strFile);
alFilenames.Add(strFile);
} catch (Exception) {
}
}
return (string[])alFilenames.ToArray(typeof(string));
}
// Public properties
public Bitmap Bitmap {
get {
return m_bm;
}
set {
if (m_bmBlack != null) {
throw new Exception("Setting bitmap on XBitmap with black counterpart!");
}
m_bm = value;
m_fDirty = true;
}
}
public string FileName {
get {
return m_strFileName;
}
set {
m_strFileName = value;
}
}
public int Width {
get {
return m_bm.Width;
}
}
public int Height {
get {
return m_bm.Height;
}
}
public bool Dirty {
get {
return m_fDirty;
}
set {
m_fDirty = value;
}
}
private static bool HasBlackCompanion(string strFile) {
// 32 bit XBitmaps have a companion black_<filename>, which
// is used for side color extraction. 8 bit XBitmaps
// do not have this. Encapsulate this knowledge here in XBitmap.
string strPath = Path.GetDirectoryName(strFile);
string strFileName = Path.GetFileName(strFile);
// Ensure the filename doesn't start with black_, otherwise raise
// an exception.
if (strFile.StartsWith("black_")) {
throw new Exception("image file with black_: " + strFile);
}
// File is ok; see if there is a black_ counterpart. If there is,
// this bitmap file is meant to be 32 bit
if (File.Exists(Path.Combine(strPath, "black_" + strFileName))) {
return true;
}
return false;
}
//
private void Load(string strFile, bool fUseFirstPaletteEntryAsTransparentColor) {
if (HasBlackCompanion(strFile)) {
Load32(strFile);
} else {
Load8(strFile, fUseFirstPaletteEntryAsTransparentColor);
}
}
private void Load32(string strFile) {
if (!HasBlackCompanion(strFile)) {
throw new Exception("doesn't have black_ counterpart: " +
strFile);
}
m_strFileName = strFile;
m_bm = new Bitmap(strFile);
string strPath = Path.GetDirectoryName(strFile);
string strFileName = Path.GetFileName(strFile);
m_bmBlack = new Bitmap(Path.Combine(strPath, "black_" + strFileName));
}
private void Load8(string strFileName, bool fUseFirstPaletteEntryAsTransparentColor) {
m_strFileName = strFileName;
m_bm = new Bitmap(strFileName);
m_bmBlack = null;
// All pixels the same color as the upper-left pixel get mapped to the
// transparent color
Color clrTransparent = Color.FromArgb(0xff, 0, 0xff);
SolidBrush brTransparent = new SolidBrush(clrTransparent);
m_bm.MakeTransparent(fUseFirstPaletteEntryAsTransparentColor ? m_bm.Palette.Entries[0] : m_bm.GetPixel(0, 0));
Bitmap bmT = new Bitmap(m_bm.Width, m_bm.Height, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(bmT)) {
// Prep the new image by filling with the transparent color
g.FillRectangle(brTransparent, 0, 0, m_bm.Width, m_bm.Height);
// Convert the Bitmap to 24-bpp while leaving transparent pixels behind
g.DrawImageUnscaled(m_bm, 0, 0);
m_bm.Dispose();
}
m_bm = bmT;
// m_bm.MakeTransparent(clrTransparent);
}
public void Save(string strFileName) {
if (strFileName == null) {
strFileName = m_strFileName;
}
m_bm.Save(strFileName);
if (m_bmBlack != null) {
string strPath = Path.GetDirectoryName(strFileName);
string strFileT = Path.GetFileName(strFileName);
m_bmBlack.Save(Path.Combine(strPath, "black_" + strFileT));
}
m_fDirty = false;
}
/*
* given h,s,l on [0..1],
* return r,g,b on [0..1]
* From Graphics Gems
*/
unsafe static void Hsl2Rgb(double h, double sl, double l,
double *r, double *g, double *b) {
double v;
v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
if (v <= 0) {
*r = *g = *b = 0.0;
} else {
double m;
double sv;
int sextant;
double fract, vsf, mid1, mid2;
m = l + l - v;
sv = (v - m ) / v;
h *= 6.0;
sextant = (int)h;
fract = h - sextant;
vsf = v * sv * fract;
mid1 = m + vsf;
mid2 = v - vsf;
switch (sextant) {
case 0: *r = v; *g = mid1; *b = m; break;
case 1: *r = mid2; *g = v; *b = m; break;
case 2: *r = m; *g = v; *b = mid1; break;
case 3: *r = m; *g = mid2; *b = v; break;
case 4: *r = mid1; *g = m; *b = v; break;
case 5: *r = v; *g = m; *b = mid2; break;
}
}
}
unsafe static void Hsl2Rgb360(double h, double s, double l,
RgbData *prgb) {
// Convert 0..360 to 0..1
double r, g, b;
Hsl2Rgb(h / 360.0, s, l, &r, &g, &b);
prgb->bRed = (byte)(r * 255.0);
prgb->bGreen = (byte)(g * 255.0);
prgb->bBlue = (byte)(b * 255.0);
}
struct RgbaData {
public RgbaData(byte bAlpha, byte bRed, byte bGreen, byte bBlue) {
this.bAlpha = bAlpha;
this.bRed = bRed;
this.bGreen = bGreen;
this.bBlue = bBlue;
}
public byte bBlue;
public byte bGreen;
public byte bRed;
public byte bAlpha;
}
struct RgbData {
public RgbData(byte bRed, byte bGreen, byte bBlue) {
this.bRed = bRed;
this.bGreen = bGreen;
this.bBlue = bBlue;
}
public byte bBlue;
public byte bGreen;
public byte bRed;
}
static RgbData[] argbSide = {
new RgbData(232, 32, 0),
new RgbData(196, 28, 0),
new RgbData(128, 8, 0),
new RgbData(92, 8, 0),
new RgbData(64, 8, 0),
};
public unsafe void SuperBlt(int xSrc, int ySrc,
BitmapData bmdDst, int xDst, int yDst, int cx, int cy,
bool fMapSideColors) {
if (m_bmBlack == null) {
SuperBlt8(xSrc, ySrc, bmdDst, xDst, yDst, cx, cy,
fMapSideColors);
} else {
SuperBlt32(xSrc, ySrc, bmdDst, xDst, yDst, cx, cy,
fMapSideColors);
}
}
public unsafe void SuperBlt32(int xSrc, int ySrc,
BitmapData bmdDst, int xDst, int yDst, int cx, int cy,
bool fMapSideColors) {
// If completely off dst bounds, just return.
if ((xDst >= bmdDst.Width || xDst + cx < 0) ||
(yDst >= bmdDst.Height) || (yDst + cy < 0)) {
return;
}
// Dst clip
if (xDst + cx > bmdDst.Width)
cx = bmdDst.Width - xDst;
if (yDst + cy > bmdDst.Height)
cy = bmdDst.Height - yDst;
if (xDst < 0) {
cx += xDst;
xSrc -= xDst;
xDst = 0;
}
if (yDst < 0) {
cy += yDst;
ySrc -= yDst;
yDst = 0;
}
BitmapData bmdSrc = m_bm.LockBits(
new Rectangle(0, 0, m_bm.Width, m_bm.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData bmdSrcBlack = m_bmBlack.LockBits(
new Rectangle(0, 0, m_bmBlack.Width, m_bmBlack.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
RgbaData* prgbSrc = (RgbaData*)((byte*)bmdSrc.Scan0 +
(ySrc * bmdSrc.Stride) + (xSrc * sizeof(RgbaData)));
RgbaData* prgbSrcBlack = (RgbaData*)((byte*)bmdSrcBlack.Scan0 +
(ySrc * bmdSrcBlack.Stride) + (xSrc * sizeof(RgbaData)));
RgbData* prgbDst = (RgbData*)((byte*)bmdDst.Scan0 +
(yDst * bmdDst.Stride) + (xDst * sizeof(RgbData)));
while (cy-- > 0) {
RgbaData* prgbSrcT = prgbSrc;
RgbaData* prgbSrcBlackT = prgbSrcBlack;
RgbData* prgbDstT = prgbDst;
for (int x = 0; x < cx; x++) {
RgbaData rgbSrc = *prgbSrcT++;
RgbaData rgbSrcBlack = *prgbSrcBlackT++;
// rgbSrc = huemap(rgbSrc - rgbSrcBlack) + rgbSrcBlack
RgbData rgbT;
int v;
v = rgbSrc.bRed - rgbSrcBlack.bRed;
if (v < 0) {
v = 0;
}
rgbT.bRed = (byte)v;
v = rgbSrc.bGreen - rgbSrcBlack.bGreen;
if (v < 0) {
v = 0;
}
rgbT.bGreen = (byte)v;
v = rgbSrc.bBlue - rgbSrcBlack.bBlue;
if (v < 0) {
v = 0;
}
rgbT.bBlue = (byte)v;
Color clrT = Color.FromArgb(rgbT.bRed, rgbT.bGreen,
rgbT.bBlue);
double hue = clrT.GetHue();
if (fMapSideColors) {
hue -= 235.0;
if (hue < 0.0) {
hue += 360.0;
}
}
Hsl2Rgb360(hue, clrT.GetSaturation(), clrT.GetBrightness(),
&rgbT);
// Add new rgb back to black
v = rgbSrcBlack.bRed + rgbT.bRed;
if (v > 255) {
v = 255;
}
rgbSrc.bRed = (byte)v;
v = rgbSrcBlack.bGreen + rgbT.bGreen;
if (v > 255) {
v = 255;
}
rgbSrc.bGreen = (byte)v;
v = rgbSrcBlack.bBlue + rgbT.bBlue;
if (v > 255) {
v = 255;
}
rgbSrc.bBlue = (byte)v;
// Alpha blend into dest
double alpha = (double)rgbSrc.bAlpha / 255.0;
double d;
d = (double)rgbSrc.bRed * alpha +
(double)prgbDstT->bRed * (1.0 - alpha);
if (d > 255.0) {
d = 255.0;
}
prgbDstT->bRed = (byte)d;
d = (double)rgbSrc.bGreen * alpha +
(double)prgbDstT->bGreen * (1.0 - alpha);
if (d > 255.0) {
d = 255.0;
}
prgbDstT->bGreen = (byte)d;
d = (double)rgbSrc.bBlue * alpha +
(double)prgbDstT->bBlue * (1.0 - alpha);
if (d > 255.0) {
d = 255.0;
}
prgbDstT->bBlue = (byte)d;
prgbDstT++;
}
// Advance to next scan line
prgbDst = (RgbData*)(((byte*)prgbDst) + bmdDst.Stride);
prgbSrc = (RgbaData*)(((byte*)prgbSrc) + bmdSrc.Stride);
prgbSrcBlack = (RgbaData*)(((byte*)prgbSrcBlack) +
bmdSrcBlack.Stride);
}
m_bm.UnlockBits(bmdSrc);
m_bmBlack.UnlockBits(bmdSrcBlack);
}
// Skips dst where src has transparent color.
// Darkens dst where src has shadow color.
// Translates side colors.
// NOTE: Performs dst but not src clipping!!!
// NOTE: Assumes src and dst BitmapData are PixelFormat.Format24bppRgb
public unsafe void SuperBlt8(int xSrc, int ySrc,
BitmapData bmdDst, int xDst, int yDst, int cx, int cy,
bool fMapSideColors) {
// If completely off dst bounds, just return.
if ((xDst >= bmdDst.Width || xDst + cx < 0) || (yDst >= bmdDst.Height) || (yDst + cy < 0))
return;
// Dst clip
if (xDst + cx > bmdDst.Width)
cx = bmdDst.Width - xDst;
if (yDst + cy > bmdDst.Height)
cy = bmdDst.Height - yDst;
if (xDst < 0) {
cx += xDst;
xSrc -= xDst;
xDst = 0;
}
if (yDst < 0) {
cy += yDst;
ySrc -= yDst;
yDst = 0;
}
BitmapData bmdSrc = m_bm.LockBits(
new Rectangle(0, 0, m_bm.Width, m_bm.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
RgbData* prgbSrc = (RgbData*)((byte*)bmdSrc.Scan0 + (ySrc * bmdSrc.Stride) + (xSrc * sizeof(RgbData)));
RgbData* prgbDst = (RgbData*)((byte*)bmdDst.Scan0 + (yDst * bmdDst.Stride) + (xDst * sizeof(RgbData)));
while (cy-- > 0) {
RgbData* prgbDstT = prgbDst;
RgbData* prgbSrcT = prgbSrc;
for (int x = 0; x < cx; x++) {
RgbData rgbSrc = *prgbSrcT++;
// Handle shadow color
if (rgbSrc.bRed == 156 && rgbSrc.bGreen == 212 & rgbSrc.bBlue == 248) {
prgbDstT->bRed = (byte)((prgbDstT->bRed * 60) / 100);
prgbDstT->bGreen = (byte)((prgbDstT->bGreen * 60) / 100);
prgbDstT->bBlue = (byte)((prgbDstT->bBlue * 60) / 100);
prgbDstT++;
// Handle transparent color
} else if (rgbSrc.bRed == 255 && rgbSrc.bGreen == 0 && rgbSrc.bBlue == 255) {
prgbDstT++;
// Handle side colors
} else if (fMapSideColors) {
if (rgbSrc.bRed == 0 && rgbSrc.bGreen == 116 && rgbSrc.bBlue == 232) {
*prgbDstT++ = argbSide[0];
} else if (rgbSrc.bRed == 0 && rgbSrc.bGreen == 96 && rgbSrc.bBlue == 196) {
*prgbDstT++ = argbSide[1];
} else if (rgbSrc.bRed == 0 && rgbSrc.bGreen == 64 && rgbSrc.bBlue == 120) {
*prgbDstT++ = argbSide[2];
} else if (rgbSrc.bRed == 0 && rgbSrc.bGreen == 48 && rgbSrc.bBlue == 92) {
*prgbDstT++ = argbSide[3];
} else if (rgbSrc.bRed == 0 && rgbSrc.bGreen == 32 && rgbSrc.bBlue == 64) {
*prgbDstT++ = argbSide[4];
} else {
*prgbDstT++ = rgbSrc;
}
// Just copy everything else unaltered
} else {
*prgbDstT++ = rgbSrc;
}
}
// Advance to next scan line
prgbDst = (RgbData*)(((byte*)prgbDst) + bmdDst.Stride);
prgbSrc = (RgbData*)(((byte*)prgbSrc) + bmdSrc.Stride);
}
m_bm.UnlockBits(bmdSrc);
}
public static Rectangle CalcRealBounds(Bitmap bm) {
Color clrTransparent = Color.FromArgb(0xff, 0, 0xff);
SolidBrush brTransparent = new SolidBrush(clrTransparent);
// OPT: this could be made faster by doing four independent edge scans
int xL = bm.Width;
int xR = 0;
int yT = bm.Height;
int yB = 0;
for (int y = 0; y < bm.Height; y++) {
for (int x = 0; x < bm.Width; x++) {
Color clr = bm.GetPixel(x, y);
if (clr != clrTransparent) {
xL = Math.Min(xL, x);
xR = Math.Max(xR, x);
yT = Math.Min(yT, y);
yB = Math.Max(yB, y);
}
}
}
int cx = xR - xL + 1;
int cy = yB - yT + 1;
#if false
Bitmap bmT = new Bitmap(cx, cy, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(bmT)) {
Rectangle rcT = new Rectangle(xL, yT, cx, cy);
g.DrawImage(bm, 0, 0, rcT, GraphicsUnit.Pixel);
}
#endif
return new Rectangle(xL, yT, cx, cy);
}
public Bitmap MakeThumbnail(int cxThumb, int cyThumb, bool fFilter) {
Rectangle rcSrc = XBitmap.CalcRealBounds(m_bm);
if (rcSrc.Width <= 0 || rcSrc.Height <= 0)
return m_bm;
int cxy = Math.Max(rcSrc.Width, rcSrc.Height);
Bitmap bmDst = new Bitmap(cxy, cxy);
Graphics gDst = Graphics.FromImage(bmDst);
gDst.Clear(Color.White);
gDst.Dispose();
int xDst = (bmDst.Width - rcSrc.Width) / 2;
int yDst = (bmDst.Height - rcSrc.Height) / 2;
BitmapData bmdDst = bmDst.LockBits(
new Rectangle(0, 0, bmDst.Width, bmDst.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
SuperBlt(rcSrc.X, rcSrc.Y, bmdDst, xDst, yDst,
rcSrc.Width, rcSrc.Height, false);
bmDst.UnlockBits(bmdDst);
Bitmap bmLarge = new Bitmap(cxThumb, cyThumb);
Graphics g = Graphics.FromImage(bmLarge);
InterpolationMode imOld = g.InterpolationMode;
g.InterpolationMode = fFilter ? InterpolationMode.Bicubic : InterpolationMode.NearestNeighbor;
PixelOffsetMode pomOld = g.PixelOffsetMode;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawImage(bmDst, 0, 0, cxThumb, cyThumb);
g.PixelOffsetMode = pomOld;
g.InterpolationMode = imOld;
g.Dispose();
bmDst.Dispose();
return bmLarge;
}
// ISerializable interface implementation
private XBitmap(SerializationInfo seri, StreamingContext stmc) {
string strFileName = seri.GetString("FileName");
strFileName = strFileName.Replace(@"\", Path.DirectorySeparatorChar.ToString());
Load(strFileName, false);
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
seri.AddValue("FileName", m_strFileName);
}
}
}

58
AniMax/XBitmapSet.cs Normal file
View File

@ -0,0 +1,58 @@
using System;
using System.Drawing;
using System.Collections;
using System.Xml;
using System.Runtime.Serialization;
namespace SpiffCode
{
/// <summary>
/// Summary description for XBitmapSet.
/// UNDONE: act as a collection of extended bitmaps
/// NOTE: CollectionBase implements IList
/// </summary>
[Serializable]
public class XBitmapSet : CollectionBase, ISerializable
{
public XBitmapSet() {
}
public XBitmap this[int i] {
get {
return (XBitmap)InnerList[i];
}
set {
InnerList[i] = value;
}
}
public int Add(XBitmap xbm) {
return ((IList)this).Add(xbm);
}
public int IndexOf(XBitmap xbm) {
return ((IList)this).IndexOf(xbm);
}
public int Add(string strFileName) {
return Add(new XBitmap(strFileName));
}
// ISerializable interface implementation
private XBitmapSet(SerializationInfo seri, StreamingContext stmc) {
for (int i = 0; i < seri.MemberCount; i++) {
XBitmap xbm = (XBitmap)seri.GetValue(i.ToString(), typeof(XBitmap));
Add(xbm);
}
}
void ISerializable.GetObjectData(SerializationInfo seri, StreamingContext stmc) {
int i = 0;
foreach (XBitmap xbm in InnerList) {
seri.AddValue(i.ToString(), xbm);
i++;
}
}
}
}

View File

@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

17
AniMax/amx/Class1.cs Normal file
View File

@ -0,0 +1,17 @@
using System;
namespace amx
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class Class1
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
}
}

167
AniMax/amx/amx.csproj Normal file
View File

@ -0,0 +1,167 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.0.9466"
SchemaVersion = "1.0"
ProjectGuid = "{8A01587F-4FC8-4F11-AA53-B05E3FB792CC}"
>
<Build>
<Settings
ApplicationIcon = ""
AssemblyKeyContainerName = ""
AssemblyName = "amx"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Library"
RootNamespace = "SpiffCode"
StartupObject = ""
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "DEBUG;TRACE"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "true"
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "TRACE"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
Optimize = "true"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
</Settings>
<References>
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.Xml"
HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
/>
<Reference
Name = "System.Runtime.Serialization.Formatters.Soap"
AssemblyName = "System.Runtime.Serialization.Formatters.Soap"
HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Runtime.Serialization.Formatters.Soap.dll"
/>
<Reference
Name = "System.Windows.Forms"
AssemblyName = "System.Windows.Forms"
HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"
/>
<Reference
Name = "SharpZipLib"
AssemblyName = "SharpZipLib"
HintPath = "..\SharpZipLib.dll"
/>
<Reference
Name = "System.Drawing"
AssemblyName = "System.Drawing"
HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"
/>
</References>
</Build>
<Files>
<Include>
<File
RelPath = "AnimDoc.cs"
Link = "..\AnimDoc.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "AssemblyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Class1.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Frame.cs"
Link = "..\Frame.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "misc.cs"
Link = "..\..\SpiffLib\misc.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "palette.cs"
Link = "..\..\SpiffLib\palette.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Strip.cs"
Link = "..\Strip.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "StripSet.cs"
Link = "..\StripSet.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "tbitmap.cs"
Link = "..\..\SpiffLib\tbitmap.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "XBitmap.cs"
Link = "..\XBitmap.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "XBitmapSet.cs"
Link = "..\XBitmapSet.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>

21
AniMax/amx/amx.sln Normal file
View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 7.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "amx", "amx.csproj", "{8A01587F-4FC8-4F11-AA53-B05E3FB792CC}"
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug
ConfigName.1 = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{8A01587F-4FC8-4F11-AA53-B05E3FB792CC}.Debug.ActiveCfg = Debug|.NET
{8A01587F-4FC8-4F11-AA53-B05E3FB792CC}.Debug.Build.0 = Debug|.NET
{8A01587F-4FC8-4F11-AA53-B05E3FB792CC}.Release.ActiveCfg = Release|.NET
{8A01587F-4FC8-4F11-AA53-B05E3FB792CC}.Release.Build.0 = Release|.NET
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

2
AniMax/deploy.bat Normal file
View File

@ -0,0 +1,2 @@
copy bin\debug\AniMax.exe ..\bin
copy amx\bin\debug\amx.dll ..\bin

2
AniMax/deploy.sh Executable file
View File

@ -0,0 +1,2 @@
cp bin/Debug/AniMax.exe ../bin
cp amx/bin/Debug/amx.dll ../bin

BIN
AniMax/grid icon.psd Normal file

Binary file not shown.

21
AniMax/licenses.licx Normal file
View File

@ -0,0 +1,21 @@
System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.ListView, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Form, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Panel, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.MainMenu, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.ContextMenu, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Label, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.MenuItem, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.TextBox, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.UserControl, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Button, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.ListBox, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.ToolBarButton, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.HScrollBar, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Timer, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.ToolBar, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.MdiClient, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Windows.Forms.Splitter, System.Windows.Forms, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Binary file not shown.

BIN
AniMax/play toggle icon.psd Normal file

Binary file not shown.

BIN
AniMax/properties icon.psd Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

41
AniMax/worklist.txt Normal file
View File

@ -0,0 +1,41 @@
5/15/02
- icon
- right click properties on Frame
- zoom control (Frames)
- info (x, y, w, h, # frames, color under pointer, ...)
- spacebar & grab hand ala Photoshop
- multiple bitmaps/Frame
- paint tools & color palette (get minimal list from Mark)
- save/load settings (layout, toggles, ...)
* version .23
* add help (invoke browser pointing to http://www.tinybit.org/AniMax)
* fix 'easy to blank out strip name' problem [fixed one way, can't reproduce other]
* new MagicLibrary
* Preview zoom control
* tank + turret preview ("Combiner")
5/18/02
- normalize bitmaps
- MRU file list
* version .24
* About dialog w/ version #
* expanded Strips and Bitmaps selections to cover whole row
* drag/drop .amx from Explorer [must be dropped in Strips window]
* Save .amx now always builds a bitmap subdir and writes all bitmaps to it
[NOTE: subdir contents are not deleted so it is possible for unused bitmaps
to accumulate. I've left it this way so we can add the bitmap dirs to CVS
and for other minor coveniences. To clean out cruft, save as .zip. Only
referenced bitmaps will be included in the .zip]
* load/save packaged animations (.zips)
6/6/02
- drag into but don't drop on Frames StripControl leaves insertion point,
scroll timer state broken
- no way to delete individual bitmaps in a frame
- reimporting altered-sized bitmaps almost certainly hoses the positioning of
the bitmap in existing frames
- need keyboard shortcut for moving forward and backward through strips
* WriteAnir multiple bitmaps/frame [limited to 2 for now]

2
BmpProof/.cvsignore Normal file
View File

@ -0,0 +1,2 @@
bin
SpiffLib

BIN
BmpProof/App.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

58
BmpProof/AssemblyInfo.cs Normal file
View File

@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

168
BmpProof/BmpProof.cs Normal file
View File

@ -0,0 +1,168 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using SpiffLib;
namespace BmpProof
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class App
{
static StringCollection gstrcFileNames = new StringCollection();
static string gstrPalette;
static Palette gpal;
static bool gf6bitRGB = false;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static unsafe int Main(string[] astrArgs)
{
// Command-line argument processing
if (astrArgs.Length == 0) {
PrintHelp();
return 0;
}
for (int i = 0; i < astrArgs.Length; i++) {
switch (astrArgs[i]) {
case "-?":
PrintHelp();
return 0;
case "-p":
gstrPalette = astrArgs[++i];
gpal = new Palette(gstrPalette);
break;
case "-6":
gf6bitRGB = true;
break;
default:
if (astrArgs[i][0] == '-') {
Console.WriteLine("Error: invalid flag '{0}'", astrArgs[i]);
return -1;
}
// Assume all 'unassociated' arguments are input filenames (potentially wildcarded)
string strDir = Path.GetDirectoryName(astrArgs[i]);
if (strDir == "")
strDir = ".";
string[] astrFileNames = Directory.GetFiles(strDir, Path.GetFileName(astrArgs[i]));
if (astrFileNames.Length == 0) {
gstrcFileNames.Add(astrArgs[i]);
} else {
foreach (string strFileName in astrFileNames) {
if (strFileName.ToLower().EndsWith(".ani")) {
string strT = Path.GetDirectoryName(strFileName) + @"\" + Path.GetFileNameWithoutExtension(strFileName) + @"\*.png";
string[] astrT = Directory.GetFiles(Path.GetDirectoryName(strT), Path.GetFileName(strT));
gstrcFileNames.AddRange(astrT);
} else {
gstrcFileNames.Add(strFileName);
}
}
}
break;
}
}
if (gpal == null) {
Console.WriteLine("A valid palette must be specified via the '-p' switch");
return -1;
}
if (gstrcFileNames.Count == 0) {
Console.WriteLine("Error: no files specified");
return -1;
}
int nReturnValue = 0;
Color clrShadow = Color.FromArgb(156, 212, 248);
Console.Write("Verifying bitmap colors...");
foreach (string strFileName in gstrcFileNames) {
Hashtable htInvalidColors = new Hashtable();
Bitmap bm = null;
try {
bm = new Bitmap(strFileName);
} catch {
Console.WriteLine("Error: {0} is not a recognized bitmap or palette file", strFileName);
continue;
}
Color clrTransparent = bm.GetPixel(0, 0);
if (gf6bitRGB)
clrTransparent = Color.FromArgb(clrTransparent.R & 0xfc, clrTransparent.G & 0xfc, clrTransparent.B & 0xfc);
// Lock down bits for speed
Rectangle rc = new Rectangle(0, 0, bm.Width, bm.Height);
BitmapData bmd = bm.LockBits(rc, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte *pbBase = (byte *)bmd.Scan0.ToPointer();
for (int y = 0; y < bm.Height; y++) {
for (int x = 0; x < bm.Width; x++) {
byte *pb = pbBase + y * bmd.Stride + x * 3;
Color clr;
if (gf6bitRGB)
clr = Color.FromArgb(pb[2] & 0xfc, pb[1] & 0xfc, pb[0] & 0xfc);
else
clr = Color.FromArgb(pb[2], pb[1], pb[0]);
int i = gpal.FindClosestEntry(clr);
if (gpal[i] != clr && clr != clrShadow && clr != clrTransparent && !htInvalidColors.ContainsKey(clr))
htInvalidColors.Add(clr, clr);
}
}
bm.UnlockBits(bmd);
// Report any invalid colors
if (htInvalidColors.Count != 0) {
if (nReturnValue == 0)
Console.WriteLine();
nReturnValue = -1;
int cclr = htInvalidColors.Count;
Color[] aclr = new Color[cclr];
htInvalidColors.Values.CopyTo(aclr, 0);
Console.Write("{0} contains {1} invalid color{2} (",
Path.GetFileName(strFileName), cclr, cclr == 1 ? "" : "s");
for (int i = 0; i < aclr.Length; i++) {
Color clr = aclr[i];
Console.Write("{0},{1},{2}", clr.R, clr.G, clr.B);
if (i != aclr.Length - 1)
Console.Write(", ");
}
Console.WriteLine(")");
}
}
if (nReturnValue == 0)
Console.WriteLine("done");
return nReturnValue;
}
//
static void PrintHelp() {
Console.WriteLine(
"Usage: BmpProof [-6] <-p filename> file[s]\n" +
"-6: convert colors to 6-bit precision before comparing\n" +
"-p: specify palette of valid colors\n" +
"files[s]: bitmap files to be processed. Wildcards allowed.");
}
}
}

115
BmpProof/BmpProof.csproj Normal file
View File

@ -0,0 +1,115 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.0.9466"
SchemaVersion = "1.0"
ProjectGuid = "{C2D0A473-D426-4F01-B8E8-FB4F6BD41A41}"
>
<Build>
<Settings
ApplicationIcon = "App.ico"
AssemblyKeyContainerName = ""
AssemblyName = "BmpProof"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Exe"
RootNamespace = "BmpProof"
StartupObject = ""
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "DEBUG;TRACE"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "true"
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "true"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "TRACE"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
Optimize = "true"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
</Settings>
<References>
<Reference
Name = "System"
AssemblyName = "System"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.Xml"
/>
<Reference
Name = "System.Drawing"
AssemblyName = "System.Drawing"
/>
<Reference
Name = "System.Windows.Forms"
AssemblyName = "System.Windows.Forms"
HintPath = "..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"
/>
</References>
</Build>
<Files>
<Include>
<File
RelPath = "App.ico"
BuildAction = "Content"
/>
<File
RelPath = "AssemblyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "BmpProof.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "SpiffLib\misc.cs"
Link = "..\SpiffLib\misc.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "SpiffLib\palette.cs"
Link = "..\SpiffLib\palette.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>

Some files were not shown because too many files have changed in this diff Show More