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:
parent
c89e5203a5
commit
4b116a1196
4 changed files with 36 additions and 20 deletions
|
@ -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
|
// 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
|
// intersection test (again) to make sure we don't start a drag
|
||||||
// when inside controls.
|
// 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 && !_dragging) {
|
||||||
if(updown == PU_DOWN) {
|
if(!result)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int hit = getHitObjects(this, x, y);
|
||||||
|
if(hit & (PUCLASS_BUTTON|PUCLASS_ONESHOT|PUCLASS_INPUT))
|
||||||
|
return result;
|
||||||
|
|
||||||
int px, py;
|
int px, py;
|
||||||
getPosition(&px, &py);
|
getPosition(&px, &py);
|
||||||
_dragging = true;
|
_dragging = true;
|
||||||
|
@ -42,9 +37,26 @@ int fgPopup::checkHit(int button, int updown, int x, int y)
|
||||||
} else {
|
} else {
|
||||||
_dragging = false;
|
_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.
|
// Callbacks.
|
||||||
|
@ -249,8 +261,13 @@ FGDialog::applyValues ()
|
||||||
void
|
void
|
||||||
FGDialog::update ()
|
FGDialog::update ()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < _liveObjects.size(); i++)
|
for (unsigned int i = 0; i < _liveObjects.size(); i++) {
|
||||||
copy_to_pui(_liveObjects[i]->node, _liveObjects[i]->object);
|
puObject *obj = _liveObjects[i]->object;
|
||||||
|
if (obj->getType() & PUCLASS_INPUT && ((puInput *)obj)->isAcceptingInput())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
copy_to_pui(_liveObjects[i]->node, obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -155,6 +155,7 @@ class fgPopup : public puPopup {
|
||||||
public:
|
public:
|
||||||
fgPopup(int x, int y) : puPopup(x, y) { _dragging = false; }
|
fgPopup(int x, int y) : puPopup(x, y) { _dragging = false; }
|
||||||
int checkHit(int b, int up, int x, int y);
|
int checkHit(int b, int up, int x, int y);
|
||||||
|
int getHitObjects(puObject *, int x, int y);
|
||||||
private:
|
private:
|
||||||
bool _dragging;
|
bool _dragging;
|
||||||
int _dX, _dY;
|
int _dX, _dY;
|
||||||
|
|
|
@ -708,7 +708,7 @@ GLubyte *hiResScreenCapture( int multiplier )
|
||||||
globals->get_renderer()->init();
|
globals->get_renderer()->init();
|
||||||
int cur_width = fgGetInt("/sim/startup/xsize");
|
int cur_width = fgGetInt("/sim/startup/xsize");
|
||||||
int cur_height = fgGetInt("/sim/startup/ysize");
|
int cur_height = fgGetInt("/sim/startup/ysize");
|
||||||
if (b1) delete( b1 );
|
delete( b1 );
|
||||||
// New empty (mostly) bitmap
|
// New empty (mostly) bitmap
|
||||||
b1 = new GlBitmap( GL_RGB, 1, 1, (unsigned char *)"123" );
|
b1 = new GlBitmap( GL_RGB, 1, 1, (unsigned char *)"123" );
|
||||||
int x,y;
|
int x,y;
|
||||||
|
|
|
@ -216,10 +216,8 @@ FGMenuBar::~FGMenuBar ()
|
||||||
void
|
void
|
||||||
FGMenuBar::init ()
|
FGMenuBar::init ()
|
||||||
{
|
{
|
||||||
if (_menuBar != 0) // FIXME: check if PUI owns the pointer
|
delete _menuBar; // FIXME: check if PUI owns the pointer
|
||||||
delete _menuBar;
|
|
||||||
make_menubar();
|
make_menubar();
|
||||||
|
|
||||||
// FIXME: temporary commands to get at
|
// FIXME: temporary commands to get at
|
||||||
// old, hard-coded dialogs.
|
// old, hard-coded dialogs.
|
||||||
add_deprecated_dialogs();
|
add_deprecated_dialogs();
|
||||||
|
|
Loading…
Add table
Reference in a new issue