diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx index a33dde1ce..803346588 100644 --- a/src/GUI/dialog.cxx +++ b/src/GUI/dialog.cxx @@ -6,15 +6,12 @@ #include // atof() -#include - #include #include #include "dialog.hxx" #include "new_gui.hxx" -#include "puList.hxx" #include "AirportList.hxx" #include "layout.hxx" @@ -49,6 +46,7 @@ GUIInfo::~GUIInfo () } } + /** * Key handler. @@ -360,13 +358,6 @@ FGDialog::~FGDialog () puDeleteObject(_object); unsigned int i; - // Delete all the arrays we made - // and were forced to keep around - // because PUI won't do its own - // memory management. - for (i = 0; i < _char_arrays.size(); i++) - destroy_char_array(_char_arrays[i]); - // Delete all the info objects we // were forced to keep around because // PUI cannot delete its own user data. @@ -393,10 +384,10 @@ FGDialog::updateValues (const char * objectName) continue; puObject *obj = _propertyObjects[i]->object; - SGPropertyNode *values = _propertyObjects[i]->values; - if (obj->getType() & PUCLASS_LIST && values) - ((puList *)obj)->newList(value_list(values)); - else + if (obj->getType() & PUCLASS_LIST) { + fgList *pl = static_cast(obj); + pl->update(); + } else copy_to_pui(_propertyObjects[i]->node, obj); } } @@ -551,9 +542,8 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight) return obj; } else if (type == "list") { - char ** entries = value_list(props); int slider_width = props->getIntValue("slider", 20); - puList * obj = new puList(x, y, x + width, y + height, entries, slider_width); + fgList * obj = new fgList(x, y, x + width, y + height, props, slider_width); if (presetSize) obj->setSize(width, height); setupObject(obj, props); @@ -622,8 +612,7 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight) return obj; } else if (type == "combo") { - char ** entries = value_list(props); - puaComboBox * obj = new puaComboBox(x, y, x + width, y + height, entries, + fgComboBox * obj = new fgComboBox(x, y, x + width, y + height, props, props->getBoolValue("editable", false)); setupObject(obj, props); #ifdef PUCOL_EDITFIELD // plib > 0.8.4 @@ -672,19 +661,7 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight) return obj; } else if (type == "select") { - vector value_nodes; - SGPropertyNode * selection_node = - fgGetNode(props->getChild("selection")->getStringValue(), true); - - for (int q = 0; q < selection_node->nChildren(); q++) - value_nodes.push_back(selection_node->getChild(q)); - - char ** entries = make_char_array(value_nodes.size()); - for (unsigned int i = 0; i < value_nodes.size(); i++) - entries[i] = strdup((char *)value_nodes[i]->getName()); - - puaSelectBox * obj = - new puaSelectBox(x, y, x + width, y + height, entries); + fgSelectBox * obj = new fgSelectBox(x, y, x + width, y + height, props); setupObject(obj, props); #ifdef PUCOL_EDITFIELD // plib > 0.8.4 setColor(obj, props, EDITFIELD); @@ -728,8 +705,7 @@ FGDialog::setupObject (puObject * object, SGPropertyNode * props) SGPropertyNode_ptr node = fgGetNode(propname, true); copy_to_pui(node, object); - SGPropertyNode * values = type == "list" ? props : 0; - PropertyObject* po = new PropertyObject(name, object, node, values); + PropertyObject* po = new PropertyObject(name, object, node); _propertyObjects.push_back(po); if(props->getBoolValue("live")) _liveObjects.push_back(po); @@ -934,34 +910,6 @@ FGDialog::getKeyCode(const char *str) return key; } -char ** -FGDialog::value_list (const SGPropertyNode *props) -{ - vector value_nodes = props->getChildren("value"); - char ** entries = make_char_array(value_nodes.size()); - for (unsigned int i = 0; i < value_nodes.size(); i++) - entries[i] = strdup((char *)value_nodes[i]->getStringValue()); - return entries; -} - -char ** -FGDialog::make_char_array (int size) -{ - char ** list = new char*[size+1]; - for (int i = 0; i <= size; i++) - list[i] = 0; - _char_arrays.push_back(list); - return list; -} - -void -FGDialog::destroy_char_array (char ** array) -{ - for (int i = 0; array[i] != 0; i++) - if (array[i]) - free(array[i]);// added with strdup - delete[] array; -} //////////////////////////////////////////////////////////////////////// @@ -970,14 +918,66 @@ FGDialog::destroy_char_array (char ** array) FGDialog::PropertyObject::PropertyObject (const char * n, puObject * o, - SGPropertyNode_ptr p, - SGPropertyNode_ptr v) + SGPropertyNode_ptr p) : name(n), object(o), - node(p), - values(v) + node(p) { } + + +//////////////////////////////////////////////////////////////////////// +// Implementation of fgList and derived pui widgets +//////////////////////////////////////////////////////////////////////// + + +fgValueList::fgValueList(SGPropertyNode *p) : + _props(p) +{ + make_list(); +} + +void +fgValueList::update() +{ + destroy_list(); + make_list(); +} + +fgValueList::~fgValueList() +{ + destroy_list(); +} + +void +fgValueList::make_list() +{ + vector value_nodes = _props->getChildren("value"); + _list = new char *[value_nodes.size() + 1]; + unsigned int i; + for (i = 0; i < value_nodes.size(); i++) + _list[i] = strdup((char *)value_nodes[i]->getStringValue()); + _list[i] = 0; +} + +void +fgValueList::destroy_list() +{ + for (int i = 0; _list[i] != 0; i++) + if (_list[i]) + free(_list[i]); + delete[] _list; +} + + + +void +fgList::update() +{ + fgValueList::update(); + newList(_list); +} + // end of dialog.cxx diff --git a/src/GUI/dialog.hxx b/src/GUI/dialog.hxx index 65c010395..f30f3cf22 100644 --- a/src/GUI/dialog.hxx +++ b/src/GUI/dialog.hxx @@ -7,13 +7,16 @@ # error This library requires C++ #endif -#include +#include #include #include // for SG_USING_STD #include #include +#undef PUCLASS_LIST +#include "puList.hxx" + #include SG_USING_STD(vector); @@ -141,30 +144,18 @@ private: // PUI provides no way for userdata to be deleted automatically // with a GUI object, so we have to keep track of all the special // data we allocated and then free it manually when the dialog - // closes. "values" is a node with "value" children and only used - // by the widget. + // closes. vector _info; struct PropertyObject { PropertyObject (const char * name, puObject * object, - SGPropertyNode_ptr node, - SGPropertyNode_ptr values = 0); + SGPropertyNode_ptr node); string name; puObject * object; SGPropertyNode_ptr node; - SGPropertyNode_ptr values; }; vector _propertyObjects; vector _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 - // dialog closes. value_list() builds such a list from "value" - // children. - char ** make_char_array (int size); - char ** value_list(const SGPropertyNode * prop); - void destroy_char_array (char **array); - vector _char_arrays; }; // @@ -191,4 +182,40 @@ private: int _dX, _dY; }; + +class fgValueList { +public: + fgValueList(SGPropertyNode *p); + virtual ~fgValueList(); + virtual void update(); + +protected: + char **_list; + +private: + void make_list(); + void destroy_list(); + SGPropertyNode_ptr _props; +}; + + +class fgList : public fgValueList, public puList { +public: + fgList(int x1, int y1, int x2, int y2, SGPropertyNode *p, int sw) : + fgValueList(p), puList(x1, y1, x2, y2, _list, sw) {} + virtual void update(); +}; + +class fgComboBox : public fgValueList, public puaComboBox { +public: + fgComboBox(int x1, int y1, int x2, int y2, SGPropertyNode *p, bool editable) : + fgValueList(p), puaComboBox(x1, y1, x2, y2, _list, editable) {} +}; + +class fgSelectBox : public fgValueList, public puaSelectBox { +public: + fgSelectBox(int x1, int y1, int x2, int y2, SGPropertyNode *p) : + fgValueList(p), puaSelectBox(x1, y1, x2, y2, _list) {} +}; + #endif // __DIALOG_HXX