]> git.mxchange.org Git - flightgear.git/commitdiff
Melchior FRANZ:
authorehofman <ehofman>
Thu, 24 Mar 2005 13:41:43 +0000 (13:41 +0000)
committerehofman <ehofman>
Thu, 24 Mar 2005 13:41:43 +0000 (13:41 +0000)
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

src/GUI/dialog.cxx
src/GUI/dialog.hxx
src/GUI/gui_funcs.cxx
src/GUI/menubar.cxx

index 00fc3de8bec6ef80aa0136276c01c2677d1fcbc3..d0a1e09b66c8ffc906ee7a6fb1d8dcba38e6e228 100644 (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)
+
+    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;
-        child = child->getNextObject();
-    }
 
-    // Finally, handle the mouse event
-    if(updown == PU_DOWN) {
         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;
+}
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // 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
index f563cda125a05b3109ae1820f88c676983dc678a..ef53d3de9408a35e387324a2e2681b8d33ecb048 100644 (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;
index 26a9df4a47f4703896c47c9f5444a622fec7c099..559d2ffb575b6d6f559ffd99140db785e1f0b9c4 100644 (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;
index d1b6d286575d092c3d6bce81cd89bc856480d4ae..364b3b414e258f1b79bdd6a6ace0f8d1271c950a 100644 (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();