From: curt Date: Tue, 4 Feb 2003 22:27:58 +0000 (+0000) Subject: James Turner: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=e8b6077c79b8bc3685bfd83da835ec40d83e187e;p=flightgear.git James Turner: Here's a change to the GUI property picker I did a few weeks back. It makes the values in the property pick 'live' (and also re-factors the picker code to use less arrays, this should be obvious from the diffs). A good demo is to open up the engine node and observe the rpm, cylinder head temp, oil pressure and so on while playing with the throttle and airspeed. It's pretty rough (some rounding of digits would help) but useful for testing (at least I think so). I'm not sure about the performance implications either, but it seems fine for me. --- diff --git a/src/GUI/prop_picker.cxx b/src/GUI/prop_picker.cxx index 0f3371fe0..aed464a4d 100755 --- a/src/GUI/prop_picker.cxx +++ b/src/GUI/prop_picker.cxx @@ -88,7 +88,7 @@ void prop_pickerRefresh() me -> find_props(); } -void prop_editInit(char * name, char * value, char * proppath) +void prop_editInit( const char * name, const char * value, char * proppath ) { if( PE_widget == 0 ) { fgPropEdit *PP = new fgPropEdit ( name, value, proppath ); @@ -96,7 +96,7 @@ void prop_editInit(char * name, char * value, char * proppath) } } -void prop_editOpen( char * name, char * value, char * proppath ) +void prop_editOpen( const char * name, const char * value, char * proppath ) { if( PE_widget == 0 ) { prop_editInit( name, value, proppath ); @@ -110,7 +110,7 @@ void prop_editOpen( char * name, char * value, char * proppath ) } // return a human readable form of the value "type" -static string getValueTypeString( const SGPropertyNode *node ) { +static string getValueTypeString( const SGPropertyNode_ptr node ) { string result; if ( node == NULL ) { @@ -235,7 +235,6 @@ void fgPropPicker::go_up_one_directory ( char *fname ) void fgPropPicker::handle_select ( puObject* list_box ) { fgPropPicker* prop_picker = (fgPropPicker*) list_box -> getUserData () ; - int selected ; list_box -> getValue ( &selected ) ; @@ -244,25 +243,29 @@ void fgPropPicker::handle_select ( puObject* list_box ) char *dst = prop_picker -> startDir ; char *src = prop_picker -> files [ selected ] ; - if ( strcmp ( src, "." ) == 0 ) - { - /* Do nothing - but better refresh anyway. */ - - prop_picker -> find_props () ; - return ; - } - - if ( strcmp ( src, ".." ) == 0 ) - { - /* Do back up one level - so refresh. */ - - go_up_one_directory ( dst ) ; - prop_picker -> find_props () ; - return ; - } + if (prop_picker->dotFiles && (selected < 2)) { + if ( strcmp ( src, "." ) == 0 ) { + /* Do nothing - but better refresh anyway. */ + + prop_picker -> find_props () ; + return ; + } else if ( strcmp ( src, ".." ) == 0 ) { + /* Do back up one level - so refresh. */ + + go_up_one_directory ( dst ) ; + prop_picker -> find_props () ; + return ; + } + } - if ( prop_picker -> dflag [ selected ] ) - { + // we know we're dealing with a regular entry, so convert + // it to an index into children[] + if (prop_picker->dotFiles) selected -= 2; + SGPropertyNode_ptr child = prop_picker->children[selected]; + assert(child != NULL); + + // check if it's a directory (had children) + if ( child->nChildren() ) { /* If this is a directory - then descend into it and refresh */ if ( strlen ( dst ) + strlen ( src ) + 2 >= PUSTRING_MAX ) @@ -285,7 +288,8 @@ void fgPropPicker::handle_select ( puObject* list_box ) "PUI: fgPropPicker - path is too long, max is %d.", PUSTRING_MAX ) ; return ; } - prop_editOpen( prop_picker -> names [ selected ], prop_picker -> values [ selected ], dst); + + prop_editOpen(child->getName(), child->getStringValue(), dst); } else { @@ -294,8 +298,8 @@ void fgPropPicker::handle_select ( puObject* list_box ) refresh just in case some other process created the file. */ - - prop_picker -> find_props () ; + // should be obsolete once we observe child add/remove on our top node + prop_picker -> find_props () ; } } @@ -314,15 +318,16 @@ void fgPropPicker::delete_arrays () if ( files ) { for ( int i=0; inChildren() == 0) + children[C]->removeChangeListener(this); + } + delete[] files; - delete[] names; - delete[] values; - delete[] dflag; + delete[] children; } } @@ -345,9 +350,6 @@ fgPropPicker::fgPropPicker ( int x, int y, int w, int h, int arrows, puGetDefaultFonts ( &LegendFont, &LabelFont ); files = NULL ; - dflag = NULL ; - names = NULL ; - values = NULL ; num_files = 0 ; strcpy ( startDir, dir ) ; @@ -400,7 +402,6 @@ fgPropPicker::fgPropPicker ( int x, int y, int w, int h, int arrows, slider -> setCallback ( fgPropPickerHandleSlider ) ; FG_FINALIZE_PUI_DIALOG( this ); - printf("fgPropPicker - End of Init\n"); } @@ -431,87 +432,64 @@ void fgPropPicker::find_props () SGPropertyNode * node = globals->get_props()->getNode(startDir); num_files = (node) ? (int)node->nChildren() : 0; - + // instantiate string objects and add [.] and [..] for subdirs if (strcmp(startDir,"/") == 0) { files = new char* [ num_files+1 ] ; - names = new char* [ num_files+1 ] ; - values = new char* [ num_files+1 ] ; - dflag = new char [ num_files+1 ] ; pi = 0; + dotFiles = false; } else { // add two for the .. and . num_files = num_files + 2; // make room for .. and . files = new char* [ num_files+1 ] ; - names = new char* [ num_files+1 ] ; - values = new char* [ num_files+1 ] ; - dflag = new char [ num_files+1 ] ; + stdString line = "."; - files [ 0 ] = new char[ strlen(line.c_str())+2 ]; + files [ 0 ] = new char[line.size()]; strcpy ( files [ 0 ], line.c_str() ); - names [ 0 ] = new char[ 2 ]; - values[ 0 ] = new char[ 2 ] ; + line = ".."; - dflag[ 0 ] = 1; - files [ 1 ] = new char[ strlen(line.c_str())+2 ]; + files [ 1 ] = new char[line.size()]; strcpy ( files [ 1 ], line.c_str() ); - names [ 1 ] = new char[ strlen(line.c_str())+2 ]; - values[ 1 ] = new char[ 2 ] ; - strcpy ( names [ 1 ], line.c_str() ); - dflag[ 1 ] = 1; pi = 2; + dotFiles = true; }; if (node) { // Get the list of children - int nChildren = node->nChildren(); - SGPropertyNode_ptr * children = new SGPropertyNode_ptr[nChildren]; - for (i = 0; i < nChildren; i++) { + num_children = node->nChildren(); + children = new SGPropertyNode_ptr[num_children]; + for (i = 0; i < num_children; i++) { children[i] = node->getChild(i); } - + // Sort the children into display order - qsort(children, nChildren, sizeof(children[0]), nodeNameCompare); + qsort(children, num_children, sizeof(children[0]), nodeNameCompare); // Make lists of the children's names, values, etc. - for (i = 0; i < nChildren; i++) { - SGPropertyNode * child = children[i]; - stdString name = child->getDisplayName(true); - names[ pi ] = new char[ strlen(name.c_str())+2 ] ; - strcpy ( names [ pi ], name.c_str() ) ; - if ( child->nChildren() > 0 ) { - dflag[ pi ] = 1 ; - files[ pi ] = new char[ strlen(name.c_str())+2 ] ; - strcpy ( files [ pi ], name.c_str() ) ; - strcat ( files [ pi ], "/" ) ; - values[ pi ] = new char[ 2 ] ; - } else { - dflag[ pi ] = 0 ; - stdString value = child->getStringValue(); - values[ pi ] = new char[ strlen(value.c_str())+2 ] ; - strcpy ( values [pi], value.c_str() ); - stdString line = name + " = '" + value + "' " + "("; - line += getValueTypeString( child ); - line += ")"; - // truncate entries to plib pui limit - if (line.length() > (PUSTRING_MAX-1)) line[PUSTRING_MAX-1] = '\0'; - files[ pi ] = new char[ strlen(line.c_str())+2 ] ; - strcpy ( files [ pi ], line.c_str() ) ; - } - // printf("files->%i of %i %s\n",pi, node->nChildren(), files [pi]); - ++pi; + for (i = 0; i < num_children; i++) { + SGPropertyNode * child = children[i]; + stdString name = child->getDisplayName(true); + + if ( child->nChildren() > 0 ) { + files[ pi ] = new char[ strlen(name.c_str())+2 ] ; + strcpy ( files [ pi ], name.c_str() ) ; + strcat ( files [ pi ], "/" ) ; + } else { + files[pi] = NULL; // ensure it's NULL before setting intial value + updateTextForEntry(i); + // observe it + child->addChangeListener(this); + } + + ++pi; } - - delete [] children; } files [ num_files ] = NULL ; - // printf("files pointer=%i/%i\n", files, num_files); - proppath -> setLabel (startDir); list_box -> newList ( files ) ; @@ -530,6 +508,41 @@ void fgPropPicker::find_props () } } +void fgPropPicker::updateTextForEntry(int index) +{ + assert((index >= 0) && (index < num_children)); + SGPropertyNode_ptr node = children[index]; + + // take a copy of the value + stdString value = node->getStringValue(); + + stdString line = node->getDisplayName() + stdString(" = '") + + value + "' " + "("; + line += getValueTypeString( node ); + line += ")"; + + // truncate entries to plib pui limit + if (line.length() >= PUSTRING_MAX) + line[PUSTRING_MAX-1] = '\0'; + + if (dotFiles) index +=2; + + // don't leak everywhere if we're updating + if (files[index]) delete[] files[index]; + + files[index] = new char[ strlen(line.c_str())+2 ] ; + strcpy ( files [ index ], line.c_str() ) ; +} + +void fgPropPicker::valueChanged(SGPropertyNode *nd) +{ + for (int C=0; C getUserData () ; @@ -555,7 +568,7 @@ void fgPropEdit::fgPropEditHandleOK ( puObject* b ) FG_POP_PUI_DIALOG( prop_edit ); } -fgPropEdit::fgPropEdit ( char *name, char *value, char *proppath ) : puDialogBox ( 0, 0 ) +fgPropEdit::fgPropEdit ( const char *name, const char *value, char *proppath ) : puDialogBox ( 0, 0 ) { puFont LegendFont, LabelFont; @@ -591,4 +604,3 @@ fgPropEdit::fgPropEdit ( char *name, char *value, char *proppath ) : puDialogBox FG_FINALIZE_PUI_DIALOG( this ); } - diff --git a/src/GUI/prop_picker.hxx b/src/GUI/prop_picker.hxx index 593b2e669..16f92aa67 100755 --- a/src/GUI/prop_picker.hxx +++ b/src/GUI/prop_picker.hxx @@ -7,17 +7,20 @@ #include #include "gui.h" +#include void prop_pickerInit(); void prop_pickerView( puObject * ); void prop_pickerRefresh(); -void prop_editInit(char * name, char * value ); -void prop_editOpen( char * name, char * value ); +void prop_editInit( const char * name, const char * value ); +void prop_editOpen( const char * name, const char * value ); class fgPropPicker ; class fgPropEdit ; -class fgPropPicker : public puDialogBox +class fgPropPicker : + public puDialogBox, + public SGPropertyChangeListener { static void handle_select ( puObject *b ) ; @@ -28,14 +31,24 @@ class fgPropPicker : public puDialogBox void delete_arrays () ; + /** update the text string in the puList using the given node and + updating the requested offset. The value of dotFiles is taken + into account before the index is applied, i.e this should be + an index into 'children' */ + void updateTextForEntry(int index); + char** files ; - char** names ; - char** values ; - char* dflag ; int num_files ; int arrow_count ; char startDir [ PUSTRING_MAX * 2 ] ; + SGPropertyNode_ptr* children; + int num_children; + + /** set if we're display the . and .. entries at the start of the + list */ + bool dotFiles; + /* puInput *input ; */ protected: @@ -59,6 +72,8 @@ public: static void go_up_one_directory ( char *fname ) ; static void chop_file ( char *fname ) ; + // over-ride the method from SGPropertyNodeListener + virtual void valueChanged (SGPropertyNode * node); } ; class fgPropEdit : public puDialogBox @@ -78,7 +93,7 @@ public: puInput *propinput ; char propPath [ PUSTRING_MAX * 2 ] ; - fgPropEdit ( char *name, char *value, char *proppath ) ; + fgPropEdit ( const char *name, const char *value, char *proppath ) ; ~fgPropEdit () {;}