Drawing Library - The Code Project - C# Libra...

来源:百度文库 编辑:神马文学网 时间:2024/04/30 01:05:55

4,470,415 members and growing!   7,014 now online. Email Password Remember me? Password problem?
HomeMFC/C++C#ASP.NETVB.NETArchitectSQLAll Topics  Help!ArticlesMessage BoardsLounge
All Topics,C#,.NET >>C# Libraries >>Unedited Reader Contributions
Drawing Library
Byjonnynolimits.
Library for creating shapes and developing tools
C# (C# 2.0)
Windows, .NET (.NET 2.0)
Win32, VS (VS2005), WinForms
Dev
Posted: 14 Sep 2006
Updated: 22 Jun 2007
Views: 43,298
Note:This is an unedited reader contribution
Announcements
Monthly Competition

Search   Articles Authors   Advanced Search
Sitemap
PrintBroken Article?BookmarkDiscussSend to a friend
39 votes for this article.
Popularity: 7.4. Rating: 4.65 out of 5.
Download demo project - 90 Kb Download source - 1000 KbDownload documentation - 900 Kb

Introduction
This is a generic library for drawing (work in progress). It is composed by some base tools and shapes. It allows you to draw all shapes that you want to create and develop any tools to manage your figures.
Using the code
This piece of code describes the implementation of a derived class from Shape and a derived class from Tool
Collapse
public class Ellipse : Shape { public Ellipse() { Geometric.AddEllipse(new System.Drawing.Rectangle(0, 0, 1, 1)); } public Ellipse(Ellipse ellipse) : base(ellipse) { } public override object Clone() { return new Ellipse(this); } } // .... public class Select : Tool { ..... // Override IActions Interface functions public override void MouseDown(IDocument document, MouseEventArgs e) { base.MouseDown(document, e); if (SelectShape(document.Shapes, e.Location) == HitPositions.None) Select.UnselectAll(document.Shapes); if (SelectedShapes != null) SelectedShapes(this, Select.GetSelectedShapes(document.Shapes)); } public override void MouseUp(IDocument document, MouseEventArgs e) { base.MouseUp(document, e); document.ActiveCursor = Cursors.Default; } ..... }
It is very important to implement the copy constructor and function Clone for every new shape, while it is convenient to ovverride IActions interface during the implementation of a new tool.
Main Schemes
In the Documentation there are these schemes
Orange color describes a hot spot class (interface or abstract class usually)
Yellow color describes active classes
Blue color describes passive classes (data containers or structs usually)
Light grey color describes classes of the framework but not important into current scheme
Dark grey color describes classes external to framework
This scheme rappresents the actual shapes hierarchy

This scheme rappresents the actual tools hierarchy

This scheme rappresents the communication channel beetween drawing panel, tools and shapes

IActions Interface contains all panel actions used by tools, for example mouse down and mouse move, but also paint function
IDocument is an interface but it is blue because it is only a connection point beetween tools and shapes and so it is a passive class
This scheme rapresents the relation between transformers and shapes. Transformers are used to handle shapes moving so if you want add any new moving you must derive only two classes (Transformer and CompositeTransformer) and not all classes in the shapes hierarchy.

This scheme rapresents the actual appearances hierarchy:

Other schemes are in Documentation.
Points of Interest
To rotate a shape, choose the rotate tool and select the shape. Take mouse clicked down and move. To rotate relative to a non center point, select a shape, click the Ctrl key, take mouse clicked down and move.

To deform a shape change the property Marked to true and choose the deform tool, take mouse clicked down on a marker and move. Try to group shapes and make same operations above.

Serialization
The serialization operations are made by XmlSerializer, a library that can be downloaded from:
I underline that performances are not very well.
Updates
Zoom functionality.
Grid on panel.
DrawFreeLine tool with possibility to decide the min offset between two consecutive points.

See Layout options to Bring To Front and Send To Back functionalities.
Last updates
Added possibility to move shapes with arrows and Control key.
Bug Fixing
Modified setters methods of Text Shape to mantain the text state after rotation.
Known bugs
Deform tool is not precise on shape border markers.
A problem with resize tool and grid enabled.
The Undo-Redo machanism is not precise.
Future developments
Improvement of tools (for example resize).
Improvement of performances.
Development of other tools.
References
For documentation:
http://www.sandcastledocs.com/Wiki%20Pages/Home.aspx
SandcastleBuilder.asp
https://secure.codeproject.com/dotnet/SandcastleCreateBat.asp
For object-oriented and color theory and many software development informations:
http://www.eptacom.com/
About jonnynolimits
I am a biomedical engineer. I work in Genoa as software developer. Currently I'm working in Visual C++ and I'm developing ActiveX controls. When I can I use .NET (C# or C++). Clickhere to view jonnynolimits's online profile.
Other popular C# Libraries articles:
IconLib - Icons Unfolded (MultiIcon and Windows Vista supported) Library to manipulate icons and icons libraries with support to create, load, save, import and export icons in ico, icl, dll, exe, cpl and src format. (Windows Vista icons supported).
OpenTheme : An open source graphic user interface (GUI) toolkit An innovative alternative to XAML and XUL
Automating Undo/Redo with .NET Generics A reusable library that can equip any action in your application with the undo/redo feature
Gios PDF .NET library A .NET library for generating impressive PDF reports.

[Top]Sign in to vote for this article:     PoorExcellent

Note: You mustSign in to post to this message board.
FAQ  Message score threshold 1.0 2.0 3.0 4.0 5.0    Search comments
View Normal (slow) Preview (slow) Message View Topic View Thread View Expanded    Per page 10 25 50 (must logon)
  Msgs 1 to 25 of 71 (Total: 71) (Refresh) First PrevNext
Subject  Author  Date

 Moving Shape  ymagirdici  3:28 3 Aug '07

Hi Jonnynolimits,
How can I moving shape with using only Up,Down,Left and Right Keys without interrups . Thaks for your helps.
Best Regards
Magir.
[Sign in |View Thread |PermaLink |Go to Thread Start]


 ghost shape  Ricardo Fig  7:34 27 Jul '07
  hi,
how to do that the ghost shape, follow the same RotateAngle than the rotated shape?
for example, if I rotate a rectangle, that the ghost shape when I clik SELECT rectangle, also show it ROTATED?
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: ghost shape  jonnynolimits  8:16 30 Jul '07
  Hello Ricardo,
The ghost shape is a shape used by tools to update every shape moving. So when you use a tool to move, rotate etc. a shape (or more shapes together), really you are updating only the ghost, in which the original shape GraphicsPath is copied. Only when you fire the mouse up event the real shape is updated.
The ghost shape (and also the derived ghosts) has a reference to the shape that it rapresents, so it simple the shape updating.
I don't know if my answer can be usefull (and clear), but if you have other questions or if you want more details...I am here
Best Regards,
Jonnynolimits
[Sign in |View Thread |PermaLink |Go to Thread Start]


 rotation  Ricardo Fig  9:20 25 Jul '07
  when you rotate a shape, it keeps some kind of horizontal rectangle in it, I managed to take this horizontal rectangle off, but what is still missing is that the mouse clicks only take effect into the rotated object, but not into the virtual horizontal rectangle.
Is it possible only to allow clicks inside of the rotated shape?
thanks
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: rotation  jonnynolimits  3:49 26 Jul '07
  Hello Ricardo,
the rectangle that you can see during every shape moving is the shape "ghost" and is used to update the shape.
In the Shape class there is the function Contains(point) that you can modify:
public bool Contains(Point point)
{
// New code
return _geometric.IsVisible(point);
// Old code
// return _geometric.GetBounds().Contains(point);
}
So, for all tools derived from Select now the shape becomes selected only if you click inside the shape.
But there are some problems:
1) In order to select a line, with the above changing, you have to be exactly on the line to select the shape.
2) But the big problem is when you use MultiSelect or Pointer (that can instantiate the MultiSelect tool). In order to select shapes MultiSelect tool checks the intersection between his rectangle and the shape ghost:
private void SelectIntersectedShapes(ShapeCollection shapes)
{
foreach (IShape shape in shapes)
{
if (Ghost.Geometric.GetBounds().IntersectsWith(
shape.Geometric.GetBounds()))
}
}
It becames very very difficult to check the intersaction between MultiSelect rectangle and the real shape form.
For the moment I didn't find a good solution to resolve your problem, but I'll try to look for it.
All suggesting are appreciated
Best Regards,
Jonnynolimits
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: rotation  Ricardo Fig  15:21 26 Jul '07
  Thank you a lot!!
just one quick question, what about the corner borders which allow to expand/compress the rectangle? how to do that those 4 boxes at corners to continuing appear correctly at the corner if the shape is rotated
Regards,
Ricardo
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: rotation  jonnynolimits  7:59 30 Jul '07
  Hello Ricardo,
Could you explain me please, I didn't understand? Do you want that resizing boxes appear also during rotation in the ghost shape?
Best Regards,
jonnynolimits
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: rotation  Ricardo Fig  11:42 30 Jul '07
  hi I will try to explain using other words
at this moment when you select a shape, a GHOST RECTANGLE is used for the selected shape, I want to replace this ghost RECTANGLE, with a drawing path exactly the same that is the shape, for example, if I rotate a rectangle, at selection I want to draw the ghost rectangle rotated, and if I draw a circle, I want that the ghost rectangle, should be displayed as the circle
hope now its more clear
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: rotation  jonnynolimits  12:36 30 Jul '07
  Hi Ricardo,
If you want to change the ghost appearance in order to modify ghost drawing you can do this:
modify the GhostAppearance drawing, overriding DrawSelection an others drawing functions. The best thing is to derive from GhostApperarance and assign the new appearance to the ghost at runtime.
Now, for drawing the ghost rectangle, i use ControlPaint.DrawSelectionFrame that draws exactly a rectangle. In order to draw exactly a cirle or a custom shape with a similar appearance is more complicate.
Best Regards,
Jonnynolimits
[Sign in |View Thread |PermaLink |Go to Thread Start]


 Group control  ymagirdici  10:14 11 Jul '07
  Hello JonnyNolimits,
I hope your works goes on well than before.
I have a problem on group control. I could not manages group's BackGroungColor apperance when making only one group by using two other groups. One of the group back ground color change. I do not want to color changes in any group and group shape in future.
Best Regard
magir
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: Group control  ymagirdici  11:02 15 Jul '07
  Hi Jonnynolimits,
I had a solution but it would not complete. Because in transform and resizing mode, shape background apperancy would be changed. If you would managed this problem in size and move in group control. It would be comple solution to me. I only changed Group body in the GroupEngine class like that
public static void Group(IDocument document)
{
ShapeCollection selectedShapes = Select.GetSelectedShapes(document.Shapes);
CompositeShape group = new CompositeShape();
group.Selected = true;
foreach (IShape shape in selectedShapes)
{
shape.Selected = false;
if (shape.Parent != null)
{
shape.Fillable = false;
document.Shapes.Remove(shape);
}
if (shape.Parent == null)
{
group.Shapes.Add(shape);
}
}
document.Shapes.Add(group);
}
Regards
Magir
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: Group control  jonnynolimits  3:19 26 Jul '07
  Hi Magir,
what you want is not immediate to resolve. Surely a changing in Group function of GroupEngine is necessary, but not only. Now I have some difficults to work on library, but I'll try to do it as soon as possible.
Thanks
Best Regards,
Jonnynolimits
[Sign in |View Thread |PermaLink |Go to Thread Start]


 Zoom question  mv-da  8:46 5 Jul '07
  Dear jonnynolimits, thanks for your great graphics library.
I have a Zoom question (drawingPanel.Zoom), the current Zoom factor is implemented as relative to its current value. But can it be implemented as an absolute zoom factor?
Hope to hear from you soon. Thanks in advance.
Kind regards,
Marcel
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: Zoom question  jonnynolimits  2:42 9 Jul '07
  Hi Marcel,
i don't understand very well. Please, could you explain me what you want pratically?
Thanks.
Best Regards,
jonnynolimits
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: Zoom question  mv-da  2:14 12 Jul '07
  Hello jonnynolimits, sorry for beeing un-clear. But this specific issue has been solved.
Thanks for your excelent work.
Kind Regards,
Marcel
[Sign in |View Thread |PermaLink |Go to Thread Start]


 Moving Shape  ymagirdici  16:12 19 Jun '07
  Hi Jonynolimits,
How could I move shape using by Up,Down,Left,Right Arrow keys unless mouse moving in your project.
Thanks for your valuable helps.
magir
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: Moving Shape  jonnynolimits  6:56 21 Jun '07
  Hi magir. You have to add this function in DrawingPanel class:
protected override bool ProcessDialogKey(Keys keyData)
{
if (Globe.Graphics.Bidimensional.Common.Select.LastSelectedShape == null)
return base.ProcessDialogKey(keyData);
ShapeCollection selectedShapes = new ShapeCollection();
Keys key = keyData & Keys.KeyCode;
if (System.Windows.Forms.Control.ModifierKeys == Keys.Control)
selectedShapes.AddRange(Globe.Graphics.Bidimensional.Common.Select.GetSelectedShapes(_shapes));
else
selectedShapes.Add(Globe.Graphics.Bidimensional.Common.Select.LastSelectedShape);
float offsetX = _gridManager.Resolution.Width;
if (_gridManager.Resolution.Width == 0)
offsetX = 1;
float offsetY = _gridManager.Resolution.Height;
if (_gridManager.Resolution.Height == 0)
offsetY = 1;
switch (key)
{
case Keys.Up:
foreach (IShape shape in selectedShapes)
shape.Transformer.Translate(0, -offsetY);
Invalidate();
break;
case Keys.Down:
foreach (IShape shape in selectedShapes)
shape.Transformer.Translate(0, offsetY);
Invalidate();
break;
case Keys.Left:
foreach (IShape shape in selectedShapes)
shape.Transformer.Translate(-offsetX, 0);
Invalidate();
break;
case Keys.Right:
foreach (IShape shape in selectedShapes)
shape.Transformer.Translate(offsetX, 0);
Invalidate();
break;
}
return base.ProcessDialogKey(keyData);
}
If you use Control button you can move more then one shape at the same time.
jonnynolimits
[Sign in |View Thread |PermaLink |Go to Thread Start]


 Grid control  ymagirdici  7:01 24 May '07
  Hello Jonnynolimits,
