1
0
Fork 0

Melchior FRANZ:

The dialog handling has been written at a time when only one dialog was
shown at the same time, and dialogs were shallow -- with only children, but
no grand-children. This makes finding a draggable spot on modern, dialogs
with nested objects quite a challenge. The patches fixes this, and other things:

- check full object tree on button press, not only the outmost layer;
  and don't give up just because we are in *something* (which could well be
  something harmless, like a group); only ignore a few, sensible objects
  (we don't want to drag after a click on a button or into an input field)

- don't lose dialogs as easily when dragging too fast (it does still happen
  if one manages to enter an editable field while dragging, but this is
  a plib problem and I don't feel like fixing that now  :-)

- don't "live"-update input fields while they are in edit mode

- remove some "if (foo) delete foo;" redundancy
This commit is contained in:
ehofman 2005-03-24 13:41:43 +00:00
parent c89e5203a5
commit 4b116a1196
4 changed files with 36 additions and 20 deletions

View file

@ -18,20 +18,15 @@ int fgPopup::checkHit(int button, int updown, int x, int y)
// tells us is that the pointer is inside the dialog. So do the
// intersection test (again) to make sure we don't start a drag
// when inside controls.
if(!result) return result;
puObject* child = getFirstChild();
if(child) child = child->getNextObject(); // Skip the puFrame
while(child) {
int cx, cy, cw, ch;
child->getAbsolutePosition(&cx, &cy);
child->getSize(&cw, &ch);
if(x >= cx && x < cx + cw && y >= cy && y < cy + ch)
return result;
child = child->getNextObject();
}
// Finally, handle the mouse event
if(updown == PU_DOWN) {
if(updown == PU_DOWN && !_dragging) {
if(!result)
return 0;
int hit = getHitObjects(this, x, y);
if(hit & (PUCLASS_BUTTON|PUCLASS_ONESHOT|PUCLASS_INPUT))
return result;
int px, py;
getPosition(&px, &py);
_dragging = true;
@ -42,9 +37,26 @@ int fgPopup::checkHit(int button, int updown, int x, int y)
} else {
_dragging = false;
}
return 1;
return result;
}
int fgPopup::getHitObjects(puObject *object, int x, int y)
{
int type = 0;
if(object->getType() & PUCLASS_GROUP)
for (puObject *obj = ((puGroup *)object)->getFirstChild();
obj; obj = obj->getNextObject())
type |= getHitObjects(obj, x, y);
int cx, cy, cw, ch;
object->getAbsolutePosition(&cx, &cy);
object->getSize(&cw, &ch);
if(x >= cx && x < cx + cw && y >= cy && y < cy + ch)
type |= object->getType();
return type;
}
////////////////////////////////////////////////////////////////////////
// Callbacks.
@ -249,8 +261,13 @@ FGDialog::applyValues ()
void
FGDialog::update ()
{
for (unsigned int i = 0; i < _liveObjects.size(); i++)
copy_to_pui(_liveObjects[i]->node, _liveObjects[i]->object);
for (unsigned int i = 0; i < _liveObjects.size(); i++) {
puObject *obj = _liveObjects[i]->object;
if (obj->getType() & PUCLASS_INPUT && ((puInput *)obj)->isAcceptingInput())
continue;
copy_to_pui(_liveObjects[i]->node, obj);
}
}
void

View file

@ -155,6 +155,7 @@ class fgPopup : public puPopup {
public:
fgPopup(int x, int y) : puPopup(x, y) { _dragging = false; }
int checkHit(int b, int up, int x, int y);
int getHitObjects(puObject *, int x, int y);
private:
bool _dragging;
int _dX, _dY;

View file

@ -708,7 +708,7 @@ GLubyte *hiResScreenCapture( int multiplier )
globals->get_renderer()->init();
int cur_width = fgGetInt("/sim/startup/xsize");
int cur_height = fgGetInt("/sim/startup/ysize");
if (b1) delete( b1 );
delete( b1 );
// New empty (mostly) bitmap
b1 = new GlBitmap( GL_RGB, 1, 1, (unsigned char *)"123" );
int x,y;

View file

@ -216,10 +216,8 @@ FGMenuBar::~FGMenuBar ()
void
FGMenuBar::init ()
{
if (_menuBar != 0) // FIXME: check if PUI owns the pointer
delete _menuBar;
delete _menuBar; // FIXME: check if PUI owns the pointer
make_menubar();
// FIXME: temporary commands to get at
// old, hard-coded dialogs.
add_deprecated_dialogs();