diff --git a/src/GUI/Makefile.am b/src/GUI/Makefile.am
index 8cb594c55..7d6d59b82 100644
--- a/src/GUI/Makefile.am
+++ b/src/GUI/Makefile.am
@@ -8,6 +8,7 @@ endif
libGUI_a_SOURCES = \
new_gui.cxx new_gui.hxx \
+ dialog.cxx dialog.hxx \
menubar.cxx menubar.hxx \
gui.cxx gui.h gui_funcs.cxx \
gui_local.cxx gui_local.hxx \
diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx
new file mode 100644
index 000000000..38c77697b
--- /dev/null
+++ b/src/GUI/dialog.cxx
@@ -0,0 +1,253 @@
+// dialog.cxx: implementation of an XML-configurable dialog box.
+
+#include
+
+#include "dialog.hxx"
+#include "new_gui.hxx"
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Callbacks.
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * Action callback.
+ */
+static void
+action_callback (puObject * object)
+{
+ 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++)
+ info->bindings[i]->fire();
+ gui->setCurrentWidget(0);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Implementation of GUIInfo.
+////////////////////////////////////////////////////////////////////////
+
+GUIInfo::GUIInfo (FGDialog * w)
+ : widget(w)
+{
+}
+
+GUIInfo::~GUIInfo ()
+{
+ for (int i = 0; i < bindings.size(); i++) {
+ delete bindings[i];
+ bindings[i] = 0;
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGDialog.
+////////////////////////////////////////////////////////////////////////
+
+FGDialog::FGDialog (SGPropertyNode_ptr props)
+ : _object(0)
+{
+ display(props);
+}
+
+FGDialog::~FGDialog ()
+{
+ 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
+FGDialog::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
+FGDialog::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
+FGDialog::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
+FGDialog::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
+FGDialog::display (SGPropertyNode_ptr props)
+{
+ if (_object != 0) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "This widget is already active");
+ return;
+ }
+
+ _object = makeObject(props, 1024, 768);
+
+ if (_object != 0) {
+ _object->reveal();
+ } else {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Widget "
+ << props->getStringValue("name", "[unnamed]")
+ << " does not contain a proper GUI definition");
+ }
+}
+
+puObject *
+FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
+{
+ int width = props->getIntValue("width", parentWidth);
+ int height = props->getIntValue("height", parentHeight);
+
+ int x = props->getIntValue("x", (parentWidth - width) / 2);
+ int y = props->getIntValue("y", (parentHeight - height) / 2);
+
+ string type = props->getName();
+ if (type == "")
+ type = props->getStringValue("type");
+ if (type == "") {
+ SG_LOG(SG_GENERAL, SG_ALERT, "No type specified for GUI object");
+ return 0;
+ }
+
+ if (type == "dialog") {
+ puPopup * dialog;
+ if (props->getBoolValue("modal", false))
+ dialog = new puDialogBox(x, y);
+ else
+ dialog = new puPopup(x, y);
+ setupGroup(dialog, props, width, height, true);
+ return dialog;
+ } else if (type == "group") {
+ puGroup * group = new puGroup(x, y);
+ setupGroup(group, props, width, height, false);
+ return group;
+ } else if (type == "input") {
+ puInput * input = new puInput(x, y, x + width, y + height);
+ setupObject(input, props);
+ return input;
+ } else if (type == "text") {
+ puText * text = new puText(x, y);
+ setupObject(text, props);
+ return text;
+ } else if (type == "button") {
+ puButton * b;
+ const char * legend = props->getStringValue("legend", "[none]");
+ if (props->getBoolValue("one-shot", true))
+ b = new puOneShot(x, y, legend);
+ else
+ b = new puButton(x, y, legend);
+ setupObject(b, props);
+ return b;
+ } else {
+ return 0;
+ }
+}
+
+void
+FGDialog::setupObject (puObject * object, SGPropertyNode * props)
+{
+ if (props->hasValue("legend"))
+ object->setLegend(props->getStringValue("legend"));
+
+ if (props->hasValue("label"))
+ object->setLabel(props->getStringValue("label"));
+
+ 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());
+ if (name != 0)
+ _propertyObjects.push_back(new PropertyObject(name, object, node));
+ }
+
+ vector 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"));
+}
+
+void
+FGDialog::setupGroup (puGroup * group, SGPropertyNode * props,
+ int width, int height, bool makeFrame)
+{
+ setupObject(group, props);
+
+ if (makeFrame)
+ new puFrame(0, 0, width, height);
+
+ int nChildren = props->nChildren();
+ for (int i = 0; i < nChildren; i++)
+ makeObject(props->getChild(i), width, height);
+ group->close();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGDialog::PropertyObject.
+////////////////////////////////////////////////////////////////////////
+
+FGDialog::PropertyObject::PropertyObject (const char * n,
+ puObject * o,
+ SGPropertyNode_ptr p)
+ : name(n),
+ object(o),
+ node(p)
+{
+}
+
+
+// end of dialog.cxx
diff --git a/src/GUI/dialog.hxx b/src/GUI/dialog.hxx
new file mode 100644
index 000000000..de2e900a9
--- /dev/null
+++ b/src/GUI/dialog.hxx
@@ -0,0 +1,116 @@
+// dialog.hxx - XML-configurable dialog box.
+
+#ifndef __DIALOG_HXX
+#define __DIALOG_HXX 1
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#include
+
+#include // for SG_USING_STD
+#include
+
+#include
+SG_USING_STD(vector);
+
+class FGDialog;
+class FGBinding;
+
+
+/**
+ * PUI userdata describing a GUI object.
+ */
+struct GUIInfo
+{
+ GUIInfo (FGDialog * w);
+ virtual ~GUIInfo ();
+
+ FGDialog * widget;
+ vector bindings;
+};
+
+
+/**
+ * Top-level GUI widget.
+ */
+class FGDialog
+{
+public:
+
+
+ /**
+ * Construct a new GUI widget configured by a property tree.
+ */
+ FGDialog (SGPropertyNode_ptr props);
+
+
+ /**
+ * Destructor.
+ */
+ virtual ~FGDialog ();
+
+
+ /**
+ * 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:
+ FGDialog (const FGDialog &); // just for safety
+
+ void display (SGPropertyNode_ptr props);
+ puObject * makeObject (SGPropertyNode * props,
+ int parentWidth, int parentHeight);
+ void setupObject (puObject * object, SGPropertyNode * props);
+ void setupGroup (puGroup * group, SGPropertyNode * props,
+ int width, int height, bool makeFrame = false);
+
+ puObject * _object;
+ vector _info;
+ struct PropertyObject {
+ PropertyObject (const char * name,
+ puObject * object,
+ SGPropertyNode_ptr node);
+ string name;
+ puObject * object;
+ SGPropertyNode_ptr node;
+ };
+ vector _propertyObjects;
+};
+
+#endif // __DIALOG_HXX
diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx
index e7c6f939f..6be566c65 100644
--- a/src/GUI/new_gui.cxx
+++ b/src/GUI/new_gui.cxx
@@ -5,251 +5,11 @@
#include
#include
-#include
-SG_USING_STD(vector);
-
#include
#include
#include "menubar.hxx"
-
-
-
-////////////////////////////////////////////////////////////////////////
-// Callbacks.
-////////////////////////////////////////////////////////////////////////
-
-/**
- * Action callback.
- */
-static void
-action_callback (puObject * object)
-{
- 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++)
- info->bindings[i]->fire();
- gui->setCurrentWidget(0);
-}
-
-
-
-////////////////////////////////////////////////////////////////////////
-// Implementation of GUIInfo.
-////////////////////////////////////////////////////////////////////////
-
-GUIInfo::GUIInfo (GUIWidget * w)
- : widget(w)
-{
-}
-
-GUIInfo::~GUIInfo ()
-{
- for (int i = 0; i < bindings.size(); i++) {
- delete bindings[i];
- bindings[i] = 0;
- }
-}
-
-
-
-////////////////////////////////////////////////////////////////////////
-// Implementation of GUIWidget.
-////////////////////////////////////////////////////////////////////////
-
-GUIWidget::GUIWidget (SGPropertyNode_ptr props)
- : _object(0)
-{
- display(props);
-}
-
-GUIWidget::~GUIWidget ()
-{
- 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
-GUIWidget::display (SGPropertyNode_ptr props)
-{
- if (_object != 0) {
- SG_LOG(SG_GENERAL, SG_ALERT, "This widget is already active");
- return;
- }
-
- _object = makeObject(props, 1024, 768);
-
- if (_object != 0) {
- _object->reveal();
- } else {
- SG_LOG(SG_GENERAL, SG_ALERT, "Widget "
- << props->getStringValue("name", "[unnamed]")
- << " does not contain a proper GUI definition");
- }
-}
-
-puObject *
-GUIWidget::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
-{
- int width = props->getIntValue("width", parentWidth);
- int height = props->getIntValue("height", parentHeight);
-
- int x = props->getIntValue("x", (parentWidth - width) / 2);
- int y = props->getIntValue("y", (parentHeight - height) / 2);
-
- string type = props->getName();
- if (type == "")
- type = props->getStringValue("type");
- if (type == "") {
- SG_LOG(SG_GENERAL, SG_ALERT, "No type specified for GUI object");
- return 0;
- }
-
- if (type == "dialog") {
- puPopup * dialog;
- if (props->getBoolValue("modal", false))
- dialog = new puDialogBox(x, y);
- else
- dialog = new puPopup(x, y);
- setupGroup(dialog, props, width, height, true);
- return dialog;
- } else if (type == "group") {
- puGroup * group = new puGroup(x, y);
- setupGroup(group, props, width, height, false);
- return group;
- } else if (type == "input") {
- puInput * input = new puInput(x, y, x + width, y + height);
- setupObject(input, props);
- return input;
- } else if (type == "text") {
- puText * text = new puText(x, y);
- setupObject(text, props);
- return text;
- } else if (type == "button") {
- puButton * b;
- const char * legend = props->getStringValue("legend", "[none]");
- if (props->getBoolValue("one-shot", true))
- b = new puOneShot(x, y, legend);
- else
- b = new puButton(x, y, legend);
- setupObject(b, props);
- return b;
- } else {
- return 0;
- }
-}
-
-void
-GUIWidget::setupObject (puObject * object, SGPropertyNode * props)
-{
- if (props->hasValue("legend"))
- object->setLegend(props->getStringValue("legend"));
-
- if (props->hasValue("label"))
- object->setLabel(props->getStringValue("label"));
-
- 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());
- if (name != 0)
- _propertyObjects.push_back(new PropertyObject(name, object, node));
- }
-
- vector 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"));
-}
-
-void
-GUIWidget::setupGroup (puGroup * group, SGPropertyNode * props,
- int width, int height, bool makeFrame)
-{
- setupObject(group, props);
-
- if (makeFrame)
- new puFrame(0, 0, width, height);
-
- int nChildren = props->nChildren();
- for (int i = 0; i < nChildren; i++)
- makeObject(props->getChild(i), width, height);
- group->close();
-}
-
-GUIWidget::PropertyObject::PropertyObject (const char * n,
- puObject * o,
- SGPropertyNode_ptr p)
- : name(n),
- object(o),
- node(p)
-{
-}
+#include "dialog.hxx"
@@ -294,16 +54,16 @@ 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]);
+ new FGDialog(_widgets[name]);
}
void
-NewGUI::setCurrentWidget (GUIWidget * widget)
+NewGUI::setCurrentWidget (FGDialog * widget)
{
_current_widget = widget;
}
-GUIWidget *
+FGDialog *
NewGUI::getCurrentWidget ()
{
return _current_widget;
diff --git a/src/GUI/new_gui.hxx b/src/GUI/new_gui.hxx
index 6b5b0b9e0..4a7f425ce 100644
--- a/src/GUI/new_gui.hxx
+++ b/src/GUI/new_gui.hxx
@@ -20,105 +20,10 @@ SG_USING_STD(map);
#include
#include
-#include
class FGMenuBar;
-class GUIWidget;
-
-
-/**
- * Information about a GUI widget.
- */
-struct GUIInfo
-{
- GUIInfo (GUIWidget * w);
- virtual ~GUIInfo ();
-
- GUIWidget * widget;
- vector bindings;
-};
-
-
-/**
- * Top-level GUI widget.
- */
-class GUIWidget
-{
-public:
-
-
- /**
- * Construct a new GUI widget configured by a property tree.
- */
- GUIWidget (SGPropertyNode_ptr props);
-
-
- /**
- * Destructor.
- */
- virtual ~GUIWidget ();
-
-
- /**
- * 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);
- puObject * makeObject (SGPropertyNode * props,
- int parentWidth, int parentHeight);
- void setupObject (puObject * object, SGPropertyNode * props);
- void setupGroup (puGroup * group, SGPropertyNode * props,
- int width, int height, bool makeFrame = false);
-
- puObject * _object;
- vector _info;
- struct PropertyObject {
- PropertyObject (const char * name,
- puObject * object,
- SGPropertyNode_ptr node);
- string name;
- puObject * object;
- SGPropertyNode_ptr node;
- };
- vector _propertyObjects;
-};
+class FGDialog;
+class FGBinding;
class NewGUI : public FGSubsystem
@@ -131,8 +36,8 @@ public:
virtual void update (double delta_time_sec);
virtual void display (const string &name);
- virtual void setCurrentWidget (GUIWidget * widget);
- virtual GUIWidget * getCurrentWidget ();
+ virtual void setCurrentWidget (FGDialog * widget);
+ virtual FGDialog * getCurrentWidget ();
virtual FGMenuBar * getMenuBar ();
@@ -142,7 +47,7 @@ private:
void readDir (const char * path);
FGMenuBar * _menubar;
- GUIWidget * _current_widget;
+ FGDialog * _current_widget;
map _widgets;
};