Thanks you for all your advice. I wonder if How I would be managed in Grid Apperance in run time condition. Specially in run time, how grid points on drawing panel would be disapeared.
My best regard
magir
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: Grid control  jonnynolimits  3:20 28 May '07
  Hi magir,
If you want manage Grid, you have to use GridManager. In the IDocument interface you can access to it in this way:
document.GridManager.
To render invisible the grid in drawing panel you must set to Empty the resolution property:
document.GridManager.Resolution = SizeF.Empty.
Regards
[Sign in |View Thread |PermaLink |Go to Thread Start]


 filling object  ymagirdici  15:24 17 May '07

Hello Jonnynolimits,
Thanks for your valuable examplanations. It could be very usefull for me.
For drawing a filled ellipse, first of all I drawing a empty ellipse in drawing panel. After I fill its inside by a click button. But I want to filled ellipse in the begining by mouse move. How I could access to the MainForm from PlygonAppearance class. Before your explanation is vice verse.
Best Regards,
magir
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: filling object  jonnynolimits  10:53 18 May '07
  Hello magir,
It's not immediated the access to MainFrame, but you can:
In the Paint function of Appearance class (and derived classes) you have IDocument interface to manage. From that you can access to DrawingPanel, that is the surface in which all drawings are drawn. This surface is child of MainFrame, so if you do:
document.DrawingPanel.Parent you obtain a Control that is MainFrame.
Regards
[Sign in |View Thread |PermaLink |Go to Thread Start]


 appearance  ymagirdici  12:24 11 May '07

Hello jonynolimits,
I could try to access to BackgroundColor1 properties inside the MainForm. But I could not succesfully. If you would show me that I would be very pleasured. Thanks of all your helps.
Ragards
Magir
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: appearance  jonnynolimits  3:24 14 May '07
  Hello magir,
the problem is that the two properties, BackgroundColor1 and BackgroundColor2, are in the derived class PolygonAppearance that derives from Appearance. Every shape has a property Appearance that is declarated as Appearance type. This choice has been decided because a line, for example, shouldn't have properties sach as BackgroundColor1 and BackgroundColor2.
So, for using the two properties you have to cast to PolygonAppearance:
Globe.Graphics.Bidimensional.Common.Shape shape = new Globe.Graphics.Bidimensional.Base.Rectangle();
((Globe.Graphics.Bidimensional.Common.PolygonAppearance)shape.Appearance).BackgroundColor1 = Color.AliceBlue;
((Globe.Graphics.Bidimensional.Common.PolygonAppearance)shape.Appearance).BackgroundColor2 = Color.Aqua;
I hope that my examplanation can be usefull
Regards
[Sign in |View Thread |PermaLink |Go to Thread Start]


 Filling Shape  ymagirdici  5:07 9 May '07
  Hello,
Thanks all your recomend. How could I fill object.
have a good works
magir
[Sign in |View Thread |PermaLink |Go to Thread Start]

 Re: Filling Shape  jonnynolimits  7:52 9 May '07
  Hello,
In order to fill an object, you can change two properties: BackgroundColor1 and BackgroundColor2, so you will obtain your filled object. If you use my demo program, you have to click Shape Properties tab, click a shape, expand Appearance properties and here you can find the two properties.
Regards
[Sign in |View Thread |PermaLink |Go to Thread Start]

Last Visit: 9:36 Tuesday 4th September, 2007 First PrevNext
General comment   News / Info   Question   Answer   Joke / Game   Admin message
Updated: 22 Jun 2007 Article content copyright jonnynolimits, 2006
everything else Copyright ©CodeProject, 1999-2007.
Web07 |Advertise on The Code Project |Privacy

The Ultimate Toolbox •ASP Alliance •Developer Fusion •Developersdex •DevGuru •Programmers Heaven •Planet Source Code •Tek-Tips Forums •
Help!
Articles
Message Boards
Lounge
What is 'The Code Project'?
General FAQ
Post a Question
Site Directory
About Us
Latest
Most Popular
Search
Site Directory
Submit an Article
Update an Article
Article Competition
Windows Vista
Visual C++
ATL / WTL / STL
COM
C++/CLI
C#
ASP.NET
VB.NET
Web Development
.NET Framework
Mobile Development
SQL / ADO / ADO.NET
XML / XSL
OS / SysAdmin
Work Issues
Article Requests
Collaboration
General Discussions
Hardware
Algorithms / Math
Design and Architecture
Subtle Bugs
Suggestions
The Soapbox