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

SelectionBuilder.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: SelectionBuilder.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.30 $ $Date: 2019年01月17日 21:21:01 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * generated by Fast Light User Interface Designer (fluid) version 1.0011
00019 ***************************************************************************/
00020 
00021 #include "SelectionBuilder.h"
00022 #include "Molecule.h"
00023 #include "SymbolTable.h"
00024 #include "ParseTree.h"
00025 #include "FL/Fl.H"
00026 #include "FL/forms.H"
00027 
00028 extern "C" int vmd_int_compare(const void *x, const void *y) {
00029 return *((const int *) x) - *((const int *) y);
00030 }
00031 
00032 extern "C" int vmd_double_compare(const void *x, const void *y) {
00033 double delta = *((const double *) x) - *((const double *) y);
00034 if (delta < 0) {
00035 return -1;
00036 }
00037 if (delta == 0) {
00038 return 0;
00039 }
00040 return 1;
00041 }
00042 
00043 extern "C" int vmd_string_compare(const void *x, const void *y) {
00044 return strcmp( *((const char **) x), *((const char **) y));
00045 }
00046 
00047 static void vmdsort_int(int *intlist, int num) {
00048 qsort(intlist, num, sizeof(int), vmd_int_compare);
00049 }
00050 
00051 static void vmdsort_double(double *dlist, int num) {
00052 qsort(dlist, num, sizeof(double), vmd_double_compare);
00053 }
00054 
00055 static void vmdsort_string(const char **jlist, int num) {
00056 qsort(jlist, num, sizeof(const char *), vmd_string_compare);
00057 }
00058 
00059 
00060 SelectionBuilder::SelectionBuilder(int xpos, int ypos, GraphicsFltkMenu *m, 
00061 Fl_Input *input, SymbolTable *sym) 
00062 : Fl_Group(xpos, ypos, 300, 330, "Selections") 
00063 {
00064 menu = m;
00065 selectiontext = input;
00066 mol = NULL;
00067 table = sym;
00068 goto_end = 0;
00069 
00070 applybutton = new Fl_Button(xpos+215, ypos+60, 70, 25, "Apply");
00071 #if defined(VMDMENU_WINDOW)
00072 applybutton->color(VMDMENU_WINDOW, FL_GRAY);
00073 #endif
00074 applybutton->callback(apply_cb, this);
00075 
00076 resetbutton = new Fl_Button(xpos+215, ypos+85, 70, 25, "Reset");
00077 #if defined(VMDMENU_WINDOW)
00078 resetbutton->color(VMDMENU_WINDOW, FL_GRAY);
00079 #endif
00080 resetbutton->callback(reset_cb, this);
00081 { Fl_Browser* o = keywordbrowser = new Fl_Hold_Browser(xpos+15, ypos+180, 135, 150, "Keyword");
00082 o->color(VMDMENU_BROWSER_BG);
00083 o->selection_color(VMDMENU_BROWSER_SEL);
00084 o->align(FL_ALIGN_TOP);
00085 o->callback(keyword_cb, this);
00086 }
00087 { Fl_Browser* o = valuebrowser = new Fl_Hold_Browser(xpos+165, ypos+180, 135, 150, "Value");
00088 o->color(VMDMENU_BROWSER_BG);
00089 o->selection_color(VMDMENU_BROWSER_SEL);
00090 o->align(FL_ALIGN_TOP);
00091 o->callback(value_cb, this);
00092 }
00093 andbutton = new Fl_Button(xpos+205, ypos+25, 35, 25, "and");
00094 #if defined(VMDMENU_WINDOW)
00095 andbutton->color(VMDMENU_WINDOW, FL_GRAY);
00096 #endif
00097 andbutton->callback(and_cb, this);
00098 orbutton = new Fl_Button(xpos+240, ypos+25, 25, 25, "or");
00099 #if defined(VMDMENU_WINDOW)
00100 orbutton->color(VMDMENU_WINDOW, FL_GRAY);
00101 #endif
00102 orbutton->callback(or_cb, this);
00103 notbutton = new Fl_Button(xpos+265, ypos+25, 35, 25, "not");
00104 #if defined(VMDMENU_WINDOW)
00105 notbutton->color(VMDMENU_WINDOW, FL_GRAY);
00106 #endif
00107 notbutton->callback(not_cb, this);
00108 macrobrowser = new Fl_Hold_Browser(xpos+15, ypos+25, 180, 85, "Singlewords");
00109 macrobrowser->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
00110 macrobrowser->align(FL_ALIGN_TOP);
00111 macrobrowser->callback(macrobrowser_cb, this);
00112 
00113 macrooutput = new Fl_Output(xpos+15, ypos+130, 285, 25, "Macro definition:");
00114 macrooutput->align(FL_ALIGN_TOP | FL_ALIGN_LEFT);
00115 macrooutput->selection_color(VMDMENU_VALUE_SEL);
00116 // leave deactivated until it's possible to edit macros from the GUI
00117 macrooutput->deactivate();
00118 end();
00119 
00120 for (int i=0; i<table->fctns.num(); i++) {
00121 if (table->fctns.data(i)->is_a == SymbolTableElement::KEYWORD)
00122 keywordbrowser->add(table->fctns.name(i));
00123 }
00124 }
00125 
00126 void SelectionBuilder::update_macrobrowser() {
00127 macrobrowser->clear();
00128 for (int i=0; i<table->fctns.num(); i++) {
00129 if (table->fctns.data(i)->is_a == SymbolTableElement::SINGLEWORD) {
00130 const char *name = table->fctns.name(i);
00131 // macros are never removed, just renamed to ""
00132 if (!strlen(name)) continue;
00133 const char *macro = table->get_custom_singleword(name);
00134 if (macro) {
00135 macrobrowser->add(name);
00136 // XXX add to text input
00137 } else {
00138 JString buf("@i");
00139 buf += name;
00140 macrobrowser->add((const char *)buf);
00141 }
00142 } 
00143 } 
00144 }
00145 
00146 void SelectionBuilder::and_cb(Fl_Widget *, void *v) {
00147 SelectionBuilder *palette = (SelectionBuilder *)v;
00148 palette->append_text("and ");
00149 }
00150 
00151 void SelectionBuilder::or_cb(Fl_Widget *, void *v) {
00152 SelectionBuilder *palette = (SelectionBuilder *)v;
00153 palette->append_text("or ");
00154 }
00155 
00156 void SelectionBuilder::not_cb(Fl_Widget *, void *v) {
00157 SelectionBuilder *palette = (SelectionBuilder *)v;
00158 palette->append_text("not ");
00159 }
00160 
00161 void SelectionBuilder::apply_cb(Fl_Widget *, void *v) {
00162 SelectionBuilder *palette = (SelectionBuilder *)v;
00163 // Try to parse the text now, to make sure it's valid. Parsing should
00164 // be very fast, not nearly so slow as actually finding the atoms.
00165 const char *seltext = palette->selectiontext->value();
00166 ParseTree *tree = palette->table->parse(seltext);
00167 if (tree) {
00168 delete tree;
00169 palette->menu->update_selection(seltext);
00170 } else {
00171 fl_message("Unable to parse this atom selection.");
00172 }
00173 }
00174 
00175 void SelectionBuilder::reset_cb(Fl_Widget *, void *v) {
00176 SelectionBuilder *palette = (SelectionBuilder *)v;
00177 palette->menu->update_selection(NULL);
00178 }
00179 
00180 void SelectionBuilder::macrobrowser_cb(Fl_Widget *, void *v) {
00181 SelectionBuilder *self = (SelectionBuilder *)v;
00182 
00183 int line = self->macrobrowser->value();
00184 if (!line) {
00185 self->macrooutput->value(NULL);
00186 return;
00187 }
00188 const char *name = self->macrobrowser->text(line);
00189 const char *macro = self->table->get_custom_singleword(name);
00190 if (macro) {
00191 // leave deactivated until it's possible to edit macros from the GUI
00192 //self->macrooutput->activate();
00193 self->macrooutput->value(macro);
00194 } else {
00195 self->macrooutput->value(name+2); // offset by two because of italics
00196 // leave deactivated until it's possible to edit macros from the GUI
00197 //self->macrooutput->deactivate();
00198 }
00199 
00200 if (Fl::event_clicks()) {
00201 JString buf(self->macrooutput->value());
00202 buf += " ";
00203 self->append_text((const char *)buf);
00204 Fl::event_clicks(-1);
00205 }
00206 }
00207 
00208 void SelectionBuilder::value_cb(Fl_Widget *, void *v) {
00209 SelectionBuilder *palette = (SelectionBuilder *)v;
00210 if (Fl::event_clicks()) {
00211 int line = palette->valuebrowser->value();
00212 if (!line) return;
00213 JString buf(palette->valuebrowser->text(line));
00214 buf += " ";
00215 //palette->selectiontext->value((const char *)buf); 
00216 palette->append_text((const char *)buf); 
00217 Fl::event_clicks(-1);
00218 }
00219 }
00220 
00221 void SelectionBuilder::keyword_cb(Fl_Widget *, void *v) {
00222 SelectionBuilder *palette = (SelectionBuilder *)v;
00223 if (Fl::event_clicks()) {
00224 // add keyword to selection text
00225 int line = palette->keywordbrowser->value();
00226 if (!line) return;
00227 JString buf(
00228 palette->keywordbrowser->text(line));
00229 buf += " ";
00230 palette->append_text(buf);
00231 Fl::event_clicks(-1);
00232 return;
00233 } 
00234 // just update the value browser
00235 palette->valuebrowser->clear();
00236 
00237 // get current name list selection, and check for a category with names
00238 const char *keyword = palette->keywordbrowser->text(
00239 palette->keywordbrowser->value());
00240 int list = palette->table->fctns.typecode(keyword);
00241 
00242 // only if a list has been selected, and is useful one, do we enter names
00243 // also, only need to fill browser if there is a molecule currently 
00244 if(palette->mol && list >= 0 && list < palette->table->fctns.num()) {
00245 // tell the atom selection commands to use the current molecule to 
00246 // get the required information. The current frame doesn't matter for
00247 // our purposes here, so just use -1 (which means the current frame)
00248 // Since we're looking only at keywords, not singlewords, macro is NULL.
00249 atomsel_ctxt context(palette->table, palette->mol, -1, NULL);
00250 
00251 // get all the info from the item in the table
00252 // first see what it does
00253 SymbolTableElement *info = palette->table->fctns.data(list);
00254 // the only one that shows anything are the KEYWORDs
00255 if (info -> is_a == SymbolTableElement::KEYWORD) {
00256 int num = palette->mol->nAtoms;
00257 int *flgs = new int[num];
00258 int i;
00259 for (i=0; i<num; i++) {
00260 flgs[i] = 1;
00261 }
00262 
00263 // initialize a hash table for finding the unique entries
00264 hash_t hash;
00265 hash_init(&hash, num);
00266 
00267 // get the the into an array whose type matches the type of the
00268 // data. That way we don't convert to string until the end 
00269 switch(info -> returns_a) { 
00270 case (SymbolTableElement::IS_INT):
00271 {
00272 int *data = new int[num];
00273 JString *strdata = new JString[num];
00274 info->keyword_int(&context, num, data, flgs);
00275 vmdsort_int(data, num);
00276 for (i=0; i<num; i++) {
00277 char buf[40];
00278 sprintf(buf, "%d", data[i]);
00279 strdata[i] = buf;
00280 if (hash_insert(&hash, (const char *)strdata[i], 0) == HASH_FAIL)
00281 palette->valuebrowser->add(buf);
00282 }
00283 delete [] data;
00284 delete [] strdata;
00285 break; 
00286 }
00287 case (SymbolTableElement::IS_FLOAT):
00288 {
00289 double *data = new double[num];
00290 JString *strdata = new JString[num];
00291 info->keyword_double(&context, num, data, flgs);
00292 vmdsort_double(data, num);
00293 for (i=0; i<num; i++) {
00294 char buf[40];
00295 float tmp = (float)data[i];
00296 sprintf(buf, "%f", tmp);
00297 strdata[i] = buf;
00298 if (hash_insert(&hash, (const char *)strdata[i], 0) == HASH_FAIL)
00299 palette->valuebrowser->add(buf);
00300 }
00301 delete [] data;
00302 delete [] strdata;
00303 break;
00304 }
00305 case (SymbolTableElement::IS_STRING):
00306 {
00307 const char **data = new const char *[num];
00308 const char **hashdata = new const char *[num];
00309 int j=0;
00310 
00311 // XXX crashes can occur here when only coords are loaded
00312 // and "structure" is displayed in the selection builder.
00313 info->keyword_string(&context, num, data, flgs);
00314 
00315 for (i=0; i<num; i++) {
00316 // XXX prevent crashes when no atom names are available
00317 if (data[i] != NULL) {
00318 if (hash_insert(&hash, data[i], 0) == HASH_FAIL)
00319 hashdata[j++] = data[i];
00320 } 
00321 }
00322 
00323 vmdsort_string(hashdata, j);
00324 for (i=0; i<j; i++) {
00325 palette->valuebrowser->add(hashdata[i]);
00326 }
00327 delete [] data;
00328 delete [] hashdata;
00329 }
00330 default: ;
00331 }
00332 hash_destroy(&hash);
00333 delete [] flgs;
00334 }
00335 }
00336 }
00337 
00338 void SelectionBuilder::append_text(const char *s) {
00339 // If there's selected text, replace it. Otherwise, just append at the end
00340 selectiontext->replace(selectiontext->position(), selectiontext->mark(), s);
00341 
00342 if (goto_end) {
00343 selectiontext->position(selectiontext->size());
00344 goto_end = 0;
00345 }
00346 }
00347 
00348 void SelectionBuilder::use_molecule(Molecule *m) {
00349 mol = m;
00350 keyword_cb(keywordbrowser, this);
00351 }
00352 
00353 void SelectionBuilder::set_selection(const char *s) {
00354 selectiontext->value(s);
00355 selectiontext->position(selectiontext->size());
00356 }

Generated on Tue Nov 18 02:48:05 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /