Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

cmd_label.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: cmd_label.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.49 $       $Date: 2019/01/17 21:21:03 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   text commands for label control
00019  ***************************************************************************/
00020 
00021 #include <string.h>
00022 #include <ctype.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <tcl.h>
00026 #include "config.h"
00027 #include "GeometryList.h"
00028 #include "GeometryMol.h"
00029 #include "utilities.h"
00030 #include "VMDApp.h"
00031 
00032 static int find_atom_from_name(Tcl_Interp *interp, const char *str, int *molid,
00033                                int *atomid) {
00034   // string must be of format ##/## where ## are numbers.
00035 
00036   // find first occurence of '/'
00037   const char *slash = strchr(str, '/');
00038   if (!slash) {
00039     Tcl_AppendResult(interp, "Illegal format: ", str, NULL); 
00040     return -1;
00041   }
00042 
00043   // make sure we have digits
00044   if (slash == str) {
00045     Tcl_AppendResult(interp, "Missing molecule specification: ", str, NULL); 
00046     return -1;
00047   }
00048   if (strlen(slash+1) == 0) {
00049     Tcl_AppendResult(interp, "Missing atom specification: ", str, NULL); 
00050     return -1;
00051   }
00052   const char *s;
00053   for (s = str; s < slash; s++) {
00054     if (!isdigit(*s)) {
00055       Tcl_AppendResult(interp, "Illegal molecule specification: ", str, NULL); 
00056       return -1;
00057     }
00058   }
00059   for (s = slash+1; *s; s++) {
00060     if (!isdigit(*s)) {
00061       Tcl_AppendResult(interp, "Illegal atom specification: ", str, NULL); 
00062       return -1;
00063     }
00064   }
00065 
00066   // Looks ok; extract the molecule and atom
00067   char *buf = new char[slash-str + 1];
00068   strncpy(buf, str, slash-str);
00069   buf[slash-str] = '\0';
00070   *molid = atoi(buf);
00071   *atomid = atoi(slash+1);
00072   return 0;
00073 }
00074 
00075 
00076 int text_cmd_label(ClientData cd, Tcl_Interp *interp, int argc,
00077                      const char *argv[]) {
00078 
00079   VMDApp *app = (VMDApp *)cd;
00080 
00081   if (argc < 2) {
00082     Tcl_SetResult(interp,
00083       (char *)
00084       "label add [Atoms|Bonds|Angles|Dihedrals] {atoms as <molid>/<atomid>}\n"
00085       "label addspring <molid> <atomid> <atomid> <k>\n"
00086       "label list              -- return label categories\n"
00087       "label list <category>   -- return id's of labels in given category\n"
00088       "label [show|hide|delete] <category> [index] -- \n\tControl specific label or all labels in category\n"
00089       "label graph <category> <index> -- Return a list of values for the given label\n\tfor all animation frames\n"
00090       "label textsize [<newsize>]\n"
00091       "label textthickness [<newthick>]\n" ,
00092       TCL_STATIC);
00093     return TCL_ERROR;
00094   }
00095   if(!strupncmp(argv[1], "add", CMDLEN)) {
00096     if(argc > 3) {
00097       int n = argc-3;
00098       const char **items = argv+3; 
00099       int *molid= new int[n];
00100       int *atmid = new int[n];
00101       int i;
00102       for(i=0; i < n; i++) {
00103         if (find_atom_from_name(interp, items[i], molid+i, atmid+i))
00104           break;
00105       }
00106       int rc = -1;
00107       if(i == n) {  // all successfully parsed
00108         rc = app->label_add(argv[2], argc-3, molid, atmid, NULL, 0.0f, 1);
00109       }
00110       delete [] molid;
00111       delete [] atmid;
00112       if (rc < 0) {
00113         Tcl_AppendResult(interp, "\nUnable to add label.", NULL);
00114         return TCL_ERROR;
00115       }
00116     }
00117     else
00118       return TCL_ERROR;
00119 
00120   }
00121   else if(!strupncmp(argv[1],"addspring",CMDLEN)) { /* add a spring */
00122     if(argc != 6) {
00123       Tcl_AppendResult(interp, "usage: label addspring <molid> <atomid> <atomid> <k>", NULL);
00124       return TCL_ERROR;
00125     }
00126     int molid[2];
00127     int atomid[2];
00128     float k;
00129     sscanf(argv[2],"%d",molid); /* convert all of the args to numbers */
00130     sscanf(argv[3],"%d",atomid);
00131     sscanf(argv[4],"%d",atomid+1);
00132     sscanf(argv[5],"%f",&k);
00133     molid[1]=molid[0];
00134     if (app->label_add("Springs", 2, molid, atomid, NULL, k, 1) < 0) {
00135       Tcl_AppendResult(interp, "Unable to add spring.", NULL);
00136       return TCL_ERROR;
00137     }
00138   }
00139   else if(!strupncmp(argv[1], "list", CMDLEN)) {
00140     if(argc == 3) {
00141       int cat =  app->geometryList->geom_list_index(argv[2]);
00142       if (cat < 0) {
00143         Tcl_AppendResult(interp, "graph list category '", argv[2], 
00144                          "' was not found", NULL);
00145         return TCL_ERROR;
00146       }
00147       // go through the list by hand
00148       GeomListPtr glist = app->geometryList->geom_list(cat);
00149       int gnum = glist->num();
00150       char s[30];
00151       GeometryMol *g;
00152       for (int i=0; i<gnum; i++) {
00153         g = (*glist)[i];
00154         Tcl_AppendResult(interp, i==0 ? "" : " ",   "{", NULL);
00155         for (int j=0; j<g->items(); j++) {
00156           // append the molecule id/atom index
00157           sprintf(s, "%d %d", g -> obj_index(j), g -> com_index(j));
00158           Tcl_AppendElement(interp, s);
00159         }
00160         // and the value and the status
00161         sprintf(s, "%f", g->ok() ? g->calculate() : 0.0);
00162         Tcl_AppendElement(interp, s);
00163         Tcl_AppendElement(interp, g -> displayed() ?  "show" : "hide");
00164         Tcl_AppendResult(interp, "}", NULL);
00165       }
00166       return TCL_OK;
00167     }
00168     else if (argc == 2) {
00169       // return the main categories
00170       for (int i=0; i<app->geometryList -> num_lists(); i++) {
00171         Tcl_AppendElement(interp,  app->geometryList -> geom_list_name(i));
00172       }
00173       return TCL_OK;
00174     } else
00175       return TCL_ERROR;
00176 
00177   } else if(!strupncmp(argv[1], "show", CMDLEN) ||
00178             !strupncmp(argv[1], "hide", CMDLEN)) {
00179     int item;
00180     if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN)))
00181       item = (-1);
00182     else if(argc == 4) {
00183       if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00184           Tcl_AppendResult(interp, " in label ", argv[1],  NULL);
00185           return TCL_ERROR;
00186       }
00187     } else
00188       return TCL_ERROR;
00189     
00190     app->label_show(argv[2], item, !strupncmp(argv[1], "show", CMDLEN));
00191     // XXX check return code
00192 
00193   } else if(!strupncmp(argv[1], "delete", CMDLEN)) {
00194     int item;
00195     if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN))) {
00196       item = (-1);
00197     } else if(argc == 4) {
00198       if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00199               Tcl_AppendResult(interp, " in label ", argv[1],  NULL);
00200               return TCL_ERROR;
00201       }
00202     } else {
00203       return TCL_ERROR;
00204     } 
00205 
00206     app->label_delete(argv[2], item);
00207     // XXX check return code
00208 
00209   } else if(!strupncmp(argv[1], "graph", CMDLEN) && argc > 3) {
00210     int item;
00211     if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00212       return TCL_ERROR;
00213     };
00214     // find the geometry
00215     int cat =  app->geometryList->geom_list_index(argv[2]);
00216     if (cat < 0) {
00217       Tcl_AppendResult(interp, "Invalid geometry type: ", argv[2], NULL);
00218       return TCL_ERROR;
00219     }
00220     // get the correct geometry pointer
00221     GeomListPtr glist = app->geometryList -> geom_list(cat);
00222     int gnum = glist -> num();
00223     if (item < 0 || item >= gnum) {
00224       char buf[512];
00225       sprintf(buf, "label %s index %d out of range", argv[2], item);
00226       Tcl_SetResult(interp, buf, TCL_VOLATILE);
00227       return TCL_ERROR;
00228     }
00229     // compute all the values
00230     GeometryMol *g = (*glist)[item];
00231     if (!g->has_value()) {
00232       Tcl_AppendResult(interp, "Geometry type ", argv[2], " has no values to graph.", NULL);
00233       return TCL_ERROR;
00234     }
00235     ResizeArray<float> gValues(1024);
00236     if (!g->calculate_all(gValues)) {
00237       Tcl_AppendResult(interp, "label has no value", NULL);
00238       return TCL_ERROR;
00239     }
00240     if (argc > 4) {
00241       // save the values in the given filename
00242       const char *filename = argv[4];
00243       FILE *outfile = fopen(filename, "w");
00244       if (!outfile) {
00245         Tcl_AppendResult(interp, "Cannot write graph data to file ",
00246           filename, NULL);
00247         return TCL_ERROR;
00248       }
00249       for (int i=0; i<gValues.num(); i++) {
00250         fprintf(outfile, "%f  %f\n", float(i), gValues[i]);
00251       }
00252       fclose(outfile);
00253     } else {
00254       char s[20];
00255             for (int count = 0; count < gValues.num(); count++) {
00256               sprintf(s, "%f", gValues[count]);
00257               Tcl_AppendElement(interp, s);
00258             }
00259     }
00260   } else if (!strupncmp(argv[1], "textsize", CMDLEN)) {
00261     if (argc == 2) {
00262       // return the current size
00263       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(app->label_get_text_size()));
00264       return TCL_OK;
00265     } else if (argc == 3) {
00266       // set new size
00267       double newsize = 1;
00268       if (Tcl_GetDouble(interp, argv[2], &newsize) != TCL_OK)
00269         return TCL_ERROR;
00270       if (!app->label_set_text_size((float) newsize)) {
00271         Tcl_AppendResult(interp, "label textsize: Unable to set size to ",
00272             argv[2], NULL);
00273         return TCL_ERROR;
00274       }
00275     } else {
00276       Tcl_SetResult(interp, (char *) "label textsize: wrong number of arguments",
00277           TCL_STATIC);
00278       return TCL_ERROR;
00279     }
00280   } else if (!strupncmp(argv[1], "textthickness", CMDLEN)) {
00281     if (argc == 2) {
00282       // return the current thickness
00283       Tcl_SetObjResult(interp, Tcl_NewDoubleObj(app->label_get_text_thickness()));
00284       return TCL_OK;
00285     } else if (argc == 3) {
00286       // set new size
00287       double newthick = 1;
00288       if (Tcl_GetDouble(interp, argv[2], &newthick) != TCL_OK)
00289         return TCL_ERROR;
00290       if (!app->label_set_text_thickness((float) newthick)) {
00291         Tcl_AppendResult(interp, "label textthickness: Unable to set thickness to ", argv[2], NULL);
00292         return TCL_ERROR;
00293       }
00294     } else {
00295       Tcl_SetResult(interp, (char *) "label textthickness: wrong number of arguments",
00296           TCL_STATIC);
00297       return TCL_ERROR;
00298     }
00299   } else if (!strupncmp(argv[1], "textoffset", CMDLEN)) {
00300     if (argc == 4) {
00301       // return current offset;
00302       const char *geomtype = argv[2];
00303       int geom;
00304       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00305       const float *offset = app->geometryList->getTextOffset(geomtype, geom);
00306       if (!offset) {
00307         Tcl_SetResult(interp, (char *) "label textoffset: Invalid geometry specified", TCL_STATIC);
00308         return TCL_ERROR;
00309       }
00310       Tcl_Obj *result = Tcl_NewListObj(0, NULL);
00311       Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[0]));
00312       Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[1]));
00313       Tcl_SetObjResult(interp, result);
00314     } else if (argc == 5) {
00315       const char *geomtype = argv[2];
00316       int geom;
00317       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00318       float x, y;
00319       if (sscanf(argv[4], "%f %f", &x, &y) != 2) {
00320         Tcl_AppendResult(interp, "Could not understand argument to label textoffset:", argv[2], NULL);
00321         return TCL_ERROR;
00322       }
00323       if (!app->label_set_textoffset(geomtype, geom, x, y)) {
00324         Tcl_SetResult(interp, (char *) "label textoffset: Invalid geometry specified", TCL_STATIC);
00325         return TCL_ERROR;
00326       }
00327     } else {
00328       Tcl_SetResult(interp, (char *) "label textoffset: wrong number of arguments",
00329           TCL_STATIC);
00330       return TCL_ERROR;
00331     }
00332   } else if (!strupncmp(argv[1], "textformat", CMDLEN)) {
00333     if (argc == 4) {
00334       // return current format
00335       const char *geomtype = argv[2];
00336       int geom;
00337       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00338       const char *format = app->geometryList->getTextFormat(geomtype, geom);
00339       if (!format) {
00340         Tcl_SetResult(interp, (char *) "label textformat: Invalid geometry specified", TCL_STATIC);
00341         return TCL_ERROR;
00342       }
00343       Tcl_SetResult(interp, (char *)format, TCL_VOLATILE);
00344     } else if (argc == 5) {
00345       const char *geomtype = argv[2];
00346       int geom;
00347       if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00348       if (!app->label_set_textformat(geomtype, geom, argv[4])) {
00349         Tcl_SetResult(interp, (char *) "label textformat failed.", TCL_STATIC);
00350         return TCL_ERROR;
00351       }
00352     } else {
00353       Tcl_SetResult(interp, (char *) "label textformat: wrong number of arguments",
00354                     TCL_STATIC);
00355       return TCL_ERROR;
00356     }
00357   }
00358   return TCL_OK;
00359 }

Generated on Fri Nov 8 02:43:58 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002