Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

src/aclvis/UIComponent.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00028 //
00029 // Some parts of this file are derived from the example code from the book:
00030 //
00031 //           Object-Oriented Programming with C++ and OSF/Motif
00032 //         by
00033 //           Douglas Young
00034 //           Prentice Hall, 1992
00035 //           ISBN 0-13-630252-1 
00036 //
00037 //         Copyright 1991 by Prentice Hall
00038 //         All Rights Reserved
00039 //
00040 //  Permission to use, copy, modify, and distribute this software for 
00041 //  any purpose except publication and without fee is hereby granted, provided 
00042 //  that the above copyright notice appear in all copies of the software.
00045 
00047 // UIComponent.C: Base class for all C++/Motif UI components
00049 
00050 #if (XlibSpecificationRelease >= 5)
00051 #include "UIComponent.h"
00052 #else
00053 #define XLIB_ILLEGAL_ACCESS
00054 #include "UIComponent.h"
00055 #undef XLIB_ILLEGAL_ACCESS
00056 #endif
00057 #include <assert.h>
00058 #include <stdio.h>
00059 #include <stdlib.h>
00060 
00061 char *strdup(const char *old)
00062 {
00063 char *new_str;
00064 if ( old == NULL ) return ( NULL );
00065 new_str = (char*) malloc((strlen(old) + 1)*sizeof(char));
00066 strcpy(new_str, old);
00067 return( new_str );
00068 }
00069 
00070 UIComponent::UIComponent ( const char *name )
00071 {
00072     _w = NULL;
00073     assert ( name != NULL );  // Make sure programmers provide name
00074     _name = strdup ( name );
00075 }
00076 
00077 void UIComponent::widgetDestroyedCallback ( Widget, 
00078                                            XtPointer clientData, 
00079                                            XtPointer )
00080 {
00081     UIComponent * obj = (UIComponent *) clientData;     
00082     
00083     obj->widgetDestroyed();
00084 }
00085 
00086 void UIComponent::widgetDestroyed()
00087 {
00088     _w = NULL;
00089 }
00090 
00091 const char * UIComponent::className()
00092 {
00093     return "UIComponent";
00094 }
00095 
00096 void UIComponent::installDestroyHandler()
00097 {
00098     assert ( _w != NULL );
00099     XtAddCallback ( _w, 
00100                    XmNdestroyCallback,
00101                    &UIComponent::widgetDestroyedCallback, 
00102                    (XtPointer) this );
00103 }
00104 
00105 void UIComponent::manage()
00106 {
00107     assert ( _w != NULL );
00108     assert ( XtHasCallbacks ( _w, XmNdestroyCallback ) ==
00109             XtCallbackHasSome );
00110     XtManageChild ( _w );
00111 }
00112 
00113 void UIComponent::unmanage()
00114 {
00115     assert ( _w != NULL );
00116     XtUnmanageChild ( _w );
00117 }
00118 
00119 
00120 UIComponent::~UIComponent()
00121 {
00122     // Make sure the widget hasn't already been destroyed
00123     
00124     if ( _w ) 
00125     {
00126         // Remove destroy callback so Xt can't call the callback
00127         // with a pointer to an object that has already been freed
00128         
00129         XtRemoveCallback ( _w, 
00130                           XmNdestroyCallback,
00131                           &UIComponent::widgetDestroyedCallback,
00132                           (XtPointer) this );   
00133 
00134         XtDestroyWidget ( _w );
00135     }
00136 
00137     free(_name);
00138 }
00139 
00140 void UIComponent::getResources ( const XtResourceList resources, 
00141                                 const int numResources )
00142 {
00143     // Check for errors
00144     
00145     assert ( _w != NULL );
00146     assert ( resources != NULL );
00147     
00148     // Retrieve the requested resources relative to the 
00149     // parent of this object's base widget
00150     
00151     XtGetSubresources ( XtParent( _w ), 
00152                        (XtPointer) this, 
00153                        _name,
00154                        className(),
00155                        resources, 
00156                        numResources,
00157                        NULL, 
00158                        0 );
00159 }
00160 
00161 void UIComponent::setDefaultResources ( const Widget w, 
00162                                          const String *resourceSpec )
00163 {
00164    int         i;       
00165    Display    *dpy = XtDisplay ( w );     // Retrieve the display pointer
00166    XrmDatabase rdb = NULL;             // A resource data base
00167 
00168    // Create an empty resource database
00169 
00170    rdb = XrmGetStringDatabase ( "" );
00171 
00172    // Add the Component resources, prepending the name of the component
00173 
00174    i = 0;
00175    while ( resourceSpec[i] != NULL )
00176    {
00177        char buf[1000];
00178 
00179        sprintf(buf, "*%s%s", _name, resourceSpec[i++]);
00180        XrmPutLineResource( &rdb, buf );
00181    }
00182 
00183    // Merge them into the Xt database, with lowest precendence
00184 
00185    if ( rdb )
00186    {
00187 #if (XlibSpecificationRelease>=5)
00188         XrmDatabase db = XtDatabase(dpy);
00189         XrmCombineDatabase(rdb, &db, FALSE);
00190 #else
00191         XrmMergeDatabases ( dpy->db, &rdb );
00192         dpy->db = rdb;
00193 #endif
00194     }
00195 }
00196 
00197 // This method gets all the resources from the app-defaults file 
00198 // (resource databse) and fills in the table (defs) if the app default 
00199 // value exists.
00200 
00201 void
00202 UIComponent::initAppDefaults(const Widget parent,
00203                              const char * cname,
00204                              UIAppDefault * defs)
00205 {
00206     XrmQuark            cQuark = XrmStringToQuark(cname);       // class quark
00207     XrmQuark            rsc[6];
00208     XrmRepresentation   rep;
00209     XrmValue            val;
00210     XrmDatabase         rdb;
00211     int                 rscIdx;
00212 
00213     // Get the database
00214 
00215 #if (XlibSpecificationRelease >= 5)
00216     if ((rdb = XrmGetDatabase(XtDisplay(parent))) == NULL)
00217     {
00218         return;                 // Can't get the database
00219     }
00220 #else
00221     Display *dpy = XtDisplay(parent);
00222     if ((rdb = dpy->db) == NULL)
00223     {
00224         return;
00225     }
00226 #endif
00227 
00228     // Look for each resource in the table
00229 
00230     while (defs->wName)
00231     {
00232         rscIdx = 0;
00233         rsc[rscIdx++] = cQuark;
00234         if (defs->wName[0] == '\0')
00235         {
00236             rsc[rscIdx++] = cQuark;
00237         }
00238         else
00239         {
00240             rsc[rscIdx++] = XrmStringToQuark(defs->wName);
00241         }
00242 
00243         if (defs->cInstName && defs->cInstName[0] != '\0')
00244         {
00245             rsc[rscIdx++] = XrmStringToQuark(defs->cInstName);
00246         }
00247 
00248         rsc[rscIdx++] = XrmStringToQuark(defs->wRsc);
00249         rsc[rscIdx++] = NULLQUARK;
00250 
00251         if (XrmQGetResource(rdb, rsc, rsc, &rep, &val))
00252         {
00253             defs->value = strdup((char*)val.addr);
00254         }
00255         defs++;
00256     }
00257 }
00258 
00259 // This method applies the app defaults for the class to a specific
00260 // instance. All the widgets in the path are loosly coupled (use *).
00261 // To override a specific instance, use a tightly coupled app defaults
00262 // resource line (use .).
00263 void
00264 UIComponent::setAppDefaults(const Widget w,
00265                             UIAppDefault * defs,
00266                             const char* inst_name )
00267 {
00268    Display*     dpy = XtDisplay ( w );  // Retrieve the display pointer
00269    XrmDatabase  rdb = NULL;             // A resource data base
00270    char         lineage[1000];
00271    char         buf[1000];
00272    Widget       parent;
00273    char         *wName;
00274 
00275    // Create an empty resource database
00276 
00277    rdb = XrmGetStringDatabase ( "" );
00278 
00279    // Get the lineage
00280 
00281    lineage[0] = '\0';
00282    parent = w;
00283 
00284    while (parent)
00285    {
00286        WidgetClass wclass = XtClass(parent);
00287 
00288        if (wclass == applicationShellWidgetClass) break;
00289 
00290        strcpy(buf, lineage);
00291        sprintf(lineage, "*%s%s", XtName(parent), buf);
00292 
00293        parent = XtParent(parent);
00294    }
00295 
00296    // Add the Component resources, prepending the name of the component
00297 
00298    while (defs->wName != NULL)
00299    {
00300        if ( !strcmp(defs->wName, "" ) ) wName = _name;
00301        else wName = (char *)(defs->wName);
00302 
00303        // See if we need to deal with this record.
00304        //   (1) If we've been passed an instance name (meaning we're
00305        //       creating a nested instance of a class), then make sure
00306        //       we're dealing with the proper nested instance.
00307        //   (2) If we're not creating a nested instance, then
00308        //       ignore resources for nested instances.
00309        //   (3) We didn't find a default value in the app-defaults
00310        if ((inst_name && strcmp(inst_name, wName)) ||   // (1)
00311            (!inst_name && defs->cInstName) ||                   // (2)
00312            (defs->value == NULL))                               // (3)
00313        {
00314            defs++;
00315            continue;
00316        }
00317 
00318        // Build up string after lineage
00319        if (defs->cInstName != NULL)
00320        {
00321            // Don't include class instance name if it is also the instance
00322            // being affected. 
00323 
00324            if (*defs->cInstName != '\0')
00325            {
00326                sprintf(buf, "%s.%s*%s.%s: %s",
00327                        lineage, wName, defs->cInstName, defs->wRsc,
00328                        defs->value);
00329            }
00330            else
00331            {
00332                sprintf(buf, "%s.%s.%s: %s",
00333                        lineage, wName, defs->wRsc, defs->value);
00334            }
00335        }
00336        else if (*defs->wName != '\0')
00337        {
00338            sprintf(buf, "%s*%s*%s.%s: %s",
00339                    lineage, _name, defs->wName, defs->wRsc, defs->value);
00340        }
00341        else
00342        {
00343            sprintf(buf, "%s*%s.%s: %s",
00344                    lineage, _name, defs->wRsc, defs->value);
00345        }
00346 
00347        XrmPutLineResource( &rdb, buf );
00348        defs++;
00349    }
00350 
00351    // Merge them into the Xt database, with lowest precendence
00352    if ( rdb )
00353    {
00354 #if (XlibSpecificationRelease >= 5)
00355         XrmDatabase db = XtDatabase(dpy);
00356         XrmCombineDatabase(rdb, &db, FALSE);
00357 #else
00358         XrmMergeDatabases ( dpy->db, &rdb );
00359         dpy->db = rdb;
00360 #endif
00361     }
00362 }
00363 
00364 /***************************************************************************
00365  * $RCSfile: UIComponent.cpp,v $   $Author: adelmann $
00366  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:34 $
00367  * IPPL_VERSION_ID: $Id: UIComponent.cpp,v 1.1.1.1 2003/01/23 07:40:34 adelmann Exp $ 
00368  ***************************************************************************/

Generated on Fri Nov 2 01:25:54 2007 for IPPL by doxygen 1.3.5