1
0
Fork 0

Reworked the XML-configurable GUI to use the same binding structure as

the keyboard, joystick, mouse, and 2D panel.  Exposed methods for
applying and updating property values in GUI fields.
This commit is contained in:
david 2002-12-22 19:52:26 +00:00
parent 6225936ead
commit 0111183153
2 changed files with 181 additions and 64 deletions

View file

@ -23,22 +23,39 @@ SG_USING_STD(vector);
static void
action_callback (puObject * object)
{
GUIData * action = (GUIData *)object->getUserData();
action->widget->action(action->command);
GUIInfo * info = (GUIInfo *)object->getUserData();
NewGUI * gui =
(NewGUI *)globals->get_subsystem_mgr()
->get_group(FGSubsystemMgr::INIT)->get_subsystem("gui");
gui->setCurrentWidget(info->widget);
for (int i = 0; i < info->bindings.size(); i++) {
std::cerr << "Firing binding " << i << ": " << info->bindings[i]->getCommandName() << std::endl;
info->bindings[i]->fire();
std::cerr << "done\n";
}
std::cerr << "All bindings fired\n";
gui->setCurrentWidget(0);
}
////////////////////////////////////////////////////////////////////////
// Implementation of GUIData.
// Implementation of GUIInfo.
////////////////////////////////////////////////////////////////////////
GUIData::GUIData (GUIWidget * w, const char * c)
: widget(w),
command(c)
GUIInfo::GUIInfo (GUIWidget * w)
: widget(w)
{
}
GUIInfo::~GUIInfo ()
{
for (int i = 0; i < bindings.size(); i++) {
delete bindings[i];
bindings[i] = 0;
}
}
////////////////////////////////////////////////////////////////////////
@ -53,7 +70,60 @@ GUIWidget::GUIWidget (SGPropertyNode_ptr props)
GUIWidget::~GUIWidget ()
{
std::cerr << "Destroying widget\n";
delete _object;
int i;
for (i = 0; i < _info.size(); i++) {
delete _info[i];
_info[i] = 0;
}
for (i = 0; i < _propertyObjects.size(); i++) {
delete _propertyObjects[i];
_propertyObjects[i] = 0;
}
}
void
GUIWidget::updateValue (const char * objectName)
{
for (int i = 0; i < _propertyObjects.size(); i++) {
if (_propertyObjects[i]->name == objectName)
_propertyObjects[i]->object
->setValue(_propertyObjects[i]->node->getStringValue());
}
}
void
GUIWidget::applyValue (const char * objectName)
{
for (int i = 0; i < _propertyObjects.size(); i++) {
if (_propertyObjects[i]->name == objectName)
_propertyObjects[i]->node
->setStringValue(_propertyObjects[i]
->object->getStringValue());
}
}
void
GUIWidget::updateValues ()
{
for (int i = 0; i < _propertyObjects.size(); i++) {
puObject * object = _propertyObjects[i]->object;
SGPropertyNode_ptr node = _propertyObjects[i]->node;
object->setValue(node->getStringValue());
}
}
void
GUIWidget::applyValues ()
{
for (int i = 0; i < _propertyObjects.size(); i++) {
puObject * object = _propertyObjects[i]->object;
SGPropertyNode_ptr node = _propertyObjects[i]->node;
node->setStringValue(object->getStringValue());
}
}
void
@ -75,42 +145,6 @@ GUIWidget::display (SGPropertyNode_ptr props)
}
}
void
GUIWidget::action (const string &command)
{
if (command == "close") {
delete this;
} else if (command == "apply") {
applyProperties();
updateProperties();
} else if (command == "update") {
updateProperties();
} else if (command == "close-apply") {
applyProperties();
delete this;
}
}
void
GUIWidget::applyProperties ()
{
for (int i = 0; i < _propertyObjects.size(); i++) {
puObject * object = _propertyObjects[i].object;
SGPropertyNode_ptr node = _propertyObjects[i].node;
node->setStringValue(object->getStringValue());
}
}
void
GUIWidget::updateProperties ()
{
for (int i = 0; i < _propertyObjects.size(); i++) {
puObject * object = _propertyObjects[i].object;
SGPropertyNode_ptr node = _propertyObjects[i].node;
object->setValue(node->getStringValue());
}
}
puObject *
GUIWidget::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
{
@ -171,17 +205,26 @@ GUIWidget::setupObject (puObject * object, SGPropertyNode * props)
if (props->hasValue("label"))
object->setLabel(props->getStringValue("label"));
if (props->hasValue("default-value-prop")) {
const char * name = props->getStringValue("default-value-prop");
SGPropertyNode_ptr node = fgGetNode(name, true);
if (props->hasValue("property")) {
const char * name = props->getStringValue("name");
if (name == 0)
name = "";
const char * propname = props->getStringValue("property");
SGPropertyNode_ptr node = fgGetNode(propname, true);
object->setValue(node->getStringValue());
_propertyObjects.push_back(PropertyObject(object, node));
if (name != 0)
_propertyObjects.push_back(new PropertyObject(name, object, node));
}
if (props->hasValue("action")) {
_actions.push_back(GUIData(this, props->getStringValue("action")));
object->setUserData(&_actions[_actions.size()-1]);
vector<SGPropertyNode_ptr> nodes = props->getChildren("binding");
if (nodes.size() > 0) {
GUIInfo * info = new GUIInfo(this);
for (int i = 0; i < nodes.size(); i++)
info->bindings.push_back(new FGBinding(nodes[i]));
object->setCallback(action_callback);
object->setUserData(info);
_info.push_back(info);
}
object->makeReturnDefault(props->getBoolValue("default"));
@ -202,9 +245,12 @@ GUIWidget::setupGroup (puGroup * group, SGPropertyNode * props,
group->close();
}
GUIWidget::PropertyObject::PropertyObject (puObject * o, SGPropertyNode_ptr n)
: object(o),
node(n)
GUIWidget::PropertyObject::PropertyObject (const char * n,
puObject * o,
SGPropertyNode_ptr p)
: name(n),
object(o),
node(p)
{
}
@ -216,6 +262,7 @@ GUIWidget::PropertyObject::PropertyObject (puObject * o, SGPropertyNode_ptr n)
NewGUI::NewGUI ()
: _current_widget(0)
{
}
@ -243,7 +290,19 @@ NewGUI::display (const string &name)
if (_widgets.find(name) == _widgets.end())
SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
else
new GUIWidget(_widgets[name]); // PUI will delete it
new GUIWidget(_widgets[name]);
}
void
NewGUI::setCurrentWidget (GUIWidget * widget)
{
_current_widget = widget;
}
GUIWidget *
NewGUI::getCurrentWidget ()
{
return _current_widget;
}
void

View file

@ -19,19 +19,22 @@ SG_USING_STD(vector);
SG_USING_STD(map);
#include <Main/fgfs.hxx>
#include <Main/fg_props.hxx>
#include <Input/input.hxx>
class GUIWidget;
/**
* User data attached to a GUI object.
* Information about a GUI widget.
*/
struct GUIData
struct GUIInfo
{
GUIData (GUIWidget * w, const char * a);
GUIInfo (GUIWidget * w);
virtual ~GUIInfo ();
GUIWidget * widget;
string command;
vector <FGBinding *> bindings;
};
@ -41,16 +44,62 @@ struct GUIData
class GUIWidget
{
public:
/**
* Construct a new GUI widget configured by a property tree.
*/
GUIWidget (SGPropertyNode_ptr props);
/**
* Destructor.
*/
virtual ~GUIWidget ();
virtual void action (const string &command);
/**
* Update the values of all GUI objects with a specific name.
*
* This method copies from the property to the GUI object.
*
* @param objectName The name of the GUI object(s) to update.
* Use the empty name for all unnamed objects.
*/
virtual void updateValue (const char * objectName);
/**
* Apply the values of all GUI objects with a specific name.
*
* This method copies from the GUI object to the property.
*
* @param objectName The name of the GUI object(s) to update.
* Use the empty name for all unnamed objects.
*/
virtual void applyValue (const char * objectName);
/**
* Update the values of all GUI objects.
*
* This method copies from the properties to the GUI objects.
*/
virtual void updateValues ();
/**
* Apply the values of all GUI objects.
*
* This method copies from the GUI objects to the properties.
*/
virtual void applyValues ();
private:
GUIWidget (const GUIWidget &); // just for safety
void display (SGPropertyNode_ptr props);
virtual void updateProperties ();
virtual void applyProperties ();
puObject * makeObject (SGPropertyNode * props,
int parentWidth, int parentHeight);
void setupObject (puObject * object, SGPropertyNode * props);
@ -58,13 +107,16 @@ private:
int width, int height, bool makeFrame = false);
puObject * _object;
vector<GUIData> _actions;
vector<GUIInfo *> _info;
struct PropertyObject {
PropertyObject (puObject * object, SGPropertyNode_ptr node);
PropertyObject (const char * name,
puObject * object,
SGPropertyNode_ptr node);
string name;
puObject * object;
SGPropertyNode_ptr node;
};
vector<PropertyObject> _propertyObjects;
vector<PropertyObject *> _propertyObjects;
};
@ -78,14 +130,20 @@ public:
virtual void update (double delta_time_sec);
virtual void display (const string &name);
virtual void setCurrentWidget (GUIWidget * widget);
virtual GUIWidget * getCurrentWidget ();
private:
void readDir (const char * path);
GUIWidget * _current_widget;
map<string,SGPropertyNode_ptr> _widgets;
};
#endif // __NEW_GUI_HXX
// end of new_gui.hxx