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: VMDTkMenu.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.20 $ $Date: 2019年01月17日 21:21:02 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * Class to manage Tk extension menus registered by the user. 00019 ***************************************************************************/ 00020 00021 #include "VMDTkMenu.h" 00022 #include "utilities.h" 00023 #include "JString.h" 00024 #include "Inform.h" 00025 00026 VMDTkMenu::VMDTkMenu(const char *menuname, const char *pathname, 00027 VMDApp *vmdapp, Tcl_Interp *tclinterp) 00028 : VMDMenu(menuname, vmdapp) { 00029 00030 interp = tclinterp; 00031 windowProc = NULL; 00032 path = NULL; 00033 if (pathname) { 00034 path = stringdup(pathname); // allocated via new [] 00035 create_window(); 00036 } 00037 } 00038 00039 void VMDTkMenu::create_window() { 00040 // register creation of this window. Gives the callback function a 00041 // chance to configure window manager options for this window so it 00042 // behaves well. 00043 JString buf("vmd_tkmenu_cb "); 00044 buf += path; 00045 buf += " create "; 00046 buf += get_name(); 00047 if (Tcl_Eval(interp, (char *)(const char *)buf) != TCL_OK) { 00048 msgErr << "Error creating Tk extension window " << get_name() << sendmsg; 00049 msgErr << Tcl_GetStringResult(interp) << sendmsg; 00050 } 00051 } 00052 00053 int VMDTkMenu::register_proc(const char *proc) { 00054 if (!proc) return FALSE; 00055 delete [] windowProc; 00056 windowProc = stringdup(proc); 00057 return TRUE; 00058 } 00059 00060 VMDTkMenu::~VMDTkMenu() { 00061 if (path) { 00062 JString buf("vmd_tkmenu_cb "); 00063 buf += path; 00064 buf += " remove"; 00065 Tcl_Eval(interp, (char *)(const char *)buf); 00066 delete [] path; // must be freed with delete [] 00067 } 00068 00069 delete [] windowProc; 00070 } 00071 00072 void VMDTkMenu::do_on() { 00073 if (!path) { 00074 // try to get the window handle from the windowProc 00075 if (!windowProc) { 00076 return; 00077 } 00078 if (Tcl_Eval(interp, windowProc) != TCL_OK) { 00079 msgErr << "Creation of window for '" << get_name() << "' failed (" 00080 << Tcl_GetStringResult(interp) << ")." << sendmsg; 00081 delete [] windowProc; 00082 windowProc = NULL; 00083 return; 00084 } 00085 path = stringdup(Tcl_GetStringResult(interp)); 00086 create_window(); 00087 } 00088 JString buf("vmd_tkmenu_cb "); 00089 buf += path; 00090 buf += " on"; 00091 Tcl_Eval(interp, (char *)(const char *)buf); 00092 } 00093 00094 void VMDTkMenu::do_off() { 00095 if (!path) return; 00096 JString buf("vmd_tkmenu_cb "); 00097 buf += path; 00098 buf += " off"; 00099 Tcl_Eval(interp, (char *)(const char *)buf); 00100 } 00101 00102 void VMDTkMenu::move(int x, int y) { 00103 if (!path) return; 00104 char numbuf[20]; 00105 sprintf(numbuf, "%d %d", x, y); 00106 JString buf("vmd_tkmenu_cb "); 00107 buf += path; 00108 buf += " move "; 00109 buf += numbuf; 00110 Tcl_Eval(interp, (char *)(const char *)buf); 00111 } 00112 00113 void VMDTkMenu::where(int &x, int &y) { 00114 if (!path) { x=y=0; return; } 00115 JString buf("vmd_tkmenu_cb "); 00116 buf += path; 00117 buf += " loc"; 00118 Tcl_Eval(interp, (char *)(const char *)buf); 00119 Tcl_Obj *result = Tcl_GetObjResult(interp); 00120 int objc; 00121 Tcl_Obj **objv; 00122 if (Tcl_ListObjGetElements(interp, result, &objc, &objv) != TCL_OK || 00123 objc != 2 || 00124 Tcl_GetIntFromObj(interp, objv[0], &x) || 00125 Tcl_GetIntFromObj(interp, objv[1], &y)) { 00126 x = y = 0; 00127 } 00128 } 00129