
"Reece Dunn" <msclrhd@hotmail.com> wrote
Andy Little wrote:
Your code looks good, but here are a few comments: [1] The general impression from users of a GUI library is that they are against using a template-based library.
I guess there are two issues here. The first and possibly most important is that users see that because things are fixed at compile time, that they cant change them at runtime. Frankly I dont know at the moment whether that will be an issue or not in practise, until I have played around some more. On the other hand it is interesting to find out how much that is thought of as runtime is actually compiletime. However the major concept here is that of achieving device independence by means of specifying dimensions (ie distances mainly) in absolute units. Essentially you (metaphorically) select the size of your drawing in some unit and then draw your lines etc on it in lengths. (The lengths in pqs perform conversions , so if you want to work in inches or meters, km or pica point you can. The example will work exactly the same conceptually if you convert all the lengths in mm to inches or whatever). The draughtsman is always working in so called "world coordinates".. (this is currently a 2D 'world). It is not up to the draughtsman , How that drawing is actually rendered on a device. Typically on the average display, the viewer of the drawing has dropdowns and scrollbars to adjust the actual scale and screen position of what has been drawn to whatever part is of interest. From the draughtsmans point of view they are literally independent of any worry about how to scale the drawing to a particular device and so on and so forth. And it might be a map of the universe or a VLSI logic circuit, but it is drawn at a scale of 1:1. The other concern may simply be the perceived complexity of templates. However if you review the code you will see that in the body of the function there is very litlle if any heavy template machinery, no more really than using (say) std::vector<T>. OTOH it might be useful to find out more detail about what the concerns of potential users are.
[2] The DeviceHandle should be hidden via an interface and have an implementation for *nix, mac, Windows and others.
Absolutely. Its early days. MFC/ ATL users may recognise 'HDC hdc; ' ;-)
[3] I strongly recommend that the graphical side (devices, pens, brushes, images, fonts, etc.) be separate from the GUI (windows/widgets, events, etc.).
Absolutely. On the issue of pens, brushes and so on, I am looking at this from another viewpoint. Typically when you want to draw a line, you want to specify a color and a thickness. So ideally a line is an object with a start point, end point, a colour and a thickness and eg dot dash (possibly a virtual "how to draw this line" function, end style: square or round etc, This gives it its own state independent of pens and so on, and also helps to make it persistent and eases combining primitives into larger more complex objects... all very OOP, but then OOP and GUIs grew up together. Similarly an area of text should have an absolute height and width and so on in pica point or mm etc as you prefer. But again no mention of any device to draw on here. The GUI framework will make use of the graphics framework for drawing
to a window's client area.
From the point of view of the above concept you have created a collection of objects in the drawing, which you can then point at a device (And here I see a windows 'window' as a device), eg via a graphics stream which then has to do the real work of figuring out how to render it. OTOH the 'device' could be a file,printer etc, while the drawing could be a file... very much like an ostream.
[4] I like how you specify independant coordinates. Is this customizable (i.e. can you change between pixels, cm, inches, etc.) and can you convert between coordinate systems (e.g. when implementing a web browser, CSS
units
can be percentages, cm, pc, pt, etc.)?
Yes anything from parsecs to nanometers, pica-point etc. However , in order to achieve device independence there should in theory be no concept of a pixel type at the "world layer". (This is actually simplifying. It is possible to use (say) double, (even) voltage-y, time-x etc, to draw in. The 'morph' functor demoed in the body of the drawFunction is also used to scale at the "world-view" layer described below, but this would require more template parameter exposure) I have separated the thing conceptually into three layers. At the top there is the world layer which is the one in which the drawing is done in 'world units' in relation to the world origin. "Living" in the world are world-elements which are objects with the attribute of a position in relation to the world origin. The "world-view" (which basically represents the user level viewport but in world units,) is just a world-element. ie it has a position in the world and can "wander about" about eg by scrolling in world units. Hence the world-view is a member of the world, but is also conceptually the second layer and is where scaling from drawing world" to "real-world" sizes is performed. The final layer is the viewport layer. This has a physical-size, but the size now is nominally 1:1 with the real world, so for a typical window it might be (say) 150mm by 100mm or whatever. This is a member of the world-view. So the (current) world-view size is then found by scaling the viewport size to world units. but obviously if the user changes the size of the viewport, this will change,as can potentially the size of a pixel. It is possible to draw objects at every layer, so for example if you draw at the "world-view" layer and then scroll, then what you have drawn will effectively remain where it is, if you get my meaning. Finally, at the viewport-layer Neither scaling Nor scrolling will change what you have drawn in relation to the viewport. Other requirements are probably a zoom origin so that zooming in on the world object at the "centre" of the viewport remains where it is , and so on. Note that the drawFunction in my original post does not need to know anything at all about these lower layers.
[5] Can you get the width and height of the drawing rectangle?
Assuming this is the "world" drawing rectangle, it can be set to whatever you wish, either fixed or expanding as elements are added to the "world" Is it
possible to create a scrolling view of a larger drawing area?
Yes, but from the point of view of this particular concept, which is a very simple one, that is a device dependent detail. However in practise to demonstrate the concept I am implementing scaling and scrolling in a windows app. Its currently being done in WTL but I may do a MFC version too. I would like to do a Linux version but will find that quite a hard road as I dont have experience on that platform. regards Andy Little