1
0
Fork 0

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.
This commit is contained in:
andy 2004-05-14 17:16:35 +00:00
parent 3f3d3b2c6f
commit bc22a50cde
4 changed files with 47 additions and 11 deletions

View file

@ -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<SGPropertyNode_ptr> nodes = props->getChildren("binding");

View file

@ -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<PropertyObject *> _propertyObjects;
vector<PropertyObject *> _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

View file

@ -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

View file

@ -69,7 +69,9 @@ NewGUI::unbind ()
void
NewGUI::update (double delta_time_sec)
{
// NO OP
map<string,FGDialog *>::iterator iter = _active_dialogs.begin();
for(/**/; iter != _active_dialogs.end(); iter++)
iter->second->update();
}
bool