// GfxEd8
// Copyright (C) 2004 Ian Cowburn
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// $Id$
//
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using GfxEdInterface;
using System.Diagnostics;
namespace GfxEd8
{
///
/// Implements a control for drawing
///
[ToolboxItem(true)]
public class GfxEditor : System.Windows.Forms.UserControl
{
private System.Windows.Forms.Label m_fgPreview;
private System.Windows.Forms.PictureBox m_edit;
private System.Windows.Forms.ComboBox m_modeList;
private System.Windows.Forms.Label m_bgPreview;
private System.Windows.Forms.NumericUpDown m_leftCol;
private System.Windows.Forms.NumericUpDown m_rightCol;
private System.Windows.Forms.PictureBox m_preview;
private System.Windows.Forms.Button m_palButton;
private System.Windows.Forms.TextBox m_name;
private System.Windows.Forms.Button m_undoButton;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ComboBox m_size;
private const uint SIZE=256;
private const uint TRANS=UInt32.MaxValue;
// These MUST match the entries in the drop down list
//
private enum Mode
{
ePlot,
eLine,
eRectangle,
eFilledRectangle,
eCircle,
eFilledCircle,
eEllipse,
eFilledEllipse,
eFloodFill,
eCopyPaste
};
//private bool m_inEditor;
private IPlugin m_plugin;
private Sprite m_sprite;
private Sprite m_undo;
private SpriteSize m_sprsize;
private Colour[] m_pal;
private uint m_width;
private uint m_height;
private Rectangle m_editRect;
private Bitmap m_editBmp;
private Rectangle m_prevRect;
private Bitmap m_prevBmp;
private uint m_gridx;
private uint m_gridy;
private uint m_mx;
private uint m_my;
private Color m_gridCol;
private bool m_drawing;
private Mode m_mode;
private uint[,] m_overlay;
private uint m_ox;
private uint m_oy;
private uint m_pen;
private CopyMenu m_cpMenu;
private uint m_cpX;
private uint m_cpY;
private uint m_cpWidth;
private uint m_cpHeight;
private uint[,] m_cpBuff;
public GfxEditor()
{
//
// InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//m_inEditor=false;
m_sprite=null;
m_gridx=8;
m_gridy=8;
m_mx=SIZE;
m_my=SIZE;
m_gridCol=Color.LightGreen;
m_editRect=m_edit.ClientRectangle;
m_editBmp=new Bitmap(m_editRect.Width,m_editRect.Height);
m_edit.Image=m_editBmp;
m_prevRect=m_edit.ClientRectangle;
m_prevBmp=new Bitmap(m_prevRect.Width,m_prevRect.Height);
m_preview.Image=m_prevBmp;
m_drawing=false;
m_mode=Mode.ePlot;
if (m_editRect.Width!=SIZE && m_editRect.Height!=SIZE)
{
throw new Exception("GfxEditor built with bad SIZE!");
}
m_modeList.SelectedIndex=0;
m_cpMenu=new CopyMenu();
}
#region Windows Forms Designer generated code
///
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
///
private void InitializeComponent() {
this.m_size = new System.Windows.Forms.ComboBox();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.m_undoButton = new System.Windows.Forms.Button();
this.m_name = new System.Windows.Forms.TextBox();
this.m_palButton = new System.Windows.Forms.Button();
this.m_preview = new System.Windows.Forms.PictureBox();
this.m_rightCol = new System.Windows.Forms.NumericUpDown();
this.m_leftCol = new System.Windows.Forms.NumericUpDown();
this.m_bgPreview = new System.Windows.Forms.Label();
this.m_modeList = new System.Windows.Forms.ComboBox();
this.m_edit = new System.Windows.Forms.PictureBox();
this.m_fgPreview = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.m_rightCol)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.m_leftCol)).BeginInit();
this.SuspendLayout();
//
// m_size
//
this.m_size.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.m_size.Location = new System.Drawing.Point(280, 64);
this.m_size.MaxDropDownItems = 16;
this.m_size.Name = "m_size";
this.m_size.Size = new System.Drawing.Size(96, 21);
this.m_size.TabIndex = 9;
this.m_size.SelectedIndexChanged += new System.EventHandler(this.OnSize);
//
// label4
//
this.label4.Location = new System.Drawing.Point(280, 128);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(32, 16);
this.label4.TabIndex = 10;
this.label4.Text = "Left";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label5
//
this.label5.Location = new System.Drawing.Point(328, 128);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(48, 16);
this.label5.TabIndex = 12;
this.label5.Text = "Right";
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label1
//
this.label1.Location = new System.Drawing.Point(280, 88);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(64, 16);
this.label1.TabIndex = 3;
this.label1.Text = "Draw Mode";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label2
//
this.label2.Location = new System.Drawing.Point(280, 8);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(64, 16);
this.label2.TabIndex = 6;
this.label2.Text = "Name";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label3
//
this.label3.Location = new System.Drawing.Point(280, 48);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(64, 16);
this.label3.TabIndex = 8;
this.label3.Text = "Size";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// m_undoButton
//
this.m_undoButton.Location = new System.Drawing.Point(8, 272);
this.m_undoButton.Name = "m_undoButton";
this.m_undoButton.Size = new System.Drawing.Size(72, 24);
this.m_undoButton.TabIndex = 16;
this.m_undoButton.Text = "Undo";
this.m_undoButton.Click += new System.EventHandler(this.OnUndo);
//
// m_name
//
this.m_name.Location = new System.Drawing.Point(280, 24);
this.m_name.Name = "m_name";
this.m_name.Size = new System.Drawing.Size(96, 20);
this.m_name.TabIndex = 7;
this.m_name.Text = "";
this.m_name.TextChanged += new System.EventHandler(this.OnNameChanged);
//
// m_palButton
//
this.m_palButton.Location = new System.Drawing.Point(280, 192);
this.m_palButton.Name = "m_palButton";
this.m_palButton.Size = new System.Drawing.Size(96, 24);
this.m_palButton.TabIndex = 14;
this.m_palButton.Text = "Palette...";
this.m_palButton.Click += new System.EventHandler(this.OnPalette);
//
// m_preview
//
this.m_preview.BackColor = System.Drawing.SystemColors.Control;
this.m_preview.Location = new System.Drawing.Point(280, 224);
this.m_preview.Name = "m_preview";
this.m_preview.Size = new System.Drawing.Size(34, 34);
this.m_preview.TabIndex = 1;
this.m_preview.TabStop = false;
//
// m_rightCol
//
this.m_rightCol.Location = new System.Drawing.Point(328, 144);
this.m_rightCol.Name = "m_rightCol";
this.m_rightCol.ReadOnly = true;
this.m_rightCol.Size = new System.Drawing.Size(40, 20);
this.m_rightCol.TabIndex = 13;
this.m_rightCol.ValueChanged += new System.EventHandler(this.OnColourChanged);
//
// m_leftCol
//
this.m_leftCol.Location = new System.Drawing.Point(280, 144);
this.m_leftCol.Name = "m_leftCol";
this.m_leftCol.ReadOnly = true;
this.m_leftCol.Size = new System.Drawing.Size(40, 20);
this.m_leftCol.TabIndex = 11;
this.m_leftCol.ValueChanged += new System.EventHandler(this.OnColourChanged);
//
// m_bgPreview
//
this.m_bgPreview.Location = new System.Drawing.Point(328, 168);
this.m_bgPreview.Name = "m_bgPreview";
this.m_bgPreview.Size = new System.Drawing.Size(40, 16);
this.m_bgPreview.TabIndex = 18;
//
// m_modeList
//
this.m_modeList.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.m_modeList.Items.AddRange(new object[] {
"Plot",
"Line",
"Rectangle",
"Filled Rect",
"Circle",
"Filled Circle",
"Ellipse",
"Filled Ellipse",
"Flood Fill",
"Copy/Paste"});
this.m_modeList.Location = new System.Drawing.Point(280, 104);
this.m_modeList.MaxDropDownItems = 16;
this.m_modeList.Name = "m_modeList";
this.m_modeList.Size = new System.Drawing.Size(96, 21);
this.m_modeList.TabIndex = 15;
this.m_modeList.SelectedIndexChanged += new System.EventHandler(this.OnModeSelect);
//
// m_edit
//
this.m_edit.BackColor = System.Drawing.SystemColors.Control;
this.m_edit.Location = new System.Drawing.Point(8, 8);
this.m_edit.Name = "m_edit";
this.m_edit.Size = new System.Drawing.Size(256, 256);
this.m_edit.TabIndex = 0;
this.m_edit.TabStop = false;
this.m_edit.MouseEnter += new System.EventHandler(this.OnEnterEditor);
this.m_edit.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
this.m_edit.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
this.m_edit.MouseLeave += new System.EventHandler(this.OnLeaveEditor);
this.m_edit.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
//
// m_fgPreview
//
this.m_fgPreview.Location = new System.Drawing.Point(280, 168);
this.m_fgPreview.Name = "m_fgPreview";
this.m_fgPreview.Size = new System.Drawing.Size(40, 16);
this.m_fgPreview.TabIndex = 17;
//
// GfxEditor
//
this.Controls.Add(this.m_bgPreview);
this.Controls.Add(this.m_fgPreview);
this.Controls.Add(this.m_undoButton);
this.Controls.Add(this.m_modeList);
this.Controls.Add(this.m_palButton);
this.Controls.Add(this.m_rightCol);
this.Controls.Add(this.label5);
this.Controls.Add(this.m_leftCol);
this.Controls.Add(this.label4);
this.Controls.Add(this.m_size);
this.Controls.Add(this.label3);
this.Controls.Add(this.m_name);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.m_preview);
this.Controls.Add(this.m_edit);
this.Name = "GfxEditor";
this.Size = new System.Drawing.Size(384, 304);
((System.ComponentModel.ISupportInitialize)(this.m_rightCol)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.m_leftCol)).EndInit();
this.ResumeLayout(false);
}
#endregion
// -------------------------------------------------------
// PUBLIC INTERFACES
// -------------------------------------------------------
#region Public Interfaces
public Color GridColour
{
set {m_gridCol=value;}
}
public IPlugin Plugin
{
set
{
m_plugin=value;
m_pal=m_plugin.Palette;
m_leftCol.Minimum=0;
m_leftCol.Maximum=m_plugin.MaxColours-1;
m_leftCol.Value=1;
m_rightCol.Minimum=0;
m_rightCol.Maximum=m_plugin.MaxColours-1;
m_rightCol.Value=0;
if (m_plugin.MaxColours<3)
{
m_leftCol.Enabled=false;
m_rightCol.Enabled=false;
}
else
{
m_leftCol.Enabled=true;
m_rightCol.Enabled=true;
}
m_size.Items.Clear();
foreach (SpriteSize sz in m_plugin.AllowedSizes)
{
m_size.Items.Add(sz);
}
m_sprite=null;
m_undo=null;
InitialiseOverlay();
m_size.SelectedIndex=0;
bool flag=false;
foreach (bool b in m_plugin.SprPalEditable)
{
flag|=b;
}
m_palButton.Enabled=flag;
m_cpBuff=null;
m_cpMenu.Mode=CopyMenu.EMode.eNothing;
}
}
public Sprite Sprite
{
get {return m_sprite;}
set
{
m_sprite=value;
m_name.Text=m_sprite.Name;
for(int f=0;fc2)
{
uint t=c2;
c2=c1;
c1=t;
}
}
private void SafePlot(int x, int y, uint col)
{
if (x>=0 && x=0 && ydx)
{
ymode=true;
d=dx*2-dy;
incrE=dx*2;
incrNE=(dx-dy)*2;
}
else
{
ymode=false;
d=dy*2-dx;
incrE=dy*2;
incrNE=(dy-dx)*2;
}
int x=x1;
int y=y1;
SafePlot(x,y,col);
if (ymode)
{
while(y!=y2)
{
if (d<=0)
{
d+=incrE;
y+=iy;
}
else
{
d+=incrNE;
y+=iy;
x+=ix;
}
SafePlot(x,y,col);
}
}
else
{
while(x!=x2)
{
if (d<=0)
{
d+=incrE;
x+=ix;
}
else
{
d+=incrNE;
y+=iy;
x+=ix;
}
SafePlot(x,y,col);
}
}
}
private void DrawRect(uint x1, uint y1,
uint x2, uint y2,
uint col, bool fill)
{
RankCoord(ref x1, ref x2);
RankCoord(ref y1, ref y2);
if (fill)
{
for(uint x=x1;x<=x2;x++)
for(uint y=y1;y<=y2;y++)
m_overlay[x,y]=col;
}
else
{
for(uint x=x1;x<=x2;x++)
{
m_overlay[x,y1]=col;
m_overlay[x,y2]=col;
}
for(uint y=y1;y<=y2;y++)
{
m_overlay[x1,y]=col;
m_overlay[x2,y]=col;
}
}
}
private void DrawEllipse(uint originx, uint originy,
uint radpointx, uint radpointy,
uint col, bool circle, bool fill)
{
int ox=(int)originx;
int oy=(int)originy;
double rx=Math.Abs(ox-(int)radpointx)+1;
double ry=Math.Abs(oy-(int)radpointy)+1;
if (circle)
{
rx=Math.Max(rx,ry);
ry=rx;
}
for(double a=0;a<=Math.PI;a+=Math.PI/180)
{
int x=(int)(Math.Sin(a)*rx);
int y=(int)(Math.Cos(a)*ry);
if (fill)
{
for(int f=-x;f<=x;f++)
SafePlot(ox+f,oy+y,col);
}
else
{
SafePlot(ox+x,oy+y,col);
SafePlot(ox-x,oy+y,col);
}
}
}
private void FloodFill(uint x, uint y, uint col, uint bg)
{
if (m_overlay[x,y]==col || m_overlay[x,y]!=bg)
{
return;
}
m_overlay[x,y]=col;
if (x>0)
FloodFill(x-1,y,col,bg);
if (y>0)
FloodFill(x,y-1,col,bg);
if (x=m_mx || e.Y<0 || e.Y>=m_my)
{
return;
}
uint x;
uint y;
x=(uint)e.X/m_gridx;
y=(uint)e.Y/m_gridy;
if (x>=m_sprite.Width || y>=m_sprite.Height)
{
return;
}
if (e.Button==MouseButtons.None)
{
switch(m_mode)
{
case Mode.eFloodFill:
if (m_drawing)
{
OverlayFromSprite();
FloodFill(m_ox,m_oy,m_pen,m_sprite[m_ox,m_oy]);
m_drawing=false;
m_undo=new Sprite(m_sprite);
ApplyOverlay();
DrawSprite();
}
break;
case Mode.eCopyPaste:
switch(m_cpMenu.Mode)
{
case CopyMenu.EMode.eMark:
if (m_drawing)
{
ClearOverlay();
Copy(m_ox,m_oy,x,y);
DrawSprite();
m_drawing=false;
}
break;
case CopyMenu.EMode.ePaste:
ClearOverlay();
Paste((int)x,(int)y,false);
DrawSprite();
break;
case CopyMenu.EMode.ePasteTransparent:
ClearOverlay();
Paste((int)x,(int)y,true);
DrawSprite();
break;
default:
break;
}
break;
default:
if (m_drawing)
{
m_drawing=false;
m_undo=new Sprite(m_sprite);
ApplyOverlay();
DrawSprite();
}
break;
}
return;
}
if (!m_drawing)
{
m_ox=x;
m_oy=y;
m_drawing=true;
if (e.Button==MouseButtons.Left)
{
m_pen=(byte)m_leftCol.Value;
}
else
{
m_pen=(byte)m_rightCol.Value;
}
}
switch(m_mode)
{
case Mode.ePlot:
m_overlay[x,y]=m_pen;
DrawSprite();
break;
case Mode.eLine:
ClearOverlay();
DrawLine(m_ox,m_oy,x,y,m_pen);
DrawSprite();
break;
case Mode.eRectangle:
ClearOverlay();
DrawRect(m_ox,m_oy,x,y,m_pen,false);
DrawSprite();
break;
case Mode.eFilledRectangle:
ClearOverlay();
DrawRect(m_ox,m_oy,x,y,m_pen,true);
DrawSprite();
break;
case Mode.eCircle:
ClearOverlay();
DrawEllipse(m_ox,m_oy,x,y,m_pen,true,false);
DrawSprite();
break;
case Mode.eFilledCircle:
ClearOverlay();
DrawEllipse(m_ox,m_oy,x,y,m_pen,true,true);
DrawSprite();
break;
case Mode.eEllipse:
ClearOverlay();
DrawEllipse(m_ox,m_oy,x,y,m_pen,false,false);
DrawSprite();
break;
case Mode.eFilledEllipse:
ClearOverlay();
DrawEllipse(m_ox,m_oy,x,y,m_pen,false,true);
DrawSprite();
break;
case Mode.eFloodFill:
break;
case Mode.eCopyPaste:
if (e.Button==MouseButtons.Right)
{
m_cpMenu.AllowPaste=(m_cpBuff!=null);
m_cpMenu.Show(m_edit,e.X,e.Y);
}
else
{
switch(m_cpMenu.Mode)
{
case CopyMenu.EMode.eMark:
ClearOverlay();
DrawMarkBox(m_ox,m_oy,x,y);
DrawSprite();
break;
case CopyMenu.EMode.ePaste:
case CopyMenu.EMode.ePasteTransparent:
m_undo=new Sprite(m_sprite);
ApplyOverlay();
DrawSprite();
m_drawing=false;
m_cpMenu.Mode=CopyMenu.EMode.eNothing;
break;
default:
break;
}
}
break;
}
}
void OnColourChanged(object sender, System.EventArgs e)
{
if (m_plugin!=null && m_sprite!=null)
{
UpdateColourPreviews();
}
}
#endregion
}
}