]> git.mxchange.org Git - flightgear.git/commitdiff
GUI windows are now draggable. This missing feature has annoyed me
authorandy <andy>
Mon, 3 May 2004 00:40:50 +0000 (00:40 +0000)
committerandy <andy>
Mon, 3 May 2004 00:40:50 +0000 (00:40 +0000)
for a while, it turned out to be pretty easy to implement.  Also, the
property picker is now non-modal, I presume the modality wasn't an
intentional feature.

src/GUI/dialog.cxx
src/GUI/dialog.hxx
src/GUI/prop_picker.cxx
src/GUI/prop_picker.hxx

index 3750d8b86cde49f1eb068b79e3d4dc54a87c2585..6d3c7c7cb2c5c7354faa75f456bb8d67bf1fa0ec 100644 (file)
@@ -8,6 +8,42 @@
 #include "puList.hxx"
 #include "AirportList.hxx"
 
+int fgPopup::checkHit(int button, int updown, int x, int y)
+{
+    int result = puPopup::checkHit(button, updown, x, y);
+
+    // This is annoying.  We would really want a true result from the
+    // superclass to indicate "handled by child object", but all it
+    // 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.  A further weirdness: plib inserts a
+    // "ghost" child which covers the whole control. (?)  Skip it.
+    if(!result) return result;
+    puObject* child = getFirstChild();
+    if(child) child = child->getNextObject();
+    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) {
+        int px, py;
+        getPosition(&px, &py);
+        _dragging = true;
+        _dX = px - x;
+        _dY = py - y;
+    } else if(updown == PU_DRAG && _dragging) {
+        setPosition(x + _dX, y + _dY);
+    } else {
+        _dragging = false;
+    }
+    return 1;
+}
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -230,7 +266,7 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
         if (props->getBoolValue("modal", false))
             dialog = new puDialogBox(x, y);
         else
-            dialog = new puPopup(x, y);
+            dialog = new fgPopup(x, y);
         setupGroup(dialog, props, width, height, true);
         return dialog;
     } else if (type == "group") {
index a399849ff457bb0b25174dc384c00aaa9d7d5096..2cb6f4ed16365ff4940c64368117d909991f97a9 100644 (file)
@@ -135,4 +135,23 @@ private:
     vector<char **> _char_arrays;
 };
 
+//
+// Custom subclass of puPopup to implement "draggable" windows in the
+// interface.  Note that this is a subclass of puPopup, not
+// puDialogBox.  Sadly, PUI (mis)uses subclassing to implement a
+// boolean property: modality.  That means that we can't implement
+// dragging of both puPopup windows and puDialogBoxes with the same
+// code.  Rather than duplicate code, I've chosen to implement only
+// "non-modal dragability" here.  Modal dialog boxes (like the exit
+// confirmation) are not draggable.
+//
+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);
+private:
+    bool _dragging;
+    int _dX, _dY;
+};
+
 #endif // __DIALOG_HXX
index 20480755fb1e38e4324cd77158ebff44d34ea830..767769ad9976ba2d7bdd41fe6480867821f7c647 100755 (executable)
@@ -346,7 +346,7 @@ fgPropPicker::~fgPropPicker ()
 */
 
 fgPropPicker::fgPropPicker ( int x, int y, int w, int h, int arrows,
-                                      const char *dir, const char *title ) : puDialogBox ( x,y )
+                                      const char *dir, const char *title ) : fgPopup ( x,y )
 {
   puFont LegendFont, LabelFont;
   puGetDefaultFonts ( &LegendFont, &LabelFont );
@@ -570,7 +570,7 @@ void fgPropEdit::fgPropEditHandleOK ( puObject* b )
   FG_POP_PUI_DIALOG( prop_edit );
 }
 
-fgPropEdit::fgPropEdit ( const char *name, const char *value, char *proppath ) : puDialogBox ( 0, 0 )
+fgPropEdit::fgPropEdit ( const char *name, const char *value, char *proppath ) : fgPopup ( 0, 0 )
 
 {
     puFont LegendFont, LabelFont;
index e2c293a742721d323b9acb3d147b1aae7ac7ca39..21018f34a77a1dd0447cf131529d8ed7cbd0f5bf 100755 (executable)
@@ -7,6 +7,7 @@
 
 #include <stdio.h>
 #include "gui.h"
+#include "dialog.hxx"
 #include <simgear/props/props.hxx>
 
 void prop_pickerInit();
@@ -19,7 +20,7 @@ class fgPropPicker       ;
 class fgPropEdit       ;
 
 class fgPropPicker : 
-    public puDialogBox,
+    public fgPopup,
     public SGPropertyChangeListener
 {
 
@@ -76,7 +77,7 @@ public:
   virtual void valueChanged (SGPropertyNode * node);
 } ;
 
-class fgPropEdit : public puDialogBox
+class fgPropEdit : public fgPopup
 {
 
   static void fgPropEditHandleCancel ( puObject *b ) ;