Author Topic: .NET Graphics Components  (Read 12816 times)

0 Members and 1 Guest are viewing this topic.

SomeCallMeDave

  • Guest
.NET Graphics Components
« on: December 21, 2007, 09:24:25 AM »
I have found myself needing to create small line diagrams for Windows apps.   So far,  I have muddled through using  System.Drawing.....
Surely there is a  better way.

I found a list of graphics components here

I was wondering what you guys were using and if you could recommend any or warn me away from any.

Right now, it would just be for experimentation, so a freebie would be preferred (or one with a trial version, at least)

BTW, I am using C#2008 Express,  but I do have VS2005 Standard.

Thanks

Glenn R

  • Guest
Re: .NET Graphics Components
« Reply #1 on: December 21, 2007, 09:44:08 AM »
SCMD,

I haven't had much of a need for this type of thing myself, however Charles Petzold's book 'Programming Microsoft Windows with C#' does have a lot of graphics drawing in it from memory.

Can you allude as to what you're trying to accomplish, maybe with some screen cappies...?

Cheers,
Glenn.

Glenn R

  • Guest
Re: .NET Graphics Components
« Reply #2 on: December 21, 2007, 09:45:36 AM »
Another thought - can you create small bitmap/png's of what you need and embed them as resources into your dll and then load/draw the resource piccy into a picturebox for example?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #3 on: December 21, 2007, 09:57:04 AM »
It does seem that GDI+ would give the most control, It might be fairly strait forward once you built your base object classes.
At one time I was pondering building a .SLD to GDI+ converter, but it’s beyond current my skill level.

SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #4 on: December 21, 2007, 09:58:40 AM »
Glenn,
Attached is a screen capture of the simple one that I have done so far. I used the Help file and some stuff from the internet to figure out the simple diagram.
 I was able to get the coordinates that I needed by creating a sketch in Autocad.  The built-in components worked OK for this, but I can see if things get more complex, the coding could get intense.


But what I would really like to do with this little app is to have a simple 3D view that would show scenario a bit more intuitively .


The bitmap route doesn't really fit for this app because the values update with each re-calc.  (I figured out how to use the mousewheel to increment the values so the user can interactively adjust the scenario.  I'm really liking C#  :) )

Glenn R

  • Guest
Re: .NET Graphics Components
« Reply #5 on: December 21, 2007, 10:02:29 AM »
SCMD,

I thought that was where you were heading. I concur with Dan - GDI+ will give the ultimate control.
Glad you're liking the .NET land of curly braces - the only way to go ;)

Nicely done BTW.

Cheers,
Glenn.

SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #6 on: December 21, 2007, 10:05:15 AM »
It does seem that GDI+ would give the most control, It might be fairly strait forward ....

Daniel,

I'm thinking that your definition of 'fairly strait forward' and mine vary a great deal  :)


SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #7 on: December 21, 2007, 10:06:39 AM »
Glenn and Daniel,

Thanks for the advice.   I will dig further into GDI+ and save my money for something more tasty :)


Thanks again,

Dave

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #8 on: December 22, 2007, 09:52:48 PM »
David,
another option - but a whole new learning curve is either DirectX or OpenGL, once you have a device context you're set, just call the drawing functions supplied with the lib and you have a full 3d environment.
I mention these as you are heading down the 3d route otherwise for 2d drawing gdi would be ok.
If you will be sure that your app will only be windows based, DirectX would be the way to go although they do revise it regularly which is a bit of a pain with hardware and maintenance etc. It's OO and pretty straight forward and there are plenty of resources/tut's on the net.

OpenGL on the other hand is easier IMO and full (hardware accelerated) support in vista is not certain afaik. Look up Colin Fahey's opengl C# wrapper if you want to go down that path. To me it's easier and you can nearly use C code line for line in C# so there's plenty of source and examples around.

If you want some more info just holler.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

quamper

  • Guest
Re: .NET Graphics Components
« Reply #9 on: December 23, 2007, 08:41:57 AM »
If you will be sure that your app will only be windows based, DirectX would be the way to go although they do revise it regularly which is a bit of a pain with hardware and maintenance etc. It's OO and pretty straight forward and there are plenty of resources/tut's on the net.

