]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/prop_picker.cxx
Fix line endings
[flightgear.git] / src / GUI / prop_picker.cxx
index 39e45c5e012ef7d913a306f2a98f69c3df26e819..a2b4de8519b9fdc9d5e4e6883a32a8ce6e59730c 100755 (executable)
 #  include <config.h>
 #endif
 
-#include "prop_picker.hxx"
-#include <Main/globals.hxx>
-
 #include <simgear/compiler.h>
-#include <simgear/misc/props.hxx>
+#include <simgear/props/props.hxx>
 
 #include STL_STRING
+
+#include <Main/globals.hxx>
+#include "new_gui.hxx"
+#include "prop_picker.hxx"
+
 SG_USING_STD(string);
 
 // A local alternative name, for use when a variable called "string" is in scope - e.g. in classes derived from puInput.
@@ -88,7 +90,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 +98,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 +112,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 ) {
@@ -146,7 +148,7 @@ void fgPropPicker::fgPropPickerHandleSlider ( puObject * slider )
   float val ;
   slider -> getValue ( &val ) ;
   val = 1.0f - val ;
-  int scroll_range = list_box->getNumItems () - list_box->getNumVisible () ;
+  int scroll_range = list_box->getNumItems () - list_box->getNumVisible() ;
   if ( scroll_range > 0 )
   {
     int index = int ( scroll_range * val + 0.5 ) ;
@@ -168,7 +170,7 @@ void fgPropPicker::fgPropPickerHandleArrow ( puObject *arrow )
   float val ;
   slider -> getValue ( &val ) ;
   val = 1.0f - val ;
-  int scroll_range = list_box->getNumItems () - list_box->getNumVisible () ;
+  int scroll_range = list_box->getNumItems () - list_box->getNumVisible() ;
   if ( scroll_range > 0 )
   {
     int index = int ( scroll_range * val + 0.5 ) ;
@@ -235,7 +237,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 +245,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 +290,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 +300,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 +320,16 @@ void fgPropPicker::delete_arrays ()
   if ( files )
   {
     for ( int i=0; i<num_files; i++ ) {
-      delete[] files[i];
-      delete[] names[i];
-      delete[] values[i];
+               delete[] files[i];
     }
 
+    for (int C=0; C<num_children; ++C) {
+        if (children[C]->nChildren() == 0)
+            children[C]->removeChangeListener(this);
+    }
+       
     delete[] files;
-    delete[] names;
-    delete[] values;
-    delete[] dflag;
+    delete[] children;
   }
 }
 
@@ -339,15 +346,17 @@ fgPropPicker::~fgPropPicker ()
 */
 
 fgPropPicker::fgPropPicker ( int x, int y, int w, int h, int arrows,
-                                      const char *dir, const char *title ) : puDialogBox ( x,y )
+                                      const char *dir, const char *title ) :
+  fgPopup ( x,y ),
+  _gui((NewGUI *)globals->get_subsystem("gui"))
 {
   puFont LegendFont, LabelFont;
   puGetDefaultFonts ( &LegendFont, &LabelFont );
+  FGColor txtcol(_gui->getColor("label"));
+  txtcol.merge(_gui->getColor("text"));
+  txtcol.merge(_gui->getColor("text-label"));
 
   files = NULL ;
-  dflag = NULL ;
-  names = NULL ;
-  values = NULL ;
   num_files = 0 ;
 
   strcpy ( startDir, dir ) ;
@@ -362,6 +371,8 @@ fgPropPicker::fgPropPicker ( int x, int y, int w, int h, int arrows,
 
   proppath = new puText            (10, h-30);
   proppath ->    setLabel          (startDir);
+  proppath ->    setColor(PUCOL_LABEL, txtcol.red(), txtcol.green(),
+                          txtcol.blue(), txtcol.alpha());
 
   slider = new puSlider (w-30,40+20*arrows,h-100-40*arrows,TRUE,20);
   slider->setValue(1.0f);
@@ -373,6 +384,8 @@ fgPropPicker::fgPropPicker ( int x, int y, int w, int h, int arrows,
   list_box -> setUserData ( this ) ;
   list_box -> setCallback ( handle_select ) ;
   list_box -> setValue ( 0 ) ;
+  list_box -> setColor(PUCOL_LABEL, txtcol.red(), txtcol.green(),
+                       txtcol.blue(), txtcol.alpha());
 
   ok_button = new puOneShot ( 10, 10, (w<170)?(w/2-5):80, 30 ) ;
   ok_button -> setLegend ( "Ok" ) ;
@@ -400,7 +413,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,104 +443,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() + 1];
     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() + 1];
     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);
     }
-
-#if 1
+       
     // Sort the children into display order
-    qsort(children, nChildren, sizeof(children[0]), nodeNameCompare);
-#else
-    // Sort the entries.  This is a simple N^2 extraction sort.  More
-    // elaborate algorithms aren't necessary for the few dozen
-    // properties we're going to sort.
-    for (i = 0; i < nChildren; i++) {
-      int j, min = i;
-      for (j = i+1; j < nChildren; j++)
-       if (nodeNameCompare(&children[j], &children[min]) < 0)
-         min = j;
-      if (i != min) {
-       SGPropertyNode_ptr tmp = children[min];
-       children[min] = children[i];
-       children[i] = tmp;
-      }
-    }
-#endif
+    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 ) ;
@@ -547,6 +519,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
+    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<num_children; ++C)
+        if (children[C] == nd) {
+            updateTextForEntry(C);
+            return;
+        }
+}
+
 void fgPropEdit::fgPropEditHandleCancel ( puObject* b )
 {
   fgPropEdit* prop_edit = (fgPropEdit*) b -> getUserData () ;
@@ -572,11 +579,15 @@ 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 ) :
+    fgPopup ( 0, 0 ),
+    _gui((NewGUI *)globals->get_subsystem("gui"))
 {
     puFont LegendFont, LabelFont;
     puGetDefaultFonts ( &LegendFont, &LabelFont );
+    FGColor txtcol(_gui->getColor("label"));
+    txtcol.merge(_gui->getColor("text"));
+    txtcol.merge(_gui->getColor("text-label"));
 
     // locate in relation to picker widget...
     int fx = PROPPICK_X;
@@ -589,6 +600,8 @@ fgPropEdit::fgPropEdit ( char *name, char *value, char *proppath ) : puDialogBox
 
     propname = new puText            (fx+10, fy+90);
     propname ->    setLabel          (name);
+    propname ->    setColor(PUCOL_LABEL, txtcol.red(), txtcol.green(),
+                            txtcol.blue(), txtcol.alpha());
         
     propinput   = new puInput           (fx+10, fy+50, fx+480, fy+80);
     propinput   ->    setValue          (value);
@@ -608,4 +621,3 @@ fgPropEdit::fgPropEdit ( char *name, char *value, char *proppath ) : puDialogBox
         
     FG_FINALIZE_PUI_DIALOG( this );
 }
-