1、Extensions to DrawTools
Author
Introduction
Alex Fr provided an excellent set of drawing tools in his DrawTools article and these tools serve as a basis for this article, which expands on the original toolset in the following ways:
- In addition to the basic Rectangle, Ellipse, Line and Scribble tools, this version adds PolyLine, Filled Ellipse, Filled Rectangle, Text and Image tools
- Multiple drawing Layers
- Zooming
- Panning
- Rotation
In this article, I will describe how Layers were implemented, as well as the Text and Image tools.
Background
See the original DrawTools article for details on how the basic application is built, class structure, etc.
It is also assumed that the reader has a working understanding of GDI+ fundamentals, including Matrices. For an excellent introduction to GDI+, see www.bobpowell.net.
Implementing Layers
Adding Layers to the application involved adding two classes, Layer
and Layers
, where Layer
defines a single Layer
and Layers
defines the collection of Layers
in an ArrayList
.
Each Layer
exposes the following properties:
private string _name;
private bool _isDirty;
private bool _visible; private bool _active; private GraphicsList _graphicsList;
Note that the Layer
contains the GraphicsList
- this is the key to the whole thing - each Layer
contains its own list of drawing objects instead of DrawArea
. DrawArea
is modified to declare a Layers
collection instead of a GraphicsList
collection:
// Define the Layers collection
private Layers _layers;
When DrawArea
is initialized, the Layers
are initialized by creating the first Layer
and setting it Active
and Visible
:
public DrawArea()
{
// create list of Layers, with one default active visible layer
_layers = new Layers();
_layers.CreateNewLayer("Default"); _panning = false; _panX = 0; _panY = 0; // This call is required by the Windows.Forms Form Designer. InitializeComponent(); }
In the Layers
class, the CreateNewLayer()
method actually creates the new Layer
:
/// <summary>
/// Create a new layer at the head of the layers list and set it /// to Active and Visible. /// </summary> /// <param name="theName">The name to assign to the new layer</param> public void CreateNewLayer(