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:
parent
3f3d3b2c6f
commit
bc22a50cde
4 changed files with 47 additions and 11 deletions
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue