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:
parent
6225936ead
commit
0111183153
2 changed files with 181 additions and 64 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue