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

py_menu.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 #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   // Check menu name actually exists
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   // If visible is not None, set visibility of window if (shownobj != Py_None)
00042   app->menu_show(name, PyObject_IsTrue(shownobj));
00043 
00044   // Return visibility status of window
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   // Check menu name actually exists
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   // If a new position is specified, move the menu
00079   if (x != -1 && y != -1)
00080     app->menu_move(name, x, y);
00081 
00082   // Return current menu location
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   // Create the menu
00107   VMDMenu *menu = new VMDTkinterMenu(name, root, app);
00108 
00109   // Try to add the menu to the root menu
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   // Check that the function is actually a callable
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   // Default for menupath is just being its own menu
00148   if (!menupath)
00149     menupath = name;
00150 
00151   // Make a new menu and try to add it to VMD
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   // Register the callback for the menu
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 

Generated on Fri Mar 29 02:46:04 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002