def _init_menubar(self): menubar = Menu(self._top) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Print to Postscript', underline=0, command=self._cframe.print_to_file, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) zoommenu = Menu(menubar, tearoff=0) zoommenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) zoommenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) zoommenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) zoommenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=28, command=self.resize) zoommenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=50, command=self.resize) menubar.add_cascade(label='Zoom', underline=0, menu=zoommenu) self._top.config(menu=menubar)
def _init_menu(self): """Init menu bar content. """ toplevel = self.winfo_toplevel() if toplevel['menu']: self._menu = self.nametowidget(name=toplevel['menu']) else: self._menu = Menu(toplevel) toplevel['menu'] = self._menu graph_options = Menu(self._menu, tearoff=0) self._menu.add_cascade(label="Graph", menu=graph_options) self._menu_index = self._menu.index("end") vertex_label_position_menu = Menu(graph_options, tearoff=0) graph_options.add_cascade(label="Label position", menu=vertex_label_position_menu) menu_var = self.winfo_name() + ".vertexlabelposition" vertex_label_position_menu.add_radiobutton(variable=menu_var, label="Auto", value="auto") vertex_label_position_menu.add_radiobutton(variable=menu_var, label="Center", value="center") graph_options.add_command(label="Save graph...", command=self.call_graph_save_dialog) self.bind("<Destroy>", self.__destroy_menu)
def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Exit", underline=1, command=self.destroy, accelerator="q") menubar.add_cascade(label="File", underline=0, menu=filemenu) actionmenu = Menu(menubar, tearoff=0) actionmenu.add_command(label="Next", underline=0, command=self.next, accelerator="n, Space") actionmenu.add_command(label="Previous", underline=0, command=self.prev, accelerator="p, Backspace") menubar.add_cascade(label="Action", underline=0, menu=actionmenu) optionmenu = Menu(menubar, tearoff=0) optionmenu.add_checkbutton( label="Remove Duplicates", underline=0, variable=self._glue.remove_duplicates, command=self._toggle_remove_duplicates, accelerator="r", ) menubar.add_cascade(label="Options", underline=0, menu=optionmenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_radiobutton(label="Tiny", variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label="Small", variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label="Medium", variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label="Large", variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label="Huge", variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label="View", underline=0, menu=viewmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", underline=0, command=self.about) menubar.add_cascade(label="Help", underline=0, menu=helpmenu) parent.config(menu=menubar)
def _init_menu(self): toplevel = self.winfo_toplevel() self._menu = Menu(toplevel) toplevel['menu'] = self._menu view = Menu(self._menu, tearoff=0) self._menu.add_cascade(label="View", menu=view) graph_view = Menu(view, tearoff=0) view.add_cascade(label="View graphs", menu=graph_view) graph_view.add_radiobutton(variable="graphframeview", label="Only one", value="onlyone") # graph_view.add_radiobutton(label="In a row", value="row", # variable=graph_view_var) graph_view.add_radiobutton(variable="graphframeview", label="In separate window", value="window")
def _init_menubar(self): menubar = Menu(self._top) filemenu = Menu(menubar, tearoff=0) filemenu.add_command( label="Print to Postscript", underline=0, command=self._cframe.print_to_file, accelerator="Ctrl-p" ) filemenu.add_command(label="Exit", underline=1, command=self.destroy, accelerator="Ctrl-x") menubar.add_cascade(label="File", underline=0, menu=filemenu) zoommenu = Menu(menubar, tearoff=0) zoommenu.add_radiobutton(label="Tiny", variable=self._size, underline=0, value=10, command=self.resize) zoommenu.add_radiobutton(label="Small", variable=self._size, underline=0, value=12, command=self.resize) zoommenu.add_radiobutton(label="Medium", variable=self._size, underline=0, value=14, command=self.resize) zoommenu.add_radiobutton(label="Large", variable=self._size, underline=0, value=28, command=self.resize) zoommenu.add_radiobutton(label="Huge", variable=self._size, underline=0, value=50, command=self.resize) menubar.add_cascade(label="Zoom", underline=0, menu=zoommenu) self._top.config(menu=menubar)
def build_selector_menu(self, choices, set_fxn, update_fxn=None, default=None): new_menu = Menu(self) choice_map = {} def build_selector_trace(var): def callback(*args): set_fxn(choice_map[var.get()]) if update_fxn: update_fxn() return callback if not default: default = choices[0] new_var = StringVar(new_menu) new_var.set(str(default)) new_var.trace('w', build_selector_trace(new_var)) for choice in choices: choice_map[str(choice)] = choice new_menu.add_radiobutton(label=str(choice).capitalize(), variable=new_var, value=str(choice)) return new_menu
def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='q') menubar.add_cascade(label='File', underline=0, menu=filemenu) actionmenu = Menu(menubar, tearoff=0) actionmenu.add_command(label='Next', underline=0, command=self.next, accelerator='n, Space') actionmenu.add_command(label='Previous', underline=0, command=self.prev, accelerator='p, Backspace') menubar.add_cascade(label='Action', underline=0, menu=actionmenu) optionmenu = Menu(menubar, tearoff=0) optionmenu.add_checkbutton(label='Remove Duplicates', underline=0, variable=self._glue.remove_duplicates, command=self._toggle_remove_duplicates, accelerator='r') menubar.add_cascade(label='Options', underline=0, menu=optionmenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar)
def add_menubar(self, parent): """ Add menubar to figure """ menubar = Menu(parent) # create a pulldown menu, and add it to the menu bar filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Open", command=self.open_file) filemenu.add_command(label="Save", command=self.save_current) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.exit) menubar.add_cascade(label="File", menu=filemenu) # create more pulldown menus toolmenu = Menu(menubar, tearoff=0) toolmenu.add_command(label="Open Toolbox", command=self.dq_tools) menubar.add_cascade(label="Tools", menu=toolmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="Show Help", command=self.help_file) menubar.add_cascade(label="Help", menu=helpmenu) # submenu cmapmenu = Menu(toolmenu, tearoff=0) cmapmenu.add_radiobutton( label='Grey', variable=self.cmap, value='gist_yarg') cmapmenu.add_radiobutton( label='Prism', variable=self.cmap, value='prism') cmapmenu.add_radiobutton(label='Jet', variable=self.cmap, value='jet') cmapmenu.add_radiobutton( label='Ncar', variable=self.cmap, value='gist_ncar') toolmenu.insert_cascade(index=2, label='Select Cmap', menu=cmapmenu) return menubar
def _init_menubar(self): self._result_size = IntVar(self.top) menubar = Menu(self.top) filemenu = Menu(menubar, tearoff=0, borderwidth=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-q') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) rescntmenu = Menu(editmenu, tearoff=0) rescntmenu.add_radiobutton(label='20', variable=self._result_size, underline=0, value=20, command=self.set_result_size) rescntmenu.add_radiobutton(label='50', variable=self._result_size, underline=0, value=50, command=self.set_result_size) rescntmenu.add_radiobutton(label='100', variable=self._result_size, underline=0, value=100, command=self.set_result_size) rescntmenu.invoke(1) editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu) menubar.add_cascade(label='Edit', underline=0, menu=editmenu) self.top.config(menu=menubar)
modify_menu.add_command(label="Clear all", command=menu_functions.clear_all) # Insert menu startup.menu.add_cascade(label="Insert", menu=insert_menu) insert_menu.add_command(label="Date", command=menu_functions.date) insert_menu.add_command(label="Line", command=menu_functions.line) # Font menu startup.menu.add_cascade(label="Font", menu=font_menu) font_menu.add_command(label="Choose font", command=menu_functions.font_chooser) # Format menu startup.menu.add_cascade(label="Format", menu=format_menu) format_menu.add_command(label="Color...", command=menu_functions.font_color) format_menu.add_separator() format_menu.add_radiobutton(label='Normal', command=menu_functions.normal) format_menu.add_radiobutton(label='Bold', command=menu_functions.bold) format_menu.add_radiobutton(label='Underline', command=menu_functions.underline) format_menu.add_radiobutton(label='Italic', command=menu_functions.italic) # Personalize menu startup.menu.add_cascade(label="Personalize", menu=personalize_menu) personalize_menu.add_command(label="Background...", command=menu_functions.background) # Help menu startup.menu.add_cascade(label="Help", menu=help_menu) help_menu.add_command(label="About...", command=menu_functions.about_command) # Export submenu export_menu.add_command(label="PDF", command=pdf_settings.export_pdf) # End of menu
class TreeNode: def __init__(self, canvas, parent, item, menuList=[]): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = 0 self.children = {} self.kidKeys = [] self.x = self.y = None self.iconimages = {} # cache of PhotoImage instances for icons self.menuList = menuList self.menuVar = IntVar() self.menuVar.set(0) self._popupMenu = None self.image_id = None if self.menuList: if self.menuList[-1] == 'Separator': self.menuList = self.menuList[:-1] self._popupMenu = Menu(self.canvas, tearoff=0) for i in range(len(self.menuList)): item = self.menuList[i] if item == 'Separator': self._popupMenu.add_separator() else: self._popupMenu.add_radiobutton( label=item, variable=self.menuVar, value=i, indicatoron=0, command=self.popupMenuCommand) def destroy(self): for key in self.kidKeys: c = self.children[key] del self.children[key] c.destroy() self.parent = None def geticonimage(self, name): try: return self.iconimages[name] except KeyError: pass file, ext = os.path.splitext(name) ext = ext or ".gif" fullname = os.path.join(ICONDIR, file + ext) image = PhotoImage(master=self.canvas, file=fullname) self.iconimages[name] = image return image def select(self, event=None): if self.selected: return self.deselectall() self.selected = 1 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() self.item.OnSelect(event) def deselect(self, event=None): if not self.selected: return self.selected = 0 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for key in self.kidKeys: child = self.children[key] child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def popupMenu(self, event=None): if self._popupMenu: self._popupMenu.post(event.widget.winfo_pointerx(), event.widget.winfo_pointery()) return "break" def popupMenuCommand(self): command = self.menuList[self.menuVar.get()] self.item.MenuCommand(command) if self.parent and (command != 'Update Explorer'): # Update parent to try to keep explorer up to date self.parent.update() def expand(self, event=None): if not self.item.IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y - 2 bottom = self.lastvisiblechild().y + 17 height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def reveal(self): # Make sure all parent nodes are marked as expanded parent = self.parent while parent: if parent.state == 'collapsed': parent.state = 'expanded' parent = parent.parent else: break # Redraw tree accordingly self.update() # Bring this item into view self.view() def lastvisiblechild(self): if self.kidKeys and self.state == 'expanded': return self.children[self.kidKeys[-1]].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(Tkinter.ALL) # XXX could be more subtle self.draw(7, 2) x0, y0, x1, y1 = self.canvas.bbox(Tkinter.ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor def draw(self, x, y): # XXX This hard-codes too many geometry constants! self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y + 17 # draw children sublist = self.item._GetSubList() if not sublist: # IsExpandable() was mistaken; that's allowed return y + 17 self.kidKeys = [] for item in sublist: key = item.GetKey() if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) self.children[key] = child self.kidKeys.append(key) # Remove unused children for key in self.children.keys(): if key not in self.kidKeys: del (self.children[key]) cx = x + 20 cy = y + 17 cylast = 0 for key in self.kidKeys: child = self.children[key] cylast = cy self.canvas.create_line(x + 9, cy + 7, cx, cy + 7, fill="gray50") cy = child.draw(cx, cy) if child.item.IsExpandable(): if child.state == 'expanded': iconname = "minusnode" callback = child.collapse else: iconname = "plusnode" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x + 9, cylast + 7, image=image) # XXX This leaks bindings until canvas is deleted: self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line( x + 9, y + 10, x + 9, cylast + 7, ##stipple="gray50", # XXX Seems broken in Tk 8.0.x fill="gray50") self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2 return cy def drawicon(self): if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "openfolder") else: imagename = self.item.GetIconName() or "folder" image = self.geticonimage(imagename) id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image) self.image_id = id self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) self.canvas.tag_bind(id, "<3>", self.popupMenu) def drawtext(self, text=None): textx = self.x + 20 - 1 texty = self.y - 1 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + 10 if text == None: text = self.item.GetText() or "<no text>" try: self.entry except AttributeError: pass else: self.edit_finish() try: label = self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) if self.selected: self.label.configure(fg="white", bg="darkblue") else: fg = self.item.GetTextFg() self.label.configure(fg=fg, bg="white") id = self.canvas.create_window(textx, texty, anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.label.bind("<3>", self.popupMenu) # Update text if necessary if text != self.label['text']: self.label['text'] = text self.text_id = id def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): text = self.item.GetTextForEdit() self.label['text'] = text self.drawtext(text) self.edit(event) else: self.select(event) def edit(self, event=None): self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, Tkinter.END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): self.drawtext() self.canvas.focus_set() def find(self, searchKey): # Search for a node who's key matches the given key # Is it this node if searchKey == self.item.GetKey(): return self # Nope, check the children sublist = self.item._GetSubList() for item in sublist: key = item.GetKey() # Use existing child or create new TreeNode if none exists if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) # Update local list of children and keys self.children[key] = child self.kidKeys.append(key) # See if node is child (or one of child's descendants) retVal = child.find(searchKey) if retVal: return retVal # Not here return None
class PopupMenuCreator: def __init__(self, atom3i): self.master = atom3i.parent self.atom3i = atom3i self.cb = atom3i.cb self.optionsDatabase = atom3i.optionsDatabase self.popupLogoPhotoimage = Embedded_Images().getPopupLogo() self.popupMenu = None self.event = None # --------------------------- Popup Utilities ------------------------------- def initilizePopupMenu(self, event): """ Create a new popup menu """ if (self.popupMenu): self.popupMenu.unpost() self.popupMenu = Menu(self.master, tearoff=0, bg="white") self.event = event def showPopupMenu(self): """ Display the popup menu """ if (self.popupMenu): self.popupMenu.post(self.event.x_root, self.event.y_root) def swapMenu(self, menu): """ This is a fix for a problem that no longer exists :p It essentially takes one menu and slaps another one in its place. """ raise Exception, "No one uses this method! But if you see this, maybe not so..." self.popupMenu.unpost() self.popupMenu = menu self.showPopupMenu() def popupRemover(self): """ Goodbye popup! """ if (self.popupMenu): self.popupMenu.unpost() self.popupMenu = None # ---------------------- Context Sensitive Menus -------------------------- def NoCursorNoSelectPopup(self, event): """ Popup menu to show when no items under the mouse, and no items selected """ self.initilizePopupMenu(event) addLogo(self) #......................... addSeperator(self) #......................... addModelAction(self) addSelectAll(self) addPaste(self) addUndo(self) addRedo(self) #......................... addSeperator(self) #......................... addFileMenu(self) addModelMenu(self) addTransformationMenu(self) addLayoutMenu(self) addExportMenu(self) #......................... addSeperator(self) #......................... addOpenLastModel(self) addOpenLastMetaModel(self) addSourcePath(self) #......................... addSeperator(self) #......................... addToggleSmoothMode(self) #......................... addSeperator(self) #......................... addExit(self) self.showPopupMenu() def NoCursorMultiSelectPopup(self, event): """ Popup menu to show when no items under the mouse, and multiple items selected """ self.initilizePopupMenu(event) addLogo(self) #......................... addSeperator(self) #......................... addLayoutMenu(self) addResizeEntity(self) addNodeLabelDragToggle(self) #......................... addSeperator(self) #......................... addSelectAll(self) addDeselectAll(self) #......................... addSeperator(self) #......................... addCut(self) addCopy(self) addPaste(self) #......................... addSeperator(self) #......................... addUndo(self) addRedo(self) #......................... addSeperator(self) #......................... addClear(self) self.showPopupMenu() def EntityAtCursorMultiSelectPopup(self, event): """ A graphical entity is under the mouse cursor, along with multiple selected items """ self.initilizePopupMenu(event) addLogo(self) #......................... addSeperator(self) #......................... addLayoutMenu(self) addEditEntity(self) addDragOverlap(self) addDrawArrow(self) addResizeEntity(self) addNodeLabelDragToggle(self) #......................... addSeperator(self) #......................... addSelectAll(self) addDeselectAll(self) #......................... addSeperator(self) #......................... addCut(self) addCopy(self) addPaste(self) #......................... addSeperator(self) #......................... addCopyAttributes(self) addPasteAttributes(self) #......................... addSeperator(self) #......................... addUndo(self) addRedo(self) #......................... addSeperator(self) #......................... addClear(self) self.showPopupMenu() def EntityAtCursorNoSelectPopup(self, event): """ A graphical entity is under the mouse cursor, but no selected items """ self.initilizePopupMenu(event) addLogo(self) #......................... addSeperator(self) #......................... addEditEntity(self) addDragOverlap(self) addDrawArrow(self) addResizeEntity(self) #......................... addSeperator(self) #......................... addSelectAll(self) addPaste(self) #......................... addSeperator(self) #......................... addCopyAttributes(self) addPasteAttributes(self) #......................... addSeperator(self) #......................... addUndo(self) addRedo(self) self.showPopupMenu() def LinkAtCursorMultiSelectPopup(self, event): """ A graphical link/connection is under the mouse cursor, along with multiple selected items """ self.initilizePopupMenu(event) addLogo(self) #......................... addSeperator(self) #......................... addLayoutMenu(self) addEditEntity(self) addDragOverlap(self) addArrowEditor(self) addResizeEntity(self) addNodeLabelDragToggle(self) #......................... addSeperator(self) #......................... addSmoothSelected(self) addToggleSmoothMode(self) #......................... addSeperator(self) #......................... addSelectAll(self) addDeselectAll(self) #......................... addSeperator(self) #......................... addCut(self) addCopy(self) addPaste(self) #......................... addSeperator(self) #......................... addCopyAttributes(self) addPasteAttributes(self) #......................... addSeperator(self) #......................... addUndo(self) addRedo(self) #......................... addSeperator(self) #......................... addClear(self) self.showPopupMenu() def LinkAtCursorNoSelectPopup(self, event): """ A graphical link/connection is under the mouse cursor, but there are no selected items """ self.initilizePopupMenu(event) addLogo(self) #......................... addSeperator(self) #......................... addEditEntity(self) addDragOverlap(self) addArrowEditor(self) #......................... addSeperator(self) #......................... addSelectAll(self) addToggleSmoothMode(self) addPaste(self) #......................... addSeperator(self) #......................... addCopyAttributes(self) addPasteAttributes(self) #......................... addSeperator(self) #......................... addUndo(self) addRedo(self) self.showPopupMenu() def ArrowEditorPopup(self, event): """ Menu for the arrow editor """ self.initilizePopupMenu(event) addLogo(self) #......................... addSeperator(self) #......................... addEditEntity(self) addInsertPoint(self) addDeletePoint(self) addSmoothSelected(self) addNodeLabelMoveToggle(self) #......................... addSeperator(self) #......................... addArrowEditorExit(self) self.showPopupMenu() # ----------------------- Popup a specific submenu ------------------------- def LayoutPopup(self, event): self.initilizePopupMenu(event) self.popupMenu = self.atom3i.layoutMenu self.showPopupMenu() def ExportPopup(self, event): self.initilizePopupMenu(event) self.popupMenu = self.atom3i.exportMenu self.showPopupMenu() def ModelPopup(self, event): self.initilizePopupMenu(event) self.popupMenu = self.atom3i.modelMenu self.showPopupMenu() def TransformationPopup(self, event): self.initilizePopupMenu(event) self.popupMenu = self.atom3i.transMenu self.showPopupMenu() def FilePopup(self, event): self.initilizePopupMenu(event) self.popupMenu = self.atom3i.filemenu self.showPopupMenu() def LastModelPopup(self, event): self.initilizePopupMenu(event) addOpenLastModelSubroutine(self, self.popupMenu) self.showPopupMenu() def LastMetaModelPopup(self, event): self.initilizePopupMenu(event) addOpenLastMetaModelSubroutine(self, self.popupMenu) self.showPopupMenu() def SourcePathPopup(self, event): self.initilizePopupMenu(event) addSourcePathSubroutine(self, self.popupMenu) self.showPopupMenu() # ------------------------ String List to PopupMenu --------------------------------- def listChoicePopup(self, title, stringList, unused=None): """ Creates a popup menu with radiobuttons labeled from the stringList. Returns the index of the label that was chosen. NOTE: choosing outside the popup implicitly chooses index 0 """ # Remove any existing popups first self.popupRemover() self.popupMenu = Menu(self.master, tearoff=0) integerVar = IntVar() self.popupMenu.add_command(label=title, command=self.popupRemover) self.popupMenu.add_separator() i = 1 for label in stringList: self.popupMenu.add_radiobutton(label=label, variable=integerVar, value=i, indicatoron=False) i += 1 # This gets the last known co-ordinates of the mouse :D # NOTE: We get co-ordinates in terms of canvas space, convert back into # screenspace first before using them... x, y = self.atom3i.cb.getLastClickCoord() dc = self.atom3i.cb.getCanvas() x, y = [x - dc.canvasx(0), y - dc.canvasy(0)] # These offsets place the menu just where I like it... x = int(x) + 40 #+ 100 y = int(y) + 40 #+ 20 # Posts the menu, and blocks program execution here on win32 only self.popupMenu.post(x, y) # Blocks program execution (all platforms) & waits for integerVar to be updated # Not ideal: If we close the popup without selecting anything this will # wait forever and execution will never get anywhere beyond this point!!! # Moreover: AToM3 will not shutdown properly! #self.master.wait_variable( integerVar ) # THEORY: This will work whether or not the post() blocks or not # Practice: Works great on WinXP with Python 2.3 # Linux? while (1): self.master.update() value = integerVar.get() # Hapiness, we got the value we wanted if (value > 0): return value # The user killed the popup! O_O elif (self.popupMenu == None): return 0 # Unhapiness, the user avoided selecting anything elif (value == 0): self.popupMenu.unpost() self.popupMenu.post(x, y) self.master.update() time.sleep(0.4) return 0 # We won't get here, but just in case... def listChoicePopupAlternative(self, title, stringList, actionLabel): """ OBSOLETE --- Delete this """ raise Exception, "No one uses this method! But if you see this, maybe not so..." """
class SurfaceManipulator(Frame): r""" A translation surface editor in tk. """ # STATIC METHODS AND OBJECTS current = None # boolean variable to remember if the hook was run! _clear_hook_was_run = 0 @staticmethod def launch(geometry = "800x700+10+10"): r"""Prefered way to gain access to a SurfaceManipulator window.""" if SurfaceManipulator.current is None: SurfaceManipulator._clear_hook() root = Tk() root.geometry(geometry) SurfaceManipulator.current=SurfaceManipulator(root) return SurfaceManipulator.current @staticmethod def _window_destroyed(surface_manipulator): if SurfaceManipulator.current is surface_manipulator: SurfaceManipulator.current = None @staticmethod def _clear_hook(): if not SurfaceManipulator._clear_hook_was_run: # Hack due to Nathan Dunfield (http://trac.sagemath.org/ticket/15152) import IPython.lib.inputhook as ih ih.clear_inputhook() SurfaceManipulator._clear_hook_was_run = 1 # NORMAL METHODS def __init__(self, parent, surface=None, surfaces=[]): r""" INPUT: - ``surfaces`` -- a list of surfaces that the editor may modify - ``surface`` -- surface selected by default - ``parent`` -- parent Tk window """ Frame.__init__(self, parent) self._parent = parent self.pack(fill="both", expand=1) # Run something when closing self._parent.wm_protocol ("WM_DELETE_WINDOW", self.exit) # Surface currently being manipulated self._surface=None # List of surfaces in editor self._surfaces=[] # More variables to initialize self._currentActor=None # Initialization of GUI self._init_menu() self._init_gui() # Setup surface list for s in surfaces: self.add_surface(s) # Setup initial surface if surface is not None: self.add_surface(surface) self.set_surface(surface) def __repr__(self): return "Surface manipulator" def add_mega_wollmilchsau(self): from geometry.mega_wollmilchsau import MegaWollmilchsau s = MegaWollmilchsau() sm,sb = s.get_bundle() self.set_surface(sb) def add_octagon(self): from geometry.similarity_surface_generators import TranslationSurfaceGenerators ss=TranslationSurfaceGenerators.regular_octagon() ss.edit() def _init_menu(self): self._menubar = Menu(self._parent) menubar=self._menubar self._parent.config(menu=menubar) #new_menu = Menu(menubar, tearoff=0) #new_menu.add_command(label="Billiard Table", command=self.on_new_similarity_surface) file_menu = Menu(menubar, tearoff=0) #file_menu.add_cascade(label="New", menu=new_menu) file_menu.add_command(label="Octagon", command=self.add_octagon) file_menu.add_command(label="MegaWollmilchsau", command=self.add_mega_wollmilchsau) file_menu.add_separator() file_menu.add_command(label="About", command=self.on_about) file_menu.add_command(label="Export PostScript", command=self.on_export) file_menu.add_command(label="Exit", command=self.exit, accelerator="Alt+F4") menubar.add_cascade(label="File", underline=0, menu=file_menu) self._surface_menu = Menu(menubar, tearoff=0) self._selected_surface = IntVar() self._selected_surface.set(-1) menubar.add_cascade(label="Surface", underline=0, menu=self._surface_menu) self._surface_menu.add_radiobutton(label="None", command=self.menu_select_surface, variable=self._selected_surface, value=-1) def _init_gui(self): self._parent.title("FlatSurf Editor") self._canvas = Canvas(self, bg="#444", width=300, height=200) self._canvas.pack(fill="both", expand=1) self.bottom_text = Label(self, text="Welcome to FlatSurf.", anchor="w") self.bottom_text.pack(fill="x", expand=0) self.set_actor(None) def add_surface(self,newsurface): r""" Add a surface to the display list for the window. Returns the index of the new surface in the surface list. """ if (newsurface==None): return -1 i=0 for s in self._surfaces: if (s==newsurface): return i i=i+1 self._surfaces.append(newsurface) newsurface.zoom_fit_nice_boundary() self._reset_surface_menu() return len(self._surfaces)-1 def exit(self): SurfaceManipulator._window_destroyed(self) self._parent.destroy() def find_bundle(self, surface): for surface_bundle in self._surfaces: if surface is surface_bundle.get_surface(): return surface_bundle return None def get_bundle(self): return self._surface def get_bundles(self): return self._surfaces def get_canvas(self): return self._canvas def get_center(self): r""" Return the center of the canvas as a pair of integers. """ return ( self.get_width()/2, self.get_height()/2 ) def get_height(self): r""" Return the height of the canvas (an integer). """ return self.get_canvas().winfo_height() def get_parent(self): return self._parent def get_surface_bundle(self): r""" Get the current surface bundle, or None if there is none. """ return self._surface def get_width(self): r""" Return the width of the canvas (an integer). """ return self.get_canvas().winfo_width() def menu_select_surface(self): r""" Called when a surface is selected from a menu. """ i = self._selected_surface.get() if i == -1: self.set_surface(None) else: self.set_surface(self._surfaces[i]) def on_about(self): self.set_text("Written by Vincent Delecroix and Pat Hooper.") def on_delete_junk(self): self._canvas.delete("junk") def on_export(self): r""" Export image as postscript file. """ myFormats = [('PostScript','*.ps')] fileName = tkFileDialog.asksaveasfilename(parent=self, filetypes=myFormats , title="Save image as...") if len(fileName ) > 0: self._canvas.update() self._canvas.postscript(file = fileName) self.set_text("Wrote image to "+fileName) # def on_new_similarity_surface(self): # s = CreateSimilaritySurfaceBundle(len(self._surfaces),self) # if s is not None: # i = self.set_surface(s) # self.set_text("Created new surface `"+self._surfaces[i].get_name()+"'.") def _on_no_surface(self): self._canvas.delete("all") def _on_zoom(self): self.set_actor(ZoomActor(self)) def _on_zoom_box(self): self.set_actor(ZoomBoxActor(self)) def _on_redraw_all(self): if self._surface is not None: self._surface.redraw_all() def _on_recenter(self): self.set_actor(RecenterActor(self)) def _reset_menus(self): r""" Reset all menus except the file and surface menu """ # The following loop removes all but the first two menus (File and Surface). num = len(self._menubar.children) for i in range(num,2,-1): self._menubar.delete(i) if self._surface!= None: self._surface.make_menus(self._menubar) def _reset_surface_menu(self): r""" Reset the surface menu. """ ### This is a hack to get the number of items in the menu: num = self._surface_menu.index(100)+1 # First we remove everything but the first entry ("None") for i in range(num-1,0,-1): #print("removing a child2: "+str(i)+" of "+str(num)) self._surface_menu.delete(i) # Add an entry for every surface in the list. for i in range( len(self._surfaces) ): surface = self._surfaces[i] self._surface_menu.add_radiobutton(label=surface.get_name(), command=self.menu_select_surface, variable=self._selected_surface, value=i) def set_text(self, text): self.bottom_text["text"]=text def set_actor(self, actor): r""" Set the current mode of user interaction. """ if (actor != self._currentActor): if self._currentActor != None: self._currentActor.on_deactivate() if (actor==None): self.set_text("Nothing going on.") # Event bindings self._canvas.unbind('<Button-1>') self._canvas.unbind('<Button-2>') self._canvas.unbind('<Button-3>') self._canvas.unbind('<Double-Button-1>') self._canvas.unbind('<Shift-Button-1>') self._canvas.unbind('<Motion>') self.unbind('<FocusIn>') self.unbind('<FocusOut>') #self._canvas.unbind('<ButtonPress-1>') self._canvas.unbind('<ButtonRelease-1>') self._canvas.unbind('<B1-Motion>') self._parent.unbind('<Key>') self._parent.unbind('<KeyRelease>') else: # Event bindings self._canvas.bind('<Button-1>', actor.single_left_click) self._canvas.bind('<Double-Button-1>', actor.double_left_click) self._canvas.bind('<Triple-Button-1>', actor.double_left_click) self._canvas.bind('<Button-2>', actor.single_middle_click) self._canvas.bind('<Double-Button-2>', actor.double_middle_click) self._canvas.bind('<Triple-Button-2>', actor.double_middle_click) self._canvas.bind('<Button-3>', actor.single_right_click) self._canvas.bind('<Double-Button-3>', actor.double_right_click) self._canvas.bind('<Triple-Button-3>', actor.double_right_click) self._canvas.bind('<Shift-Button-1>', actor.shift_click) self._canvas.bind('<Motion>', actor.mouse_moved) #self._canvas.bind('<ButtonPress-1>', actor.left_mouse_pressed) self._canvas.bind('<ButtonRelease-1>', actor.left_mouse_released) self._canvas.bind('<B1-Motion>',actor.left_dragged) self.bind('<FocusIn>', actor.focus_in) self.bind('<FocusOut>', actor.focus_out) self._parent.bind('<Key>', actor.key_press) self._parent.bind('<KeyRelease>', actor.key_release) self._currentActor=actor self._currentActor.on_activate() def set_surface(self,surface_bundle): r""" Set the current surface to the one given by surface_bundle """ i = self.add_surface(surface_bundle) if surface_bundle != self._surface: self._canvas.delete("all") self._surface=surface_bundle self._surface_menu.invoke(i+1) if i >= 0: self.set_text("Switched to `"+self._surface.get_name()+"'.") self._parent.title(self._surface.get_name()) self._reset_menus() # stop the actor (was a bug). self.set_actor(None) if isinstance(self._surface, EditorRenderer): self._surface.initial_render() else: self.set_text("No surface selected.") self._parent.title("FlatSurf Editor") self._reset_menus() self.set_actor(None) return i def surface_renamed(self): if self._surface is not None: self._parent.title(self._surface.get_name()) self._reset_surface_menu()
def setup_menu(self): """ Creates a drop down menu bar at the top of the tool """ menu_bar = Menu(self.__root) # File Menu menu_file = Menu(menu_bar, tearoff=0) menu_file.add_command(label='Import file', command=self.import_file) menu_file.add_command(label='Save all shapes', command=lambda: self.save_as_json(save_all=True)) menu_file.add_command(label='Settings', command=self.settings_dialog) menu_file.add_separator() menu_file.add_command(label='Exit', command=self.close) menu_bar.add_cascade(label='File', menu=menu_file) # Edit Menu menu_edit = Menu(menu_bar, tearoff=0) menu_edit.add_command(label='Select all shapes', command=self.__shapemanager.select_all) menu_edit.add_command(label='Deselect all shapes', command=self.__shapemanager.deselect_all) menu_bar.add_cascade(label='Edit', menu=menu_edit) # Polygon Menu menu_polygon = Menu(menu_bar, tearoff=0) menu_polygon.add_command(label='Import/Manage Database', command=self.import_dialog) menu_polygon.add_command(label='Export All to Database', command=self.export_db) menu_polygon.add_command( label='Export Selected to Database', command=lambda: self.export_db(only_selected=True)) menu_polygon.add_separator() menu_polygon.add_command(label='Create New Database', command=lambda: Calipso.create_db()) menu_polygon.add_command(label='Select Database', command=lambda: Calipso.select_db()) menu_polygon.add_separator() menu_polygon.add_command(label='Import Archive to Database', command=Calipso.import_json_db) menu_polygon.add_command(label='Export Database to Archive', command=Calipso.export_json_db) menu_bar.add_cascade(label='Polygon', menu=menu_polygon) # View Menu menu_views = Menu(menu_bar, tearoff=0) menu_views.add_radiobutton(label='Backscatter 532', variable=self.plot_type, value=Plot.backscattered) menu_views.add_radiobutton(label='Depolarization', variable=self.plot_type, value=Plot.depolarized) menu_views.add_radiobutton(label='Vertical Feature Mask', variable=self.plot_type, value=Plot.vfm) menu_views.add_radiobutton(label='Ice Water Phase', variable=self.plot_type, value=Plot.iwp) menu_views.add_radiobutton(label='Horizontal Averaging', variable=self.plot_type, value=Plot.horiz_avg) menu_views.add_radiobutton(label='Aerosol Subtype', variable=self.plot_type, value=Plot.aerosol_subtype) menu_bar.add_cascade(label='Views', menu=menu_views) self.plot_type.set(1) # Set initial value to backscatter # Help Menu menu_help = Menu(menu_bar, tearoff=0) menu_help.add_command( label='Documentation', command=lambda: webbrowser.open_new(constants.HELP_PAGE)) menu_help.add_command(label='About', command=self.about) menu_bar.add_cascade(label='Help', menu=menu_help) # configure menu to screen self.__root.config(menu=menu_bar)
def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Match', underline=0, command=self.match, accelerator='Ctrl-m') rulemenu.add_command(label='Expand', underline=0, command=self.expand, accelerator='Ctrl-e') rulemenu.add_separator() rulemenu.add_command(label='Backtrack', underline=0, command=self.backtrack, accelerator='Ctrl-b') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animation_frames, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animation_frames, value=10, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animation_frames, value=5, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animation_frames, value=2, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar)
def createInterface(self): # The interior of the toplevel panel interior = self.interior() interior['relief'] = Tkinter.FLAT # Add placer commands to menubar self.menuBar.addmenu('Placer', 'Placer Panel Operations') self.menuBar.addmenuitem('Placer', 'command', 'Zero Node Path', label='Zero All', command=self.zeroAll) self.menuBar.addmenuitem('Placer', 'command', 'Reset Node Path', label='Reset All', command=self.resetAll) self.menuBar.addmenuitem('Placer', 'command', 'Print Node Path Info', label='Print Info', command=self.printNodePathInfo) self.menuBar.addmenuitem('Placer', 'command', 'Toggle widget visability', label='Toggle Widget Vis', command=SEditor.toggleWidgetVis) self.menuBar.addmenuitem( 'Placer', 'command', 'Toggle widget manipulation mode', label='Toggle Widget Mode', command=SEditor.manipulationControl.toggleObjectHandlesMode) # Get a handle to the menu frame menuFrame = self.menuFrame self.nodePathMenu = Pmw.ComboBox( menuFrame, labelpos=Tkinter.W, label_text='Node Path:', entry_width=20, selectioncommand=self.selectNodePathNamed, scrolledlist_items=self.nodePathNames) self.nodePathMenu.selectitem('selected') self.nodePathMenuEntry = ( self.nodePathMenu.component('entryfield_entry')) self.nodePathMenuBG = ( self.nodePathMenuEntry.configure('background')[3]) self.nodePathMenu.pack(side='left', fill='x', expand=1) self.bind(self.nodePathMenu, 'Select node path to manipulate') modeMenu = Pmw.OptionMenu(menuFrame, items=('Relative To:', 'Orbit:'), initialitem='Relative To:', command=self.setMovementMode, menubutton_width=8) modeMenu.pack(side='left', expand=0) self.bind(modeMenu, 'Select manipulation mode') self.refNodePathMenu = Pmw.ComboBox( menuFrame, entry_width=16, selectioncommand=self.selectRefNodePathNamed, scrolledlist_items=self.refNodePathNames) self.refNodePathMenu.selectitem('parent') self.refNodePathMenuEntry = ( self.refNodePathMenu.component('entryfield_entry')) self.refNodePathMenu.pack(side='left', fill='x', expand=1) self.bind(self.refNodePathMenu, 'Select relative node path') self.undoButton = Button(menuFrame, text='Undo', command=SEditor.undo) if SEditor.undoList: self.undoButton['state'] = 'normal' else: self.undoButton['state'] = 'disabled' self.undoButton.pack(side='left', expand=0) self.bind(self.undoButton, 'Undo last operation') self.redoButton = Button(menuFrame, text='Redo', command=SEditor.redo) if SEditor.redoList: self.redoButton['state'] = 'normal' else: self.redoButton['state'] = 'disabled' self.redoButton.pack(side='left', expand=0) self.bind(self.redoButton, 'Redo last operation') # Create and pack the Pos Controls posGroup = Pmw.Group(interior, tag_pyclass=Menubutton, tag_text='Position', tag_font=('MSSansSerif', 14), tag_activebackground='#909090', ring_relief=Tkinter.RIDGE) posMenubutton = posGroup.component('tag') self.bind(posMenubutton, 'Position menu operations') posMenu = Menu(posMenubutton, tearoff=0) posMenu.add_command(label='Set to zero', command=self.zeroPos) posMenu.add_command(label='Reset initial', command=self.resetPos) posMenubutton['menu'] = posMenu posGroup.pack(side='left', fill='both', expand=1) posInterior = posGroup.interior() # Create the dials self.posX = self.createcomponent('posX', (), None, Floater, (posInterior, ), text='X', relief=Tkinter.FLAT, value=0.0, label_foreground='Red') self.posX['commandData'] = ['x'] self.posX['preCallback'] = self.xformStart self.posX['postCallback'] = self.xformStop self.posX['callbackData'] = ['x'] self.posX.pack(expand=1, fill='both') self.posY = self.createcomponent('posY', (), None, Floater, (posInterior, ), text='Y', relief=Tkinter.FLAT, value=0.0, label_foreground='#00A000') self.posY['commandData'] = ['y'] self.posY['preCallback'] = self.xformStart self.posY['postCallback'] = self.xformStop self.posY['callbackData'] = ['y'] self.posY.pack(expand=1, fill='both') self.posZ = self.createcomponent('posZ', (), None, Floater, (posInterior, ), text='Z', relief=Tkinter.FLAT, value=0.0, label_foreground='Blue') self.posZ['commandData'] = ['z'] self.posZ['preCallback'] = self.xformStart self.posZ['postCallback'] = self.xformStop self.posZ['callbackData'] = ['z'] self.posZ.pack(expand=1, fill='both') # Create and pack the Hpr Controls hprGroup = Pmw.Group(interior, tag_pyclass=Menubutton, tag_text='Orientation', tag_font=('MSSansSerif', 14), tag_activebackground='#909090', ring_relief=Tkinter.RIDGE) hprMenubutton = hprGroup.component('tag') self.bind(hprMenubutton, 'Orientation menu operations') hprMenu = Menu(hprMenubutton, tearoff=0) hprMenu.add_command(label='Set to zero', command=self.zeroHpr) hprMenu.add_command(label='Reset initial', command=self.resetHpr) hprMenubutton['menu'] = hprMenu hprGroup.pack(side='left', fill='both', expand=1) hprInterior = hprGroup.interior() # Create the dials self.hprH = self.createcomponent('hprH', (), None, AngleDial, (hprInterior, ), style='mini', text='H', value=0.0, relief=Tkinter.FLAT, label_foreground='blue') self.hprH['commandData'] = ['h'] self.hprH['preCallback'] = self.xformStart self.hprH['postCallback'] = self.xformStop self.hprH['callbackData'] = ['h'] self.hprH.pack(expand=1, fill='both') self.hprP = self.createcomponent('hprP', (), None, AngleDial, (hprInterior, ), style='mini', text='P', value=0.0, relief=Tkinter.FLAT, label_foreground='red') self.hprP['commandData'] = ['p'] self.hprP['preCallback'] = self.xformStart self.hprP['postCallback'] = self.xformStop self.hprP['callbackData'] = ['p'] self.hprP.pack(expand=1, fill='both') self.hprR = self.createcomponent('hprR', (), None, AngleDial, (hprInterior, ), style='mini', text='R', value=0.0, relief=Tkinter.FLAT, label_foreground='#00A000') self.hprR['commandData'] = ['r'] self.hprR['preCallback'] = self.xformStart self.hprR['postCallback'] = self.xformStop self.hprR['callbackData'] = ['r'] self.hprR.pack(expand=1, fill='both') # Create and pack the Scale Controls # The available scaling modes self.scalingMode = StringVar() self.scalingMode.set('Scale Uniform') # The scaling widgets scaleGroup = Pmw.Group(interior, tag_text='Scale Uniform', tag_pyclass=Menubutton, tag_font=('MSSansSerif', 14), tag_activebackground='#909090', ring_relief=Tkinter.RIDGE) self.scaleMenubutton = scaleGroup.component('tag') self.bind(self.scaleMenubutton, 'Scale menu operations') self.scaleMenubutton['textvariable'] = self.scalingMode # Scaling menu scaleMenu = Menu(self.scaleMenubutton, tearoff=0) scaleMenu.add_command(label='Set to unity', command=self.unitScale) scaleMenu.add_command(label='Reset initial', command=self.resetScale) scaleMenu.add_radiobutton(label='Scale Free', variable=self.scalingMode) scaleMenu.add_radiobutton(label='Scale Uniform', variable=self.scalingMode) scaleMenu.add_radiobutton(label='Scale Proportional', variable=self.scalingMode) self.scaleMenubutton['menu'] = scaleMenu # Pack group widgets scaleGroup.pack(side='left', fill='both', expand=1) scaleInterior = scaleGroup.interior() # Create the dials self.scaleX = self.createcomponent('scaleX', (), None, Floater, (scaleInterior, ), text='X Scale', relief=Tkinter.FLAT, min=0.0001, value=1.0, resetValue=1.0, label_foreground='Red') self.scaleX['commandData'] = ['sx'] self.scaleX['callbackData'] = ['sx'] self.scaleX['preCallback'] = self.xformStart self.scaleX['postCallback'] = self.xformStop self.scaleX.pack(expand=1, fill='both') self.scaleY = self.createcomponent('scaleY', (), None, Floater, (scaleInterior, ), text='Y Scale', relief=Tkinter.FLAT, min=0.0001, value=1.0, resetValue=1.0, label_foreground='#00A000') self.scaleY['commandData'] = ['sy'] self.scaleY['callbackData'] = ['sy'] self.scaleY['preCallback'] = self.xformStart self.scaleY['postCallback'] = self.xformStop self.scaleY.pack(expand=1, fill='both') self.scaleZ = self.createcomponent('scaleZ', (), None, Floater, (scaleInterior, ), text='Z Scale', relief=Tkinter.FLAT, min=0.0001, value=1.0, resetValue=1.0, label_foreground='Blue') self.scaleZ['commandData'] = ['sz'] self.scaleZ['callbackData'] = ['sz'] self.scaleZ['preCallback'] = self.xformStart self.scaleZ['postCallback'] = self.xformStop self.scaleZ.pack(expand=1, fill='both') # Make sure appropriate labels are showing self.setMovementMode('Relative To:') # Set up placer for inital node path self.selectNodePathNamed('init') self.selectRefNodePathNamed('parent') # Update place to reflect initial state self.updatePlacer() # Now that you're done setting up, attach commands self.posX['command'] = self.xform self.posY['command'] = self.xform self.posZ['command'] = self.xform self.hprH['command'] = self.xform self.hprP['command'] = self.xform self.hprR['command'] = self.xform self.scaleX['command'] = self.xform self.scaleY['command'] = self.xform self.scaleZ['command'] = self.xform
def create_menu(self, root): # create menu bar. menubar = Menu(root) # create file menu and add commands menu_file = Menu(menubar, tearoff=0) menu_open = menu_file.add_command( command=self.menu_file_open, label='%s' % LANG_MAP[self._lang]['Open'].center(10)) menu_clear = menu_file.add_command( command=self.menu_file_clear, label='%s' % LANG_MAP[self._lang]['Clear'].center(10)) menu_file.add_separator() menu_exit = menu_file.add_command( command=self.menu_file_exit, label='%s' % LANG_MAP[self._lang]['Exit'].center(10)) # create config menu and add commands menu_config = Menu(menubar, tearoff=0) # create language nemu and add cascade menu_lang = Menu(menu_config, tearoff=0) self._lang_set = IntVar() menu_lang.add_radiobutton(label='English', command=self.menu_config_lang, variable=self._lang_set, value=0) menu_lang.add_radiobutton(label='中文', command=self.menu_config_lang, variable=self._lang_set, value=1) self._lang_set.set(self._lang) mbar_lang = menu_config.add_cascade(menu=menu_lang, label='%s' % LANG_MAP[self._lang]['Lang']) # create output menu menu_output = Menu(menu_config, tearoff=0) menu_output.add_command(command=self.menu_config_output, label='%s' % self._output if self._output else 'None') mbar_output = menu_config.add_cascade(menu=menu_output, label='%s' % LANG_MAP[self._lang]['Output']) # create configuration menu and add cascade menu_debug = Menu(menu_config, tearoff=0) self._debug_v_set = IntVar() self._debug_d_set = IntVar() self._debug_D_set = IntVar() menu_debug.add_checkbutton(label='-v View', onvalue=1, variable=self._debug_v_set, command=self.menu_config_debug) menu_debug.add_checkbutton(label='-d Debug', onvalue=1, variable=self._debug_D_set, command=self.menu_config_debug) menu_debug.add_radiobutton(label='d1 Debug Basic', value=0x01, variable=self._debug_d_set, command=self.menu_config_debug) menu_debug.add_radiobutton(label='d2 Debug Advance', value=0x02, variable=self._debug_d_set, command=self.menu_config_debug) mbar_debug = menu_config.add_cascade(menu=menu_debug, label='%s' % LANG_MAP[self._lang]['Debug']) # create help menu menu_help = Menu(menubar, tearoff=0) menu_about = menu_help.add_command(command=self.menu_help_about, label='%s' % LANG_MAP[self._lang]['About']) # add cascade to menu bar. mbar_file = menubar.add_cascade(menu=menu_file, label='%s' % LANG_MAP[self._lang]['File']) mbar_config = menubar.add_cascade(menu=menu_config, label='%s' % LANG_MAP[self._lang]['Config']) mbar_help = menubar.add_cascade(menu=menu_help, label='%s' % LANG_MAP[self._lang]['Help']) root['menu'] = menubar self._wm['mbar_file'] = mbar_file self._wm['mbar_config'] = mbar_config self._wm['mbar_help'] = mbar_help self._wm['menu_file'] = menu_file self._wm['menu_help'] = menu_help self._wm['mbar_lang'] = mbar_lang self._wm['mbar_output'] = mbar_output self._wm['mbar_debug'] = mbar_debug self._wm['menu_open'] = menu_open self._wm['menu_clear'] = menu_clear self._wm['menu_exit'] = menu_exit self._wm['menu_output'] = menu_output self._wm['menu_about'] = menu_about
def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Reset Parser", underline=0, command=self.reset, accelerator="Del") filemenu.add_command(label="Print to Postscript", underline=0, command=self.postscript, accelerator="Ctrl-p") filemenu.add_command(label="Exit", underline=1, command=self.destroy, accelerator="Ctrl-x") menubar.add_cascade(label="File", underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label="Edit Grammar", underline=5, command=self.edit_grammar, accelerator="Ctrl-g") editmenu.add_command(label="Edit Text", underline=5, command=self.edit_sentence, accelerator="Ctrl-t") menubar.add_cascade(label="Edit", underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label="Step", underline=1, command=self.step, accelerator="Space") rulemenu.add_separator() rulemenu.add_command(label="Match", underline=0, command=self.match, accelerator="Ctrl-m") rulemenu.add_command(label="Expand", underline=0, command=self.expand, accelerator="Ctrl-e") rulemenu.add_separator() rulemenu.add_command(label="Backtrack", underline=0, command=self.backtrack, accelerator="Ctrl-b") menubar.add_cascade(label="Apply", underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton( label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar ) viewmenu.add_separator() viewmenu.add_radiobutton(label="Tiny", variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label="Small", variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label="Medium", variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label="Large", variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label="Huge", variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label="View", underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animation_frames, value=0) animatemenu.add_radiobutton( label="Slow Animation", underline=0, variable=self._animation_frames, value=10, accelerator="-" ) animatemenu.add_radiobutton( label="Normal Animation", underline=0, variable=self._animation_frames, value=5, accelerator="=" ) animatemenu.add_radiobutton( label="Fast Animation", underline=0, variable=self._animation_frames, value=2, accelerator="+" ) menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", underline=0, command=self.about) helpmenu.add_command(label="Instructions", underline=0, command=self.help, accelerator="F1") menubar.add_cascade(label="Help", underline=0, menu=helpmenu) parent.config(menu=menubar)
def BuildMainFrame(self): from Tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from Tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master,activeborderwidth=0,bd=0) self.master.config(menu=menu) filemenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N',command=self.NewCommand) filemenu.add_command(label="Open...",accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...",accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit",accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu,modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename,menu=scriptsubmenu) editmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Edit",underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script",menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F',command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file,value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file,value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file,value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1',command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0','1.0'] self.suggestionswindow = Toplevel(bg='#ffffff',bd=0,height=50,width=600,highlightthickness=0,takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow,bg='#ffffff',bd=1,fg='#336699',activestyle='none',highlightthickness=0,height=9) self.suggestionslist.insert(END,"foo") self.suggestionslist.pack(side=TOP,fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0,weight=1) self.master.columnconfigure(0,weight=1) content = Frame(self.master,bd=0,padx=2,pady=2) content.grid(row=0,column=0,sticky=N+S+W+E) content.rowconfigure(0,weight=1,minsize=50) content.rowconfigure(1,weight=0) content.columnconfigure(0,weight=1) panes = PanedWindow(content,orient=VERTICAL,bd=1,sashwidth=8,sashpad=0,sashrelief=RAISED,showhandle=True) panes.grid(row=0,column=0,sticky=N+S+W+E) frame1 = Frame(panes,bd=0) frame1.grid(row=0,column=0,sticky=N+S+W+E) frame1.columnconfigure(0,weight=1) frame1.columnconfigure(1,weight=0) frame1.rowconfigure(0,weight=1) panes.add(frame1,height=300,minsize=20) frame2 = Frame(panes,bd=0) frame2.grid(row=1,column=0,sticky=N+S+W+E) frame2.columnconfigure(0,weight=1) frame2.columnconfigure(1,weight=0) frame2.rowconfigure(0,weight=1) panes.add(frame2,minsize=20) self.text_input = Text(frame1, bg='#ffffff',bd=1,highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1,orient=VERTICAL,command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2,state=DISABLED,bd=1,bg='#ffffff',highlightthickness=0) self.output_scrollbar = Scrollbar(frame2,orient=VERTICAL,command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content,bd=1,bg='#ffffff',state=DISABLED,highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0,column=0,sticky=N+S+W+E) self.input_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_output.grid(row=0,column=0,sticky=N+S+W+E) self.output_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_entry.grid(row=1,column=0,sticky=N+S+W+E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script",menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry,self.output_stream)
class SurfaceManipulator(Frame): r""" A translation surface editor in tk. """ # STATIC METHODS AND OBJECTS current = None # boolean variable to remember if the hook was run! _clear_hook_was_run = 0 @staticmethod def launch(geometry="800x700+10+10"): r"""Prefered way to gain access to a SurfaceManipulator window.""" if SurfaceManipulator.current is None: SurfaceManipulator._clear_hook() root = Tk() root.geometry(geometry) SurfaceManipulator.current = SurfaceManipulator(root) return SurfaceManipulator.current @staticmethod def _window_destroyed(surface_manipulator): if SurfaceManipulator.current is surface_manipulator: SurfaceManipulator.current = None @staticmethod def _clear_hook(): if not SurfaceManipulator._clear_hook_was_run: # Hack due to Nathan Dunfield (http://trac.sagemath.org/ticket/15152) import IPython.lib.inputhook as ih ih.clear_inputhook() SurfaceManipulator._clear_hook_was_run = 1 # NORMAL METHODS def __init__(self, parent, surface=None, surfaces=[]): r""" INPUT: - ``surfaces`` -- a list of surfaces that the editor may modify - ``surface`` -- surface selected by default - ``parent`` -- parent Tk window """ Frame.__init__(self, parent) self._parent = parent self.pack(fill="both", expand=1) # Run something when closing self._parent.wm_protocol("WM_DELETE_WINDOW", self.exit) # Surface currently being manipulated self._surface = None # List of surfaces in editor self._surfaces = [] # More variables to initialize self._currentActor = None # Initialization of GUI self._init_menu() self._init_gui() # Setup surface list for s in surfaces: self.add_surface(s) # Setup initial surface if surface is not None: self.add_surface(surface) self.set_surface(surface) def __repr__(self): return "Surface manipulator" def add_mega_wollmilchsau(self): from geometry.mega_wollmilchsau import MegaWollmilchsau s = MegaWollmilchsau() sm, sb = s.get_bundle() self.set_surface(sb) def add_octagon(self): from geometry.similarity_surface_generators import TranslationSurfaceGenerators ss = TranslationSurfaceGenerators.regular_octagon() ss.edit() def _init_menu(self): self._menubar = Menu(self._parent) menubar = self._menubar self._parent.config(menu=menubar) #new_menu = Menu(menubar, tearoff=0) #new_menu.add_command(label="Billiard Table", command=self.on_new_similarity_surface) file_menu = Menu(menubar, tearoff=0) #file_menu.add_cascade(label="New", menu=new_menu) file_menu.add_command(label="Octagon", command=self.add_octagon) file_menu.add_command(label="MegaWollmilchsau", command=self.add_mega_wollmilchsau) file_menu.add_separator() file_menu.add_command(label="About", command=self.on_about) file_menu.add_command(label="Export PostScript", command=self.on_export) file_menu.add_command(label="Exit", command=self.exit, accelerator="Alt+F4") menubar.add_cascade(label="File", underline=0, menu=file_menu) self._surface_menu = Menu(menubar, tearoff=0) self._selected_surface = IntVar() self._selected_surface.set(-1) menubar.add_cascade(label="Surface", underline=0, menu=self._surface_menu) self._surface_menu.add_radiobutton(label="None", command=self.menu_select_surface, variable=self._selected_surface, value=-1) def _init_gui(self): self._parent.title("FlatSurf Editor") self._canvas = Canvas(self, bg="#444", width=300, height=200) self._canvas.pack(fill="both", expand=1) self.bottom_text = Label(self, text="Welcome to FlatSurf.", anchor="w") self.bottom_text.pack(fill="x", expand=0) self.set_actor(None) def add_surface(self, newsurface): r""" Add a surface to the display list for the window. Returns the index of the new surface in the surface list. """ if (newsurface == None): return -1 i = 0 for s in self._surfaces: if (s == newsurface): return i i = i + 1 self._surfaces.append(newsurface) newsurface.zoom_fit_nice_boundary() self._reset_surface_menu() return len(self._surfaces) - 1 def exit(self): SurfaceManipulator._window_destroyed(self) self._parent.destroy() def find_bundle(self, surface): for surface_bundle in self._surfaces: if surface is surface_bundle.get_surface(): return surface_bundle return None def get_bundle(self): return self._surface def get_bundles(self): return self._surfaces def get_canvas(self): return self._canvas def get_center(self): r""" Return the center of the canvas as a pair of integers. """ return (self.get_width() / 2, self.get_height() / 2) def get_height(self): r""" Return the height of the canvas (an integer). """ return self.get_canvas().winfo_height() def get_parent(self): return self._parent def get_surface_bundle(self): r""" Get the current surface bundle, or None if there is none. """ return self._surface def get_width(self): r""" Return the width of the canvas (an integer). """ return self.get_canvas().winfo_width() def menu_select_surface(self): r""" Called when a surface is selected from a menu. """ i = self._selected_surface.get() if i == -1: self.set_surface(None) else: self.set_surface(self._surfaces[i]) def on_about(self): self.set_text("Written by Vincent Delecroix and Pat Hooper.") def on_delete_junk(self): self._canvas.delete("junk") def on_export(self): r""" Export image as postscript file. """ myFormats = [('PostScript', '*.ps')] fileName = tkFileDialog.asksaveasfilename(parent=self, filetypes=myFormats, title="Save image as...") if len(fileName) > 0: self._canvas.update() self._canvas.postscript(file=fileName) self.set_text("Wrote image to " + fileName) # def on_new_similarity_surface(self): # s = CreateSimilaritySurfaceBundle(len(self._surfaces),self) # if s is not None: # i = self.set_surface(s) # self.set_text("Created new surface `"+self._surfaces[i].get_name()+"'.") def _on_no_surface(self): self._canvas.delete("all") def _on_zoom(self): self.set_actor(ZoomActor(self)) def _on_zoom_box(self): self.set_actor(ZoomBoxActor(self)) def _on_redraw_all(self): if self._surface is not None: self._surface.redraw_all() def _on_recenter(self): self.set_actor(RecenterActor(self)) def _reset_menus(self): r""" Reset all menus except the file and surface menu """ # The following loop removes all but the first two menus (File and Surface). num = len(self._menubar.children) for i in range(num, 2, -1): self._menubar.delete(i) if self._surface != None: self._surface.make_menus(self._menubar) def _reset_surface_menu(self): r""" Reset the surface menu. """ ### This is a hack to get the number of items in the menu: num = self._surface_menu.index(100) + 1 # First we remove everything but the first entry ("None") for i in range(num - 1, 0, -1): #print("removing a child2: "+str(i)+" of "+str(num)) self._surface_menu.delete(i) # Add an entry for every surface in the list. for i in range(len(self._surfaces)): surface = self._surfaces[i] self._surface_menu.add_radiobutton( label=surface.get_name(), command=self.menu_select_surface, variable=self._selected_surface, value=i) def set_text(self, text): self.bottom_text["text"] = text def set_actor(self, actor): r""" Set the current mode of user interaction. """ if (actor != self._currentActor): if self._currentActor != None: self._currentActor.on_deactivate() if (actor == None): self.set_text("Nothing going on.") # Event bindings self._canvas.unbind('<Button-1>') self._canvas.unbind('<Button-2>') self._canvas.unbind('<Button-3>') self._canvas.unbind('<Double-Button-1>') self._canvas.unbind('<Shift-Button-1>') self._canvas.unbind('<Motion>') self.unbind('<FocusIn>') self.unbind('<FocusOut>') #self._canvas.unbind('<ButtonPress-1>') self._canvas.unbind('<ButtonRelease-1>') self._canvas.unbind('<B1-Motion>') self._parent.unbind('<Key>') self._parent.unbind('<KeyRelease>') else: # Event bindings self._canvas.bind('<Button-1>', actor.single_left_click) self._canvas.bind('<Double-Button-1>', actor.double_left_click) self._canvas.bind('<Triple-Button-1>', actor.double_left_click) self._canvas.bind('<Button-2>', actor.single_middle_click) self._canvas.bind('<Double-Button-2>', actor.double_middle_click) self._canvas.bind('<Triple-Button-2>', actor.double_middle_click) self._canvas.bind('<Button-3>', actor.single_right_click) self._canvas.bind('<Double-Button-3>', actor.double_right_click) self._canvas.bind('<Triple-Button-3>', actor.double_right_click) self._canvas.bind('<Shift-Button-1>', actor.shift_click) self._canvas.bind('<Motion>', actor.mouse_moved) #self._canvas.bind('<ButtonPress-1>', actor.left_mouse_pressed) self._canvas.bind('<ButtonRelease-1>', actor.left_mouse_released) self._canvas.bind('<B1-Motion>', actor.left_dragged) self.bind('<FocusIn>', actor.focus_in) self.bind('<FocusOut>', actor.focus_out) self._parent.bind('<Key>', actor.key_press) self._parent.bind('<KeyRelease>', actor.key_release) self._currentActor = actor self._currentActor.on_activate() def set_surface(self, surface_bundle): r""" Set the current surface to the one given by surface_bundle """ i = self.add_surface(surface_bundle) if surface_bundle != self._surface: self._canvas.delete("all") self._surface = surface_bundle self._surface_menu.invoke(i + 1) if i >= 0: self.set_text("Switched to `" + self._surface.get_name() + "'.") self._parent.title(self._surface.get_name()) self._reset_menus() # stop the actor (was a bug). self.set_actor(None) if isinstance(self._surface, EditorRenderer): self._surface.initial_render() else: self.set_text("No surface selected.") self._parent.title("FlatSurf Editor") self._reset_menus() self.set_actor(None) return i def surface_renamed(self): if self._surface is not None: self._parent.title(self._surface.get_name()) self._reset_surface_menu()
def __init__(self, master, visible=True): self.root = master Menu.__init__(self, master.root) # "ticked" menu options self.sc3_plugins = BooleanVar() self.sc3_plugins.set(SC3_PLUGINS) self.cpu_usage = IntVar() self.cpu_usage.set(CPU_USAGE) self.latency = IntVar() self.latency.set(CLOCK_LATENCY) # File menu filemenu = Menu(self, tearoff=0) filemenu.add_command(label="New Document", command=self.root.newfile, accelerator="Ctrl+N") filemenu.add_command(label="Open", command=self.root.openfile, accelerator="Ctrl+O") filemenu.add_command(label="Save", command=self.root.save, accelerator="Ctrl+S") filemenu.add_command(label="Save As...", command=self.root.saveAs) self.add_cascade(label="File", menu=filemenu) # Edit menu editmenu = Menu(self, tearoff=0) editmenu.add_command(label="Undo", command=self.root.undo, accelerator="Ctrl+Z") editmenu.add_command(label="Redo", command=self.root.redo, accelerator="Ctrl+Y") editmenu.add_separator() editmenu.add_command(label="Cut", command=self.root.edit_cut, accelerator="Ctrl+X") editmenu.add_command(label="Copy", command=self.root.edit_copy, accelerator="Ctrl+C") editmenu.add_command(label="Paste", command=self.root.edit_paste, accelerator="Ctrl+V") editmenu.add_command(label="Select All", command=self.root.select_all, accelerator="Ctrl+A") editmenu.add_separator() editmenu.add_command(label="Increase Font Size", command=self.root.zoom_in, accelerator="Ctrl+=") editmenu.add_command(label="Decrease Font Size", command=self.root.zoom_out, accelerator="Ctrl+-") editmenu.add_separator() editmenu.add_command(label="Clear Console", command=self.root.clear_console) editmenu.add_command(label="Toggle Menu", command=self.root.toggle_menu, accelerator="Ctrl+M") editmenu.add_checkbutton(label="Toggle Window Transparency", command=self.root.toggle_transparency, variable=self.root.transparent) self.add_cascade(label="Edit", menu=editmenu) # Note: Alt renders properly to look like Option, so we don't need a # conditional for those shortcuts codemenu = Menu(self, tearoff=0) codemenu.add_command(label="Evaluate Block", command=self.root.exec_block, accelerator="{}+Return".format(ctrl)) codemenu.add_command(label="Evaluate Line", command=self.root.exec_line, accelerator="Alt+Return") codemenu.add_command(label="Clear Scheduling Clock", command=self.root.killall, accelerator="{}+.".format(ctrl)) codemenu.add_separator() codemenu.add_command(label="Toggle Console", command=self.root.toggle_console) codemenu.add_command(label="Export Console Log", command=self.root.export_console) codemenu.add_separator() codemenu.add_checkbutton(label="Use SC3 Plugins", command=self.root.toggle_sc3_plugins, variable=self.sc3_plugins) codemenu.add_separator() codemenu.add_checkbutton(label="Listen for connections", command=self.root.allow_connections, variable=self.root.listening_for_connections) self.add_cascade(label="Language", menu=codemenu) # Help helpmenu = Menu(self, tearoff=0) helpmenu.add_command(label="Display help message", comman=self.root.help, accelerator="{}+{}".format( ctrl, self.root.help_key)) helpmenu.add_command(label="Visit FoxDot Homepage", command=self.root.openhomepage) helpmenu.add_command(label="Documentation", command=self.root.opendocumentation) helpmenu.add_separator() cpu_menu = Menu(self, tearoff=0) cpu_menu.add_radiobutton(label="Low", variable=self.cpu_usage, value=0, command=self.set_cpu_usage) cpu_menu.add_radiobutton(label="Medium", variable=self.cpu_usage, value=1, command=self.set_cpu_usage) cpu_menu.add_radiobutton(label="High", variable=self.cpu_usage, value=2, command=self.set_cpu_usage) helpmenu.add_cascade(label="CPU Usage", menu=cpu_menu) lat_menu = Menu(self, tearoff=0) lat_menu.add_radiobutton(label="Low", variable=self.latency, value=0, command=self.set_latency) lat_menu.add_radiobutton(label="Medium", variable=self.latency, value=1, command=self.set_latency) lat_menu.add_radiobutton(label="High", variable=self.latency, value=2, command=self.set_latency) helpmenu.add_cascade(label="Clock Latency", menu=lat_menu) helpmenu.add_separator() helpmenu.add_command(label="Open Samples Folder", command=self.root.open_samples_folder) helpmenu.add_command(label="Open config file (advanced)", command=self.root.open_config_file) self.add_cascade(label="Help & Settings", menu=helpmenu) # Tutorials tutorialmenu = Menu(self, tearoff=0) for tutorial in GET_TUTORIAL_FILES(): filename = os.path.basename(tutorial).replace(".py", "") data = filename.split("_") num = data[0] name = " ".join(data[1:]).title() tutorialmenu.add_command(label="Load Tutorial {}: {}".format( num, name), command=partial(self.root.loadfile, tutorial)) self.add_cascade(label="Tutorials", menu=tutorialmenu) # Add to root self.visible = visible if self.visible: master.root.config(menu=self)
class TreeNode: def __init__(self, canvas, parent, item, menuList = []): self.canvas = canvas self.parent = parent self.item = item self.state = 'collapsed' self.selected = 0 self.children = {} self.kidKeys = [] self.x = self.y = None self.iconimages = {} # cache of PhotoImage instances for icons self.menuList = menuList self.menuVar = IntVar() self.menuVar.set(0) self._popupMenu = None self.image_id = None if self.menuList: if self.menuList[-1] == 'Separator': self.menuList = self.menuList[:-1] self._popupMenu = Menu(self.canvas, tearoff = 0) for i in range(len(self.menuList)): item = self.menuList[i] if item == 'Separator': self._popupMenu.add_separator() else: self._popupMenu.add_radiobutton( label = item, variable = self.menuVar, value = i, indicatoron = 0, command = self.popupMenuCommand) def destroy(self): for key in self.kidKeys: c = self.children[key] del self.children[key] c.destroy() self.parent = None def geticonimage(self, name): try: return self.iconimages[name] except KeyError: pass file, ext = os.path.splitext(name) ext = ext or ".gif" fullname = os.path.join(ICONDIR, file + ext) image = PhotoImage(master=self.canvas, file=fullname) self.iconimages[name] = image return image def select(self, event=None): if self.selected: return self.deselectall() self.selected = 1 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() self.item.OnSelect(event) def deselect(self, event=None): if not self.selected: return self.selected = 0 if self.parent != None: if self.parent.state == 'expanded': self.canvas.delete(self.image_id) self.drawicon() self.drawtext() def deselectall(self): if self.parent: self.parent.deselectall() else: self.deselecttree() def deselecttree(self): if self.selected: self.deselect() for key in self.kidKeys: child = self.children[key] child.deselecttree() def flip(self, event=None): if self.state == 'expanded': self.collapse() else: self.expand() self.item.OnDoubleClick() return "break" def popupMenu(self, event=None): if self._popupMenu: self._popupMenu.post(event.widget.winfo_pointerx(), event.widget.winfo_pointery()) return "break" def popupMenuCommand(self): command = self.menuList[self.menuVar.get()] self.item.MenuCommand(command) if self.parent and (command != 'Update Explorer'): # Update parent to try to keep explorer up to date self.parent.update() def expand(self, event=None): if not self.item.IsExpandable(): return if self.state != 'expanded': self.state = 'expanded' self.update() self.view() def collapse(self, event=None): if self.state != 'collapsed': self.state = 'collapsed' self.update() def view(self): top = self.y - 2 bottom = self.lastvisiblechild().y + 17 height = bottom - top visible_top = self.canvas.canvasy(0) visible_height = self.canvas.winfo_height() visible_bottom = self.canvas.canvasy(visible_height) if visible_top <= top and bottom <= visible_bottom: return x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion']) if top >= visible_top and height <= visible_height: fraction = top + height - visible_height else: fraction = top fraction = float(fraction) / y1 self.canvas.yview_moveto(fraction) def reveal(self): # Make sure all parent nodes are marked as expanded parent = self.parent while parent: if parent.state == 'collapsed': parent.state = 'expanded' parent = parent.parent else: break # Redraw tree accordingly self.update() # Bring this item into view self.view() def lastvisiblechild(self): if self.kidKeys and self.state == 'expanded': return self.children[self.kidKeys[-1]].lastvisiblechild() else: return self def update(self): if self.parent: self.parent.update() else: oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() self.canvas.delete(Tkinter.ALL) # XXX could be more subtle self.draw(7, 2) x0, y0, x1, y1 = self.canvas.bbox(Tkinter.ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor def draw(self, x, y): # XXX This hard-codes too many geometry constants! self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': return y+17 # draw children sublist = self.item._GetSubList() if not sublist: # IsExpandable() was mistaken; that's allowed return y+17 self.kidKeys = [] for item in sublist: key = item.GetKey() if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) self.children[key] = child self.kidKeys.append(key) # Remove unused children for key in self.children.keys(): if key not in self.kidKeys: del(self.children[key]) cx = x+20 cy = y+17 cylast = 0 for key in self.kidKeys: child = self.children[key] cylast = cy self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50") cy = child.draw(cx, cy) if child.item.IsExpandable(): if child.state == 'expanded': iconname = "minusnode" callback = child.collapse else: iconname = "plusnode" callback = child.expand image = self.geticonimage(iconname) id = self.canvas.create_image(x+9, cylast+7, image=image) # XXX This leaks bindings until canvas is deleted: self.canvas.tag_bind(id, "<1>", callback) self.canvas.tag_bind(id, "<Double-1>", lambda x: None) id = self.canvas.create_line(x+9, y+10, x+9, cylast+7, ##stipple="gray50", # XXX Seems broken in Tk 8.0.x fill="gray50") self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2 return cy def drawicon(self): if self.selected: imagename = (self.item.GetSelectedIconName() or self.item.GetIconName() or "openfolder") else: imagename = self.item.GetIconName() or "folder" image = self.geticonimage(imagename) id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image) self.image_id = id self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) self.canvas.tag_bind(id, "<3>", self.popupMenu) def drawtext(self, text=None): textx = self.x+20-1 texty = self.y-1 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", text=labeltext) self.canvas.tag_bind(id, "<1>", self.select) self.canvas.tag_bind(id, "<Double-1>", self.flip) x0, y0, x1, y1 = self.canvas.bbox(id) textx = max(x1, 200) + 10 if text==None: text = self.item.GetText() or "<no text>" try: self.entry except AttributeError: pass else: self.edit_finish() try: label = self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) if self.selected: self.label.configure(fg="white", bg="darkblue") else: fg = self.item.GetTextFg() self.label.configure(fg=fg, bg="white") id = self.canvas.create_window(textx, texty, anchor="nw", window=self.label) self.label.bind("<1>", self.select_or_edit) self.label.bind("<Double-1>", self.flip) self.label.bind("<3>", self.popupMenu) # Update text if necessary if text != self.label['text']: self.label['text'] = text self.text_id = id def select_or_edit(self, event=None): if self.selected and self.item.IsEditable(): text = self.item.GetTextForEdit() self.label['text'] = text self.drawtext(text) self.edit(event) else: self.select(event) def edit(self, event=None): self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) self.entry.selection_range(0, Tkinter.END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("<Return>", self.edit_finish) self.entry.bind("<Escape>", self.edit_cancel) def edit_finish(self, event=None): try: entry = self.entry del self.entry except AttributeError: return text = entry.get() entry.destroy() if text and text != self.item.GetText(): self.item.SetText(text) text = self.item.GetText() self.label['text'] = text self.drawtext() self.canvas.focus_set() def edit_cancel(self, event=None): self.drawtext() self.canvas.focus_set() def find(self, searchKey): # Search for a node who's key matches the given key # Is it this node if searchKey == self.item.GetKey(): return self # Nope, check the children sublist = self.item._GetSubList() for item in sublist: key = item.GetKey() # Use existing child or create new TreeNode if none exists if self.children.has_key(key): child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) # Update local list of children and keys self.children[key] = child self.kidKeys.append(key) # See if node is child (or one of child's descendants) retVal = child.find(searchKey) if retVal: return retVal # Not here return None
def _init_menubar(self, parent): menubar = Menu(parent) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Reset Parser', underline=0, command=self.reset, accelerator='Del') filemenu.add_command(label='Print to Postscript', underline=0, command=self.postscript, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label='Edit Grammar', underline=5, command=self.edit_grammar, accelerator='Ctrl-g') editmenu.add_command(label='Edit Text', underline=5, command=self.edit_sentence, accelerator='Ctrl-t') menubar.add_cascade(label='Edit', underline=0, menu=editmenu) rulemenu = Menu(menubar, tearoff=0) rulemenu.add_command(label='Step', underline=1, command=self.step, accelerator='Space') rulemenu.add_separator() rulemenu.add_command(label='Shift', underline=0, command=self.shift, accelerator='Ctrl-s') rulemenu.add_command(label='Reduce', underline=0, command=self.reduce, accelerator='Ctrl-r') rulemenu.add_separator() rulemenu.add_command(label='Undo', underline=0, command=self.undo, accelerator='Ctrl-u') menubar.add_cascade(label='Apply', underline=0, menu=rulemenu) viewmenu = Menu(menubar, tearoff=0) viewmenu.add_checkbutton(label="Show Grammar", underline=0, variable=self._show_grammar, command=self._toggle_grammar) viewmenu.add_separator() viewmenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) viewmenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) viewmenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) viewmenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=18, command=self.resize) viewmenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=24, command=self.resize) menubar.add_cascade(label='View', underline=0, menu=viewmenu) animatemenu = Menu(menubar, tearoff=0) animatemenu.add_radiobutton(label="No Animation", underline=0, variable=self._animate, value=0) animatemenu.add_radiobutton(label="Slow Animation", underline=0, variable=self._animate, value=20, accelerator='-') animatemenu.add_radiobutton(label="Normal Animation", underline=0, variable=self._animate, value=10, accelerator='=') animatemenu.add_radiobutton(label="Fast Animation", underline=0, variable=self._animate, value=4, accelerator='+') menubar.add_cascade(label="Animate", underline=1, menu=animatemenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label='About', underline=0, command=self.about) helpmenu.add_command(label='Instructions', underline=0, command=self.help, accelerator='F1') menubar.add_cascade(label='Help', underline=0, menu=helpmenu) parent.config(menu=menubar)
class App(Frame): def __init__(self, master=None): self.master = master Frame.__init__(self, master, relief=SUNKEN, bd=2) self.gcode = [] self.slicing = False self.printing = False self.connected = False self.monitorTemp = False self.paused = False self.sdpresent = False self.sdlisting = False self.sdchecking = False self.sdprinting = False self.sdpaused = False self.sduploading = False self.sdbytes = 0 self.sdmaxbytes = 0 self.insidelisting = False self.readingFirmware = False self.sdfiles = [] self.bedtemp = float(0) self.bedtarget = float(0) self.exttemp = float(0) self.exttarget = float(0) self.acceleration = 0 self.m114count = 0 self.speedcount = 0 self.location = [0, 0, 0, 0] self.pausePoint = [0, 0, 0, 0] self.percent = 0.0 self.ets = "??" self.gcodeInfo = None self.GCodeFile = None self.StlFile = None self.Profile = None self.printStartLine = 0 self.startTime = 0 self.endTime = 0 self.elapsedTime = 0 self.FanSpeed = 0 self.FeedMultiply = 100 self.ExtrudeMultiply = 100 self.timingReport = None self.filamentReport = None self.measurementsReport = None self.macroButtons = None self.rpt1re = re.compile(" *T:([0-9\.]+) *E:[0-9\.]+ *B:([0-9\.]+)") self.rpt2re = re.compile(" *T:([0-9\.]+) *E:[0-9\.]+ *W:.*") self.locrptre = re.compile("^X:([0-9\.\-]+)Y:([0-9\.\-]+)Z:([0-9\.\-]+)E:([0-9\.\-]+) *Count") self.speedrptre = re.compile("Fan speed:([0-9]+) Feed Multiply:([0-9]+) Extrude Multiply:([0-9]+)") self.sdre = re.compile("SD printing byte *([0-9]+) *\/ *([0-9]+)") self.printer = printcore() self.settings = Settings() self.settings.cmdFolder = cmd_folder self.logger = Logger(self) if self.settings.speedcommand is not None: allow_while_printing.append(self.settings.speedcommand) self.acceleration = self.settings.acceleration self.dataLoggers = {} for d in DLLIST: self.dataLoggers[d] = DataLogger(self, d) self.skeinforge = Skeinforge(self.settings) self.slic3r = Slic3r(self.settings) self.httpServer = RepRapServer(self, self.printer, self.settings, self.logger, self.settings.port) self.menubar = Menu(self) self.filemenu = Menu(self.menubar, tearoff=0) self.menubar.add_cascade(label="File", menu=self.filemenu) self.filemenu.add_command(label="Slice", command=self.openSTLFile) self.filemenu.add_command(label="Load GCode", command=self.openGCodeFile) self.slicemenuindex = self.filemenu.index("Slice") self.loadgcodemenuindex = self.filemenu.index("Load GCode") self.filemenu.add_separator() self.filemenu.add_command(label="Exit", command=self.quitApp) self.editmenu = Menu(self.menubar, tearoff=0) self.menubar.add_cascade(label="Edit", menu=self.editmenu) self.editmenu.add_command(label="Settings", command=self.editSettings) self.editmenu.add_command(label="Firmware Settings", command=self.FirmwareSettings) self.editmenu.add_separator() self.editmenu.add_command(label=GCODE_MENU_TEXT, command=self.doGEdit, state=DISABLED) self.slicermenu = Menu(self.menubar, tearoff=0) self.menubar.add_cascade(label="Slicer", menu=self.slicermenu) self.rbSlicer = StringVar() self.slicermenu.add_radiobutton( label="Skeinforge", command=self.selSlicer, value=SKEINFORGE, variable=self.rbSlicer ) self.slicermenu.add_command(label="Settings", command=self.skeinforgeSettings) self.slicermenu.add_command(label="Choose Profile", command=self.chooseSFProfile) self.SFprofileindex = self.slicermenu.index("Choose Profile") self.setSFProfileMenuText() self.slicermenu.add_command(label="Alterations", command=self.doEditAlterations) self.slicermenu.add_separator() self.slicermenu.add_radiobutton(label="Slic3r", command=self.selSlicer, value=SLIC3R, variable=self.rbSlicer) self.slicermenu.add_command(label="Settings", command=self.slic3rSettings) self.slicermenu.add_command(label="Choose Profile", command=self.chooseS3Profile) self.S3profileindex = self.slicermenu.index("Choose Profile") self.setS3ProfileMenuText() self.rbSlicer.set(self.settings.slicer) self.macromenu = Menu(self.menubar, tearoff=0) self.menubar.add_cascade(label="Macros", menu=self.macromenu) self.macromenu.add_command(label="New", command=self.doNewMacro) self.macromenu.add_command(label="Edit", command=self.doEditMacro) self.macromenu.add_command(label="Delete", command=self.doDelMacro) self.macromenu.add_separator() self.cbShowMacroButtons = BooleanVar() self.cbShowMacroButtons.set(self.settings.showmacrobuttons) self.macromenu.add_checkbutton( label="Show Macro Buttons", command=self.doShowButtons, onvalue=True, offvalue=False, variable=self.cbShowMacroButtons, ) self.macromenu.add_separator() self.runmacromenu = Menu(self.macromenu, tearoff=0) self.loadMacros() self.macromenu.add_cascade(label="Run", menu=self.runmacromenu) self.reportmenu = Menu(self.menubar, tearoff=0) self.menubar.add_cascade(label="View", menu=self.reportmenu) self.cbShowPrevious = BooleanVar() self.cbShowPrevious.set(self.settings.showprevious) self.reportmenu.add_checkbutton( label="Show Previous Layer", command=self.toggleShowPrevious, onvalue=True, offvalue=False, variable=self.cbShowPrevious, ) self.cbShowMoves = BooleanVar() self.cbShowMoves.set(self.settings.showmoves) self.reportmenu.add_checkbutton( label="Show Non-extrusion Moves", command=self.toggleShowMoves, onvalue=True, offvalue=False, variable=self.cbShowMoves, ) self.reportmenu.add_separator() self.reportmenu.add_command(label="Show Hours of Usage", command=self.doDataLogReport) self.reportmenu.add_command(label="Reset Hours of Usage", command=self.doDataLogReset) self.reportmenu.add_separator() self.reportmenu.add_command(label="Layer by Layer Timing", command=self.doTimingReport) self.reportmenu.add_command(label="Layer by Layer Filament Usage", command=self.doFilamentReport) self.reportmenu.add_command(label="GCode Measurements", command=self.doMeasurementsReport) self.toolsmenu = Menu(self.menubar, tearoff=0) n = 0 if self.settings.platercmd is not None: n += 1 self.toolsmenu.add_command(label="Plater", command=self.doPlater) if self.settings.gcodeviewcmd is not None: n += 1 self.toolsmenu.add_command(label="GCode Viewer", command=self.doGCodeView) if self.settings.stlviewcmd is not None: n += 1 self.toolsmenu.add_command(label="STL Viewer", command=self.doSTLView) if self.settings.openscadcmd is not None: n += 1 self.toolsmenu.add_command(label="OpenSCAD", command=self.doOpenSCAD) if n > 0: self.menubar.add_cascade(label="Tools", menu=self.toolsmenu) try: self.master.config(menu=self.menubar) except AttributeError: self.master.tk.call(master, "config", "-menu", self.menubar) self.toolbar = ToolBar(self, self.printer, self.settings, self.logger) self.toolbar.grid(row=1, column=1, columnspan=4, sticky=W) self.ctl = MoveControl(self, self.printer, self.settings, self.logger) self.ctl.grid(row=2, column=1, rowspan=3, sticky=N) self.extr = Extruder(self, self.printer, self.settings, self.logger) self.extr.grid(row=2, column=2, rowspan=1, sticky=N + E + W) self.temps = Temperatures(self, self.printer, self.settings, self.logger) self.temps.grid(row=3, column=2, rowspan=2, sticky=N + E + W) self.gc = GcFrame(self, None, [], self.settings, self.logger) self.gc.grid(row=2, column=3, rowspan=3, sticky=N) self.statline = Status(self, self.printer, self.settings, self.logger) self.statline.grid(row=5, column=1, columnspan=4, sticky=E + W) self.logger.grid(row=2, column=4, rowspan=2, sticky=N + E + W) self.sendgcode = SendGCode(self, self.printer, self.settings, self.logger) self.sendgcode.grid(row=4, column=4, sticky=N + E + W) self.printer.errorcb = self.errorcb self.printer.sendcb = self.sendcb self.printer.recvcb = self.recvcb self.sd = SDCard(self, self.printer, self.settings, self.logger) self.firmware = FirmwareParms(self, self.printer, self.settings, self.logger) self.bind(MWM_FIRMWARECOMPLETE, self.firmwareReportComplete) self.bind(MWM_SLICERCOMPLETE, self.sliceComplete) self.bind(MWM_GCODELOADCOMPLETE, self.loadgcodeFinished) self.bind(MWM_GEDITMEASURECOMPLETE, self.geditMeasureComplete) self.bind(MWM_REQUESTPOSITIONREPORT, self.requestPosition) self.doShowButtons() def doStopAll(self): self.toolbar.doPause() self.temps.doOffBed() self.temps.doOffExt() def requestPosition(self, *arg): self.m114count += 1 self.printer.send_now("M400") # finish all moves self.printer.send_now("M114") def doShowButtons(self): self.settings.showmacrobuttons = self.cbShowMacroButtons.get() == 1 self.settings.setModified() if self.settings.showmacrobuttons: self.macroButtons = MacroButtons(self, self.printer, self.settings, self.logger) else: if self.macroButtons: self.macroButtons.close() self.macroButtons = None def toggleShowPrevious(self): self.settings.showprevious = self.cbShowPrevious.get() == 1 self.settings.setModified() self.gc.drawCanvas() def toggleShowMoves(self): self.settings.showmoves = self.cbShowMoves.get() == 1 self.settings.setModified() self.gc.drawCanvas() def selSlicer(self): self.settings.slicer = self.rbSlicer.get() self.settings.setModified() self.toolbar.setSliceText() def macroButtonClose(self): self.settings.showmacrobuttons = False self.settings.setModified() self.cbShowMacroButtons.set(False) def firmwareReportComplete(self, *arg): p = self.firmware.reportComplete() if p is not None: self.acceleration = p["m204_s"].getFlash() print "Retrieved acc value of ", self.acceleration def openSTLFile(self): if self.printing: self.logger.logMsg("Cannot open a new file while printing") return if self.StlFile is None: fn = askopenfilename( filetypes=[("STL files", "*.stl"), ("G Code files", "*.gcode")], initialdir=self.settings.lastdirectory ) else: fn = askopenfilename( filetypes=[("STL files", "*.stl"), ("G Code files", "*.gcode")], initialdir=self.settings.lastdirectory, initialfile=os.path.basename(self.StlFile), ) if fn: self.settings.lastdirectory = os.path.dirname(os.path.abspath(fn)) self.settings.setModified() if fn.lower().endswith(".gcode"): self.StlFile = None self.loadgcode(fn) elif fn.lower().endswith(".stl"): self.StlFile = fn self.doSlice(fn) else: self.logger.logMsg("Invalid file type") def openGCodeFile(self): if self.printing: self.logger.logMsg("Cannot open a new file while printing") return fn = askopenfilename(filetypes=[("G Code files", "*.gcode")], initialdir=self.settings.lastdirectory) if fn: self.settings.lastdirectory = os.path.dirname(os.path.abspath(fn)) self.settings.setModified() if fn.lower().endswith(".gcode"): self.StlFile = None self.loadgcode(fn) else: self.logger.logMsg("Invalid file type") else: self.toolbar.clearCancelMode() def loadgcode(self, fn): self.GCodeFile = fn self.gcodeloadSuccess = True self.toolbar.setLoading(True) self.loader = threading.Thread(target=self.loadgcodeThread) self.loader.daemon = True self.loader.start() def loadgcodeFinished(self, *arg): self.toolbar.setLoading(False) if self.gcodeloadSuccess: self.showMetrics() def loadgcodeThread(self): try: self.gcode = [] l = list(open(self.GCodeFile)) for s in l: self.gcode.append(s.rstrip()) self.logger.logMsg("read %d lines from %s" % (len(self.gcode), os.path.basename(self.GCodeFile))) except: self.logger.logMsg("Problem reading gcode from %s" % self.GCodeFile) self.gcode = [] self.GCodeFile = None if len(self.gcode) != 0: self.logger.logMsg("Processing...") self.gc.loadFile(self.GCodeFile, self.gcode) self.printStartLine = self.gc.getPrintStartLine() self.gcodeInfo = GCode(self.gcode) self.logger.logMsg("Measuring...") self.gcodeInfo.measure(self.acceleration) self.estEta = self.gcodeInfo.totalduration self.timeLayers = self.gcodeInfo.layerdurations else: self.gcodeloadSuccess = False self.event_generate(MWM_GCODELOADCOMPLETE) def replace(self, s, slicer): if slicer == SLIC3R: d = os.path.expandvars(os.path.expanduser(self.settings.s3profiledir)) profile = os.path.join(d, self.slic3r.getProfile() + ".ini") else: profile = self.skeinforge.getProfile() d = {} d["%starttime%"] = time.strftime("%H:%M:%S", time.localtime(self.startTime)) d["%endtime%"] = time.strftime("%H:%M:%S", time.localtime(self.endTime)) d["%elapsed%"] = formatElapsed(self.elapsedTime) d["%profile%"] = profile d["%slicer%"] = self.settings.slicer if self.StlFile is not None: d["%stlbase%"] = os.path.basename(self.StlFile) d["%stl%"] = self.StlFile else: d["%stlbase%"] = "" d["%stl%"] = "" if self.GCodeFile is not None: d["%gcodebase%"] = os.path.basename(self.GCodeFile) d["%gcode%"] = self.GCodeFile else: d["%gcodebase%"] = "" d["%gcode%"] = "" for t in d.keys(): if d[t] is not None: s = s.replace(t, d[t]) s = s.replace('""', "") return s def showMetrics(self): if len(self.gcode) != 0: self.paused = False self.toolbar.initializeToolbar() self.toolbar.checkAllowPrint() self.allowGEdit() self.logger.logMsg( "Width: %f mm (%f -> %f)" % (self.gcodeInfo.width, self.gcodeInfo.xmin, self.gcodeInfo.xmax) ) self.logger.logMsg( "Depth: %f mm (%f -> %f)" % (self.gcodeInfo.depth, self.gcodeInfo.ymin, self.gcodeInfo.ymax) ) self.logger.logMsg( "Height: is %f mm (%f -> %f)" % (self.gcodeInfo.height, self.gcodeInfo.zmin, self.gcodeInfo.zmax) ) self.logger.logMsg("Total extrusion length: %f mm" % self.gcodeInfo.filament_length()) self.logger.logMsg("Estimated print time: %s" % formatElapsed(self.estEta)) def calcEta(self, line, timeThusFar): foundLayer = False for i in range(len(self.timeLayers)): if self.timeLayers[i][0] > line: foundLayer = True break if not foundLayer: return 0 currentLayer = i - 1 if currentLayer < 0: return 0 totalInLayer = self.timeLayers[i][0] - self.timeLayers[currentLayer][0] printedInLayer = line - self.timeLayers[currentLayer][0] pct = printedInLayer / float(totalInLayer) thisLayerTime = (self.timeLayers[currentLayer][1]) * pct ratio = (self.timeLayers[currentLayer][2] - self.timeLayers[currentLayer][1] + thisLayerTime) / float( timeThusFar ) ne = self.estEta / float(ratio) return ne - timeThusFar def doTimingReport(self): if not self.printing: self.logger.logMsg("Only available while printing") return self.timingReport = TimingReport(self, self.printer, self.settings, self.logger) def closeTimingReport(self): if self.timingReport is not None: self.timingReport.cleanup() self.timingReport.destroy() self.timingReport = None def doMeasurementsReport(self): if not self.gcodeInfo: self.logger.logMsg("Only available when GCode loaded") return self.measurementsReport = MeasurementsReport(self, self.printer, self.settings, self.logger) def closeMeasurementsReport(self): if self.measurementsReport is not None: self.measurementsReport.destroy() self.measurementsReport = None def doFilamentReport(self): if not self.gcodeInfo: self.logger.logMsg("Only available when GCode loaded") return if len(self.gcodeInfo.filLayers) == 0: self.logger.logMsg("No filament usage in this gcode") return self.filamentReport = FilamentReport(self, self.printer, self.settings, self.logger) def closeFilamentReport(self): if self.filamentReport is not None: self.filamentReport.destroy() self.filamentReport = None def closeAllReports(self): self.closeTimingReport() self.closeFilamentReport() self.closeMeasurementsReport() def doPlater(self): s = self.replace(self.settings.platercmd, self.settings.slicer) args = shlex.split(os.path.expandvars(os.path.expanduser(s))) subprocess.Popen(args, close_fds=True) def doGCodeView(self): s = self.replace(self.settings.gcodeviewcmd, self.settings.slicer) args = shlex.split(os.path.expandvars(os.path.expanduser(s))) subprocess.Popen(args, close_fds=True) def doSTLView(self): s = self.replace(self.settings.stlviewcmd, self.settings.slicer) self.logger.logMsg(s) args = shlex.split(os.path.expandvars(os.path.expanduser(s))) subprocess.Popen(args, close_fds=True) def doOpenSCAD(self): s = self.replace(self.settings.openscadcmd, self.settings.slicer) args = shlex.split(os.path.expandvars(os.path.expanduser(s))) subprocess.Popen(args, close_fds=True) def doSlice(self, fn): self.paused = False self.toolbar.initializeToolbar() self.slicerfn = fn self.slicing = True self.slicerCancel = False self.toolbar.setCancelMode() if self.settings.slicer == SLIC3R: self.GCodeFile = fn.replace(".stl", ".gcode") cmd = self.replace(os.path.expandvars(os.path.expanduser(self.settings.s3cmd)), SLIC3R) else: self.GCodeFile = fn.replace(".stl", "_export.gcode") cmd = self.replace(os.path.expandvars(os.path.expanduser(self.settings.sfcmd)), SKEINFORGE) self.slicer = threading.Thread(target=self.slicerThread, args=(cmd,)) self.slicer.daemon = True self.slicer.start() def slicerThread(self, cmd): args = shlex.split(cmd) p = subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) obuf = "" while not self.slicerCancel: o = p.stdout.read(1) if o == "": break if o == "\r" or o == "\n": self.logger.logMsg(obuf) obuf = "" elif ord(o) < 32: pass else: obuf += o if self.slicerCancel: p.kill() p.wait() self.event_generate(MWM_SLICERCOMPLETE) def sliceComplete(self, *arg): self.slicing = False self.toolbar.clearCancelMode() if self.slicerCancel: self.slicerCancel = False self.logger.logMsg("Slicing was cancelled") return self.logger.logMsg("Slicing has completed successfully") if os.path.exists(self.GCodeFile): self.loadgcode(self.GCodeFile) else: self.logger.logMsg("Unable to find slicer output file: %s" % self.GCodeFile) def allowGEdit(self): self.editmenu.entryconfig(self.editmenu.index(GCODE_MENU_TEXT), state=NORMAL) def allowSliceMenu(self, flag=True): s = NORMAL if not flag: s = DISABLED self.filemenu.entryconfig(self.slicemenuindex, state=s) def allowLoadGCodeMenu(self, flag=True): s = NORMAL if not flag: s = DISABLED self.filemenu.entryconfig(self.loadgcodemenuindex, state=s) def doGEdit(self): GEditor(self, self.gcode, None) def geditMeasureComplete(self, *arg): self.showMetrics() def gEditSave(self, newgcode, fn, editwindow): if fn == None: self.gcode = newgcode self.meas = threading.Thread(target=self.geditMeasureThread) self.meas.daemon = True self.meas.start() return False else: try: f = open(fn, "w") for l in newgcode: f.write(l + "\n") f.close() self.logger.logMsg("Alterations %s successfully saved" % fn) return True except: self.logger.logMsg("Unable to open %s for output" % fn) return False def geditMeasureThread(self): self.logger.logMsg("Processing...") self.gcodeInfo = GCode(self.gcode) self.logger.logMsg("Measuring...") self.gcodeInfo.measure(self.acceleration) self.estEta = self.gcodeInfo.totalduration self.timeLayers = self.gcodeInfo.layerdurations self.event_generate(MWM_GEDITMEASURECOMPLETE) def doSD(self): if not self.sd.isActive(): self.sd.start() def setToolbarSDPrint(self): self.toolbar.setSDPrint() def startUpload(self): self.sduploading = True self.toolbar.doPrint() def printerAvailable(self, silent=False, cmd="xx"): if not self.connected: if not silent: self.logger.logMsg("Unable to comply - printer not on-line") return False if (self.printing or self.sdprinting) and cmd.upper() not in allow_while_printing: if not silent: self.logger.logMsg("Unable to comply - currently printing") return False return True def printerConnected(self, flag): self.sendgcode.activate(flag) self.connected = flag if flag: self.firmware.start(True) def updateScreen(self): if self.printing: self.gc.updatePrintProgress(self.printer.queueindex) def errorcb(self, s): self.logger.logMsg(s.rstrip()) def sendcb(self, s): # self.logger.logMsg("Sent: %s" % s) pass def recvcb(self, s): if self.readingFirmware: if "M92" in s: X = self.parseG(s, "X") Y = self.parseG(s, "Y") Z = self.parseG(s, "Z") E = self.parseG(s, "E") self.firmware.m92(X, Y, Z, E) return elif "M201" in s: X = self.parseG(s, "X") Y = self.parseG(s, "Y") Z = self.parseG(s, "Z") E = self.parseG(s, "E") self.firmware.m201(X, Y, Z, E) return elif "M203" in s: X = self.parseG(s, "X") Y = self.parseG(s, "Y") Z = self.parseG(s, "Z") E = self.parseG(s, "E") self.firmware.m203(X, Y, Z, E) return elif "M204" in s: S = self.parseG(s, "S") T = self.parseG(s, "T") self.firmware.m204(S, T) return elif "M205" in s: S = self.parseG(s, "S") T = self.parseG(s, "T") B = self.parseG(s, "B") X = self.parseG(s, "X") Z = self.parseG(s, "Z") E = self.parseG(s, "E") self.firmware.m205(S, T, B, X, Z, E) return elif "M206" in s: X = self.parseG(s, "X") Y = self.parseG(s, "Y") Z = self.parseG(s, "Z") self.firmware.m206(X, Y, Z) return elif "M301" in s: P = self.parseG(s, "P") I = self.parseG(s, "I") D = self.parseG(s, "D") self.firmware.m301(P, I, D) return elif ( ("Steps per unit" in s) or ("Acceleration:" in s) or ("Maximum Acceleration" in s) or ("Maximum feedrates" in s) or ("Advanced variables" in s) or ("Home offset" in s) or ("PID settings" in s) or ("Stored settings retreived" in s) ): return if self.sdchecking: if "SD card ok" in s: self.sdchecking = False self.sdpresent = True self.sd.sdCheckComplete(True) return elif "SD init fail" in s: self.sdchecking = False self.sdpresent = False self.sd.sdCheckComplete(False) return if self.sdlisting: if "Begin file list" in s: self.insidelisting = True self.sdfiles = [] return elif "End file list" in s: self.sdlisting = False self.insidelisting = False self.sd.sdListComplete(self.sdfiles) return else: if self.insidelisting: self.sdfiles.append(s.strip()) return if "SD printing byte" in s: m = self.sdre.search(s) t = m.groups() if len(t) != 2: return self.sdbytes = int(t[0]) self.sdmaxbytes = int(t[1]) return elif "Done printing file" in s: if self.sdprinting: self.sdprinting = False self.toolbar.clearSDPrint() m = self.speedrptre.search(s) if m: t = m.groups() if len(t) >= 3: if self.settings.forcefanspeed: ns = int(t[0]) if ns != self.FanSpeed: self.logger.logMsg("Asserting fan speed of %d" % self.FanSpeed) self.toolbar.forceFanSpeed(self.FanSpeed) else: self.FanSpeed = int(t[0]) self.FeedMultiply = int(t[1]) self.ExtrudeMultiply = int(t[2]) self.toolbar.syncSpeeds() if self.speedcount > 0: self.speedcount -= 1 return m = self.locrptre.search(s) if m: t = m.groups() if len(t) >= 4: self.location[XAxis] = float(t[0]) self.location[YAxis] = float(t[1]) self.location[ZAxis] = float(t[2]) self.location[EAxis] = float(t[3]) if self.m114count != 0: self.m114count -= 1 if self.m114count < 0: self.m114count = 0 return if s.startswith("ok"): return if s.startswith("echo:"): s = s[5:] m = self.rpt1re.search(s) if m: t = m.groups() if len(t) >= 1: self.exttemp = float(t[0]) if len(t) >= 2: self.bedtemp = float(t[1]) self.temps.updateTempDisplay(self.bedtemp, self.exttemp) m = self.rpt2re.search(s) if m: t = m.groups() if len(t) >= 1: self.exttemp = float(t[0]) self.temps.updateTempDisplay(self.bedtemp, self.exttemp) self.logger.logMsg(s.rstrip()) def parseG(self, s, v): l = s.split() for p in l: if p.startswith(v): try: return float(p[1:]) except: return None return None def editSettings(self): # TO DO pass def slic3rSettings(self): s = self.replace(self.settings.s3config, SLIC3R) args = shlex.split(os.path.expandvars(os.path.expanduser(s))) subprocess.Popen(args, close_fds=True) def skeinforgeSettings(self): s = self.replace(self.settings.sfconfig, SKEINFORGE) args = shlex.split(os.path.expandvars(os.path.expanduser(s))) subprocess.Popen(args, close_fds=True) def chooseS3Profile(self): pl = self.slic3r.getProfileOptions() if len(pl) > 0: l = ListBoxChoice( clist=pl.keys(), master=self, title="Choose Slic3r Profile", message="Choose Slic3r profile" ) pn = l.returnValue() if pn: self.slic3r.setProfile(pn) self.setS3ProfileMenuText() self.toolbar.setSliceText() else: self.logger.logMsg("Unable to retrieve available slic3r profiles") def chooseSFProfile(self): pl = self.skeinforge.getProfileOptions() if len(pl) > 0: l = ListBoxChoice( clist=pl.keys(), master=self, title="Choose Skeinforge Profile", message="Choose Skeinforge profile" ) pn = l.returnValue() if pn: self.skeinforge.setProfile(pn) self.setSFProfileMenuText() self.toolbar.setSliceText() else: self.logger.logMsg("Unable to retrieve available skeinforge profiles") def setS3ProfileMenuText(self): self.slicermenu.entryconfig(self.S3profileindex, label="Choose Profile (%s)" % self.slic3r.getProfile()) def setSFProfileMenuText(self): self.slicermenu.entryconfig(self.SFprofileindex, label="Choose Profile (%s)" % self.skeinforge.getProfile()) def quitApp(self): self.cleanUp() self.master.quit() def cleanUp(self): if self.connected: self.printer.disconnect() if self.slicing: self.slicerCancel = True self.httpServer.close() self.statline.cleanUp() self.settings.cleanUp() def doEditMacro(self): idir = os.path.join(self.settings.cmdFolder, "macros") try: l = os.listdir(idir) except: self.logger.logMsg("Unable to get listing from macros directory: " + idir) return r = [] for f in sorted(l): if f.endswith(".macro"): r.append(f) l = ListBoxChoice(master=self, title="Macro Files", message="Choose a macro to edit", clist=r) fn = l.returnValue() if fn: try: fn = os.path.join(idir, fn) with open(fn) as f: text = f.read() self.macroEdit = MacroEdit(self, self.printer, self.settings, self.logger, fn, text) except: self.logger.logMsg("Unable to open %s for input" % fn) def doEditAlterations(self): idir = os.path.expandvars(os.path.expanduser(self.settings.sfalterationsdir)) try: l = os.listdir(idir) except: self.logger.logMsg("Unable to get listing from alterations directory: " + idir) return r = [] for f in sorted(l): if f.endswith(".gcode"): r.append(f) l = ListBoxChoice(master=self, title="Alteration Files", message="Choose an alteration file to edit", clist=r) fn = l.returnValue() if fn: try: fn = os.path.join(idir, fn) text = [line.strip() for line in open(fn)] GEditor(self, text, fn) except: self.logger.logMsg("Unable to open %s for input" % fn) def doNewMacro(self): self.macroEdit = MacroEdit(self, self.printer, self.settings, self.logger, None, "") def doDelMacro(self): idir = os.path.join(self.settings.cmdFolder, "macros") try: l = os.listdir(idir) except: self.logger.logMsg("Unable to get listing from macros directory: " + idir) return r = [] for f in sorted(l): if f.endswith(".macro"): r.append(f) l = ListBoxChoice(master=self, title="Macro Files", message="Choose a macro to delete", clist=r) fn = l.returnValue() if fn: if askyesno("Delete?", "Are you sure you want to delete this macro?", parent=self): try: os.unlink(os.path.join(idir, fn)) self.adjustMacroMenu(fn, True) if self.settings.getMacroList().delMacroByName(fn): self.settings.setModified() if self.settings.showmacrobuttons: self.macroButtons.close() self.macroButtons = MacroButtons(self, self.printer, self.settings, self.logger) except: self.logger.logMsg("Unable to delete %s" % fn) def macroEditSave(self, fn, text, btn, editwindow): if fn == None: idir = os.path.join(self.settings.cmdFolder, "macros") try: l = os.listdir(idir) except: self.logger.logMsg("Unable to get listing from macros directory: " + idir) return r = [] for f in sorted(l): if f.endswith(".macro"): r.append(f) l = ListBoxChoice( master=self, title="Macro Files", message="Choose a macro to overwrite", clist=r, newmessage="or enter new file name:", ) fn = l.returnValue() if fn: fn = os.path.join(idir, fn) if not fn.endswith(".macro"): fn += ".macro" if fn is None: return False try: f = open(fn, "w") f.write(text) f.close() self.settings.setModified() if btn != None: if not self.settings.getMacroList().addMacro(btn[0], btn[1], os.path.basename(fn), btn[2]): self.settings.getMacroList().setMacroByName(btn[0], btn[1], os.path.basename(fn), btn[2]) self.settings.setModified() if self.settings.showmacrobuttons: self.macroButtons.close() self.macroButtons = MacroButtons(self, self.printer, self.settings, self.logger) self.adjustMacroMenu(fn) self.logger.logMsg("Macro %s successfully saved" % fn) return True except: self.logger.logMsg("Unable to open %s for output" % fn) return False def macroEditExit(self, fn): pass def loadMacros(self): p = os.path.join(".", "macros") if not os.path.exists(p): os.makedirs(p) self.macroList = {} for filename in sorted(os.listdir(p)): if filename.endswith(".macro"): n = os.path.splitext(filename)[0] self.macroList[n] = 1 self.runmacromenu.add_command(label=n, command=lambda m=n: self.doMacro(m)) def adjustMacroMenu(self, fn, delete=False): mn = os.path.splitext(os.path.basename(fn))[0] if not delete: if mn in self.macroList: # nothing to be done here pass else: self.macroList[mn] = 1 self.runmacromenu.add_command(label=mn, command=lambda m=mn: self.doMacro(name=mn)) else: # delete the menu entry if mn in self.macroList: self.runmacromenu.delete(self.runmacromenu.index(mn)) del self.macroList[mn] else: # huh?? pass def doMacro(self, name=None, fname=None, silent=False): if name: if not silent: self.logger.logMsg("Invoking macro: %s" % name) n = os.path.join(self.settings.cmdFolder, "macros", name + ".macro") elif fname: if not silent: self.logger.logMsg("Invoking macro file: %s" % fname) n = os.path.join(self.settings.cmdFolder, "macros", fname) else: self.logger.logMsg("Error - must provide a macro name or filename") return try: l = list(open(n)) for s in l: sl = s.lower() if sl.startswith("@log "): self.logger.logMsg(self.replace(s[5:].strip(), self.settings.slicer)) elif sl.startswith("@sh "): s = self.replace(sl[4:], self.settings.slicer) args = shlex.split(os.path.expandvars(os.path.expanduser(s))) subprocess.Popen(args, close_fds=True) else: verb = s.split()[0] if self.printerAvailable(cmd=verb): self.printer.send_now(s) else: self.logger.logMsg("Printer not available for %s command" % verb) if not silent: self.logger.logMsg("End of macro") except: self.logger.logMsg("Error attempting to invoke macro file %s" % n) def FirmwareSettings(self): if self.connected: if not self.firmware.isActive(): self.firmware.start() else: self.logger.logMsg("Unable to comply - printer not on-line") def doDataLogReport(self): for d in DLLIST: self.logger.logMsg("%s Usage: %s" % (DLNAMES[d], self.dataLoggers[d].getToNowStr())) def doDataLogReset(self): DataLogReset(self)
class PopupMenuCreator: def __init__(self, atom3i ): self.master = atom3i.parent self.atom3i = atom3i self.cb = atom3i.cb self.optionsDatabase = atom3i.optionsDatabase self.popupLogoPhotoimage = Embedded_Images().getPopupLogo() self.popupMenu = None self.event = None # --------------------------- Popup Utilities ------------------------------- def initilizePopupMenu( self, event ): """ Create a new popup menu """ if( self.popupMenu ): self.popupMenu.unpost() self.popupMenu = Menu(self.master , tearoff=0, bg = "white") self.event = event def showPopupMenu( self ): """ Display the popup menu """ if( self.popupMenu ): self.popupMenu.post(self.event.x_root, self.event.y_root) def swapMenu(self, menu ): """ This is a fix for a problem that no longer exists :p It essentially takes one menu and slaps another one in its place. """ raise Exception, "No one uses this method! But if you see this, maybe not so..." self.popupMenu.unpost() self.popupMenu = menu self.showPopupMenu() def popupRemover(self): """ Goodbye popup! """ if( self.popupMenu ): self.popupMenu.unpost() self.popupMenu = None # ---------------------- Context Sensitive Menus -------------------------- def NoCursorNoSelectPopup( self,event ): """ Popup menu to show when no items under the mouse, and no items selected """ self.initilizePopupMenu( event ) addLogo( self ) #......................... addSeperator( self ) #......................... addModelAction( self ) addSelectAll( self ) addPaste( self ) addUndo( self ) addRedo( self ) #......................... addSeperator( self ) #......................... addFileMenu( self ) addModelMenu( self ) addTransformationMenu( self ) addLayoutMenu( self ) addExportMenu( self ) #......................... addSeperator( self ) #......................... addOpenLastModel( self ) addOpenLastMetaModel(self) addSourcePath( self ) #......................... addSeperator( self ) #......................... addToggleSmoothMode( self ) #......................... addSeperator( self ) #......................... addExit( self ) self.showPopupMenu() def NoCursorMultiSelectPopup(self,event): """ Popup menu to show when no items under the mouse, and multiple items selected """ self.initilizePopupMenu( event ) addLogo( self ) #......................... addSeperator( self ) #......................... addLayoutMenu( self ) addResizeEntity( self ) addNodeLabelDragToggle( self ) #......................... addSeperator( self ) #......................... addSelectAll( self ) addDeselectAll( self ) #......................... addSeperator( self ) #......................... addCut( self ) addCopy( self ) addPaste( self ) #......................... addSeperator( self ) #......................... addUndo( self ) addRedo( self ) #......................... addSeperator( self ) #......................... addClear( self ) self.showPopupMenu() def EntityAtCursorMultiSelectPopup(self,event): """ A graphical entity is under the mouse cursor, along with multiple selected items """ self.initilizePopupMenu( event ) addLogo( self ) #......................... addSeperator( self ) #......................... addLayoutMenu( self ) addEditEntity( self ) addDragOverlap( self ) addDrawArrow( self ) addResizeEntity( self ) addNodeLabelDragToggle( self ) #......................... addSeperator( self ) #......................... addSelectAll( self ) addDeselectAll( self ) #......................... addSeperator( self ) #......................... addCut( self ) addCopy( self ) addPaste( self ) #......................... addSeperator( self ) #......................... addCopyAttributes( self ) addPasteAttributes( self ) #......................... addSeperator( self ) #......................... addUndo( self ) addRedo( self ) #......................... addSeperator( self ) #......................... addClear( self ) self.showPopupMenu() def EntityAtCursorNoSelectPopup(self,event): """ A graphical entity is under the mouse cursor, but no selected items """ self.initilizePopupMenu( event ) addLogo( self ) #......................... addSeperator( self ) #......................... addEditEntity( self ) addDragOverlap( self ) addDrawArrow( self ) addResizeEntity( self ) #......................... addSeperator( self ) #......................... addSelectAll( self ) addPaste( self ) #......................... addSeperator( self ) #......................... addCopyAttributes( self ) addPasteAttributes( self ) #......................... addSeperator( self ) #......................... addUndo( self ) addRedo( self ) self.showPopupMenu() def LinkAtCursorMultiSelectPopup(self,event): """ A graphical link/connection is under the mouse cursor, along with multiple selected items """ self.initilizePopupMenu( event ) addLogo( self ) #......................... addSeperator( self ) #......................... addLayoutMenu( self ) addEditEntity( self ) addDragOverlap( self ) addArrowEditor( self ) addResizeEntity( self ) addNodeLabelDragToggle( self ) #......................... addSeperator( self ) #......................... addSmoothSelected( self ) addToggleSmoothMode( self ) #......................... addSeperator( self ) #......................... addSelectAll( self ) addDeselectAll( self ) #......................... addSeperator( self ) #......................... addCut( self ) addCopy( self ) addPaste( self ) #......................... addSeperator( self ) #......................... addCopyAttributes( self ) addPasteAttributes( self ) #......................... addSeperator( self ) #......................... addUndo( self ) addRedo( self ) #......................... addSeperator( self ) #......................... addClear( self ) self.showPopupMenu() def LinkAtCursorNoSelectPopup(self,event): """ A graphical link/connection is under the mouse cursor, but there are no selected items """ self.initilizePopupMenu( event ) addLogo( self ) #......................... addSeperator( self ) #......................... addEditEntity( self ) addDragOverlap( self ) addArrowEditor( self ) #......................... addSeperator( self ) #......................... addSelectAll( self ) addToggleSmoothMode( self ) addPaste( self ) #......................... addSeperator( self ) #......................... addCopyAttributes( self ) addPasteAttributes( self ) #......................... addSeperator( self ) #......................... addUndo( self ) addRedo( self ) self.showPopupMenu() def ArrowEditorPopup(self,event): """ Menu for the arrow editor """ self.initilizePopupMenu( event ) addLogo( self ) #......................... addSeperator( self ) #......................... addEditEntity( self ) addInsertPoint( self ) addDeletePoint( self ) addSmoothSelected( self ) addNodeLabelMoveToggle( self ) #......................... addSeperator( self ) #......................... addArrowEditorExit( self ) self.showPopupMenu() # ----------------------- Popup a specific submenu ------------------------- def LayoutPopup(self,event): self.initilizePopupMenu( event ) self.popupMenu = self.atom3i.layoutMenu self.showPopupMenu() def ExportPopup(self,event): self.initilizePopupMenu( event ) self.popupMenu = self.atom3i.exportMenu self.showPopupMenu() def ModelPopup(self,event): self.initilizePopupMenu( event ) self.popupMenu = self.atom3i.modelMenu self.showPopupMenu() def TransformationPopup(self,event): self.initilizePopupMenu( event ) self.popupMenu = self.atom3i.transMenu self.showPopupMenu() def FilePopup(self,event): self.initilizePopupMenu( event ) self.popupMenu = self.atom3i.filemenu self.showPopupMenu() def LastModelPopup(self,event): self.initilizePopupMenu( event ) addOpenLastModelSubroutine( self, self.popupMenu ) self.showPopupMenu() def LastMetaModelPopup(self,event): self.initilizePopupMenu( event ) addOpenLastMetaModelSubroutine( self, self.popupMenu ) self.showPopupMenu() def SourcePathPopup(self,event): self.initilizePopupMenu( event ) addSourcePathSubroutine( self, self.popupMenu ) self.showPopupMenu() # ------------------------ String List to PopupMenu --------------------------------- def listChoicePopup(self, title, stringList, unused = None ): """ Creates a popup menu with radiobuttons labeled from the stringList. Returns the index of the label that was chosen. NOTE: choosing outside the popup implicitly chooses index 0 """ # Remove any existing popups first self.popupRemover() self.popupMenu = Menu(self.master , tearoff=0) integerVar = IntVar() self.popupMenu.add_command( label=title, command=self.popupRemover ) self.popupMenu.add_separator() i = 1 for label in stringList: self.popupMenu.add_radiobutton( label=label, variable=integerVar, value=i,indicatoron=False ) i += 1 # This gets the last known co-ordinates of the mouse :D # NOTE: We get co-ordinates in terms of canvas space, convert back into # screenspace first before using them... x,y = self.atom3i.cb.getLastClickCoord() dc = self.atom3i.cb.getCanvas() x,y = [x-dc.canvasx(0),y-dc.canvasy(0)] # These offsets place the menu just where I like it... x = int(x) +40 #+ 100 y = int(y) +40 #+ 20 # Posts the menu, and blocks program execution here on win32 only self.popupMenu.post( x,y ) # Blocks program execution (all platforms) & waits for integerVar to be updated # Not ideal: If we close the popup without selecting anything this will # wait forever and execution will never get anywhere beyond this point!!! # Moreover: AToM3 will not shutdown properly! #self.master.wait_variable( integerVar ) # THEORY: This will work whether or not the post() blocks or not # Practice: Works great on WinXP with Python 2.3 # Linux? while( 1 ): self.master.update() value = integerVar.get() # Hapiness, we got the value we wanted if( value > 0 ): return value # The user killed the popup! O_O elif( self.popupMenu == None ): return 0 # Unhapiness, the user avoided selecting anything elif( value == 0 ): self.popupMenu.unpost() self.popupMenu.post( x,y ) self.master.update() time.sleep( 0.4 ) return 0 # We won't get here, but just in case... def listChoicePopupAlternative(self, title, stringList, actionLabel ): """ OBSOLETE --- Delete this """ raise Exception, "No one uses this method! But if you see this, maybe not so..." """ optionList = [OptionDialog.BOOL_BUTTON_ENTRY,actionLabel] options = dict() optionOrder = list() for i in range(0,len(stringList)): options[i] = [False,optionList,stringList[i],''] optionOrder.append(i) i+=1 dialog = OptionDialog(self.master, title, options,optionOrder, grab = False, position = self.atom3i.cb.getLastClickCoordInRootCoords() ) if( dialog.isCanceled() ): return 0 options = dialog.getOptionsDatabase() i = 1 for option in optionOrder: if( options[option][0] ): return i i += 1 return 0 """
# 在菜单项 "操作" 下面添加一个名为 "开始实验" 的选项 fileMenu.add_command(label="开始实验", command=_startTest) # 添加一条横线 fileMenu.add_separator() # 在菜单项 "操作" 下面添加一个名为 "退出系统" 的选项 fileMenu.add_command(label="退出系统", command=_quit) # 添加一条横线 fileMenu.add_separator() algorithmMenu = Menu(menuBar) menuBar.add_cascade(label="分析算法", menu=algorithmMenu) algorithmMenu.add_radiobutton(label="CNN") # 添加一条横线 algorithmMenu.add_separator() algorithmMenu.add_radiobutton(label="CSP+SVM") # 添加一条横线 algorithmMenu.add_separator() algorithmMenu.add_radiobutton(label="CSP+BP") # 添加一条横线 algorithmMenu.add_separator() algorithmMenu.add_radiobutton(label="WPT1+SVM") # 添加一条横线 algorithmMenu.add_separator() algorithmMenu.add_radiobutton(label="WPT2+SVM") # 添加一条横线 algorithmMenu.add_separator() algorithmMenu.add_radiobutton(label="WPT1+SVM")
def _init_menubar(self): self._result_size = IntVar(self.top) self._cntx_bf_len = IntVar(self.top) self._cntx_af_len = IntVar(self.top) menubar = Menu(self.top) filemenu = Menu(menubar, tearoff=0, borderwidth=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-q') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) rescntmenu = Menu(editmenu, tearoff=0) rescntmenu.add_radiobutton(label='20', variable=self._result_size, underline=0, value=20, command=self.set_result_size) rescntmenu.add_radiobutton(label='50', variable=self._result_size, underline=0, value=50, command=self.set_result_size) rescntmenu.add_radiobutton(label='100', variable=self._result_size, underline=0, value=100, command=self.set_result_size) rescntmenu.invoke(1) editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu) cntxmenu = Menu(editmenu, tearoff=0) cntxbfmenu = Menu(cntxmenu, tearoff=0) cntxbfmenu.add_radiobutton(label='60 characters', variable=self._cntx_bf_len, underline=0, value=60, command=self.set_cntx_bf_len) cntxbfmenu.add_radiobutton(label='80 characters', variable=self._cntx_bf_len, underline=0, value=80, command=self.set_cntx_bf_len) cntxbfmenu.add_radiobutton(label='100 characters', variable=self._cntx_bf_len, underline=0, value=100, command=self.set_cntx_bf_len) cntxbfmenu.invoke(1) cntxmenu.add_cascade(label='Before', underline=0, menu=cntxbfmenu) cntxafmenu = Menu(cntxmenu, tearoff=0) cntxafmenu.add_radiobutton(label='70 characters', variable=self._cntx_af_len, underline=0, value=70, command=self.set_cntx_af_len) cntxafmenu.add_radiobutton(label='90 characters', variable=self._cntx_af_len, underline=0, value=90, command=self.set_cntx_af_len) cntxafmenu.add_radiobutton(label='110 characters', variable=self._cntx_af_len, underline=0, value=110, command=self.set_cntx_af_len) cntxafmenu.invoke(1) cntxmenu.add_cascade(label='After', underline=0, menu=cntxafmenu) editmenu.add_cascade(label='Context', underline=0, menu=cntxmenu) menubar.add_cascade(label='Edit', underline=0, menu=editmenu) self.top.config(menu=menubar)
def BuildMainFrame(self): from Tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from Tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master, activeborderwidth=0, bd=0) self.master.config(menu=menu) filemenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N', command=self.NewCommand) filemenu.add_command(label="Open...", accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...", accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit", accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu, modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename, menu=scriptsubmenu) editmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Edit", underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script", menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F', command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file, value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file, value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file, value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1', command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0', '1.0'] self.suggestionswindow = Toplevel(bg='#ffffff', bd=0, height=50, width=600, highlightthickness=0, takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow, bg='#ffffff', bd=1, fg='#336699', activestyle='none', highlightthickness=0, height=9) self.suggestionslist.insert(END, "foo") self.suggestionslist.pack(side=TOP, fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) content = Frame(self.master, bd=0, padx=2, pady=2) content.grid(row=0, column=0, sticky=N + S + W + E) content.rowconfigure(0, weight=1, minsize=50) content.rowconfigure(1, weight=0) content.columnconfigure(0, weight=1) panes = PanedWindow(content, orient=VERTICAL, bd=1, sashwidth=8, sashpad=0, sashrelief=RAISED, showhandle=True) panes.grid(row=0, column=0, sticky=N + S + W + E) frame1 = Frame(panes, bd=0) frame1.grid(row=0, column=0, sticky=N + S + W + E) frame1.columnconfigure(0, weight=1) frame1.columnconfigure(1, weight=0) frame1.rowconfigure(0, weight=1) panes.add(frame1, height=300, minsize=20) frame2 = Frame(panes, bd=0) frame2.grid(row=1, column=0, sticky=N + S + W + E) frame2.columnconfigure(0, weight=1) frame2.columnconfigure(1, weight=0) frame2.rowconfigure(0, weight=1) panes.add(frame2, minsize=20) self.text_input = Text(frame1, bg='#ffffff', bd=1, highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1, orient=VERTICAL, command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2, state=DISABLED, bd=1, bg='#ffffff', highlightthickness=0) self.output_scrollbar = Scrollbar(frame2, orient=VERTICAL, command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content, bd=1, bg='#ffffff', state=DISABLED, highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0, column=0, sticky=N + S + W + E) self.input_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_output.grid(row=0, column=0, sticky=N + S + W + E) self.output_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_entry.grid(row=1, column=0, sticky=N + S + W + E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script", menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry, self.output_stream)
class tkFileSelector() : def __init__(self,master,start_dir=expanduser("~"),filetypes=[],title="Select a music file.",color_1="#000000",color_2="#00c0c0",highlight_color_items="#c9c9c9") : ''' master == root_window == Tk() use color_1 and color_2 and bg_items and fg_items and highlight_color_items for colors personalisation. filetypes must "Strictly" be a list of extension beginning with an asterix followed by a point and the extension (in lowercase) or an empty list for no filtering. filetypes=["*.mp3","*.wav"] per example. Or insert an, item '*' for all filetype in combination with defined filetypes. for borderwidth and relief settings look at the code ''' # Constrcut GUI for the file selection toplevel. self.toplevel=Toplevel(master,bg=color_1,borderwidth=1,relief="sunken") self.toplevel.resizable(width=False, height=False) self.toplevel.title(title) self.dir_selection_frame=Frame(self.toplevel,bg=color_1,borderwidth=8/2,relief="groove") # Frame container for directory fields. self.dir_name_entry=Entry(self.toplevel,justify="center",width=50,bg=color_2,fg=color_1) # This will contains the current directory relative dirname self.dir_name_separator=Button(self.toplevel,width=1,relief="sunken",bg=color_1,fg=color_2) # An separator self.dir_back_button=Button(self.toplevel,width=6,relief="raised",bg=color_2,fg=color_1,text="Back",command=self.folder_go_back) # Change directory back button. self.canvas_frame=Frame(self.toplevel,borderwidth=8,relief="groove") # Frame for the file selection window canvas and his scrollbar. self.canvas=Canvas(self.canvas_frame,height=20*9,width=18*28,bg=color_2) # File selection window. self.canvas_scrollbar=Scrollbar(self.canvas_frame,orient=HORIZONTAL, bg=color_2,troughcolor=color_1,command=self.canvas.xview) # File selection window scrollbar. self.canvas.configure(xscrollcommand=self.canvas_scrollbar.set) self.file_selection_frame=Frame(self.toplevel,bg=color_1,borderwidth=8/2,relief="groove") # Frame container for filename fields. self.file_name_entry=Entry(self.toplevel,justify="center",width=50,bg=color_2,fg=color_1) # This will contains the basename (relative) of the selected file. self.file_name_separator=Button(self.toplevel,width=1,relief="sunken",bg=color_1,fg=color_2) # An separator. self.file_filter_menubutton = Menubutton(self.file_selection_frame, text='',relief="groove",width=8,bg=color_2,fg=color_1) # Menubutton for filetype filter. self.file_filter_extension="" if filetypes : self.file_filter_menu= Menu(self.file_filter_menubutton,borderwidth=3,relief="groove") # We use a menu for the filetypes filtering. i=0 self.file_filter_var=StringVar(master=None, value=filetypes[i], name=None) # Control varaible for current filetype and initialize with the first filetype item. self.file_filter_menubutton.config(text=filetypes[i]) self.file_filter_extension=filetypes[i][1::] while i < len(filetypes) : # Creating radiobutton to change the filetype filter. self.file_filter_menu.add_radiobutton(label=filetypes[i], variable=self.file_filter_var,value=filetypes[i],background=color_2,command=self.set_filetype_filter ) i += 1 self.file_filter_menubutton.configure(menu= self.file_filter_menu) self.buttons_frame=Frame(self.toplevel,bg=color_2,borderwidth=8,relief="groove",height=50,width=18*3) # Frame container for the buttons. self.button_cancel=Button(self.buttons_frame,bg=color_2,fg=color_1,text="Quit",borderwidth=8/2,relief="groove",width=8,command=self.item_selection_quit) self.button_home=Button(self.buttons_frame,bg=color_2,fg=color_1,text="Home",borderwidth=8/2,relief="groove",width=8,command=self.item_selection_home) self.button_ok=Button(self.buttons_frame,bg=color_2,fg=color_1,text=" OK ",borderwidth=8/2,relief="groove",width=8,command=self.item_selection_ok) self.start_dir=start_dir # Start folder. self.curdir=start_dir # Current folder. self.last_dir=[] # Container for the precedent folders we visit. self.last_dir.append(start_dir) # Append start folder. self.select_filepath="" # Value to return by file selection. self.dir_name_entry.insert(0,"../"+basename(self.curdir)) if not color_2 : self.items_bg="#D9D9D9" else : self.items_bg=color_2 self.items_fg=color_1 self.highlight_color_items=highlight_color_items self.init_icons() self.ls_dir() self.update_canvas() self.dir_selection_frame.grid(row=0,column=0,sticky="WE") self.dir_name_entry.grid(row=0,column=0,in_=self.dir_selection_frame,sticky="NSEW") self.dir_name_separator.grid(row=0,column=1,in_=self.dir_selection_frame,sticky="EW") self.dir_back_button.grid(row=0,column=2,in_=self.dir_selection_frame,sticky="EW") self.canvas_frame.grid(row=1,column=0,sticky="WE") self.canvas.grid(row=0,column=0,in_=self.canvas_frame) self.canvas_scrollbar.grid(row=1,column=0,in_=self.canvas_frame,sticky="WE") self.file_selection_frame.grid(row=2,column=0,sticky="WE") self.file_name_entry.grid(row=0,column=0,in_=self.file_selection_frame,sticky="NSEW") self.file_name_separator.grid(row=0,column=1,in_=self.file_selection_frame,sticky="EW") self.file_filter_menubutton.grid(row=0,column=2,in_=self.file_selection_frame,sticky="NS") self.buttons_frame.grid(row=3,column=0,sticky="NSEW") self.button_cancel.grid(row=0,column=2,padx=32+3,pady=4,in_=self.buttons_frame) self.button_home.grid(row=0,column=4,padx=32+3,pady=4,in_=self.buttons_frame) self.button_ok.grid(row=0,column=6,padx=34+3,pady=4,in_=self.buttons_frame) self.toplevel.wait_window() def init_icons(self) : # Folder and file icons, design by me. self.image_folder=Image.open("/usr/share/ScreenLocker/Images/file_selector/folder_icon.png") self.imagetk_folder=ImageTk.PhotoImage(image=self.image_folder) self.image_file=Image.open("/usr/share/ScreenLocker/Images/file_selector/file_icon.png") self.imagetk_file=ImageTk.PhotoImage(image=self.image_file) def ls_dir(self) : ''' List an directory and split the result in folders and files containers. Finally sort the 2 containers.''' folder_content=listdir(self.curdir) self.cur_folder_entries=len(folder_content) self.cur_folder_list=[] self.cur_files_list=[] folder_content.sort() for v in folder_content : if isdir(self.curdir+"/"+v) : self.cur_folder_list.append(unicode(v,encoding='utf-8')) elif isfile(self.curdir+"/"+v) : self.cur_files_list.append(unicode(v,encoding='utf-8')) self.cur_folder_list.sort() self.cur_files_list.sort() def update_canvas(self) : ''' Generating the content from the File selection window (an canvas)''' self.clear_canvas() i=0 # global folder and file iterator. pos_x=0 # Coordinates for the rows. pos_y=0 # Coordinates in the columns. max_len=0 # Column max folder|filename length. max_len_save=0 # Saved value for filling empty canvas scrollregion. while i < len(self.cur_folder_list) : # Generating the folder items of the current folder exec(u"folder_icon_{0}=Label(self.canvas,text='{1}',image=self.imagetk_folder,relief='flat',width=17,height=17,bg=self.items_bg)".format(str(i),self.cur_folder_list[i].replace("'","\\'"))) exec(u"folder_name_{0}=Label(self.canvas,text='{1}',relief='flat',width={2},font='Monospace 9 bold',justify='left',bg=self.items_bg,fg=self.items_fg)".format(str(i),self.cur_folder_list[i].replace("'","\\'"),int(len(" "+self.cur_folder_list[i])))) if int(len(" "+self.cur_folder_list[i])) > max_len : # Update longest folder name in this column. max_len=int(len(" "+self.cur_folder_list[i])) # Storing the value for max length of the longest folder name in this column. max_len_save=max_len # Value to save for filling if the generating content take minus place as the canvas scrollregion. exec("folder_icon_{0}.bind('<Double-1>',self.select_folder)".format(str(i))) exec("folder_name_{0}.bind('<Double-1>',self.select_folder)".format(str(i))) exec("folder_name_{0}.bind('<Enter>',self.highlight_item_enter)".format(str(i))) exec("folder_name_{0}.bind('<Leave>',self.highlight_item_leave)".format(str(i))) exec("folder_icon_{0}.pack(side='left',fill=BOTH)".format(str(i))) exec("folder_name_{0}.pack(side='right',fill=BOTH)".format(str(i))) exec("self.canvas.create_window(({1},{2}),anchor='nw',window=folder_icon_{0})".format(str(i),pos_x,pos_y)) exec("self.canvas.create_window(({1}+17+1,{2}),anchor='nw',window=folder_name_{0})".format(str(i),pos_x,pos_y)) pos_y += 20 # column increment 17 height of an items + 3 pixels padding. if ( i % 9 == 0) and not i == 0 : # An column can contains 9 items and we change column. pos_y=0 # Column position updating. pos_x += 17 + (max_len*9) # Update the x coordinates according the maximal length of foldername in this column ( (9 pixels == font size) (17 pixels for the folder item icon) ) . max_len=0 i += 1 # Go to the next item. ii=0 # Files iterator. while ii < len(self.cur_files_list) : # Generating the files items of the current folder. if (self.file_filter_extension and self.cur_files_list[ii].lower().endswith(self.file_filter_extension)) or not self.file_filter_extension : # applying filter of no filetype filering. exec(u"file_icon_{0}=Label(self.canvas,text='{1}',image=self.imagetk_file,relief='flat',width=17,height=17,bg=self.items_bg)".format(str(i),self.cur_files_list[ii].replace("'","\\'"))) exec(u"file_name_{0}=Label(self.canvas,text='{1}',relief='flat',width={2},font='Monospace 9 normal',justify='left',bg=self.items_bg,fg=self.items_fg)".format(str(i),self.cur_files_list[ii].replace("'","\\'"),int(len(" "+self.cur_files_list[ii])))) if int(len(" "+self.cur_files_list[ii])) > max_len : # Update longest filename in this column. max_len=int(len(" "+self.cur_files_list[ii])) # Storing the value for max length of the longest filename in this column. max_len_save=max_len # Value to save for filling if the generating content take minus place as the canvas scrollregion. exec("file_icon_{0}.bind('<Double-1>',self.select_file)".format(str(i))) exec("file_name_{0}.bind('<Double-1>',self.select_file)".format(str(i))) exec("file_name_{0}.bind('<Enter>',self.highlight_item_enter)".format(str(i))) exec("file_name_{0}.bind('<Leave>',self.highlight_item_leave)".format(str(i))) exec("file_icon_{0}.pack(side='left',fill=BOTH)".format(str(i))) exec("file_name_{0}.pack(side='right',fill=BOTH)".format(str(i))) exec("self.canvas.create_window(({1},{2}),anchor='nw',window=file_icon_{0})".format(str(i),pos_x,pos_y)) exec("self.canvas.create_window(({1}+17+1,{2}),anchor='nw',window=file_name_{0})".format(str(i),pos_x,pos_y)) pos_y += 20 # column increment 17 height of an items + 3 pixels padding. if ( i % 9 == 0) and not i == 0 : # An column can contains 9 items and we change column. # Note: we check the common file & folder iterator. pos_y=0 # Column position updating. pos_x += 17 + (max_len*9) # Update the x coordinates according the maximal length of filename in this column ( (9 pixels == font size) (17 pixels for the file item icon) ). max_len=0 i += 1 ii += 1 if not pos_x+(max_len_save*9)+17 < 18*28 : # items collection greater than the canvas scrollregion. self.canvas.config(scrollregion=(0,0,pos_x+(max_len_save*9)+17,0)) else : # items collection littler than the canvas scrollregion. self.canvas.config(scrollregion=(0,0,18*28,0)) def clear_canvas(self) : for child in self.canvas.children.values() : child.destroy() def highlight_item_enter(self,event) : event.widget.config(bg=self.highlight_color_items) def highlight_item_leave(self,event) : event.widget.config(bg=self.items_bg) def select_folder(self,event) : if isdir(self.curdir+"/"+event.widget.cget("text").lstrip()) : # event.widget.cget("text") return the selected folder. sea the update_canvas() method. self.select_filepath="" self.file_name_entry.delete(0,END) if self.curdir.startswith('//') : # Bugfix. self.curdir=self.curdir[1::] self.last_dir.append(self.curdir) else : self.last_dir.append(self.curdir) for v in self.last_dir : # Bigfix if self.last_dir.count(v) > 1 : self.last_dir.remove(v) try : # in case of access right this will fail immediatelly listdir(self.curdir+"/"+event.widget.cget("text")) self.curdir=self.curdir+"/"+event.widget.cget("text") self.dir_name_entry.delete(0,END) self.dir_name_entry.insert(0,"../"+event.widget.cget("text")) self.ls_dir() self.update_canvas() except : pass def select_file(self,event) : if isfile(self.curdir+"/"+event.widget.cget("text")) : # Set the value to return and fill the file selection field. self.select_filepath=self.curdir+"/"+event.widget.cget("text") self.file_name_entry.delete(0,END) self.file_name_entry.insert(0,event.widget.cget("text")) def folder_go_back(self) : if len(self.last_dir) > 1 : self.curdir=self.last_dir.pop(-1) # pop the last value from the visited folder folders else : # In case we have yet only 1 folder in the visited folder container. if self.last_dir[0].rfind("/") : # The value of the container is not the root folder ( / ) but not the /home/username folder who can be only visited folder. self.last_dir[0]=self.last_dir[0][0:self.last_dir[0].rfind("/")] self.curdir=self.last_dir[0] elif self.last_dir[0].rfind("/") == 0 : # The value of the container is the root folder. self.last_dir[0]="/" self.curdir=self.last_dir[0] else : # The value is the /home/username directory self.curdir=self.last_dir[0] self.file_name_entry.delete(0,END) self.select_filepath="" self.dir_name_entry.delete(0,END) self.dir_name_entry.insert(0,"../"+basename(self.curdir)) self.ls_dir() self.update_canvas() def set_filetype_filter(self) : '''Change filetype filter.''' self.file_filter_menubutton.config(text=self.file_filter_var.get()) self.file_filter_extension=self.file_filter_var.get()[1::] # Contains the selected filetype ( in form '.'+filetype ). self.file_name_entry.delete(0,END) self.select_filepath="" self.ls_dir() self.update_canvas() def item_selection_ok(self) : '''Return the selected filepath or empty string and destroy File_selector instance''' if self.select_filepath : self.toplevel.destroy() return True def item_selection_quit(self) : '''destroy File_selector instance''' self.toplevel.destroy() return False def item_selection_home(self) : '''Change current directory to the /home/username folder''' self.curdir=expanduser("~") self.select_filepath="" self.file_name_entry.delete(0,END) self.last_dir=[] self.last_dir.append(expanduser("~")) self.dir_name_entry.delete(0,END) self.dir_name_entry.insert(0,"../"+basename(self.curdir)) self.ls_dir() self.update_canvas()
def createInterface(self): # The interior of the toplevel panel interior = self.interior() interior['relief'] = Tkinter.FLAT # Add placer commands to menubar self.menuBar.addmenu('Placer', 'Placer Panel Operations') self.menuBar.addmenuitem('Placer', 'command', 'Zero Node Path', label = 'Zero All', command = self.zeroAll) self.menuBar.addmenuitem('Placer', 'command', 'Reset Node Path', label = 'Reset All', command = self.resetAll) self.menuBar.addmenuitem('Placer', 'command', 'Print Node Path Info', label = 'Print Info', command = self.printNodePathInfo) self.menuBar.addmenuitem( 'Placer', 'command', 'Toggle widget visability', label = 'Toggle Widget Vis', command = SEditor.toggleWidgetVis) self.menuBar.addmenuitem( 'Placer', 'command', 'Toggle widget manipulation mode', label = 'Toggle Widget Mode', command = SEditor.manipulationControl.toggleObjectHandlesMode) # Get a handle to the menu frame menuFrame = self.menuFrame self.nodePathMenu = Pmw.ComboBox( menuFrame, labelpos = Tkinter.W, label_text = 'Node Path:', entry_width = 20, selectioncommand = self.selectNodePathNamed, scrolledlist_items = self.nodePathNames) self.nodePathMenu.selectitem('selected') self.nodePathMenuEntry = ( self.nodePathMenu.component('entryfield_entry')) self.nodePathMenuBG = ( self.nodePathMenuEntry.configure('background')[3]) self.nodePathMenu.pack(side = 'left', fill = 'x', expand = 1) self.bind(self.nodePathMenu, 'Select node path to manipulate') modeMenu = Pmw.OptionMenu(menuFrame, items = ('Relative To:', 'Orbit:'), initialitem = 'Relative To:', command = self.setMovementMode, menubutton_width = 8) modeMenu.pack(side = 'left', expand = 0) self.bind(modeMenu, 'Select manipulation mode') self.refNodePathMenu = Pmw.ComboBox( menuFrame, entry_width = 16, selectioncommand = self.selectRefNodePathNamed, scrolledlist_items = self.refNodePathNames) self.refNodePathMenu.selectitem('parent') self.refNodePathMenuEntry = ( self.refNodePathMenu.component('entryfield_entry')) self.refNodePathMenu.pack(side = 'left', fill = 'x', expand = 1) self.bind(self.refNodePathMenu, 'Select relative node path') self.undoButton = Button(menuFrame, text = 'Undo', command = SEditor.undo) if SEditor.undoList: self.undoButton['state'] = 'normal' else: self.undoButton['state'] = 'disabled' self.undoButton.pack(side = 'left', expand = 0) self.bind(self.undoButton, 'Undo last operation') self.redoButton = Button(menuFrame, text = 'Redo', command = SEditor.redo) if SEditor.redoList: self.redoButton['state'] = 'normal' else: self.redoButton['state'] = 'disabled' self.redoButton.pack(side = 'left', expand = 0) self.bind(self.redoButton, 'Redo last operation') # Create and pack the Pos Controls posGroup = Pmw.Group(interior, tag_pyclass = Menubutton, tag_text = 'Position', tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', ring_relief = Tkinter.RIDGE) posMenubutton = posGroup.component('tag') self.bind(posMenubutton, 'Position menu operations') posMenu = Menu(posMenubutton, tearoff = 0) posMenu.add_command(label = 'Set to zero', command = self.zeroPos) posMenu.add_command(label = 'Reset initial', command = self.resetPos) posMenubutton['menu'] = posMenu posGroup.pack(side='left', fill = 'both', expand = 1) posInterior = posGroup.interior() # Create the dials self.posX = self.createcomponent('posX', (), None, Floater, (posInterior,), text = 'X', relief = Tkinter.FLAT, value = 0.0, label_foreground = 'Red') self.posX['commandData'] = ['x'] self.posX['preCallback'] = self.xformStart self.posX['postCallback'] = self.xformStop self.posX['callbackData'] = ['x'] self.posX.pack(expand=1,fill='both') self.posY = self.createcomponent('posY', (), None, Floater, (posInterior,), text = 'Y', relief = Tkinter.FLAT, value = 0.0, label_foreground = '#00A000') self.posY['commandData'] = ['y'] self.posY['preCallback'] = self.xformStart self.posY['postCallback'] = self.xformStop self.posY['callbackData'] = ['y'] self.posY.pack(expand=1,fill='both') self.posZ = self.createcomponent('posZ', (), None, Floater, (posInterior,), text = 'Z', relief = Tkinter.FLAT, value = 0.0, label_foreground = 'Blue') self.posZ['commandData'] = ['z'] self.posZ['preCallback'] = self.xformStart self.posZ['postCallback'] = self.xformStop self.posZ['callbackData'] = ['z'] self.posZ.pack(expand=1,fill='both') # Create and pack the Hpr Controls hprGroup = Pmw.Group(interior, tag_pyclass = Menubutton, tag_text = 'Orientation', tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', ring_relief = Tkinter.RIDGE) hprMenubutton = hprGroup.component('tag') self.bind(hprMenubutton, 'Orientation menu operations') hprMenu = Menu(hprMenubutton, tearoff = 0) hprMenu.add_command(label = 'Set to zero', command = self.zeroHpr) hprMenu.add_command(label = 'Reset initial', command = self.resetHpr) hprMenubutton['menu'] = hprMenu hprGroup.pack(side='left',fill = 'both', expand = 1) hprInterior = hprGroup.interior() # Create the dials self.hprH = self.createcomponent('hprH', (), None, AngleDial, (hprInterior,), style = 'mini', text = 'H', value = 0.0, relief = Tkinter.FLAT, label_foreground = 'blue') self.hprH['commandData'] = ['h'] self.hprH['preCallback'] = self.xformStart self.hprH['postCallback'] = self.xformStop self.hprH['callbackData'] = ['h'] self.hprH.pack(expand=1,fill='both') self.hprP = self.createcomponent('hprP', (), None, AngleDial, (hprInterior,), style = 'mini', text = 'P', value = 0.0, relief = Tkinter.FLAT, label_foreground = 'red') self.hprP['commandData'] = ['p'] self.hprP['preCallback'] = self.xformStart self.hprP['postCallback'] = self.xformStop self.hprP['callbackData'] = ['p'] self.hprP.pack(expand=1,fill='both') self.hprR = self.createcomponent('hprR', (), None, AngleDial, (hprInterior,), style = 'mini', text = 'R', value = 0.0, relief = Tkinter.FLAT, label_foreground = '#00A000') self.hprR['commandData'] = ['r'] self.hprR['preCallback'] = self.xformStart self.hprR['postCallback'] = self.xformStop self.hprR['callbackData'] = ['r'] self.hprR.pack(expand=1,fill='both') # Create and pack the Scale Controls # The available scaling modes self.scalingMode = StringVar() self.scalingMode.set('Scale Uniform') # The scaling widgets scaleGroup = Pmw.Group(interior, tag_text = 'Scale Uniform', tag_pyclass = Menubutton, tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', ring_relief = Tkinter.RIDGE) self.scaleMenubutton = scaleGroup.component('tag') self.bind(self.scaleMenubutton, 'Scale menu operations') self.scaleMenubutton['textvariable'] = self.scalingMode # Scaling menu scaleMenu = Menu(self.scaleMenubutton, tearoff = 0) scaleMenu.add_command(label = 'Set to unity', command = self.unitScale) scaleMenu.add_command(label = 'Reset initial', command = self.resetScale) scaleMenu.add_radiobutton(label = 'Scale Free', variable = self.scalingMode) scaleMenu.add_radiobutton(label = 'Scale Uniform', variable = self.scalingMode) scaleMenu.add_radiobutton(label = 'Scale Proportional', variable = self.scalingMode) self.scaleMenubutton['menu'] = scaleMenu # Pack group widgets scaleGroup.pack(side='left',fill = 'both', expand = 1) scaleInterior = scaleGroup.interior() # Create the dials self.scaleX = self.createcomponent('scaleX', (), None, Floater, (scaleInterior,), text = 'X Scale', relief = Tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = 'Red') self.scaleX['commandData'] = ['sx'] self.scaleX['callbackData'] = ['sx'] self.scaleX['preCallback'] = self.xformStart self.scaleX['postCallback'] = self.xformStop self.scaleX.pack(expand=1,fill='both') self.scaleY = self.createcomponent('scaleY', (), None, Floater, (scaleInterior,), text = 'Y Scale', relief = Tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = '#00A000') self.scaleY['commandData'] = ['sy'] self.scaleY['callbackData'] = ['sy'] self.scaleY['preCallback'] = self.xformStart self.scaleY['postCallback'] = self.xformStop self.scaleY.pack(expand=1,fill='both') self.scaleZ = self.createcomponent('scaleZ', (), None, Floater, (scaleInterior,), text = 'Z Scale', relief = Tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = 'Blue') self.scaleZ['commandData'] = ['sz'] self.scaleZ['callbackData'] = ['sz'] self.scaleZ['preCallback'] = self.xformStart self.scaleZ['postCallback'] = self.xformStop self.scaleZ.pack(expand=1,fill='both') # Make sure appropriate labels are showing self.setMovementMode('Relative To:') # Set up placer for inital node path self.selectNodePathNamed('init') self.selectRefNodePathNamed('parent') # Update place to reflect initial state self.updatePlacer() # Now that you're done setting up, attach commands self.posX['command'] = self.xform self.posY['command'] = self.xform self.posZ['command'] = self.xform self.hprH['command'] = self.xform self.hprP['command'] = self.xform self.hprR['command'] = self.xform self.scaleX['command'] = self.xform self.scaleY['command'] = self.xform self.scaleZ['command'] = self.xform
def __init__(self,game): assert type(game) is Game self.root = Tk() self.root.title('SET') self.root.resizable(0,0) self.root.withdraw() GUIHandler.screenwidth = self.root.winfo_screenwidth() GUIHandler.screenheight = self.root.winfo_screenheight() if GUIHandler.screenwidth < 1024 or GUIHandler.screenheight < 768: showerror("Resolution Error","Your screen's resolution is likely not the best choice to run this game. Minimum resolution for this game is at least 1024x768.") raise ResolutionError(GUIHandler.screenwidth,GUIHandler.screenheight) GUIHandler.windowwidth = GUIHandler.screenwidth // 3 GUIHandler.windowheight = GUIHandler.screenheight // 1.5 self.buttonField = None self.checkButtonField = None self.Game = game self.Field = game.field assert self.Game assert self.Field self.root.geometry('%dx%d+%d+%d' % (GUIHandler.windowwidth, GUIHandler.windowheight, self.root.winfo_screenwidth()/8, self.root.winfo_screenheight()/8)) menu = Menu(self.root) gamemenu = Menu(menu,tearoff=0) gamemenu.add_command(label='New Game',command=lambda:self.startNewGame(),accelerator="F2") gamemenu.add_command(label='Leaderboards',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) gamemenu.add_command(label='Exit',command=lambda:self.root.destroy(),accelerator="Alt-F4") menu.add_cascade(label='Game',menu=gamemenu) settingmenu = Menu(menu,tearoff=0) gamedifficulty = Menu(settingmenu,tearoff=0) gamedifficulty.add_radiobutton(label='Beginner',command=lambda :self.changeGameDifficulty(Difficulty.BEGINNER),accelerator="B") gamedifficulty.add_radiobutton(label='Novice',command=lambda :self.changeGameDifficulty(Difficulty.NOVICE),accelerator="N") gamedifficulty.add_radiobutton(label='Advanced',command=lambda :self.changeGameDifficulty(Difficulty.ADVANCED),accelerator="A") settingmenu.add_cascade(label='Game Difficulty',menu=gamedifficulty) timedmode = Menu(settingmenu,tearoff=0) timedmode.add_radiobutton(label='On',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) timedmode.add_radiobutton(label='Off',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) settingmenu.add_cascade(label='Timed Mode',menu=timedmode) timeddifficulty = Menu(settingmenu,tearoff=0) timeddifficulty.add_radiobutton(label='Easy',accelerator="E") timeddifficulty.add_radiobutton(label='Medium',accelerator="M") timeddifficulty.add_radiobutton(label='Hard',accelerator="H") settingmenu.add_cascade(label='Timed Difficulty',menu=timeddifficulty) menu.add_cascade(label='Settings',menu=settingmenu) helpmenu = Menu(menu,tearoff=0) helpmenu.add_command(label='About SET',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) menu.add_cascade(label='Help',menu=helpmenu) self.root.config(menu=menu) self.root.bind('<F2>',lambda e:gamemenu.invoke(0)) self.root.bind('L',lambda e:gamemenu.invoke(1)) self.root.bind('<Alt-F4>',lambda e:gamemenu.invoke(2)) self.root.bind('b',lambda e:gamedifficulty.invoke(Difficulty.BEGINNER)) self.root.bind('n',lambda e:gamedifficulty.invoke(Difficulty.NOVICE)) self.root.bind('a',lambda e:gamedifficulty.invoke(Difficulty.ADVANCED)) self.remainderLabel = Label(self.root,text="There are %d set(s) remaining on the board." % self.Game.numSetsRemaining(),bg="white",relief=Tkinter.RAISED,font=('Helvetica',12)) self.remainderLabel.place(x=(GUIHandler.windowwidth-self.remainderLabel.winfo_reqwidth())//2,y=3*GUIHandler.windowheight//4) timer = Label(self.root,text="Untimed Mode",bg="green",relief=Tkinter.RAISED,font=('Helvetica',12)) timer.place(x=(GUIHandler.windowwidth-timer.winfo_reqwidth())//2,y=3*GUIHandler.windowheight//4.5) hintbutton = Button(text="Hint, please!",font=("Helvetica",12),command=lambda :self.getHint()) hintbutton.place(x=(GUIHandler.windowwidth-hintbutton.winfo_reqwidth())//2,y=3*GUIHandler.windowheight//3.5) self.userSetsCreated = Toplevel(self.root) self.userSetsHeight = 0 self.userSetsCreated.title("Sets Created") self.userSetsCreated.geometry("%dx%d+%d+%d" % (Card.pixelWidth*3, self.userSetsCreated.winfo_screenheight(), self.root.winfo_pointerx()+self.userSetsCreated.winfo_reqwidth(),0)) self.userSetsCreated.protocol("WM_DELETE_WINDOW",0) self.userSetsCreated.resizable(0,0) self.root.focus_set() self.updateCardsOnField(self.Field)