1
0
Fork 0

drop plib render callback, validate <format> in setupObject(), and apply

it in copy_to_pui()
This commit is contained in:
mfranz 2007-04-02 12:12:23 +00:00
parent 851e860b52
commit d9cbdb53ff
2 changed files with 92 additions and 78 deletions

View file

@ -17,6 +17,60 @@
#include "layout.hxx" #include "layout.hxx"
static const int FORMAT_BUFSIZE = 255;
/**
* Makes sure the format matches '[ -+#]?\d*(\.\d*)?l?[fs]', with only
* one number or string placeholder and otherwise arbitrary prefix and
* postfix. Return value: 0 .. number, 1 .. string, -1 .. invalid
*/
static int
validate_format(const char *format)
{
const int INVALID = -1;
const char *f = format;
bool is_number, l = false;
for (; *f; f++) {
if (*f == '%') {
if (f[1] == '%')
f++;
else
break;
}
}
if (*f++ != '%')
return INVALID;
if (*f == ' ' || *f == '+' || *f == '-' || *f == '#')
f++;
while (*f && isdigit(*f))
f++;
if (*f == '.') {
f++;
while (*f && isdigit(*f))
f++;
}
if (*f == 'l')
l = true, f++;
if (*f == 'f')
is_number = true;
else if (*f == 's') {
if (l)
return INVALID;
is_number = false;
} else
return INVALID;
for (++f; *f; f++) {
if (*f == '%') {
if (f[1] == '%')
f++;
else
return INVALID;
}
}
return is_number ? 0 : 1;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -34,11 +88,17 @@ struct GUIInfo
FGDialog * dialog; FGDialog * dialog;
vector <SGBinding *> bindings; vector <SGBinding *> bindings;
int key; int key;
char *text;
char *format;
bool format_for_string;
}; };
GUIInfo::GUIInfo (FGDialog * d) GUIInfo::GUIInfo (FGDialog * d)
: dialog(d), : dialog(d),
key(-1) key(-1),
text(0),
format(0),
format_for_string(false)
{ {
} }
@ -48,6 +108,8 @@ GUIInfo::~GUIInfo ()
delete bindings[i]; delete bindings[i];
bindings[i] = 0; bindings[i] = 0;
} }
delete [] text;
delete [] format;
} }
@ -190,71 +252,6 @@ action_callback (puObject * object)
} }
static void
format_callback(puObject *obj, int dx, int dy, void *n)
{
SGPropertyNode *node = (SGPropertyNode *)n;
const char *format = node->getStringValue("format"), *f = format;
bool number, l = false;
// make sure the format matches '[ -+#]?\d*(\.\d*)?l?[fs]'
for (; *f; f++) {
if (*f == '%') {
if (f[1] == '%')
f++;
else
break;
}
}
if (*f++ != '%')
return;
if (*f == ' ' || *f == '+' || *f == '-' || *f == '#')
f++;
while (*f && isdigit(*f))
f++;
if (*f == '.') {
f++;
while (*f && isdigit(*f))
f++;
}
if (*f == 'l')
l = true, f++;
if (*f == 'f')
number = true;
else if (*f == 's') {
if (l)
return;
number = false;
} else
return;
for (++f; *f; f++) {
if (*f == '%') {
if (f[1] == '%')
f++;
else
return;
}
}
char buf[256];
const char *src = obj->getLabel();
if (number) {
float value = atof(src);
snprintf(buf, 256, format, value);
} else {
snprintf(buf, 256, format, src);
}
buf[255] = '\0';
SGPropertyNode *result = node->getNode("formatted", true);
result->setStringValue(buf);
obj->setLabel(result->getStringValue());
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Static helper functions. // Static helper functions.
@ -269,7 +266,18 @@ copy_to_pui (SGPropertyNode * node, puObject * object)
// Treat puText objects specially, so their "values" can be set // Treat puText objects specially, so their "values" can be set
// from properties. // from properties.
if(object->getType() & PUCLASS_TEXT) { if(object->getType() & PUCLASS_TEXT) {
object->setLabel(node->getStringValue()); GUIInfo *info = (GUIInfo *)object->getUserData();
if(info && info->format) {
if(info->format_for_string)
snprintf(info->text, FORMAT_BUFSIZE, info->format, node->getStringValue());
else
snprintf(info->text, FORMAT_BUFSIZE, info->format, node->getDoubleValue());
info->text[FORMAT_BUFSIZE] = '\0';
object->setLabel(info->text);
} else {
object->setLabel(node->getStringValue());
}
return; return;
} }
@ -516,7 +524,7 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
int y = props->getIntValue("y", (parentHeight - height) / 2); int y = props->getIntValue("y", (parentHeight - height) / 2);
string type = props->getName(); string type = props->getName();
if (type == "") if (type.empty())
type = "dialog"; type = "dialog";
if (type == "dialog") { if (type == "dialog") {
@ -583,13 +591,6 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
puText * obj = new puText(x, y); puText * obj = new puText(x, y);
setupObject(obj, props); setupObject(obj, props);
if (props->getNode("format")) {
SGPropertyNode *live = props->getNode("live");
if (live && live->getBoolValue())
obj->setRenderCallback(format_callback, props);
else
format_callback(obj, x, y, props);
}
// Layed-out objects need their size set, and non-layout ones // Layed-out objects need their size set, and non-layout ones
// get a different placement. // get a different placement.
if (presetSize) if (presetSize)
@ -728,7 +729,7 @@ FGDialog::setupObject (puObject * object, SGPropertyNode * props)
SGPropertyNode * dest = fgGetNode("/sim/bindings/gui", true); SGPropertyNode * dest = fgGetNode("/sim/bindings/gui", true);
vector<SGPropertyNode_ptr> bindings = props->getChildren("binding"); vector<SGPropertyNode_ptr> bindings = props->getChildren("binding");
if (bindings.size() > 0) { if (type == "text" || bindings.size() > 0) {
GUIInfo * info = new GUIInfo(this); GUIInfo * info = new GUIInfo(this);
info->key = props->getIntValue("keynum", -1); info->key = props->getIntValue("keynum", -1);
if (props->hasValue("key")) if (props->hasValue("key"))
@ -753,6 +754,19 @@ FGDialog::setupObject (puObject * object, SGPropertyNode * props)
if (type == "input" && props->getBoolValue("live")) if (type == "input" && props->getBoolValue("live"))
object->setDownCallback(action_callback); object->setDownCallback(action_callback);
if (type == "text") {
const char *format = props->getStringValue("format", 0);
if (format) {
int type = validate_format(props->getStringValue("format", 0));
if (type >= 0) {
info->format = new char[strlen(format) + 1];
strcpy(info->format, format);
info->format_for_string = type == 1;
info->text = new char[FORMAT_BUFSIZE + 1];
}
}
}
object->setUserData(info); object->setUserData(info);
_info.push_back(info); _info.push_back(info);
} }
@ -781,7 +795,7 @@ void
FGDialog::setColor(puObject * object, SGPropertyNode * props, int which) FGDialog::setColor(puObject * object, SGPropertyNode * props, int which)
{ {
string type = props->getName(); string type = props->getName();
if (type == "") if (type.empty())
type = "dialog"; type = "dialog";
if (type == "textbox" && props->getBoolValue("editable")) if (type == "textbox" && props->getBoolValue("editable"))
type += "-editable"; type += "-editable";

View file

@ -53,7 +53,7 @@ void
NewGUI::reinit () NewGUI::reinit ()
{ {
reset(true); reset(true);
fgSetBool("/sim/signals/reinit-gui", 1); fgSetBool("/sim/signals/reinit-gui", true);
} }
void void