Simple object-oriented 2D graphics framework for use in Visual C++?
We're building a method of connecting components visually via a GUI in a Visual C++ application (MFC). Simple things like clicking on boxes and drawing lines between those that are connected, and storing information on them. The problem is that we're making all this by ourselves from the ground up in GDI and it quickly becomes a heck of a lot of code to maintain.
Are we really reinventing the wheel here?
I've looked around on the web for components that provide an object-oriented 2D framework (vector graphics being interesting here). Object-oriented in the sense that a square on the screen is a square object in code, or at least that you can store custom information on the graphical object. It should support retrieving information on object positions etc in code to draw lines between objects, and detect whether the mouse is over an object or not.
Not really complicated things, but it becomes quite complicated and hard to maintain if there are hundreds or thousands of line to maintain just because you wrote all of it yourself, not to mention the potential for bugs creeping in, that would be avoided in a mature framework.
Have you had a look at direct2d which is kinda the replacement for gdi. http://blogs.technet.com/thomasolsen/archive/2008/10/29/introducing-the-microsoft-direct2d-api.aspx http://msdn.microsoft.com/en-us/library/dd370990(VS.85).aspx
As an SVG library that looks useful (thanks Malkocoglu for the idea!), I found this one: libboard. The simplicity in the code samples look awesome; my only remaining issue would then be in having the user interact with its generated SVG drawings. :/ AFAIK, it doesn't even include a renderer, much less a method to interact with its drawing. I'm not sure I'm willing to develop an SVG parser myself to control these needs. But the code simplicity to programmatically build the drawings look like just what I'm after. Hmm.
I'm sure you will go with an OO package, but don't expect miracles. Here's why.
I assume you start out with some application data, a set of application objects, let's call them objects A.
You could use a package of OO graphical objects to represent the graphical view of objects A, call this new set of objects G.
Now you have two sets of objects, A and G, either one of which could change dynamically, and you are faced with the problem of keeping them in correct correspondence. Not only do you have to generate G from A, you have to modify G when A changes, and modify A when G changes. This calls for lots of event-driven linkage code, and you can never be sure you've handled every case correctly. You can easily get into situations where what you see is not what you get. (WYSINWYG)
I have two suggestions:
- What you're doing
Have a "paint" routine that directly renders objects A (using "blt" if you want to avoid flashing). Attach simple graphical information to objects A, like screen position and size. Handle mouse events yourself, for highlighting, dragging, creating wires, etc. This may seem like a lot of trouble, but it avoids all the linkage trouble you get into with redundant sets of objects. And, you have complete control of the code.
- An oddball method that I use: Differential Execution
This is a general technique for managing redundant sets of objects. However, it has a tough learning curve. Most programmers are not up to it, but it does reduce code and guarantee correctness.
The description of "drawing objects and connect them together", sounds vaguely like something that Fig (xfig / winfig / et al) handles.
Another product that might fit the purpose (albeit at a price) is Visio -- the Microsoft Office Visio SDK (see http://office.microsoft.com/en-us/visio/HA101656401033.aspx) is supposedly quite rich.
I have not looked either fig or Visio from a programmer's standpoint, however, so I have no idea what the underlying code looks like, or whether it's suitable for your purpose... But I think they both are good starting points for inspiration. Perhaps there is another graph/figure library out there that might suit your purpose.
BTW, while noodling (er, Googling) around on this, I stumbled across AGD - automatic graph drawing at http://www.ads.tuwien.ac.at/research/graphDrawing.html. Again, not sure how suitable it is for your particular situation, but it seemed interesting enough to point it out.