using System;
using System.Collections;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Windows.Forms;
namespace CraftSynth.ImageEditor
{
///
/// Collection of s used to organize the drawing surface
///
[Serializable]
public class Layers : ISerializable, IDisposable
{
// Contains the list of Layers
private ArrayList layerList;
private bool _isDirty;
///
/// Dirty is True if any graphic element in any Layer is dirty, else False
///
public bool Dirty
{
get
{
if (_isDirty == false)
{
foreach (Layer l in layerList)
{
if (l.Dirty)
{
_isDirty = true;
break;
}
}
}
return _isDirty;
}
//set
//{
// foreach (Layer l in layerList)
// l.Dirty = false;
// _isDirty = false;
//}
}
private const string entryCount = "LayerCount";
private const string entryLayer = "LayerType";
public Layers()
{
layerList = new ArrayList();
}
///
/// Returns the index of the Active Layer - only one Layer may be active at any one time
///
public int ActiveLayerIndex
{
get
{
int i = 0;
foreach (Layer l in layerList)
{
if (l.IsActive)
break;
i++;
}
return i;
}
}
protected Layers(SerializationInfo info, StreamingContext context)
{
layerList = new ArrayList();
int n = info.GetInt32(entryCount);
for (int i = 0; i < n; i++)
{
string typeName;
typeName = info.GetString(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryLayer, i));
object _layer;
_layer = Assembly.GetExecutingAssembly().CreateInstance(typeName);
((Layer)_layer).LoadFromStream(info, i);
layerList.Add(_layer);
}
}
///
/// Save object to serialization stream
///
///
///
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(entryCount, layerList.Count);
int i = 0;
foreach (Layer l in layerList)
{
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryLayer, i),
l.GetType().FullName);
l.SaveToStream(info, i);
i++;
}
}
///
/// Draw all objects contained in all visible layers
///
/// Graphics object to draw on
public void Draw(Graphics g)
{
foreach (Layer l in layerList)
{
if (l.IsVisible)
l.Draw(g);
}
}
///
/// Clear all objects in the list
///
///
/// true if at least one object is deleted
///
public bool Clear()
{
bool result = (layerList.Count > 0);
foreach (Layer l in layerList)
l.Graphics.Clear();
if (layerList.Count > 0)
{
for (int i = layerList.Count - 1; i >= 0; i--)
{
if (layerList[i] != null)
{
((DrawObject) layerList[i]).Dispose();
}
layerList.RemoveAt(i);
}
}
// Create a default Layer since there must be at least one Layer at all times
CreateNewLayer("Default");
// Set dirty flag based on result. Result is true only if at least one item was cleared and since the list is empty, there can be nothing dirty.
if (result)
_isDirty = false;
return result;
}
///
/// Returns number layers in the collection - useful for for loops
///
public int Count
{
get { return layerList.Count; }
}
///
/// Allows iterating through the list of layers using a for loop
///
/// the index of the layer to return
/// the specified layer object
public Layer this[int index]
{
get
{
if (index < 0 ||
index >= layerList.Count)
return null;
return (Layer)layerList[index];
}
}
///
/// Adds a new layer to the collection
///
/// The layer object to add
public void Add(Layer obj)
{
layerList.Add(obj);
// insert to the top of z-order
//layerList.Insert(0, obj);
}
///
/// Create a new layer at the head of the layers list and set it to Active and Visible.
///
/// The name to assign to the new layer
public void CreateNewLayer(string theName)
{
// Deactivate the currently active Layer
if (layerList.Count > 0)
((Layer)layerList[ActiveLayerIndex]).IsActive = false;
// Create new Layer, set it visible and active
Layer l = new Layer();
l.IsVisible = true;
l.IsActive = true;
l.LayerName = theName;
// Initialize empty GraphicsList for future objects
l.Graphics = new GraphicsList();
// Add to Layers collection
Add(l);
}
///
/// Inactivate the active by setting all layers to inactive.
/// Brute force approach
///
public void InactivateAllLayers()
{
foreach (Layer l in layerList)
{
l.IsActive = false;
// Make sure nothing is selected on the currently active layer before switching layers.
if (l.Graphics != null)
l.Graphics.UnselectAll();
}
}
///
/// Makes the specified invisible
///
/// index of to make invisible
public void MakeLayerInvisible(int p)
{
if (p > -1 &&
p < layerList.Count)
((Layer)layerList[p]).IsVisible = false;
}
///
/// Makes the specified visible
///
/// index of to make visible
public void MakeLayerVisible(int p)
{
if (p > -1 &&
p < layerList.Count)
((Layer)layerList[p]).IsVisible = true;
}
///
/// Changes the active to the one indicated
///
/// index of the to activate
public void SetActiveLayer(int p)
{
//// If the current layer is the same as the layer we are switching to, then do nothing.
//if (ActiveLayerIndex == p)
// return;
// Ensure the index is valid
if (p > -1 &&
p < layerList.Count)
{
// Make sure nothing is selected on the currently active layer before switching layers.
//if (((Layer)layerList[ActiveLayerIndex]).Graphics != null)
// ((Layer)layerList[ActiveLayerIndex]).Graphics.UnselectAll();
//((Layer)layerList[ActiveLayerIndex]).IsActive = false;
((Layer)layerList[p]).IsActive = true;
((Layer)layerList[p]).IsVisible = true;
}
}
///
/// Removes the specified from the collection - deleting all graphic objects the contains
///
/// index of the to remove
public void RemoveLayer(int p)
{
if (ActiveLayerIndex == p)
{
MessageBox.Show("Cannot Remove the Active Layer");
return;
}
if (layerList.Count == 1)
{
MessageBox.Show("There is only one Layer in this drawing! You Cannot Remove the Only Layer!");
return;
}
// Ensure the index is valid
if (p > -1 &&
p < layerList.Count)
{
((Layer)layerList[p]).Graphics.Clear();
layerList.RemoveAt(p);
}
}
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
// Flag: Has Dispose already been called?
bool _disposed = false;
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
// Free any managed objects here.
//
if (layerList != null)
{
foreach (Layer layer in layerList)
{
if (layer != null)
{
layer.Dispose();
}
}
}
}
// Free any unmanaged objects here.
//
this._disposed = true;
}
}
~Layers()
{
this.Dispose(false);
}
}
}