00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "py_commands.h"
00010 #include "VMDTkinterMenu.h"
00011 #include "VMDApp.h"
00012
00013 static const char show_doc[] =
00014 "Show or hide a registered window, or queries window visibility\n\n"
00015 "Args:\n"
00016 " name (str): Window name\n"
00017 " visible (bool): Whether or not window is visible, or None to query"
00018 "Returns:\n"
00019 " (bool): Updated visibility status of menu";
00020 static PyObject *py_menushow(PyObject *self, PyObject *args, PyObject *kwargs) {
00021 const char *kwlist[] = {"name", "visible", NULL};
00022 PyObject *shownobj = Py_None;
00023 PyObject *result;
00024 char *name;
00025
00026 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O!:menu.show",
00027 (char**) kwlist, &name,
00028 &PyBool_Type, &shownobj))
00029 return NULL;
00030
00031 VMDApp *app;
00032 if (!(app = get_vmdapp()))
00033 return NULL;
00034
00035
00036 if (app->menu_id(name) == -1) {
00037 PyErr_Format(PyExc_ValueError, "No such menu '%s' to show/hide", name);
00038 return NULL;
00039 }
00040
00041
00042 app->menu_show(name, PyObject_IsTrue(shownobj));
00043
00044
00045 result = app->menu_status(name) ? Py_True : Py_False;
00046 Py_INCREF(result);
00047 return result;
00048 }
00049
00050
00051 static const char loc_doc[] =
00052 "Sets or queries menu location\n\n"
00053 "Args:\n"
00054 " name (str): Menu name\n"
00055 " location (tuple of ints): (x,y) position to set menu location, or None\n"
00056 " to query current menu location\n"
00057 "Returns:\n"
00058 " (tuple of ints): (x, y) updated menu location";
00059 static PyObject* py_location(PyObject *self, PyObject *args, PyObject *kwargs) {
00060 const char *kwlist[] = {"name", "location", NULL};
00061 int x = -1, y = -1;
00062 char *name;
00063
00064 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|(ii):menu.location",
00065 (char**) kwlist, &name, &x, &y))
00066 return NULL;
00067
00068 VMDApp *app;
00069 if (!(app = get_vmdapp()))
00070 return NULL;
00071
00072
00073 if (app->menu_id(name) == -1) {
00074 PyErr_Format(PyExc_ValueError, "No such menu '%s' to set location", name);
00075 return NULL;
00076 }
00077
00078
00079 if (x != -1 && y != -1)
00080 app->menu_move(name, x, y);
00081
00082
00083 app->menu_location(name, x, y);
00084 return Py_BuildValue("(ii)", x, y);
00085 }
00086
00087
00088 static const char add_doc[] =
00089 "Add a new entry to a VMD menu\n\n"
00090 "Args:\n"
00091 " name (str): Name of new menu to add\n"
00092 " root (TKinter menu): Root menu to add this menu under\n";
00093 static PyObject* py_addmenu(PyObject *self, PyObject *args, PyObject *kwargs) {
00094 const char *kwlist[] = {"name", "root", NULL};
00095 PyObject *root;
00096 char *name;
00097
00098 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO:menu.add", (char**) kwlist,
00099 &name, &root))
00100 return NULL;
00101
00102 VMDApp *app;
00103 if (!(app = get_vmdapp()))
00104 return NULL;
00105
00106
00107 VMDMenu *menu = new VMDTkinterMenu(name, root, app);
00108
00109
00110 if (!app->add_menu(menu)) {
00111 delete menu;
00112 PyErr_Format(PyExc_ValueError, "Could not add menu '%s'", name);
00113 return NULL;
00114 }
00115 app->menu_add_extension(name,name);
00116
00117 Py_INCREF(Py_None);
00118 return Py_None;
00119 }
00120
00121
00122 static const char register_doc[] =
00123 "Add an item to a menu and register a function to be called when it is "
00124 "selected.\n\nArgs:\n"
00125 " name (str): Name of menu to add\n"
00126 " function (callable): Function to call when menu selected\n"
00127 " menupath (str): Path to add menu to, if it will be a submenu.\n"
00128 " Defaults to adding to the root menu";
00129 static PyObject* py_registermenu(PyObject *self, PyObject *args,
00130 PyObject *kwargs) {
00131 const char *kwlist[] = {"name", "function", "menupath", NULL};
00132 char *menupath = NULL;
00133 PyObject *func;
00134 char *name;
00135
00136 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|s:menu.register",
00137 (char**) kwlist, &name, &func, &menupath))
00138 return NULL;
00139
00140
00141 if (!PyCallable_Check(func)) {
00142 PyErr_Format(PyExc_ValueError, "function argument for menu '%s' must "
00143 "be callable", name);
00144 return NULL;
00145 }
00146
00147
00148 if (!menupath)
00149 menupath = name;
00150
00151
00152 VMDApp *app;
00153 if (!(app = get_vmdapp()))
00154 return NULL;
00155
00156 VMDTkinterMenu *menu = new VMDTkinterMenu(name, NULL, app);
00157 if (!app->add_menu(menu)) {
00158 delete menu;
00159 PyErr_Format(PyExc_ValueError, "Could not add menu '%s'", name);
00160 return NULL;
00161 }
00162
00163
00164 menu->register_windowproc(func);
00165 app->menu_add_extension(name,menupath);
00166
00167 Py_INCREF(Py_None);
00168 return Py_None;
00169 }
00170
00171
00172 static PyMethodDef methods[] = {
00173 {"add", (PyCFunction)py_addmenu, METH_VARARGS | METH_KEYWORDS, add_doc},
00174 {"register", (PyCFunction)py_registermenu, METH_VARARGS | METH_KEYWORDS, register_doc},
00175 {"show", (PyCFunction)py_menushow, METH_VARARGS | METH_KEYWORDS, show_doc},
00176 {"location", (PyCFunction)py_location, METH_VARARGS | METH_KEYWORDS, loc_doc},
00177 {NULL, NULL}
00178 };
00179
00180
00181 static const char menu_moddoc[] =
00182 "Methods to manipulate GUI menus";
00183
00184
00185 #if PY_MAJOR_VERSION >= 3
00186 static struct PyModuleDef menudef = {
00187 PyModuleDef_HEAD_INIT,
00188 "vmdmenu",
00189 menu_moddoc,
00190 -1,
00191 methods,
00192 };
00193 #endif
00194
00195
00196 PyObject* initvmdmenu(void) {
00197 #if PY_MAJOR_VERSION >= 3
00198 PyObject *m = PyModule_Create(&menudef);
00199 #else
00200 PyObject *m = Py_InitModule3("vmdmenu", methods, menu_moddoc);
00201 #endif
00202 return m;
00203 }
00204