OpenGL on the other hand is easier IMO and full (hardware accelerated) support in vista is not certain afaik. Look up Colin Fahey's opengl C# wrapper if you want to go down that path. To me it's easier and you can nearly use C code line for line in C# so there's plenty of source and examples around.

DirectX and OpenGL might be overkill. But if you do go that route, MDX (Managed DirectX is no more) they replaced it with the XNA framework. If you are looking at doing DirectX then the .NET then SlimDX is the way to go http://slimdx.mdxinfo.com/

For OpenGL you have the http://www.taoframework.com/ and SDL.NET http://cs-sdl.sourceforge.net/index.php/Main_Page Both of those are really nice .NET wrappers.

But for what you're doing GDI+ is probably best

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #10 on: December 23, 2007, 09:41:13 AM »
Here is how I might start out with GDI+
Build a set of geometry/object classes, then add extension methods to the
System.Drawing.Graphics class to draw your stuff.

In this case, I created an extension method to draw an AutoCAD line on a form  8-)

Code: [Select]
public static class GraphicsExtension
  {
    public static void DrawLine(this Graphics m_this, Autodesk.AutoCAD.DatabaseServices.Line line)
    {
      Pen pn = new Pen(Color.White);
      m_this.DrawLine(pn, new Point((int)line.StartPoint.X, (int)line.StartPoint.Y),
                          new Point((int)line.EndPoint.X, (int)line.EndPoint.Y));
     

    }
  }

Code: [Select]
   private void panel1_Paint(object sender, PaintEventArgs e)
    {
      Graphics g = e.Graphics;
      Line line1 = new Line(new Point3d(30, 30, 0), new Point3d(220, 220, 0));
      Line line2 = new Line(new Point3d(220, 30, 0), new Point3d(30, 220, 0));
      g.DrawLine(line1);
      g.DrawLine(line2);
    }



It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #11 on: December 26, 2007, 12:38:40 PM »
..Surely there is a  better way...

You are right, this is too much work to use out of the box for simple lines and text. I want/need something similar for my casework application, a more dynamic graphic that updates with changes. I am working on a small set of classes to make these tasks more intuitive. I’ll post code once I am little further along and if people are interested.

example of what I have so far

Code: [Select]

     Graphics g = e.Graphics;
      Pen pen = new Pen(Color.PapayaWhip);//hmmm interesting

      EntityList ents = new EntityList();

      ents.Add(new Text(g, textBox1.Text,
                        new Font("Verdana", 16), new SolidBrush(Color.Red), Center));

      ents.Add(new Ellipse(g, Center, 35, 10, pen, 33));//rotated
      ents.Add(new Line(g, pt1, pt2, pen));
      ents.Add(new Line(g, pt2, pt3, pen));
      ents.Add(new Line(g, pt3, pt4, pen));
      ents.Add(new Line(g, pt4, pt1, pen));
      ents.Add(new Circle(g, Center, diameter, pen));
      ents.Add(new Ellipse(g, Center, 35, 10, pen, -33));//rotated
      ents.Add(new Ellipse(g, Center, 35, 10, pen));
      ents.Draw();

      //rotated text
      Text txt = new Text(g, "Rotated", new Font("Verdana", 16),
                          new SolidBrush(Color.Red), new PointF(200, 200), -45);//rotated

      txt.Draw();



Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: .NET Graphics Components
« Reply #12 on: December 26, 2007, 12:44:07 PM »

Ooops, missed this thread.
looks like fun guys !
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #13 on: January 23, 2008, 02:01:37 AM »
Anyone want to play? Add Stuff?

Make a form
Make a panel
Make a paint event (see pic)
The origin is bottom left

See the sample code:
Code: [Select]
private void panel1_Paint(object sender, PaintEventArgs e)
    {
      DrawSpace drawSpace = new DrawSpace(panel1, e.Graphics);
      Pen pen = new Pen(Color.PapayaWhip);//hmmm interesting

      Line line1 = new Line(drawSpace, new PointF(10, 10), new PointF(100, 100), pen);
      line1.Draw();

      Text txt = new Text(drawSpace, "Rotated", new Font("Verdana", 16),
                          new SolidBrush(Color.Red), new PointF(100, 100), 45);//rotated
      txt.Draw();

      Ellipse ell = new Ellipse(drawSpace, new PointF(100, 200), 30, 50, pen, -45);
      ell.Draw();

      //
      EntityList eList = new EntityList();
      eList.Add(new Circle(drawSpace, new PointF(100, 100), 30, pen));
      eList.Add(new Line(drawSpace, new PointF(100, 100), new PointF(100, 200), pen));
      eList.Add(new Circle(drawSpace, drawSpace.LLPoint, 30, pen));
      eList.Add(new Arc(drawSpace, drawSpace.CenterPoint, 45, 0, 180, pen));
      eList.Draw();
    }

SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #14 on: January 23, 2008, 07:09:51 AM »
Very nice Daniel. 

I know how my free time will be spent today  :)

Thanks for sharing.



It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #15 on: January 23, 2008, 09:54:00 AM »
Let me know what you think, It’s a *Very* rough draft. I wanted to get opinions on moving the origin to the lower left before I went any further.  :mrgreen:

SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #16 on: January 23, 2008, 10:15:22 AM »
IMO, moving the origin is a great idea.  Having it there makes 'plotting' points much more intuitive.

I'm hoping that I will have some time today or tomorrow to dig into it , if I can stop forex trading on that site that Mick posted :)

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #17 on: January 23, 2008, 04:13:58 PM »
IMO, moving the origin is a great idea.  Having it there makes 'plotting' points much more intuitive.

For a CAD type system that is the best choice as most understand the Cartesian coordinate system.

I'm not sure how GDI+ works in regards to panning and zooming, if this is required the origin will need to be re-calc'd in relation to the panel corner and the scene re-drawn to suit.
This is where I find lib's like Opengl are a bit more intuitive once you get going, they take care of the scene to screen transformations and others and let you draw in the 'scene' or model space.

Quote
I'm hoping that I will have some time today or tomorrow to dig into it , if I can stop forex trading on that site that Mick posted :)

hehe, addictive isn't it!
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #18 on: January 23, 2008, 06:26:44 PM »
hehe, addictive isn't it!

It is!  And it seems sooooo easy when I'm using their play-money  :-D



SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #19 on: January 23, 2008, 06:29:44 PM »
So here is my attempt at extending Daniel's class.

It is still a very rough draft,  but it might have some potential.
Still needs lots of properties,  more constructors,.......

And it was a great learning exercise for me

Code: [Select]
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
           
            DrawSpace drawSpace = new DrawSpace(panel1, e.Graphics);
            Pen pen = new Pen(Color.Black);//hmmm interesting

            Chart chart1 = new Chart(drawSpace, 100, 5);
            chart1.Draw();

        }


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #20 on: January 23, 2008, 10:29:38 PM »
David, Very Nice
Do you mind if I add this in?

SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #21 on: January 23, 2008, 10:37:58 PM »
Don't add it yet.

I had a few problems in that version.  I am cleaning those up and adding a few methods.

Code: [Select]

      private void panel1_Paint(object sender, PaintEventArgs e)
        {
           
            DrawSpace drawSpace = new DrawSpace(panel1, e.Graphics);
            Pen pen = new Pen(Color.Black)

            Chart chart1 = new Chart(drawSpace, 100, 100);
            chart1.HorizontalTicks = 10;
            chart1.VerticalTicks = 10;
            chart1.Draw();
            chart1.DrawBarVert(75, 10, 60, Color.Red);
            chart1.DrawBarHorz(55, 10, 50, Color.Blue);
            chart1.PlotPoint(10, 10, Color.Red, 3);
            chart1.PlotPoint(15, 15, Color.Red, 3);
            chart1.PlotPoint(20, 20, Color.Red, 3);

            PointF[] graph = new PointF[4];
            graph[0].X = 0; graph[0].Y = 0;
            graph[1].X = 10; graph[1].Y = 1;
            graph[2].X = 15; graph[2].Y = 45;
            graph[3].X = 66; graph[3].Y = 92;
            chart1.PlotLine(graph, Color.Purple);

        }


