|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThis project will allow the user to use a vector graphics interface to draw and edit shapes. Those shapes can then be converted into GDI+ code that you can drag into your application project. BackgroundOver the years, there have been a number of applications that have required more graphics functionality than what the standard MS controls have provided. I always had to revert to coding all of the graphics by hand, or creating an image from a third-party app and painting it on my control. However, there is a problem with both these methods. The first method requires a considerable amount of time. The second method doesn't allow for any theme changes in the program, unless you draw and load multiple variations of the same image. This C# project is the solution to many frustrating hours of using the previous methods. I trust that many of you will find the code as useful as it has been to me. Using the codeI have defined the following shapes that function as vector graphics shapes. All inherit from the base class,
To avoid any confusion about the code structure, let me explain some things. We'll start in the Shape.cs file and touch on some of the highlights. The Mouse eventsThere are three mouse methods that are created and bear the same name as MS control mouse event handlers. However, to reduce the size and complexity of the code, the Shape.cs mouse code behaves slightly different from MS's code. The public virtual EventData MouseDown(MouseEventArgs e)
{
eventData.WasHit = HitTest(e);
if (eventData.WasHit)
{
isSelected = true;
painter.State.IsSelected = true;
...(additional code)
}
else if(isSelected)
{
isSelected = false
painter.State.IsSelected = false;
eventData.NeedsPainted = true;
}
eventData;
}
A few things are worth noting about the code above. Notice that the method is marked protected override void GeneratePath()
{
//Creates a triangle shape
_Path = new System.Drawing.Drawing2D.GraphicsPath();
_Path.AddLine(Location.X + (Size.Width/2), Location.Y,
Location.X + Size.Width, Location.Y+Size.Height);
_Path.AddLine(Location.X + Size.Width, Location.Y+Size.Height,
Location.X, Location.Y+Size.Height);
_Path.AddLine(Location.X, Location.Y+Size.Height,
Location.X + (Size.Width});
}
Another important item is the
As its name implies, Drawing vector shapesWhile I could have created a massive library of complex shapes and conversion methods, I wanted to keep the project size down for this article. This framework should provide a foundation for you to expand or create additional shapes and drawing capabilities. The polygon is by far the most complex shape in the project. Other code examples that I have seen did not allow the user to convert the lines to Bezier curves. In my opinion, Beziers improve the look of an image far greater than short straight lines. I will also note that this is my first polygon object to create. If anyone has suggestions on improving the polygon or any other code section, I welcome your input. When creating a polygon, the shape will keep adding nodes with the As you can see, you can change the shape's name and set some other important properties in regards to code generation. When you select each of the properties, a description of the property will appear on the right. Read each of these carefully to understand how they will affect the code output! It's important to note that the GDI Generation Properties will be updated as you select them. However, when editing the " Tracing an imageThere is a cool feature I added in tracing out a third-party image. While trying to draw a complex shape from a JPEG, I got frustrated from having to guess the exact coordinates of the shape area. From that frustration, I inserted a feature where you can import an image: BMP, JPG, GIF, or PNG into the background of the drawing area. To access this feature, navigate to: File -> Set Background Image. Generating GDI+ codeOnce all the shapes have been drawn and the desired values are set, it's time to let the code generation begin! As the code is being generated, there is an important property that affects the output of all the shapes: the " Step 1. To generate the shape code, navigate to: File -> View GDI+ Code. This will generate the code for a C# class file and load it into the code viewer, which is simply a multi-line textbox. Why do we generating code that defines a class file? Simply put, any GDI+ image that is moderately complex can be pretty lengthy. For example, the "Toucan.cs" file that you saw at the beginning is roughly 600 lines of code! This is not loosely generated code either. With one or two minor exceptions, I wouldn't write it any differently than if I was having to code the class by hand. If you are generating the project for the first time, you will receive a message informing you to create a name for the output class. Make sure to follow the naming conventions set forth by Microsoft to avoid an illegal class name. The code viewer will now open, and all appropriate shape and paint code will be loaded into it. Step 2. Copy all contents, then paste the code into an empty C# class file. Be sure to name the class file the same as your generated class name to avoid confusion. Step 3. To begin using the new class, create a Windows Form, and create a new instance of the generated GDI+ class at the top. A default namespace, " //Create a toucan object
MyCustomGraphics.Toucan toucan = new MyCustomGraphics.Toucan();
Step 4. Next, trap the form's protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//paint the toucan
e.Graphics.DrawImageUnscaled(toucan.Image, 0, 0);
}
Any shape that has been written to accept changes (color, bounds, etc.) has an enumerated value assigned to it. For example, if the " //Sets the wing color
toucan.SetColor(MyCustomGraphics.Toucan.eShapeColor.LeftBeak, Color.Brown);
toucan.RefreshImage();
//refresh the form's surface area
this.Invalidate();
Let's look at the code example above. It's important to note that no rendering updates will be done until you call the That's all folks! I trust this article has been helpful and informative. The topics discussed would each take a whole article to cover every bit of information thoroughly. Hopefully, this condensed article answered some of the main questions that will arise. Keep your eyes open, because I may write a future article on efficient ways to implement the generated class files.
|
||||||||||||||||||||||