From bc22a50cdeb4db1b298f6f6b3e8046f0763f2fbb Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 14 May 2004 17:16:35 +0000 Subject: [PATCH] Fix the slider to request a non-zero length, and make its width a little larger. The text widget can now be meaningfully associated with a property; in PUI, it's "value" isn't the same thing as its label, but we can hack things to treat them symmetrically. Commit an experimental "live" property that can be set on widgets to cause them to update their values every frame. This works great for text widgets, as above. Note that this synchronization is input-only: no support is provided (or needed -- the GUI only changes when the user does something) for writing those properties out every frame. --- src/GUI/dialog.cxx | 39 +++++++++++++++++++++++++++++++++------ src/GUI/dialog.hxx | 6 ++++++ src/GUI/layout.cxx | 9 +++++---- src/GUI/new_gui.cxx | 4 +++- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx index ae1f96270..06d5e0a71 100644 --- a/src/GUI/dialog.cxx +++ b/src/GUI/dialog.cxx @@ -17,11 +17,10 @@ int fgPopup::checkHit(int button, int updown, int x, int y) // 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. + // when inside controls. if(!result) return result; puObject* child = getFirstChild(); - if(child) child = child->getNextObject(); + if(child) child = child->getNextObject(); // Skip the puFrame while(child) { int cx, cy, cw, ch; child->getAbsolutePosition(&cx, &cy); @@ -108,6 +107,11 @@ copy_to_pui (SGPropertyNode * node, puObject * object) object->setValue(node->getStringValue()); break; } + + // Treat puText objects specially, so their "values" can be set + // from properties. + if(object->getType() & PUCLASS_TEXT) + object->setLabel(node->getStringValue()); } @@ -228,6 +232,13 @@ FGDialog::applyValues () _propertyObjects[i]->node); } +void +FGDialog::update () +{ + for (unsigned int i = 0; i < _liveObjects.size(); i++) + copy_to_pui(_liveObjects[i]->node, _liveObjects[i]->object); +} + void FGDialog::display (SGPropertyNode * props) { @@ -239,9 +250,14 @@ FGDialog::display (SGPropertyNode * props) int screenw = globals->get_props()->getIntValue("/sim/startup/xsize"); int screenh = globals->get_props()->getIntValue("/sim/startup/ysize"); + bool userx = props->hasValue("x"); + bool usery = props->hasValue("y"); + bool userw = props->hasValue("width"); + bool userh = props->hasValue("height"); + LayoutWidget wid(props); int pw=0, ph=0; - if(!props->hasValue("width") || !props->hasValue("height")) + if(!userw || !userh) wid.calcPrefSize(&pw, &ph); pw = props->getIntValue("width", pw); ph = props->getIntValue("height", ph); @@ -251,6 +267,13 @@ FGDialog::display (SGPropertyNode * props) _object = makeObject(props, screenw, screenh); + // Remove automatically generated properties, so the layout looks + // the same next time around. + if(!userx) props->removeChild("x"); + if(!usery) props->removeChild("y"); + if(!userw) props->removeChild("width"); + if(!userh) props->removeChild("height"); + if (_object != 0) { _object->reveal(); } else { @@ -346,6 +369,8 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight) slider->setMinValue(props->getFloatValue("min", 0.0)); slider->setMaxValue(props->getFloatValue("max", 1.0)); setupObject(slider, props); + if(presetSize) + slider->setSize(width, height); return slider; } else if (type == "dial") { puDial * dial = new puDial(x, y, width); @@ -394,8 +419,10 @@ FGDialog::setupObject (puObject * object, SGPropertyNode * props) const char * propname = props->getStringValue("property"); SGPropertyNode_ptr node = fgGetNode(propname, true); copy_to_pui(node, object); - if (name != 0) - _propertyObjects.push_back(new PropertyObject(name, object, node)); + PropertyObject* po = new PropertyObject(name, object, node); + _propertyObjects.push_back(po); + if(props->getBoolValue("live")) + _liveObjects.push_back(po); } vector nodes = props->getChildren("binding"); diff --git a/src/GUI/dialog.hxx b/src/GUI/dialog.hxx index 2cb6f4ed1..f563cda12 100644 --- a/src/GUI/dialog.hxx +++ b/src/GUI/dialog.hxx @@ -91,6 +91,11 @@ public: virtual void applyValues (); + /** + * Update state. Called on active dialogs before rendering. + */ + virtual void update (); + private: // Private copy constructor to avoid unpleasant surprises. @@ -127,6 +132,7 @@ private: SGPropertyNode_ptr node; }; vector _propertyObjects; + vector _liveObjects; // PUI doesn't copy arrays, so we have to allocate string arrays // and then keep pointers so that we can delete them when the diff --git a/src/GUI/layout.cxx b/src/GUI/layout.cxx index 40f16a326..7842fcacc 100644 --- a/src/GUI/layout.cxx +++ b/src/GUI/layout.cxx @@ -63,8 +63,9 @@ void LayoutWidget::calcPrefSize(int* w, int* h) *w = 17*UNIT; *h = 6*UNIT; } else if (isType("slider")) { - if(getBool("vertical")) *w = 3*UNIT; - else *h = 3*UNIT; + *w = *h = 17*UNIT; + if(getBool("vertical")) *w = 4*UNIT; + else *h = 4*UNIT; } else if (isType("list") || isType("airport-list") || isType("dial")) { *w = *h = 12*UNIT; } @@ -152,8 +153,8 @@ void LayoutWidget::layout(int x, int y, int w, int h) w = h = 3*UNIT; } else if (isType("slider")) { // Fix the thickness to a constant - if(getBool("vertical")) { x += (w-3*UNIT)/2; w = 3*UNIT; } - else { y += (h-3*UNIT)/2; h = 3*UNIT; } + if(getBool("vertical")) { x += (w-4*UNIT)/2; w = 4*UNIT; } + else { y += (h-4*UNIT)/2; h = 4*UNIT; } } // Set out output geometry diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx index 6b233a343..65bdd9add 100644 --- a/src/GUI/new_gui.cxx +++ b/src/GUI/new_gui.cxx @@ -69,7 +69,9 @@ NewGUI::unbind () void NewGUI::update (double delta_time_sec) { - // NO OP + map::iterator iter = _active_dialogs.begin(); + for(/**/; iter != _active_dialogs.end(); iter++) + iter->second->update(); } bool -- 2.39.5