[interfacekit] Re: programming problems
- From: Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>
- To: interfacekit@xxxxxxxxxxxxx
- Date: Tue, 03 Feb 2004 02:32:40 +0100
On 2004-02-02 at 16:17:00 [+0100], Adi Oanca wrote:
> Ingo Weinhold wrote:
>
> > That's not surprising, given how the constants are constructed. Apparently
> > it is possible to individually specify for each side whether it shall
> > follow the top, left, bottom, right, center (or nothing) of the parent
> > view.
> Apparently, this is written in BeBook, so we already know that!
You must have a different edition of the BeBook, since both the plain R5
BeBook as well as annotated one only explain the B_FOLLOW_* constants, not
how they are constructed.
> > Anyway you can decompose the resizing mode like that:
> >
> > uint32 mode = ResizingMode();
> > uint32 topMode = (mode >> 12) & 0xf;
> > uint32 leftMode = (mode >> 8) & 0xf;
> > uint32 bottomMode = (mode >> 4) & 0xf;
> > uint32 rightMode = mode & 0xf;
> >
> > And then analyze the value for each side:
> >
> > // top side follows...
> > switch (topMode) {
> > case 0:
> > // ... nothing
> > break;
> > case _VIEW_TOP_:
> > // ... parent's top
> > break;
> > case _VIEW_LEFT_:
> > // ... parent's left? -- meaning?
> > break;
> > case _VIEW_BOTTOM_:
> > // ... parent's bottom
> > break;
> > case _VIEW_RIGHT_:
> > // ... parent's right? -- meaning?
> > break;
> > case _VIEW_CENTER_:
> > // ... parent's vertical center
> > break;
> > }
> Did you read the hole email I previously sent?
I did.
> I said:
> "and I've come upon a problem at witch I want an easy answer, answer
> that I failed to find so far."
>
> Easy Ingo, easy! I'm not going to write all those structures for a
> simple point.Set(x,y)!
If you re-read your original mail yourself, you will find (at least I do)
that it sounds like you have no solution at all, since the only thing you
mention is something which doesn't work and is far enough off track to
suggest that.
Really, this game starts to annoy me. I reply to mails, when I feel, that my
answer can be of some help, and I'm glad, if it indeed is. But when the
reaction is to question of my ability to read a six line mail carefully
enough to grasp its meaning, then I really wonder why to waste my time in the
first place.
> Anyway, I had a solution but I was not fond of it. In the mean time it
> appears I've found one:
>
> // resize/move horizontaly
> if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_
> && (rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_){
> printf("1\n");
> }
> else if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_){
> printf("2\n");
> }
> else if ((rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_){
> printf("3\n");
> }
> else if ((rmask & 0x00000f00UL)>>8 == _VIEW_CENTER_){
> printf("4\n");
> }
> else { // illegal flag. Do nothing.
> printf("5\n");
> }
This case distinction is incomplete, as you, for instance, don't catch cases
like
_rule_(0, _VIEW_LEFT_, 0, _VIEW_CENTER_)
or
_rule_(0, _VIEW_CENTER_, 0, _VIEW_RIGHT_).
Not to mention unusual settings like
_rule_(0, 0, 0, _VIEW_LEFT_)
or
_rule_(0, _VIEW_RIGHT_, 0, 0).
Or perhaps meaningless (but still to be proven so) things like
_rule_(0, _VIEW_TOP_, 0, 0).
> // resize/move verticaly
> if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_
> && (rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_){
> printf("1\n");
> }
> else if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_){
> printf("2\n");
> }
> else if ((rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_){
> printf("3\n");
> }
> else if ((rmask & 0x0000f000UL)>>12 == _VIEW_CENTER_){
> printf("4\n");
> }
> else { // illegal flag. Do nothing.
> printf("5\n");
> }
Ditto.
> I did tried to use B_FOLLOW_* flags but they lead to a very ugly
> looking code. So I adopted those 5 undocumented flags with the help of
> which the code seems more readable, but still not easy!
>
> NOW, I have an idea!
> ...
> And this what it came out:
>
> Ingo Weinhold wrote:
> > On 2004-02-01 at 23:06:23 [+0100], Andrew Bachmann wrote:
> >>Assuming that the constants are multi-bit, I think the most reliable
> way to
> >>test would be to use a
> >>construct like this:
> >>
> >>if (ResizingMode() & B_FOLLOW_LEFT_RIGHT == B_FOLLOW_LEFT_RIGHT)
> >>....
> >>if (ResizingMode() & B_FOLLOW_LEFT == B_FOLLOW_LEFT)
> >>....
> >>if (ResizingMode() & B_FOLLOW_RIGHT == B_FOLLOW_RIGHT)
> >>....
> >
> >
> > This won't work in general, since it holds for instance:
> > B_FOLLOW_BOTTOM & B_FOLLOW_TOP == B_FOLLOW_TOP
> But will work if placed in the proper order!
> Had tried that before, but it is only now I got inspired. :-)
>
> And, that order is:
> // resize/move horizontaly
> if ((rmask & B_FOLLOW_H_CENTER) == B_FOLLOW_H_CENTER){
> printf("1\n");
> }
> else if ((rmask & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT){
> printf("2\n");
> }
> else if ((rmask & B_FOLLOW_RIGHT) == B_FOLLOW_RIGHT){
> printf("3\n");
> }
> else if ((rmask & B_FOLLOW_LEFT) == B_FOLLOW_LEFT){
> printf("4\n");
> }
> else { // illegal flag. Do nothing.
> printf("5\n");
> }
>
> // resize/move verticaly
> if ((rmask & B_FOLLOW_V_CENTER) == B_FOLLOW_V_CENTER){
> printf("1\n");
> }
> else if ((rmask & B_FOLLOW_BOTTOM) == B_FOLLOW_BOTTOM){
> printf("2\n");
> }
> else if ((rmask & B_FOLLOW_TOP_BOTTOM) == B_FOLLOW_TOP_BOTTOM){
> printf("3\n");
> }
> else if ((rmask & B_FOLLOW_TOP) == B_FOLLOW_TOP){
> printf("4\n");
> }
> else { // illegal flag. Do nothing.
> printf("5\n");
> }
Ouch! Sorry, but what you're doing is fighting the structure. The resizing
mode is a four component field and &-ing multiple components at once with
constants that are not intended for this purpose simply isn't a clean
solution. Don't misunderstand me, it may work, but I wouldn't even care to
check if it does.
OK, let me guess, what the actual problem is, that shall be solved (at least
it's the only thing I imagine why one would want to analyze the resizing
mode): The frame of a parent view has changed and the task is to compute the
new frame of a child view according to its resizing mode.
Given:
BRect oldParentFrame, newParentFrame;
BRect oldChildFrame;
uint32 resizingMode;
To be computed:
BRect newChildFrame;
Algorithm:
// decompose the mode
uint32 topMode = (resizingMode >> 12) & 0xf;
uint32 leftMode = (resizingMode >> 8) & 0xf;
uint32 bottomMode = (resizingMode >> 4) & 0xf;
uint32 rightMode = resizingMode & 0xf;
// compute centers
float oldHCenter = floor((oldParentFrame.left + oldParentFrame.right) / 2);
float newHCenter = floor((newParentFrame.left + newParentFrame.right) / 2);
float oldVCenter = floor((oldParentFrame.top + oldParentFrame.bottom) / 2);
float newVCenter = floor((newParentFrame.top + newParentFrame.bottom) / 2);
// compute parent frame deltas
float dl = newParentFrame.left - oldParentFrame.left;
float dt = newParentFrame.top - oldParentFrame.top;
float dr = newParentFrame.right - oldParentFrame.right;
float db = newParentFrame.bottom - oldParentFrame.bottom;
float dhc = newHCenter - oldHCenter;
float dhv = newVCenter - oldVCenter;
// compute the new child frame
newChildFrame = oldChildFrame;
newChildFrame.left += resize_delta(leftMode, dl, dt, dr, db, dhc);
newChildFrame.top += resize_delta(topMode, dl, dt, dr, db, dvc);
newChildFrame.right += resize_delta(rightMode, dl, dt, dr, db, dhc);
newChildFrame.bottom += resize_delta(bottomMode, dl, dt, dr, db, dvc);
Helper function:
float
resize_delta(uint32 mode, float dl, float dt, float dr, float db, float dc)
{
switch (topMode) {
case _VIEW_TOP_: return dt;
case _VIEW_LEFT_: return dl;
case _VIEW_BOTTOM_: return db;
case _VIEW_RIGHT_: return dr;
case _VIEW_CENTER_: return dc;
case 0: default: return 0;
}
}
If weird combinations like _VIEW_TOP_ or _VIEW_BOTTOM_ for the left side
shall be ignored (that remains to be checked), they can either be filtered
out in the constructor respectively SetResizingMode() and/or one can do it
like that:
newChildFrame.left += resize_delta(leftMode, dl, 0, dr, 0, dhc);
> I think we shall make this public. Others may have the same problem.
Mmh, I can't imagine who could possibly be interested in analyzing a resizing
mode. I mean, the API user sets it at view construction or later via
SetResizingMode(), but why should one care to check it later on?
CU, Ingo
- Follow-Ups:
- [interfacekit] Re: programming problems
- From: Adi Oanca
- References:
- [interfacekit] programming problems
- From: Adi Oanca
- [interfacekit] Re: programming problems
- From: Ingo Weinhold
- [interfacekit] Re: programming problems
- From: Adi Oanca
Other related posts:
- » [interfacekit] programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- » [interfacekit] Re: programming problems
- [interfacekit] Re: programming problems
- From: Adi Oanca
- [interfacekit] programming problems
- From: Adi Oanca
- [interfacekit] Re: programming problems
- From: Ingo Weinhold
- [interfacekit] Re: programming problems
- From: Adi Oanca