]> git.mxchange.org Git - flightgear.git/commitdiff
make dialogs resizable with Ctrl-dragging
authormfranz <mfranz>
Sat, 10 Jan 2009 21:58:26 +0000 (21:58 +0000)
committerTim Moore <timoore@redhat.com>
Mon, 12 Jan 2009 12:03:55 +0000 (13:03 +0100)
At the moment the dialog grows to North-East. Only dialogs with
the <resizable> flag set to true are resizable.

src/GUI/dialog.cxx
src/GUI/dialog.hxx
src/GUI/layout.cxx

index 41a967aa19dbc4725e1ac32f749474fed89d8c92..dad53b3ddecccc8d384483a3ecacea9719c3d850 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <Input/input.hxx>
 #include <Scripting/NasalSys.hxx>
+#include <Main/fg_os.hxx>
 
 #include "dialog.hxx"
 #include "new_gui.hxx"
@@ -87,6 +88,7 @@ struct GUIInfo
     void apply_format(SGPropertyNode *);
 
     FGDialog * dialog;
+    SGPropertyNode_ptr node;
     vector <SGBinding *> bindings;
     int key;
     string label, legend, text, format;
@@ -190,7 +192,9 @@ puObject *fgPopup::getActiveInputField(puObject *object)
  */
 int fgPopup::checkHit(int button, int updown, int x, int y)
 {
-    int result = puPopup::checkHit(button, updown, x, y);
+    int result = 0;
+    if (updown != PU_DRAG)
+        result = puPopup::checkHit(button, updown, x, y);
 
     if (!_draggable)
        return result;
@@ -209,13 +213,44 @@ int fgPopup::checkHit(int button, int updown, int x, int y)
         if (hit & (PUCLASS_BUTTON|PUCLASS_ONESHOT|PUCLASS_INPUT))
             return result;
 
-        int px, py;
-        getPosition(&px, &py);
+        getPosition(&_dlgX, &_dlgY);
+        getSize(&_dlgW, &_dlgH);
+        _modifier = fgGetKeyModifiers();
         _dragging = true;
-        _dX = px - x;
-        _dY = py - y;
+        _startX = x;
+        _startY = y;
+
     } else if (updown == PU_DRAG && _dragging) {
-        setPosition(x + _dX, y + _dY);
+        if (_modifier & KEYMOD_CTRL) {
+            if (!_resizable)
+                return result;
+
+            int w = _dlgW + x - _startX;
+            int h = _dlgH + y - _startY;
+
+            GUIInfo *info = (GUIInfo *)getUserData();
+            if (info && info->node) {
+                int y = _dlgY; // + _dlgH - h;
+                int pw, ph;
+                LayoutWidget wid(info->node);
+                wid.calcPrefSize(&pw, &ph);
+                if (w < pw)
+                    w = pw;
+                if (h < ph)
+                    h = ph;
+
+                // first child is always the dialog background puFrame
+                getFirstChild()->setSize(w, h);
+                setSize(w, h);
+                setPosition(_dlgX, y);
+
+                wid.layout(_dlgX, y, w, h);
+                applySize(static_cast<puObject *>(this));
+            }
+        } else {
+            setPosition(x + _dlgX - _startX, y + _dlgY - _startY);
+        }
+
     } else {
         _dragging = false;
     }
@@ -241,6 +276,36 @@ int fgPopup::getHitObjects(puObject *object, int x, int y)
     return type;
 }
 