I will post a revised version later tonight or in the morning that I would be happy for you to add.

Also,  I have a design question.  For my new methods, I create Entity(s) in the method.  Should I call the draw method directly on the new Entitiy(s) from within that method.  Or would it be better to create an EntityList,  add the new Entity(s) to it, and then call the EntityList.draw  method in the Chart Draw override?

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #22 on: January 23, 2008, 10:56:54 PM »
...
Also,  I have a design question.  For my new methods, I create Entity(s) in the method.  Should I call the draw method directly on the new Entitiy(s) from within that method.  Or would it be better to create an EntityList,  add the new Entity(s) to it, and then call the EntityList.draw  method in the Chart Draw override?

Yes, creating a class that holds a list of entities would be the go, this way you are creating a scene graph or 'model' class to hold the entities, then from you panel's OnPaint() method (your panel would have a class member of your 'scene' class) you simply add a myScene.Draw() call to re-paint the scene with the objects.

You could also keep the scene class separate from the panel, this way you can draw the scene in any panel you like.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #23 on: January 23, 2008, 11:07:13 PM »
Also,  I have a design question.  For my new methods, I create Entity(s) in the method.  Should I call the draw method directly on the new Entitiy(s) from within that method.  Or would it be better to create an EntityList,  add the new Entity(s) to it, and then call the EntityList.draw  method in the Chart Draw override?

6 of 1, it’s really the same method in the end

I was thinking of making this an open source project, where people can add stuff when they’re not trading.  :laugh:
I’m trying to learn how to use Mark’s subversion space, maybe this would be a good test project


MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #24 on: January 23, 2008, 11:21:55 PM »
6 of 1, it’s really the same method in the end


not really, now the project is growing it's an ideal time to start using OOP to it's potential.

IOW, why not create say a class called ChartDrawableEnt as a base class which holds basic stuff like colours, line types etc then derive new types from it such as ChartBar, ChartLine etc.

Within wach of these derived classes you implement (override) a Draw() method which it inherits from the base, in here is where your drawing for that type of object mojo lives.

Now, once you have a few drawables it's really easy to add them to the 'scene' using polymorphism.

