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

VMDFltkMenu.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: VMDFltkMenu.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.29 $ $Date: 2019年01月17日 21:21:02 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * Class to manage FLTK menus within VMD.
00019 ***************************************************************************/
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 
00024 #include <FL/Fl.H>
00025 #include <FL/Fl_Choice.H>
00026 #include "VMDFltkMenu.h"
00027 #include "VMDApp.h"
00028 #include "utilities.h"
00029 
00030 void VMDFltkMenu::window_cb(Fl_Widget *w, void *) {
00031 VMDFltkMenu *m = (VMDFltkMenu *)w;
00032 m->app->menu_show(m->get_name(), 0);
00033 }
00034 
00035 
00036 VMDFltkMenu::VMDFltkMenu(const char *menuname,const char *title,VMDApp *vmdapp) 
00037 : VMDMenu(menuname, vmdapp), Fl_Window(0,0,NULL) {
00038 _title=stringdup(title);
00039 Fl_Window::label(_title);
00040 #if defined(VMDMENU_WINDOW)
00041 Fl_Window::color(VMDMENU_WINDOW);
00042 #endif
00043 callback(window_cb);
00044 }
00045 
00046 
00047 VMDFltkMenu::~VMDFltkMenu() {
00048 delete [] _title;
00049 }
00050 
00051 
00052 void VMDFltkMenu::do_on() {
00053 Fl_Window::show();
00054 }
00055 
00056 
00057 void VMDFltkMenu::do_off() {
00058 Fl_Window::hide();
00059 }
00060 
00061 
00062 void VMDFltkMenu::move(int x, int y) {
00063 Fl_Widget::position(x,y);
00064 }
00065 
00066 
00067 void VMDFltkMenu::where(int &x, int &y) {
00068 x = Fl_Widget::x();
00069 y = Fl_Widget::y();
00070 }
00071 
00072 
00073 void fill_fltk_molchooser(Fl_Choice *choice, VMDApp *app, 
00074 const char *extramenu) {
00075 int nummols = app->num_molecules();
00076 int has_extra = (extramenu == NULL) ? 0 : 1;
00077 int need_full_regen = 0;
00078 char buf[1024];
00079 
00080 // compute number of items in the menu, not counting the ending NULL marker.
00081 int menusz = choice->size() - 1;
00082 
00083 #if 1
00084 // Optimize the cases where the chooser must be regenerated:
00085 // If the chooser is empty, we need to regenerate.
00086 // If the chooser is larger than needed, we have to 
00087 // re-create it from scratch since some molecule was 
00088 // potentially deleted from the middle.
00089 // If the size remains fixed, then we need to regenerate
00090 // because we are getting called to rename an existing molecule or
00091 // to change its state.
00092 // If the size grows by exactly one, then we can just add the new
00093 // molecule, and we don't need to regen, otherwise we have to regen.
00094 if ((menusz <= has_extra) ||
00095 (menusz >= (nummols + has_extra)) || 
00096 ((nummols + has_extra) - menusz) > 1) {
00097 need_full_regen = 1;
00098 // printf("full regen: msz: %d sz: %d N: %d extra: %d\n", 
00099 // choice->size(), menusz, nummols, has_extra);
00100 } else {
00101 // printf("add-newmol: msz: %d sz: %d N: %d extra: %d\n", 
00102 // choice->size(), menusz, nummols, has_extra);
00103 }
00104 #else
00105 need_full_regen = 1;
00106 #endif
00107 
00108 // either update (add an item) or completely regenerate the chooser contents
00109 if (need_full_regen) {
00110 choice->clear();
00111 
00112 if (has_extra)
00113 choice->add(extramenu);
00114 
00115 for (int i=0; i<nummols; i++) {
00116 int id = app->molecule_id(i);
00117 const char *s = app->molecule_name(id); 
00118 
00119 // Truncate molecule name to first 25 chars...
00120 // We must ensure we never find menu items by name, or that we 
00121 // truncate the search string identically to the way we do it here.
00122 sprintf(buf, "%d: %-.25s%s", id, s, 
00123 app->molecule_is_displayed(id) ? "" : " (off)");
00124 
00125 // Fltk doesn't allow adding a menu item with the same name as
00126 // an existing item, so we use replace, which also avoids 
00127 // problems with the escape characters interpreted by add()
00128 int ind = choice->add("foobar");
00129 choice->replace(ind, buf);
00130 }
00131 } else {
00132 // we just need to add one new molecule...
00133 int i = nummols - 1;
00134 int id = app->molecule_id(i);
00135 const char *s = app->molecule_name(id); 
00136 
00137 // Truncate molecule name to first 25 chars...
00138 // We must ensure we never find menu items by name, or that we 
00139 // truncate the search string identically to the way we do it here.
00140 sprintf(buf, "%d: %-.25s%s", id, s, 
00141 app->molecule_is_displayed(id) ? "" : " (off)");
00142 
00143 // Fltk doesn't allow adding a menu item with the same name as
00144 // an existing item, so we use replace, which also avoids 
00145 // problems with the escape characters interpreted by add()
00146 int ind = choice->add("foobar");
00147 choice->replace(ind, buf);
00148 }
00149 }
00150 
00151 
00152 char * escape_fltk_menustring(const char * menustring) {
00153 char * newstr;
00154 int len = strlen(menustring);
00155 int i, j;
00156 
00157 // don't bother being precise, these are just menu strings, and they're
00158 // going to be freed immediately, so allocate largest possible memory block
00159 // we'll ever need (every char being escape) and avoid running through the
00160 // string twice to accurately count the number of escaped characters.
00161 newstr = (char *) malloc(((len * 2) + 1) * sizeof(char)); 
00162 if (newstr == NULL) 
00163 return NULL;
00164 
00165 i=0;
00166 j=0;
00167 while (menustring[i] != '0円') {
00168 // insert an escape character if necessary
00169 if (menustring[i] == '/' ||
00170 menustring[i] == '\\' ||
00171 menustring[i] == '_') {
00172 newstr[j] = '\\'; 
00173 j++;
00174 } else if (menustring[i] == '&') {
00175 // FLTK won't escape '&' characters for some reason, so I skip 'em
00176 i++;
00177 continue;
00178 }
00179 
00180 newstr[j] = menustring[i];
00181 i++;
00182 j++;
00183 } 
00184 newstr[j] = '0円'; // null terminate the string
00185 
00186 return newstr;
00187 }
00188 
00189 
00190 // Find the menu index with a name that matches the string.
00191 // Only checks leaf node menu names, not full pathnames currently
00192 static int find_menu_from_string(const char *namestr, const Fl_Menu *m) {
00193 // don't crash and burn on a NULL name or menu object
00194 if (namestr == NULL || m == NULL)
00195 return -1;
00196 
00197 // FLTK 1.1.7 XXX should do the same use the built-in
00198 // find_item() or item_pathname() routines to do the same work we do below
00199 
00200 // FLTK 1.1.4 -- only checks leaf node menu names, ignores full pathname
00201 // find leaf menu name from full menu path
00202 const char *nstr;
00203 if ((nstr = strrchr(namestr, '/')) == NULL)
00204 nstr = namestr;
00205 else
00206 nstr++;
00207 
00208 int i, val;
00209 for (val=-1, i=0; i<m->size()-1; i++) {
00210 const char *mstr = m[i].text;
00211 // compare leaf submenu item name against left color mode name
00212 if ((mstr != NULL) && (!strcmp(nstr, mstr))) {
00213 val=i;
00214 break;
00215 }
00216 }
00217 
00218 return val;
00219 }
00220 
00221 
00222 // Set the chooser to the menu name matching the given string.
00223 // Only checks the leaf node menu names, not full pathnames currently
00224 void set_chooser_from_string(const char *namestr, class Fl_Choice *chooser) {
00225 int m = find_menu_from_string(namestr, chooser->menu());
00226 
00227 // don't set the menu if we can't find the string
00228 if (m >= 0)
00229 chooser->value(m);
00230 }
00231 
00232 
00233 

Generated on Mon Nov 17 02:47:23 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

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