Re: [boost] Re: thoughts on a GUI component library

In-Reply-To: <cpsv4p$foa$1@sea.gmane.org> michaeltoksvig@yahoo.com (michael toksvig) wrote (abridged):
you might consider adding operator[] to point and size
also, consider defining area in terms of 2 points, and adding operator[] to that, too
I was about to say the same thing :-) I'd go further, and expose the array. class box { point data_[2]; public: point *data() { return data_; } static size_t size() { return 2; } point &operator[]( size_t i ) { assert(i < 2); return data_[i]; } // Maybe begin/end too. const point &top_left() { return data_[0]; } const point &bottom_right() { return data_[1]; } float top() { return data_[0][1]; } float left() { return data_[0][0]; } float bottom() { return data_[1][1]; } float right() { return data_[1][0]; } size extent() const { return bottom_right() - top_left(); } float width() const { return right() - left(); } float height() const { return bottom() - top(); } point centre() const { return top_right() + extent()/2; } // ... void set_top_left( const point &p ); void set_top( float f ); void set_centre( const point &p ); // ... }; This is because you will almost certainly want transforms that act on arrays of points, and it will sometimes be convenient if they can act on rectangles too. I would provide get/set methods which are independent of representation. I'd consider allowing things like ++box.top() too. Currently I think the convenience is not worth the loss of purity. ++box[0][1] should work, though. On naming... I think "area" is the wrong name. To me an area can be any shape, or alternatively, every shape has an area. I would expect circle.area() to return pi*r*r. "Rectangle" is better, but what we actually have here is a special kind of rectangle which is aligned with the axis. A rotated rectangle needs more than 2 points. So conceptually we need two rectangle types. I suggest "rectangle" is reserved for the general case, and the aligned one is called "box". As in "bounding box". It has the benefit of being short. I see no benefit in using "position" instead of the usual "point". "Point" is shorter. It's hard to improve on "size" :-) I would seriously consider replacing float with a typedef, perhaps with another typedef for distances and offsets. Even without type checking, I think using more exact type names helps to clarify thought. [Later...] I've looked at the code in the zip file now. I see it doesn't match the email. It uses a different representation and adds several member functions, although not as many as me. I am surprised to see things like size*size and size/size. I see the design is being driven by the needs of a windowing system, when I am being driven by the needs of a graphics/drawing system. That has led to different results, which I suspect is a bad thing. At any rate, it has convinced me that exposing raw member variables (like area.pos) is a mistake. -- Dave Harris, Nottingham, UK

On Fri, 17 Dec 2004 13:06 +0000 (GMT), Dave Harris <brangdon@cix.compulink.co.uk> wrote:
[...] So conceptually we need two rectangle types. I suggest "rectangle" is reserved for the general case, and the aligned one is called "box". As in "bounding box". It has the benefit of being short. Not sure. In computer graphics you specifically talk about "axis-aligned bounding boxes". To me, "box" is the 3d version of "rectangle".
Cheers, Michael