Scene scene = new Scene();
scene.AddEntity(myLine(p1, p2));
scene.AddEntity(myBar(p1, p2, width)
etc.
This can be done from the gui also.

Then in your panel paint method you just need to call scene.Draw(); to paint all of your objects.

Scene.Draw() would look something like this -

For each ChartDrawableEnt in entlist
    ent.Draw();

this is a much more dynamic solution I think.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #25 on: January 24, 2008, 12:12:09 AM »
Mick,

This is kind of what I have done.
I have a base class called Entity, that has a virtual method Draw(). There is also an EntityList class that also has a method called Draw(), that calls the Draw() method on each item in the collection. My thought was that new graphics should derive from the Entity class which can be added to the EntityList or drawn on its own

Here is where things get funky, since I have inverted the Y axis to move the origin to the lower left, some objects don’t behave well. For example text, I have to reset the matrix before the text is drawn or it will be inverted. I made a class called DrawSpace. It’s my idea that this class hold the matrix/space information, incase an Entity needs to temporarily alter the matrix or the origin.

Code: [Select]
private void panel1_Paint(object sender, PaintEventArgs e)
    {
      DrawSpace drawSpace = new DrawSpace(panel1, e.Graphics);
      Pen pen = new Pen(Color.PapayaWhip);
      EntityList eList = new EntityList();
      eList.Add(new Circle(drawSpace, new PointF(100, 100), 30, pen));
      eList.Add(new Line(drawSpace, new PointF(100, 100), new PointF(100, 200), pen));
      eList.Add(new Circle(drawSpace, drawSpace.LLPoint, 30, pen));
      eList.Add(new Arc(drawSpace, drawSpace.CenterPoint, 45, 0, 180, pen));
      eList.Draw();
    }

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #26 on: January 24, 2008, 12:48:00 AM »

In the code above I'd be adding the ent's in another method, maybe a draw graph button or OnInitPanel say. The only call I'd have in my paint method is eList.Draw(), this way your avoiding adding the ents every time the window paints!!

IRT to the DrawSpace, you should only need to have a method that transforms point data from panel coords to scene coord's, this is the last thing that needs doing before drawing, text may be a bit tricky as you say but you are only inverting the y axis in effect so you only need to change that I think.

You will probably need something like a graphics system ents that takes your scene coord's and xforms them just before painting, like the worldDraw() uses in arx.

In say your line class's draw method would then look something like this -

Draw()
{
   // get and set your pens etc here:
   gs.addLine(p1, p2);

}

and the gs.addLine method does the xform mojo. Does that make sense??
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #27 on: January 24, 2008, 12:56:40 AM »
I agree that this would make sense from a performance point of view.
But how would I make the variables P1, and P2 dynamic in nature, without having to reconstruct the Entity?
Say if someone wanted to alter the value of P1 via a textbox.

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #28 on: January 24, 2008, 01:01:07 AM »
The pipeline goes something like this -

Add your objects to the scene
->
Model Transformation - translate the scene coord's to the view coord's (i.e. if you move the origin, all ents go too).
This involves clipping out things outside the panel, the panel should look after that though.
->
Viewing transformatiom - transforming all of the scene to fit into the viewport/panel, you would do this by scaling the scene coord's to the panel/viewport size.

I haven't looked at the gdi stuff at all and it may look after it all for you, it's good to know what's happening though.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #29 on: January 24, 2008, 01:08:15 AM »
I agree that this would make sense from a performance point of view.
But how would I make the variables P1, and P2 dynamic in nature, without having to reconstruct the Entity?
Say if someone wanted to alter the value of P1 via a textbox.

Ok, this is where it gets 'deep', if you remember in arx how you add and get entities, you will need to do something like that, i.e. create a db of sorts so you can get your ent's by id (your ent lists is starting to look more like a dictionary ;) ).
How do you get the id from the ent with user interaction? good question, I haven't a clue with GDI+ but with most grfx lib's they have a selection buffer ability which is a bit hard to explain just now but if you want I can go through it with you.

This is the problem, the vast majority of examples show you the easiest ways to create and populate a graphics widget, what they don't go into is the complexity of making it dynamic and user interactive.
I love this stuff so if you want, just throw a question and I'll see if I can help, I'm a bit busy to jump in the app though.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: .NET Graphics Components
« Reply #30 on: January 24, 2008, 01:19:47 AM »
Wow! GDI+ Cad  :-D
It seems I have a lot to learn. What I ought to do is examine some of the .NET gaming engines and see if there is something I can use/learn from.  :mrgreen:

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #31 on: January 24, 2008, 01:32:42 AM »
There's plenty to choose from, most of them are based on opengl or directx, most have a scene graph etc all set up as well.

when I was playing with java I used their graphics lib (java3d I think), it was very good and easy to learn, very powerfull and 3d to boot, but...
« Last Edit: January 24, 2008, 01:36:57 AM by MickD »
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

SomeCallMeDave

  • Guest
Re: .NET Graphics Components
« Reply #32 on: January 24, 2008, 06:47:43 AM »
With all of the above read (not fully understood, but read),  attached is the current Chart.cs


My original question about design popped into my head when I thought about how to erase something.  I know I can re-draw it using the panel backcolor property,  but wasn't sure of the best way to handle that re-draw.


Daniel,  if you want to add this class to your project,  feel free.   I will keep extending it as I have time.   I need it for a work-out log that I am creating (so the timing was perfect).

Thanks Daniel and Mick!!   Trade On.   :-D

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: .NET Graphics Components
« Reply #33 on: January 24, 2008, 04:42:46 PM »
...
My original question about design popped into my head when I thought about how to erase something.  I know I can re-draw it using the panel backcolor property,  but wasn't sure of the best way to handle that re-draw.
...


In regards to erasing objects, what acad does is have an erased flag for each entity, if it is set it won't get drawn in the next paint event. When you file out your objects, the items flagged should not be written to file either. If you just want to hide something you would also need a visible flag which works the same way only it will still be written to file.

....then there's undo!!

Have fun.

>> Thanks Daniel and Mick!!   Trade On.   :-D
Will do :)
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien