00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tcl.h>
00022 #include <stdlib.h>
00023 #include "VMDApp.h"
00024 #include "TclCommands.h"
00025 #include "config.h"
00026
00027 int text_cmd_color(ClientData cd, Tcl_Interp *interp, int argc, const char *argv[]) {
00028
00029 VMDApp *app = (VMDApp *)cd;
00030
00031 if (argc < 2) {
00032
00033 Tcl_SetResult(interp,
00034 (char *)
00035 "color change rgb <color> [<grayscale> | <r g b>]\n"
00036 " (when no value is specified, the color is reset to its default value)\n"
00037 "color scale [method|midpoint|min|max] <value>\n"
00038 "color scale colors <method> [<mincolor> <midcolor> <maxcolor>]\n"
00039 "color <category> <name> [new color]",
00040 TCL_STATIC);
00041 return TCL_ERROR;
00042 }
00043
00044 if (!strupncmp(argv[1], "change", CMDLEN) && argc > 3) {
00045 if (!strupncmp(argv[2], "rgb", CMDLEN)) {
00046 float r = 0.5, g = 0.5, b = 0.5;
00047 if (app->color_index(argv[3]) < 0) {
00048 Tcl_SetResult(interp, (char *) "color change: invalid color specified", TCL_STATIC);
00049 return TCL_ERROR;
00050 }
00051 if (argc == 4) {
00052
00053 if (!app->color_default_value(argv[3], &r, &g, &b)) {
00054 Tcl_SetResult(interp, (char *) "Unable to get default values for color", TCL_STATIC);
00055 return TCL_ERROR;
00056 }
00057 app->color_change_rgb(argv[3], r, g, b);
00058 return TCL_OK;
00059 } else {
00060 double rr;
00061 if (Tcl_GetDouble(interp, argv[4], &rr) != TCL_OK) {
00062 Tcl_AppendResult(interp, " in color change", NULL);
00063 return TCL_ERROR;
00064 }
00065 r = (float) rr;
00066 if (argc == 5) {
00067 if (!app->color_change_rgb(argv[3], r, r, r)) {
00068 Tcl_SetResult(interp, (char *) "Unable to change color", TCL_STATIC);
00069 return TCL_ERROR;
00070 }
00071 } else if (argc == 7) {
00072 double gg, bb;
00073 if (Tcl_GetDouble(interp, argv[5], &gg) != TCL_OK ||
00074 Tcl_GetDouble(interp, argv[6], &bb) != TCL_OK) {
00075 Tcl_AppendResult(interp, " in color change", NULL);
00076 return TCL_ERROR;
00077 }
00078 g = (float) gg;
00079 b = (float) bb;
00080 if (!app->color_change_rgb(argv[3], r, g, b)) {
00081 Tcl_SetResult(interp, (char *) "Unable to change color", TCL_STATIC);
00082 return TCL_ERROR;
00083 }
00084 } else {
00085 Tcl_SetResult(interp, (char *) "color change needs 1 (or 3) parameters", TCL_STATIC);
00086 return TCL_ERROR;
00087 }
00088 return TCL_OK;
00089 }
00090 } else if (!strupncmp(argv[2], "rgblist", CMDLEN)) {
00091 const char **colcmds;
00092 int i, num_colcmds;
00093 if (Tcl_SplitList(interp, argv[3], &num_colcmds, &colcmds) != TCL_OK) {
00094 Tcl_AppendResult(interp, "cannot split color command name list", NULL);
00095 return TCL_ERROR;
00096 }
00097
00098 char **colnames=(char **) calloc(1, num_colcmds * sizeof(char *));
00099 float *colors=(float *) calloc(1, num_colcmds * 3 * sizeof(float));
00100
00101 int fail=0;
00102 for (i=0; i<num_colcmds; i++) {
00103 char tmpbuf[1024];
00104 if (sscanf(colcmds[i], "%s %f %f %f", tmpbuf,
00105 &colors[i*3], &colors[i*3 + 1], &colors[i*3 + 2]) != 4) {
00106 fail=i;
00107 break;
00108 }
00109 colnames[i] = strdup(tmpbuf);
00110 }
00111
00112 if (!fail &&
00113 !app->color_change_rgblist(num_colcmds, (const char **) colnames, colors)) {
00114 Tcl_SetResult(interp, (char *) "Unable to change color namelist", TCL_STATIC);
00115 }
00116
00117 int freecnt=num_colcmds;
00118 if (fail)
00119 freecnt=fail;
00120
00121 for (i=0; i<freecnt; i++) {
00122 free(colnames[i]);
00123 }
00124 free(colnames);
00125
00126 if (colcmds)
00127 Tcl_Free((char *) colcmds);
00128
00129 if (fail) {
00130 Tcl_AppendResult(interp, "cannot split/copy color command name list", NULL);
00131 return TCL_ERROR;
00132 }
00133 } else if (!strupncmp(argv[2], "namelist", CMDLEN)) {
00134 const char **colcmds;
00135 int i, num_colcmds;
00136 if (Tcl_SplitList(interp, argv[3], &num_colcmds, &colcmds) != TCL_OK) {
00137 Tcl_AppendResult(interp, "cannot split color command name list", NULL);
00138 return TCL_ERROR;
00139 }
00140
00141 char **colcats=(char **) calloc(1, num_colcmds * sizeof(char *));
00142 char **colnames=(char **) calloc(1, num_colcmds * sizeof(char *));
00143 char **colors=(char **) calloc(1, num_colcmds * sizeof(char *));
00144
00145 int fail=0;
00146 for (i=0; i<num_colcmds; i++) {
00147 int cnt;
00148 const char **cmdparts;
00149 if (Tcl_SplitList(interp, colcmds[i], &cnt, &cmdparts) == TCL_OK) {
00150 if (cnt == 3) {
00151 colcats[i] = strdup(cmdparts[0]);
00152 colnames[i] = strdup(cmdparts[1]);
00153 colors[i] = strdup(cmdparts[2]);
00154 } else {
00155 fail=i;
00156 break;
00157 }
00158 Tcl_Free((char *) cmdparts);
00159 }
00160 }
00161
00162 if (!fail &&
00163 !app->color_change_namelist(num_colcmds, colcats, colnames, colors)) {
00164 Tcl_SetResult(interp, (char *) "Unable to change color namelist", TCL_STATIC);
00165 }
00166
00167 int freecnt=num_colcmds;
00168 if (fail)
00169 freecnt=fail;
00170
00171 for (i=0; i<freecnt; i++) {
00172 free(colcats[i]);
00173 free(colnames[i]);
00174 free(colors[i]);
00175 }
00176 free(colcats);
00177 free(colnames);
00178 free(colors);
00179
00180 if (colcmds)
00181 Tcl_Free((char *) colcmds);
00182
00183 if (fail) {
00184 Tcl_AppendResult(interp, "cannot split/copy color command name list", NULL);
00185 return TCL_ERROR;
00186 }
00187 }
00188 } else if (!strupncmp(argv[1], "scale", CMDLEN)) {
00190 if (argc >= 4 && !strupncmp(argv[2], "colors", CMDLEN)) {
00191 if (argc == 4) {
00192 int ind = app->colorscale_method_index(argv[3]);
00193 float vals[3][3];
00194 if (!app->get_colorscale_colors(ind, vals[0], vals[1], vals[2])) {
00195 Tcl_AppendResult(interp, "no colors available for method '", argv[3], "'.", NULL);
00196 return TCL_ERROR;
00197 }
00198 Tcl_Obj *result = Tcl_NewListObj(0,NULL);
00199 for (int i=0; i<3; i++) {
00200 Tcl_Obj *elem = Tcl_NewListObj(0, NULL);
00201 for (int j=0; j<3; j++) {
00202 Tcl_ListObjAppendElement(interp,elem,Tcl_NewDoubleObj(vals[i][j]));
00203 }
00204 Tcl_ListObjAppendElement(interp, result, elem);
00205 }
00206 Tcl_SetObjResult(interp, result);
00207 return TCL_OK;
00208 } else if (argc == 7) {
00209 int ind = app->colorscale_method_index(argv[3]);
00210 float vals[3][3];
00211 for (int i=0; i<3; i++) {
00212
00213 int rc = tcl_get_vector(argv[4+i], vals[i], interp);
00214 if (rc != TCL_OK) {
00215 if (!app->color_value(argv[4+i], vals[i]+0, vals[i]+1, vals[i]+2)) {
00216 return TCL_ERROR;
00217 }
00218
00219 Tcl_ResetResult(interp);
00220 }
00221 }
00222 if (!app->set_colorscale_colors(ind, vals[0], vals[1], vals[2])) {
00223 Tcl_AppendResult(interp, "Unable to set colorscale colors for method '", argv[3], "'.", NULL);
00224 return TCL_ERROR;
00225 }
00226 return TCL_OK;
00227 }
00228 }
00229 if (argc == 4) {
00230 if (!strupncmp(argv[2], "method", CMDLEN)) {
00231 int ind = app->colorscale_method_index(argv[3]);
00232 if (ind < 0) {
00233 char tmpstring[1024];
00234 sprintf(tmpstring, "color scale method '%s' not recognized", argv[3]);
00235 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00236 return TCL_ERROR;
00237 }
00238 app->colorscale_setmethod(ind);
00239 } else {
00240 float mid=0, min=0, max=0;
00241 int rev=0, posterize=0;
00242
00243 float newval = (float) atof(argv[3]);
00244 if (!strupncmp(argv[2], "midpoint", CMDLEN)) mid = newval;
00245 else if (!strupncmp(argv[2], "min", CMDLEN)) min = newval;
00246 else if (!strupncmp(argv[2], "max", CMDLEN)) max = newval;
00247 else if (!strupncmp(argv[2], "reverse", CMDLEN)) rev = atoi(argv[3]);
00248 else if (!strupncmp(argv[2], "posterize", CMDLEN)) {
00249 posterize = 0;
00250 if (!strupcmp(argv[3], "off")) {
00251 posterize = 0;
00252 } else {
00253 if (sscanf(argv[3], "%d", &posterize) != 1) {
00254 posterize = 0;
00255 }
00256 }
00257 }
00258 else {
00259 char tmpstring[1024];
00260 sprintf(tmpstring, "color scale option '%s' not recognized", argv[2]);
00261 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00262 return TCL_ERROR;
00263 }
00264 app->colorscale_setparams(mid, min, max, rev, posterize);
00265 }
00266 } else {
00267 Tcl_SetResult(interp, (char *) "color scale [method|midpoint|min|max] <value>", TCL_STATIC);
00268 return TCL_ERROR;
00269 }
00270 } else if ((argc == 3 || argc == 4) && !strupncmp(argv[1], "restype", CMDLEN)) {
00271 if (argc == 3) {
00272 const char *result = app->color_get_restype(argv[2]);
00273 if (!result) {
00274 Tcl_AppendResult(interp, "No restype for residue '", argv[2], "'",
00275 NULL);
00276 return TCL_ERROR;
00277 }
00278 Tcl_SetResult(interp, (char *)result, TCL_STATIC);
00279 } else {
00280 if (!app->color_set_restype(argv[2], argv[3])) {
00281 if (!app->color_change_name(argv[1], argv[2], argv[3])) {
00282 Tcl_AppendResult(interp, "Unable to set restype: invalid restype '",
00283 argv[3],
00284 "' specified -- or unable to change color name",
00285 NULL);
00286 return TCL_ERROR;
00287 }
00288 }
00289 }
00290 } else if(argc == 3) {
00291
00292 const char *colorname;
00293 if (app->color_get_from_name(argv[1], argv[2], &colorname)) {
00294 Tcl_SetResult(interp, (char*) colorname, TCL_STATIC);
00295 return TCL_OK;
00296 } else {
00297 Tcl_SetResult(interp, (char *) "Unable to get color name", TCL_STATIC);
00298 return TCL_ERROR;
00299 }
00300 } else if(argc == 4) {
00301 if (!app->color_change_name(argv[1], argv[2], argv[3])) {
00302 Tcl_SetResult(interp, (char *) "Unable to change color name", TCL_STATIC);
00303 return TCL_ERROR;
00304 }
00305 } else if (argc == 6 && !strupncmp(argv[1], "add", CMDLEN)
00306 && !strupncmp(argv[2], "item", CMDLEN)) {
00307 if (!app->color_add_item(argv[3], argv[4], argv[5])) {
00308 Tcl_SetResult(interp, (char *) "Error adding color item.", TCL_STATIC);
00309 return TCL_ERROR;
00310 }
00311 } else {
00312 return TCL_ERROR;
00313 }
00314
00315
00316 return TCL_OK;
00317 }
00318