// 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 } }