correct, axis-aligned rectangles and boxes can be thought of as multi-dimensional ranges this implies that area (or whatever) could be defined as: struct area { point low; point high; point &operator[](size_t i) { return (&low)[i]; } // contentious, i know // things you'd expect from a range bool contains(const point &p) { return !strict_less(p, low) && strict_less(p, high); } }; note that area could be templated with the point type, since it would work just as well for float, point3d, etc. /tox "Michael Walter" <michael.walter@gmail.com> wrote in message news:877e9a1704121705302ac4bce4@mail.gmail.com...
On Fri, 17 Dec 2004 13:06 +0000 (GMT), Dave Harris <brangdon@cix.compulink.co.uk> wrote:
[...] So conceptually we need two rectangle types. I suggest "rectangle" is reserved for the general case, and the aligned one is called "box". As in "bounding box". It has the benefit of being short. Not sure. In computer graphics you specifically talk about "axis-aligned bounding boxes". To me, "box" is the 3d version of "rectangle".
Cheers, Michael _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Dave Harris wrote:
In-Reply-To: <cpsv4p$foa$1@sea.gmane.org> michaeltoksvig@yahoo.com (michael toksvig) wrote (abridged):
you might consider adding operator[] to point and size
also, consider defining area in terms of 2 points, and adding operator[] to that, too
I was about to say the same thing :-) I'd go further, and expose the array.
class box { point data_[2]; [snip] };
I think that this is the wrong representation.
This is because you will almost certainly want transforms that act on arrays of points, and it will sometimes be convenient if they can act on rectangles too.
Translation: a.pos += gui::size( 5, 7 ); Scaling: a.size += gui::size( 10, 20 ); Rotation: n/a since you are assuming that each side has an angle of 90 degrees (allowing for two point representations).
I would provide get/set methods which are independent of representation. I'd consider allowing things like ++box.top() too. Currently I think the convenience is not worth the loss of purity. ++box[0][1] should work, though.
If you have point high, low; then which corner is "high"? Likewise, using top_left, bottom_right is bad. In general, storing a rectangle as a set of two points is the wrong representation, especially for portability. Windows defines (0, 0) to be the top left corner, while Mac/Cocoa define it to be the bottom left corner. Therefore, in order to extract the two points in any of the above point set representations, you need platform dependant information about the coordinate orientation. This complicates matters similar to my initial attempt (using properties) by having to rely on platform dependant mapping every time you are referencing the rectangle data. Having a (point, size) notation, similar to the Cocoa representation, you remove the need for platform dependancy (except when mapping between the native type and the independant type). Also, this representation simplifies translation and scaling (see above). You do not need to worry about the direction of the size type since this is resolved for you by the operating system. Granted, gui::rect( 10, 15, 100, 150 ) will be orientated differently on Windows and Mac, but for the operating system user, they will be orientated correctly.
On naming... I think "area" is the wrong name.
I have revised the names for area (now rect with a typedef for rectangle if you prefer to use the longer name) and position (now point).
I see no benefit in using "position" instead of the usual "point". "Point" is shorter.
I was aiming at adding information to the name, for example move( point pt ); // move to the new point move( position pos ); // change the position I have conceeded the point (pun intended!) and changed the name. It may be a good idea to typedef point as position, like I do with rect.
It's hard to improve on "size" :-)
:)
I would seriously consider replacing float with a typedef, perhaps with another typedef for distances and offsets. Even without type checking, I think using more exact type names helps to clarify thought.
I am now using a UDT called metric (re: mathematics) to represent the values. See the other messages in the thread for discussions on this.
[Later...]
I've looked at the code in the zip file now. I see it doesn't match the email. It uses a different representation and adds several member functions, although not as many as me. I am surprised to see things like size*size and size/size.
On review, I have removed size/size, size*size. As for the representation change: this is an evolving library, but the essence remains the same, so discussion here is still valid. I do not intend on posting the full member function list as these e-mails are long enough already! If you are interested, take a look at the code (as you have done). I appreciate the feedback. Regards, Reece

If you have point high, low; then which corner is "high"? Likewise, using top_left, bottom_right is bad. In general, storing a rectangle as a set of two points is the wrong representation, especially for
"Reece Dunn" <msclrhd@hotmail.com> wrote in message news:cq90bq$r7v$1@sea.gmane.org... portability.
not "high" as in "high on the screen"; "high" as in "value is high", "higher than low". maybe "max" and "min" are better names (as in cocoa). pos x size requires knowledge about the origin, too, doesn't it? i am assuming that pos+size brings you to the opposite corner of the rectangle, and also that both components of size are positive for a non-empty rectangle. therefore pos represents different corners depending on the origin. and "a.size += gui::size(10, 20);" will move the top-right corner in e.g. cocoa and the bottom-right corner in e.g. windows. ergo no better or worse than 2 points, just different i'd definitely add operator[] to point and size, though. anywhere you can write a loop, you don't make a copy-paste error regards, michael toksvig
participants (4)
-
brangdon@cix.compulink.co.uk
-
michael toksvig
-
Michael Walter
-
Reece Dunn