+void fgPopup::applySize(puObject *object)
+{
+    // compound plib widgets use setUserData() for internal purposes, so refuse to
+    // descend into anything that has more bits set than the following
+    const int validUserData = PUCLASS_VALUE|PUCLASS_OBJECT|PUCLASS_GROUP|PUCLASS_INTERFACE
+            |PUCLASS_FRAME|PUCLASS_TEXT|PUCLASS_BUTTON|PUCLASS_ONESHOT|PUCLASS_INPUT
+            |PUCLASS_ARROW|PUCLASS_DIAL|PUCLASS_POPUP;
+
+    int type = object->getType();
+    if (type & PUCLASS_GROUP && !(type & ~validUserData))
+        for (puObject *obj = ((puGroup *)object)->getFirstChild();
+                obj; obj = obj->getNextObject())
+            applySize(obj);
+
+    GUIInfo *info = (GUIInfo *)object->getUserData();
+    if (!info)
+        return;
+
+    SGPropertyNode *n = info->node;
+    if (!n) {
+        SG_LOG(SG_GENERAL, SG_ALERT, "applySize: no props");
+        return;
+    }
+    int x = n->getIntValue("x");
+    int y = n->getIntValue("y");
+    int w = n->getIntValue("width", 4);
+    int h = n->getIntValue("height", 4);
+    object->setPosition(x, y);
+    object->setSize(w, h);
+}
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -537,10 +602,11 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
     if (type == "dialog") {
         puPopup * obj;
         bool draggable = props->getBoolValue("draggable", true);
+        bool resizable = props->getBoolValue("resizable", false);
         if (props->getBoolValue("modal", false))
             obj = new puDialogBox(x, y);
         else
-            obj = new fgPopup(x, y, draggable);
+            obj = new fgPopup(x, y, resizable, draggable);
         setupGroup(obj, props, width, height, true);
         setColor(obj, props);
         return obj;
@@ -560,6 +626,7 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
     } else if (type == "hrule" || type == "vrule") {
         puFrame * obj = new puFrame(x, y, x + width, y + height);
         obj->setBorderThickness(0);
+        setupObject(obj, props);
         setColor(obj, props, BACKGROUND|FOREGROUND|HIGHLIGHT);
         return obj;
 
@@ -697,6 +764,7 @@ FGDialog::setupObject (puObject * object, SGPropertyNode * props)
     _info.push_back(info);
     object->setLabelPlace(PUPLACE_CENTERED_RIGHT);
     object->makeReturnDefault(props->getBoolValue("default"));
+    info->node = props;
 
     if (props->hasValue("legend")) {
         info->legend = props->getStringValue("legend");
index 09b76232f6a86d3b06f55032aabdc118335d1ea7..f9fb4227f4528985a0aa56dbfed26a8d9117c59b 100644 (file)
@@ -175,16 +175,22 @@ private:
 //
 class fgPopup : public puPopup {
 public:
-    fgPopup(int x, int y, bool d = true) : puPopup(x, y) { _dragging = false; _draggable = d;}
+    fgPopup(int x, int y, bool r = true, bool d = true) :
+            puPopup(x, y), _draggable(d), _resizable(r), _dragging(false)
+    {}
     int checkHit(int b, int up, int x, int y);
     int checkKey(int key, int updown);
     int getHitObjects(puObject *, int x, int y);
     puObject *getKeyObject(puObject *, int key);
     puObject *getActiveInputField(puObject *);
+    void applySize(puObject *);
 private:
     bool _draggable;
+    bool _resizable;
     bool _dragging;
-    int _dX, _dY;
+    int _modifier;
+    int _dlgX, _dlgY, _dlgW, _dlgH;
+    int _startX, _startY;
 };
 
 
index aeec747c657ab9de237ba446572f3d924edde68c..5bfd3524340ea1b8118def305388851e4847967c 100644 (file)
@@ -72,7 +72,8 @@ void LayoutWidget::calcPrefSize(int* w, int* h)
         *w = *h = 17*UNIT;
         if(getBool("vertical")) *w = 4*UNIT;
         else                    *h = 4*UNIT;
-    } else if (isType("list") || isType("airport-list") || isType("dial")) {
+    } else if (isType("list") || isType("airport-list")
+            || isType("property-list") || isType("dial")) {
         *w = *h = 12*UNIT;
     } else if (isType("hrule")) {
         *h = 1;