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_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 create_menu(self): menu = Menu(self.window) game = Menu(menu, tearoff=0) game.add_command(label="New", command=self.create_game, underline=0) game.add_command(label="Quit", command=self.bye, underline=0) menu.add_cascade(label="Game", menu=game, underline=0) settings = Menu(menu, tearoff=0) settings.add_checkbutton(label="Show valid positions", variable=self.show_valid_positions, command=self.toggle_show_valid_positions, underline=0) menu.add_cascade(label="Settings", menu=settings, underline=0) help = Menu(menu, tearoff=0) help.add_command(label="About", command=self.show_credits, underline=0) menu.add_cascade(label="Help", menu=help, underline=0) self.window.config(menu=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)
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 TkAdmin(TkWindow, RPCComponent): """ Development graphical user interface for cape systems. """ unique = True directory_name = "TkAdmin" # TODO: # * Clean up user interface # * Develop interaction elements for all primitives def __init__(self): self.nodelist = {} self.messages = [] self.title = "cape TkAdmin - [%s]" % identity.SystemName super(TkAdmin, self).__init__() self.Configuration['fixsender'] = False self.Configuration['autoclear'] = True self.Configuration['autoscan'] = True self.Configuration['showresponses'] = False self.autoscan.set(self.Configuration['autoscan']) self.fixsender.set(self.Configuration['fixsender']) self.autoclear.set(self.Configuration['autoclear']) self.showresponses.set(self.Configuration['showresponses']) # The invisibleroot is necessary to avoid stopping Tk's eventloop # upon closure of tkWindows. # TODO: Good idea to already activate here? # TODO: Don't we need a central InvisibleWindow thats kept inbetween destruction of tkinterfaces? self._invisibleRoot = tkInvisibleWindow().activate() # self.clearInput = tkinter.BooleanVar() self.MapViewer = None def __on_ButtonClear_Press(self, Event=None): self.clearEntry() def __on_ButtonTransmit_Release(self, Event=None): self.usertransmit() def __on_EntryInput_Enter__C(self, Event=None): self.usertransmit() def __on_ButtonClearResponses_Press(self, Event=None): self.__TextResponses.clear() def showMessage(self, ev=None): msglb = self.__MessageLog._listbox sel = msglb.curselection() if len(sel) > 1: self.logwarning("Multiple messages selected to display. Can't.") msg = self.messages[int(sel[0])] msgdialog = TkMessageDialog(self.window, msg) def composeMessage(self, name="", node="", sender=None): if not sender: sender = self.name msg = Message(sender=sender, recipientnode=node, recipient=name) msgdialog = TkMessageDialog(self.window, msg, onclosecallback=self.transmit) def clearEntry(self): self.__EntryInput.delete(0, END) self.__FrameInput['bg'] = self.defaultcolors['bg'] # self.__EntryInput['fg'] = self.defaultcolors['fg'] def scanregistry(self, node=""): msg = Message(sender=self.name, recipientnode=node, recipient=self.systemregistry, func="listRegisteredComponents", arg=None ) self.transmit(msg) msg = Message(sender=self.name, recipientnode=node, recipient=self.systemregistry, func="listRegisteredTemplates", arg=None ) self.transmit(msg) def scangateways(self): msg = Message(sender=self.name, recipient=self.systemdispatcher, func="listgateways" ) self.transmit(msg) def dumpnodelist(self): from pprint import pprint pprint(self.nodelist) def scancomponent(self, name, node=""): self.logdebug("Scanning component '%s'." % name) msg = Message(sender=self.name, recipientnode=node, recipient=name, func="getComponentInfo", arg=None) self.transmit(msg) def createcomponent(self, name, node=""): self.loginfo("Creating component from template '%s'." % name) msg = Message(sender=self.name, recipientnode=node, recipient=self.systemregistry, func="createComponent", arg={'templatename': name}) self.transmit(msg) def copystring(self, name): self.window.clipboard_clear() self.window.clipboard_append(name) def callComplexMethod(self, componentname, node, func): self.loginfo("Creating function dialog for '%s'@'%s'." % (func, componentname)) componentlist = self.nodelist[node]['componentlist'] component = componentlist[componentname] componentinfo = component["info"] methods = componentinfo["methods"] methodregister = methods[func] InputDialog = TkRPCArgDialog(self.window, self.callComplexMethodFinal, componentname, node, func, methodregister) def callComplexMethodFinal(self, name, node, func, args): self.loginfo("Finally calling func '%s'@'%s' with args '%s'" % (func, name, args)) msg = Message(sender=self.name, recipientnode=node, recipient=name, func=func, arg=args) self.transmit(msg) def callSimpleMethod(self, name, node, func): self.loginfo("Calling '%s'@'%s'." % (func, name)) msg = Message(sender=self.name, recipient=name, recipientnode=node, func=func, arg=None) self.transmit(msg) def transmit(self, msg): self.logdebug("Transmitting Message '%s'" % msg) self.recordMessage(msg) self.send(msg, "outbox") def recordMessage(self, msg): self.messages.append(msg) self.updateMessageLog() def updateMessageLog(self): loglistbox = self.__MessageLog._listbox loglistbox.delete(0, END) # GAH. Addition should be sufficient. CHANGE! for msg in sorted(self.messages, key=lambda msg: msg.timestamp): loglistbox.insert(END, msg) if msg.recipient == self.name: loglistbox.itemconfig(END, bg='green', fg='black') else: loglistbox.itemconfig(END, bg='red', fg='black') def editidentity(self): self.logerror("Not implemented. Here is a dump of this node's identity:") self.loginfo(identity.Systemidentity) self.loginfo(identity.SystemUUID) def usertransmit(self): def send(msg): if self.fixsender.get() and msg.sender != self.name: self.loginfo("Fixing sender to '%s'." % self.name) msg.sender = self.name self.loginfo("Transmitting message '%s'" % msg) self.transmit(msg) self.__FrameInput['bg'] = self.defaultcolors['bg'] message = self.__EntryInput.get() if len(message) <= 1: self.logdebug("No message to send entered.") return try: msg = jsonpickle.decode(message) send(msg) except ValueError as e: errmsg = 'Invalid JSON:\n%s' % e self.logerror(e) if "column" in errmsg: col = errmsg.split("(char ")[1].split(")")[0] col = col.split(" -")[0] self.__EntryInput.icursor(col) self.logwarning(errmsg) self.__FrameInput['bg'] = 'red' # self.__FrameInput['fg'] = 'yellow' messagebox.showinfo("Transmit failed!", errmsg) if self.autoclear.get(): self.clearEntry() def rebuildNodeMenu(self): NodeMenu = self.__MenuNodes NodeMenu.delete(4, END) for node in self.nodelist: NodeMenu.add_cascade(menu=self.nodelist[node]['menu'], label=node if node != "" else "LOCAL") def __handleNewNode(self, node): if node not in self.nodelist: self.loginfo("New node appeared! Hmm.") else: self.loginfo("Node rescanned.") print self.__MenuNodes componentlist = {} ComponentMenu = Menu(self.__MenuNodes) ComponentMenu.add_command(label="Scan", command=lambda node=node: self.scanregistry(node)) ComponentMenu.add_command(label="Copy Name", command=lambda node=node: self.copystring(node)) ComponentMenu.add_separator() nodeinfo = {'componentlist': componentlist, 'menu': ComponentMenu} self.nodelist[node] = nodeinfo def handleResponse(self, msg): self.recordMessage(msg) def __addComponents(components, node): componentlist = self.nodelist[node]['componentlist'] ComponentMenu = self.nodelist[node]['menu'] for comp in components: self.loginfo("Adding component '%s@%s'" % (comp, node)) if self.autoscan.get() and comp not in componentlist: self.scancomponent(comp, node) FuncMenu = Menu(ComponentMenu) FuncMenu.add_command(label="Scan", command=lambda (name,node)=(comp, node): self.scancomponent(name, node)) FuncMenu.add_command(label="Copy Name", command=lambda name=comp: self.copystring(name)) FuncMenu.add_command(label="Compose...", command=lambda (name,node)=(comp,node): self.composeMessage(name, node)) FuncMenu.add_separator() FuncMenu = Menu(ComponentMenu) ComponentMenu.add_cascade(label=comp, menu=FuncMenu) componentlist[comp] = {'menu': FuncMenu} def __handleListRegisteredTemplates(msg): MenuTemplates = self.__MenuTemplates MenuTemplates.delete(0, END) for template in sorted(msg.arg): node = '' MenuTemplates.add_command(label=template, command=lambda (name,node)=(template, node): self.createcomponent(name, node)) self.__MenuTemplates = MenuTemplates def __handleComponentInfo(msg): node = msg.sendernode if node not in self.nodelist: self.logerror('Node unknown') else: componentlist = self.nodelist[node]['componentlist'] if msg.sender not in componentlist: if self.autoscan.get(): self.loginfo("Unknown component '%s'. Rescanning registry." % msg.senderid) self.scanregistry(node) else: self.loginfo("Unknown component's ('%s') info encountered. Ignoring.") else: self.logdebug("Got a component's ('%s') RPC info. Parsing." % msg.sender) if componentlist[msg.sender] == 'scanned': self.logdebug("Scan from a self-created component returned.") component = msg.sender result = msg.arg componentlist[component]["info"] = result FuncMenu = componentlist[component]["menu"] FuncMenu.delete(5, END) mr = result['methods'] for meth in mr: self.logdebug("Got method '%s'." % meth) if len(mr[meth]['args']) > 0: FuncMenu.add_command(label=meth, command=lambda (node, name, meth)=(node, component, meth): self.callComplexMethod(name, node, meth)) else: FuncMenu.add_command(label=meth, command=lambda (node, name, meth)=(node, component, meth): self.callSimpleMethod(name, node, meth)) def __handleCreateComponent(msg): node = msg.sendernode component = msg.arg if node not in self.nodelist: self.__handleNewNode(node) componentlist = self.nodelist[node]['componentlist'] __addComponents([component], node) def __handleRegisteredComponents(msg): node = msg.sendernode self.loginfo("Got a list of registered components from '%s'. Parsing." % node) self.__handleNewNode(node) # Schema nodelist: # {nodeUUID: {'componentlist': componentlist, 'menu': ComponentMenu} # Schema componentlist: # {componentname: {'funclist': funclist, 'menu': funcmenu} # Schema funclist: # {func: menu} components = msg.arg __addComponents(components, node) self.rebuildNodeMenu() def __handleGatewayList(msg): self.loginfo("Received a list of connected nodes.") for node in msg.arg: self.__handleNewNode(node) if self.autoscan.get(): self.scanregistry(node) self.rebuildNodeMenu() if isinstance(msg, Message): if msg.sender == self.systemdispatcher: if msg.func == "listgateways": __handleGatewayList(msg) if msg.sender == self.systemregistry and not msg.error: if msg.func == "createComponent": __handleCreateComponent(msg) if msg.func == "listRegisteredComponents": __handleRegisteredComponents(msg) elif msg.func == "listRegisteredTemplates": __handleListRegisteredTemplates(msg) if msg.func == "getComponentInfo": if not msg.error: __handleComponentInfo(msg) if msg.func in ("renderArea", "renderCoord"): if not msg.error: if self.MapViewer: self.MapViewer.drawMap(msg.arg) else: self.MapViewer = TkMapDialog(msg.arg) self.MapViewer.activate() def scanlinetest(self): polygon = [[50, 5], [100, 270], [150, 270], [220, 30]] ScanlineTestDialog = TkScanlineTestDialog(polygon) def quit(self): self.logcritical("Shutting down hard.") try: import cherrypy self.loginfo("WebGate running. Stopping cherrypy first.") cherrypy.engine.stop() except ImportError: self.loginfo("WebGate not running. Not killing cherrypy.") Scheduler.scheduler.run.stop() def setupWindow(self): self.logdebug("Setting up TkAdmin GUI") Pmw.initialise(self.window) self.window.title(self.title) ### Menu ### self.__FrameMenu = Frame(self.window) self.__FrameMenu.pack(anchor='n', side='top') self.__Menu = Menu(self.window) self.__MenuFile = Menu(self.__Menu) self.__MenuEdit = Menu(self.__Menu) self.__MenuMessage = Menu(self.__Menu) self.__MenuSettings = Menu(self.__Menu) self.__MenuSystem = Menu(self.__Menu) self.__Menu.add_cascade(menu=self.__MenuFile, label="File") self.__Menu.add_cascade(menu=self.__MenuEdit, label="Edit") self.__Menu.add_cascade(menu=self.__MenuMessage, label="Message") self.__Menu.add_cascade(menu=self.__MenuSettings, label="Settings") self.__Menu.add_cascade(menu=self.__MenuSystem, label="System") self.window.config(menu=self.__Menu) self.__MenuFile.add_command(label="Update Message Log", command=self.updateMessageLog) self.__MenuFile.add_command(label="Quit", command=self.quit) self.autoscan = BooleanVar() self.fixsender = BooleanVar() self.autoclear = BooleanVar() self.showresponses = BooleanVar() self.__MenuMessage.add_command(label="View", command=self.showMessage) self.__MenuMessage.add_command(label="Compose New", command=self.composeMessage) self.__MenuSettings.add_checkbutton(label="Fix sender", onvalue=True, offvalue=False, variable=self.fixsender) self.__MenuSettings.add_checkbutton(label="Autoscan", onvalue=True, offvalue=False, variable=self.autoscan) self.__MenuSettings.add_checkbutton(label="Autoclear", onvalue=True, offvalue=False, variable=self.autoclear) self.__MenuSettings.add_checkbutton(label="Show responses", onvalue=True, offvalue=False, variable=self.showresponses) self.__MenuSystem.add_command(label="View/Edit identity", command=self.editidentity) self.__MenuTemplates = Menu(self.__MenuSystem) self.__MenuSystem.add_cascade(label='Create Component', menu=self.__MenuTemplates) self.__MenuNodes = Menu(self.__Menu) self.__MenuNodes.add_command(label="Update connected nodes", command=self.scangateways) self.__MenuNodes.add_command(label="Scan Local", command=self.scanregistry) self.__MenuNodes.add_command(label="Dump Nodelist", command=self.dumpnodelist) self.__MenuNodes.add_separator() self.__Menu.add_cascade(menu=self.__MenuNodes, label="Nodes") ### /Menu ### ### Output ### self.__FrameOutput = Frame(self.window) self.__FrameOutput.pack(side='top', fill='both', expand='yes') self.__NotebookOutput = Pmw.NoteBook(self.__FrameOutput) self.__NotebookOutput.pack(fill='both', expand=1) self.__PageMessages = self.__NotebookOutput.add('Messages') self.__PageMap = self.__NotebookOutput.add('Map') self.__PageResponses = self.__NotebookOutput.add('Responses') #self.__PageLog = self.__NotebookOutput.add('Log') # Needs a loggercomponent and revised logging first self.__MessageLog = Pmw.ScrolledListBox(self.__PageMessages) self.__MessageLog.pack(expand='yes', fill='both') self.__NotebookOutput.tab('Messages').focus_set() self.__FrameInput = Frame(self.window, borderwidth=2) self.__FrameInput.pack(anchor='s', expand='no', fill='x', side='top') self.__FrameStatusbar = Frame(self.window, relief='raised') self.__FrameStatusbar.pack(anchor='sw', side='top') # ,fill='x' self.__LabelStatus = Label(self.__FrameStatusbar, text='Ready.') self.__LabelStatus.pack(anchor='w', expand='yes', side='top') # ,fill='both' self.__FrameResponses = Frame(self.__PageResponses, background="yellow") self.__FrameResponsesHeader = Frame(self.__FrameResponses) self.__LabelResponses = Label(self.__FrameResponsesHeader, text='Responses') self.__LabelResponses.pack(anchor='e', side='right', fill='x') self.__ButtonClearResponses = Button(self.__FrameResponsesHeader, text='Clear') self.__ButtonClearResponses.pack(anchor='w', side='left') self.__FrameResponsesHeader.pack(anchor='n', fill='x', side=TOP) self.__TextResponses = Pmw.ScrolledText(self.__FrameResponses) self.__TextResponses.pack(expand=1, fill='both', side=BOTTOM) self.__FrameResponses.pack(expand=1, fill="both") #self.__FrameLog = Frame(self.__PageLog) #self.__FrameLog.pack(side='left', expand=1, fill="both") #self.__FrameLogHeader = Frame(self.__FrameLog) #self.__FrameLogHeader.pack(anchor='n',expand='yes', fill='x', side='top') #self.__LabelLog = Label(self.__FrameLogHeader,text='Log') #self.__LabelLog.pack(anchor='e',side='right', fill='both') #self.__ButtonClearLog = Button(self.__FrameLogHeader, text='Clear') #self.__ButtonClearLog.pack(anchor='w',side='left') #self.__TextLog = Pmw.ScrolledText(self.__FrameLog) #self.__TextLog.pack(expand=1,fill='both') self.__MapCanvas = Canvas(self.__PageMap) self.__MapCanvas.pack(expand=1, fill='both') self.__NotebookOutput.setnaturalsize() ### /Output ### ### Input ### self.__FrameInputEntry = Frame(self.__FrameInput) self.__EntryInput = Entry(self.__FrameInput) self.__EntryInput.pack(expand='yes', fill='both', side='left') self.__FrameTransmitButton = Frame(self.__FrameInput) self.__FrameTransmitButton.pack(anchor='w', side='left') self.__ButtonTransmit = Button(self.__FrameTransmitButton , text='Transmit') self.__ButtonTransmit.pack(expand='yes', fill='both', side='top') self.__FrameClearButton = Frame(self.__FrameInput) self.__FrameClearButton.pack(anchor='w', side='left') self.__ButtonClear = Button(self.__FrameClearButton, text='Clear') self.__ButtonClear.pack(expand='yes', fill='both', side='top') self.__FrameInputEntry.pack(side='left') ### /Input ### ### Bindings ### self.__MessageLog._listbox.bind("<Double-Button-1>", self.showMessage) self.__ButtonClearResponses.bind('<ButtonRelease-1>' , self.__on_ButtonClearResponses_Press) self.__ButtonTransmit.bind('<ButtonRelease-1>' , self.__on_ButtonTransmit_Release) self.__ButtonClear.bind('<ButtonPress-1>', self.__on_ButtonClear_Press) self.__EntryInput.bind('<Control-Return>', self.__on_EntryInput_Enter__C) self.defaultcolors = {'bg': self.window['bg'], 'fg': self.__EntryInput['fg']} def main(self): """ Main loop. Stub method, reimplement with your own functionality. Must regularly call self.tkupdate() to ensure tk event processing happens. """ if self.autoscan.get(): self.loginfo("Local autoscan initiated.") self.scanregistry() while not self.isDestroyed(): yield 1 if self.dataReady("control"): msg = self.recv("control") if isinstance(msg, producerFinished) or isinstance(msg, shutdownMicroprocess): self.send(msg, "signal") self.window.destroy() if self.dataReady("inbox"): msg = self.recv("inbox") self.logdebug("Received message '%s'" % msg) self.handleRPC(msg) if self.showresponses.get(): self.__TextResponses.insert(END, "%s\n" % msg) self.tkupdate()
class FileNamePurifierGUI(Frame): appWidth = 480 appHeight = 360 """ TODO: add "old separators" menu (possibly including camelCase and custom) if(camelCase or custom): add logic in Parser add "preserve text" box to prevent wiping of '.' from names when needed add logic to make the separators exclusive add logic to allow the use of camelCase as a separator """ #important instance variables: """ Separators: self.spacesButton self.underscoresButton self.camelcaseButton self.finalCustomSeparator self.periodButton """ """ break up by: self.breakUpByBraces self.breakUpByParens self.breakUpByBrackets self.breakUpByCamelCase """ """ append to: self.finalAppendToFrontText self.finalAppendToEndText """ """ misc: self.affectSubfolders self.cleanFolderNames self.finalRemoveFirstInstanceText """ """ #newSeparator is a string because self.finalCustomSeparator is a string newSeparator = " " if(self.underscoresButton.get()): newSeparator = "_" elif(self.camelcaseButton.get()): pass elif(len(self.finalCustomSeparator) > 0): newSeparator = self.finalCustomSeparator elif(self.periodButton.get()): newSeparator = "." parser = Parser(self.finalAppendToFrontText, self.finalAppendToEndText, [self.finalRemoveFirstInstanceText], [], [], [' ', '_', '.'], newSeparator, self.breakUpByBraces, self.breakUpByParens, self.breakUpByBrackets, self.breakUpByCamelCase, ) """ def __init__(self, parent, width, height): Frame.__init__(self, parent) self.appWidth = width self.appHeight = height self.parent = parent self.initUI() self.centerWindow() self.dir_opt = {} self.finalAppendToEndText = "" self.finalAppendToFrontText = "" self.finalRemoveFirstInstanceText = "" def askDirectory(self): self.addDirectoryText(askdirectory(**self.dir_opt).rstrip('\r\n')) def addDirectoryText(self, stringToAdd): self.directoryText.config(state = NORMAL) self.directoryText.delete("0.0", END) self.directoryText.insert("0.0", stringToAdd.rstrip('\r\n')) self.directoryText.config(state = DISABLED) def GetNewSeparator(self): newSeparator = "" if(self.spacesButton.get()): newSeparator = " "; elif(self.underscoresButton.get()): newSeparator = "_"; elif(self.camelcaseButton.get()): #TODO: implement seperate by camelcase pass elif(self.periodButton.get()): newSeparator = "." elif(len(self.finalCustomSeparator) > 0): newSeparator = self.finalCustomSeparator return newSeparator def ReadOldSeparatorList(self): oldSeparatorList = [] if(self.oldSpacesButton.get()): oldSeparatorList.append(" ") if(self.oldUnderscoresButton.get()): oldSeparatorList.append("_") if(self.oldPeriodButton.get()): oldSeparatorList.append(".") return oldSeparatorList def CreatePurifierForOptions(self): purifier = FileNamePurifier(self.finalAppendToFrontText, self.finalAppendToEndText, [self.finalRemoveFirstInstanceText], [], [], self.ReadOldSeparatorList(), self.GetNewSeparator(), self.breakUpByBraces.get(), self.breakUpByParens.get(), self.breakUpByBrackets.get(), self.breakUpByCamelCase.get(), self.oldCamelcaseButton.get(), self.camelcaseButton.get()) return purifier def purifyFiles(self): if(len(self.directoryText.get("0.0", END)) > 0): selectorAndPurifier = FileSelectorAndPurifier(self.affectSubfolders.get(), self.cleanFolderNames.get(), self.directoryText.get("0.0", END), self.CreatePurifierForOptions()) tkMessageBox.showinfo("FileNamePurifier", "Purifying FileNames. Please Wait.") selectorAndPurifier.PurifyFileNames() tkMessageBox.showinfo("FileNamePurifier", "FileName Purification Complete!") def CreateOldSeparatorMenu(self): self.oldSeparatorMenu = Menu(self.optionsMenu, tearoff=0) self.oldSpacesButton = BooleanVar() self.oldUnderscoresButton = BooleanVar() self.oldCamelcaseButton = BooleanVar() self.oldPeriodButton = BooleanVar() self.oldSeparatorMenu.add_checkbutton(label="Spaces", onvalue=True, offvalue=False, variable=self.oldSpacesButton) self.oldSpacesButton.set(True) self.oldSeparatorMenu.add_checkbutton(label="Underscores", onvalue=True, offvalue=False, variable=self.oldUnderscoresButton) self.oldUnderscoresButton.set(True) #self.oldSeparatorMenu.add_command(label="Custom Separator", command=self.customSeparatorFrame) self.oldSeparatorMenu.add_checkbutton(label="CamelCase", onvalue=True, offvalue=False, variable=self.oldCamelcaseButton) self.oldSeparatorMenu.add_checkbutton(label="Period", onvalue=True, offvalue=False, variable=self.oldPeriodButton) self.optionsMenu.add_cascade(label="Old Separator", menu=self.oldSeparatorMenu) def addSubMenus(self): self.CreateOldSeparatorMenu() self.createNewSeparatorMenu() self.addSubCheckbuttons() self.createBreakUpByMenu() self.createAppendTextMenu() self.optionsMenu.add_command(label="Remove First Instance Of", command=self.removeFirstInstanceFrame) def submitRemoveFirstInstanceText(self): self.finalRemoveFirstInstanceText = self.removeFirstInstanceText.get("0.0", END) def removeFirstInstanceFrame(self): root = Tk() removeFirstInstanceFrame = Frame(root) removeFirstInstanceFrame.pack(fill=BOTH, expand=1) self.removeFirstInstanceText = Text(removeFirstInstanceFrame) self.removeFirstInstanceText.config(width = 80, height = 1) self.removeFirstInstanceText.pack() removeFirstButton = Button(removeFirstInstanceFrame, text="Submit", command=self.submitRemoveFirstInstanceText) removeFirstButton.pack() root.title("Enter text to remove the first instance of: ") root.mainloop() def submitAppendToFrontText(self): self.finalAppendToFrontText = self.appendToFrontText.get("0.0", END) def appendToFrontFrame(self): root = Tk() frame= Frame(root) frame.pack(fill=BOTH, expand=1) self.appendToFrontText = Text(frame) self.appendToFrontText.config(width = 80, height = 1) self.appendToFrontText.pack() submitButton = Button(frame, text="Submit", command=self.submitAppendToFrontText) submitButton.pack() root.title("Enter text to append to the front: ") root.mainloop() def submitAppendToEndText(self): self.finalAppendToEndText = self.appendToEndText.get("0.0", END) def appendToEndFrame(self): root = Tk() frame= Frame(root) frame.pack(fill=BOTH, expand=1) self.appendToEndText = Text(frame) self.appendToEndText.config(width = 80, height = 1) self.appendToEndText.pack() submitButton = Button(frame, text="Submit", command=self.submitAppendToEndText) submitButton.pack() root.title("Enter text to append to the end: ") root.mainloop() def createAppendTextMenu(self): self.appendText = Menu(self.optionsMenu, tearoff=0) self.appendText.add_command(label="Append To Front", command=self.appendToFrontFrame) self.appendText.add_command(label="Append To End", command=self.appendToEndFrame) self.optionsMenu.add_cascade(label="Append Text", menu=self.appendText) def createBreakUpByMenu(self): self.delimitersMenu = Menu(self.optionsMenu, tearoff=0) self.breakUpByBraces = BooleanVar() self.breakUpByParens = BooleanVar() self.breakUpByBrackets = BooleanVar() self.breakUpByCamelCase = BooleanVar() self.breakUpByParens.set(True) self.breakUpByBrackets.set(True) self.delimitersMenu.add_checkbutton(label="Braces", onvalue=True, offvalue=False, variable=self.breakUpByBraces) self.delimitersMenu.add_checkbutton(label="Parentheses", onvalue=True, offvalue=False, variable=self.breakUpByParens) self.delimitersMenu.add_checkbutton(label="Brackets", onvalue=True, offvalue=False, variable=self.breakUpByBrackets) self.delimitersMenu.add_checkbutton(label="CamelCase", onvalue=True, offvalue=False, variable=self.breakUpByCamelCase) self.optionsMenu.add_cascade(label="Delimiters", menu=self.delimitersMenu) def submitCustomSeparator(self): self.finalCustomSeparator = self.customSeparator.get("0.0", END) def customSeparatorFrame(self): root = Tk() frame= Frame(root) frame.pack(fill=BOTH, expand=1) self.customSeparator = Text(frame) self.customSeparator.config(width = 80, height = 1) self.customSeparator.pack() submitButton = Button(frame, text="Submit", command=self.submitCustomSeparator) submitButton.pack() root.title("Enter a custom separator:") root.mainloop() def ToggleNonUnderscoresOff(self): self.spacesButton.set(False) self.camelcaseButton.set(False) self.periodButton.set(False) def ToggleNonSpacesOff(self): self.underscoresButton.set(False) self.camelcaseButton.set(False) self.periodButton.set(False) def ToggleNonCamelCaseOff(self): self.spacesButton.set(False) self.underscoresButton.set(False) self.periodButton.set(False) def ToggleNonPeriodOff(self): self.spacesButton.set(False) self.camelcaseButton.set(False) self.underscoresButton.set(False) def createNewSeparatorMenu(self): self.newSeparatorMenu = Menu(self.optionsMenu, tearoff=0) self.spacesButton = BooleanVar() self.underscoresButton = BooleanVar() self.camelcaseButton = BooleanVar() self.periodButton = BooleanVar() self.newSeparatorMenu.add_checkbutton(label="Spaces", onvalue=True, offvalue=False, variable=self.spacesButton, command=self.ToggleNonSpacesOff) self.spacesButton.set(True) self.newSeparatorMenu.add_checkbutton(label="Underscores", onvalue=True, offvalue=False, variable=self.underscoresButton, command=self.ToggleNonUnderscoresOff) self.newSeparatorMenu.add_command(label="Custom Separator", command=self.customSeparatorFrame) self.newSeparatorMenu.add_checkbutton(label="CamelCase", onvalue=True, offvalue=False, variable=self.camelcaseButton, command=self.ToggleNonCamelCaseOff) self.newSeparatorMenu.add_checkbutton(label="Period", onvalue=True, offvalue=False, variable=self.periodButton, command=self.ToggleNonPeriodOff) self.optionsMenu.add_cascade(label="New Separator", menu=self.newSeparatorMenu) def addSubCheckbuttons(self): self.affectSubfolders = BooleanVar() self.cleanFolderNames = BooleanVar() self.optionsMenu.add_checkbutton(label="Affect Subfolders", onvalue=True, offvalue=False, variable=self.affectSubfolders) self.optionsMenu.add_checkbutton(label="Clean Folder Names", onvalue=True, offvalue=False, variable=self.cleanFolderNames) self.affectSubfolders.set(True) self.cleanFolderNames.set(True) def initUI(self): self.parent.title("Filename Purifier") self.pack(fill=BOTH, expand=1) self.directoryButton = Button(self, text="Choose Directory", command=self.askDirectory) self.directoryButton.place(x = self.appWidth/3, y = 70) self.directoryText = Text() self.directoryText.config(width = 40, height = 1) self.directoryText.config(state = DISABLED) self.directoryText.place(x = 100, y = 120) self.purifyButton = Button(self, text="Purify Files", command=self.purifyFiles) self.purifyButton.place(x = self.appWidth/3 + 25, y = 170) self.menubar = Menu(self) self.optionsMenu = Menu(self.menubar, tearoff=0) self.addSubMenus() self.menubar.add_cascade(label="Options", menu=self.optionsMenu) self.parent.config(menu=self.menubar) def centerWindow(self): screenWidth = self.parent.winfo_screenwidth() screenHeight = self.parent.winfo_screenheight() x = (screenWidth - self.appWidth)/2 y = (screenHeight - self.appHeight)/2 self.parent.geometry('%dx%d+%d+%d' % (self.appWidth, self.appHeight, x, y))
def __init__(self, master, visible=True): self.root = master Menu.__init__(self, master.root) self.sc3_plugins = BooleanVar() self.sc3_plugins.set(SC3_PLUGINS) self.listening = BooleanVar() self.listening.set(False) # Set font self.config(font="CodeFont") # 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.selectall, 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="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) # Code menu ctrl = "Command" if SYSTEM == MAC_OS else "Ctrl" # 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.allow_connections, variable=self.listening) self.add_cascade(label="Language", menu=codemenu) # Help helpmenu = Menu(self, tearoff=0) helpmenu.add_command(label="Visit FoxDot Homepage", command=self.root.openhomepage) helpmenu.add_command(label="Documentation", command=self.root.opendocumentation) 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) ## settingsmenu.add_command(label="Change Colours...", command=self.root.toggleMenu) 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)
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)
def __init__(self, master, visible=True): self.root = master Menu.__init__(self, master.root) # File menu filemenu = Menu(self, tearoff=0) filemenu.add_command(label="New Document", command=self.new_file, accelerator="Ctrl+N") filemenu.add_command(label="Save", command=self.save_file, accelerator="Ctrl+S") filemenu.add_command(label="Open", command=self.open_file, accelerator="Ctrl+O") filemenu.add_separator() filemenu.add_command(label="Start logging performance", command=lambda: "break") filemenu.add_command(label="Import logged performance", command=self.root.ImportLog) self.add_cascade(label="File", menu=filemenu) # Edit menu editmenu = Menu(self, tearoff=0) editmenu.add_command(label="Cut", command=self.root.Cut, accelerator="Ctrl+X") editmenu.add_command(label="Copy", command=self.root.Copy, accelerator="Ctrl+C") editmenu.add_command(label="Paste", command=self.root.Paste, accelerator="Ctrl+V") editmenu.add_command(label="Select All", command=self.root.SelectAll, accelerator="Ctrl+/") editmenu.add_separator() editmenu.add_command(label="Increase Font Size", command=self.root.IncreaseFontSize, accelerator="Ctrl+=") editmenu.add_command(label="Decrease Font Size", command=self.root.DecreaseFontSize, accelerator="Ctrl+-") editmenu.add_separator() editmenu.add_command(label="Toggle Menu", command=self.root.ToggleMenu, accelerator="Ctrl+M") editmenu.add_separator() editmenu.add_command(label="Edit Colours", command=self.root.EditColours) editmenu.add_checkbutton(label="Toggle Window Transparency", command=self.root.ToggleTransparency, variable=self.root.transparent) self.add_cascade(label="Edit", menu=editmenu) # Code menu codemenu = Menu(self, tearoff=0) codemenu.add_command(label="Evaluate Code", command=self.root.Evaluate, accelerator="Ctrl+Return") codemenu.add_command(label="Evaluate Single Line", command=self.root.SingleLineEvaluate, accelerator="Alt+Return") codemenu.add_command(label="Stop All Sound", command=self.root.stopSound, accelerator="Ctrl+.") codemenu.add_command(label="Re-sync text", command=self.root.syncText) codemenu.add_command(label="Font colour merge", command=self.root.beginFontMerge) codemenu.add_separator() # Allow choice of interpreter langmenu = Menu(self, tearoff=0) for name, interpreter in langnames.items(): langmenu.add_checkbutton(label=langtitles[name], command=partial(self.root.set_interpreter, interpreter), variable=self.root.interpreters[name]) codemenu.add_cascade(label="Choose language", menu=langmenu) self.add_cascade(label="Code", menu=codemenu) # Creative constraint menu constraintmenu = Menu(self, tearoff=0) # Get the names of constraints from . import constraints constraints = vars(constraints) for name in constraints: if not name.startswith("_"): constraintmenu.add_checkbutton( label=name.title(), command=partial(self.root.set_constraint, name), variable=self.root.creative_constraints[name]) self.add_cascade(label="Constraints", menu=constraintmenu) # Help helpmenu = Menu(self, tearoff=0) helpmenu.add_command(label="Documentation", command=self.root.OpenGitHub) self.add_cascade(label="Help", menu=helpmenu) # Add to root self.visible = visible if self.visible: master.root.config(menu=self)
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)
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="Export Console Log", command=self.root.export_console) editmenu.add_command(label="Toggle Console", command=self.root.toggle_console) editmenu.add_separator() 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) editmenu.add_checkbutton(label="Toggle Auto-fill Prompt", command=self.root.toggle_prompt, variable=self.root.show_prompt) 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_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) if filename.endswith(".py"): filename = filename.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)
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 TkAdmin(TkWindow, RPCComponent): """ Development graphical user interface for cape systems. """ unique = True directory_name = "TkAdmin" # TODO: # * Clean up user interface # * Develop interaction elements for all primitives def __init__(self): self.nodelist = {} self.messages = [] self.title = "cape TkAdmin - [%s]" % identity.SystemName super(TkAdmin, self).__init__() self.Configuration['fixsender'] = False self.Configuration['autoclear'] = True self.Configuration['autoscan'] = True self.Configuration['showresponses'] = False self.autoscan.set(self.Configuration['autoscan']) self.fixsender.set(self.Configuration['fixsender']) self.autoclear.set(self.Configuration['autoclear']) self.showresponses.set(self.Configuration['showresponses']) # The invisibleroot is necessary to avoid stopping Tk's eventloop # upon closure of tkWindows. # TODO: Good idea to already activate here? # TODO: Don't we need a central InvisibleWindow thats kept inbetween destruction of tkinterfaces? self._invisibleRoot = tkInvisibleWindow().activate() # self.clearInput = tkinter.BooleanVar() self.MapViewer = None def __on_ButtonClear_Press(self, Event=None): self.clearEntry() def __on_ButtonTransmit_Release(self, Event=None): self.usertransmit() def __on_EntryInput_Enter__C(self, Event=None): self.usertransmit() def __on_ButtonClearResponses_Press(self, Event=None): self.__TextResponses.clear() def showMessage(self, ev=None): msglb = self.__MessageLog._listbox sel = msglb.curselection() if len(sel) > 1: self.logwarning("Multiple messages selected to display. Can't.") msg = self.messages[int(sel[0])] msgdialog = TkMessageDialog(self.window, msg) def composeMessage(self, name="", node="", sender=None): if not sender: sender = self.name msg = Message(sender=sender, recipientnode=node, recipient=name) msgdialog = TkMessageDialog(self.window, msg, onclosecallback=self.transmit) def clearEntry(self): self.__EntryInput.delete(0, END) self.__FrameInput['bg'] = self.defaultcolors['bg'] # self.__EntryInput['fg'] = self.defaultcolors['fg'] def scanregistry(self, node=""): msg = Message(sender=self.name, recipientnode=node, recipient=self.systemregistry, func="listRegisteredComponents", arg=None) self.transmit(msg) msg = Message(sender=self.name, recipientnode=node, recipient=self.systemregistry, func="listRegisteredTemplates", arg=None) self.transmit(msg) def scangateways(self): msg = Message(sender=self.name, recipient=self.systemdispatcher, func="listgateways") self.transmit(msg) def dumpnodelist(self): from pprint import pprint pprint(self.nodelist) def scancomponent(self, name, node=""): self.logdebug("Scanning component '%s'." % name) msg = Message(sender=self.name, recipientnode=node, recipient=name, func="getComponentInfo", arg=None) self.transmit(msg) def createcomponent(self, name, node=""): self.loginfo("Creating component from template '%s'." % name) msg = Message(sender=self.name, recipientnode=node, recipient=self.systemregistry, func="createComponent", arg={'templatename': name}) self.transmit(msg) def copystring(self, name): self.window.clipboard_clear() self.window.clipboard_append(name) def callComplexMethod(self, componentname, node, func): self.loginfo("Creating function dialog for '%s'@'%s'." % (func, componentname)) componentlist = self.nodelist[node]['componentlist'] component = componentlist[componentname] componentinfo = component["info"] methods = componentinfo["methods"] methodregister = methods[func] InputDialog = TkRPCArgDialog(self.window, self.callComplexMethodFinal, componentname, node, func, methodregister) def callComplexMethodFinal(self, name, node, func, args): self.loginfo("Finally calling func '%s'@'%s' with args '%s'" % (func, name, args)) msg = Message(sender=self.name, recipientnode=node, recipient=name, func=func, arg=args) self.transmit(msg) def callSimpleMethod(self, name, node, func): self.loginfo("Calling '%s'@'%s'." % (func, name)) msg = Message(sender=self.name, recipient=name, recipientnode=node, func=func, arg=None) self.transmit(msg) def transmit(self, msg): self.logdebug("Transmitting Message '%s'" % msg) self.recordMessage(msg) self.send(msg, "outbox") def recordMessage(self, msg): self.messages.append(msg) self.updateMessageLog() def updateMessageLog(self): loglistbox = self.__MessageLog._listbox loglistbox.delete(0, END) # GAH. Addition should be sufficient. CHANGE! for msg in sorted(self.messages, key=lambda msg: msg.timestamp): loglistbox.insert(END, msg) if msg.recipient == self.name: loglistbox.itemconfig(END, bg='green', fg='black') else: loglistbox.itemconfig(END, bg='red', fg='black') def editidentity(self): self.logerror( "Not implemented. Here is a dump of this node's identity:") self.loginfo(identity.Systemidentity) self.loginfo(identity.SystemUUID) def usertransmit(self): def send(msg): if self.fixsender.get() and msg.sender != self.name: self.loginfo("Fixing sender to '%s'." % self.name) msg.sender = self.name self.loginfo("Transmitting message '%s'" % msg) self.transmit(msg) self.__FrameInput['bg'] = self.defaultcolors['bg'] message = self.__EntryInput.get() if len(message) <= 1: self.logdebug("No message to send entered.") return try: msg = jsonpickle.decode(message) send(msg) except ValueError as e: errmsg = 'Invalid JSON:\n%s' % e self.logerror(e) if "column" in errmsg: col = errmsg.split("(char ")[1].split(")")[0] col = col.split(" -")[0] self.__EntryInput.icursor(col) self.logwarning(errmsg) self.__FrameInput['bg'] = 'red' # self.__FrameInput['fg'] = 'yellow' messagebox.showinfo("Transmit failed!", errmsg) if self.autoclear.get(): self.clearEntry() def rebuildNodeMenu(self): NodeMenu = self.__MenuNodes NodeMenu.delete(4, END) for node in self.nodelist: NodeMenu.add_cascade(menu=self.nodelist[node]['menu'], label=node if node != "" else "LOCAL") def __handleNewNode(self, node): if node not in self.nodelist: self.loginfo("New node appeared! Hmm.") else: self.loginfo("Node rescanned.") print self.__MenuNodes componentlist = {} ComponentMenu = Menu(self.__MenuNodes) ComponentMenu.add_command( label="Scan", command=lambda node=node: self.scanregistry(node)) ComponentMenu.add_command( label="Copy Name", command=lambda node=node: self.copystring(node)) ComponentMenu.add_separator() nodeinfo = {'componentlist': componentlist, 'menu': ComponentMenu} self.nodelist[node] = nodeinfo def handleResponse(self, msg): self.recordMessage(msg) def __addComponents(components, node): componentlist = self.nodelist[node]['componentlist'] ComponentMenu = self.nodelist[node]['menu'] for comp in components: self.loginfo("Adding component '%s@%s'" % (comp, node)) if self.autoscan.get() and comp not in componentlist: self.scancomponent(comp, node) FuncMenu = Menu(ComponentMenu) FuncMenu.add_command( label="Scan", command=lambda (name, node)=(comp, node): self.scancomponent(name, node)) FuncMenu.add_command( label="Copy Name", command=lambda name=comp: self.copystring(name)) FuncMenu.add_command( label="Compose...", command=lambda (name, node)=(comp, node): self.composeMessage(name, node)) FuncMenu.add_separator() FuncMenu = Menu(ComponentMenu) ComponentMenu.add_cascade(label=comp, menu=FuncMenu) componentlist[comp] = {'menu': FuncMenu} def __handleListRegisteredTemplates(msg): MenuTemplates = self.__MenuTemplates MenuTemplates.delete(0, END) for template in sorted(msg.arg): node = '' MenuTemplates.add_command(label=template, command=lambda (name, node)=(template, node): self. createcomponent(name, node)) self.__MenuTemplates = MenuTemplates def __handleComponentInfo(msg): node = msg.sendernode if node not in self.nodelist: self.logerror('Node unknown') else: componentlist = self.nodelist[node]['componentlist'] if msg.sender not in componentlist: if self.autoscan.get(): self.loginfo( "Unknown component '%s'. Rescanning registry." % msg.senderid) self.scanregistry(node) else: self.loginfo( "Unknown component's ('%s') info encountered. Ignoring." ) else: self.logdebug("Got a component's ('%s') RPC info. Parsing." % msg.sender) if componentlist[msg.sender] == 'scanned': self.logdebug( "Scan from a self-created component returned.") component = msg.sender result = msg.arg componentlist[component]["info"] = result FuncMenu = componentlist[component]["menu"] FuncMenu.delete(5, END) mr = result['methods'] for meth in mr: self.logdebug("Got method '%s'." % meth) if len(mr[meth]['args']) > 0: FuncMenu.add_command( label=meth, command=lambda (node, name, meth)=(node, component, meth): self. callComplexMethod(name, node, meth)) else: FuncMenu.add_command( label=meth, command=lambda (node, name, meth)=(node, component, meth): self. callSimpleMethod(name, node, meth)) def __handleCreateComponent(msg): node = msg.sendernode component = msg.arg if node not in self.nodelist: self.__handleNewNode(node) componentlist = self.nodelist[node]['componentlist'] __addComponents([component], node) def __handleRegisteredComponents(msg): node = msg.sendernode self.loginfo( "Got a list of registered components from '%s'. Parsing." % node) self.__handleNewNode(node) # Schema nodelist: # {nodeUUID: {'componentlist': componentlist, 'menu': ComponentMenu} # Schema componentlist: # {componentname: {'funclist': funclist, 'menu': funcmenu} # Schema funclist: # {func: menu} components = msg.arg __addComponents(components, node) self.rebuildNodeMenu() def __handleGatewayList(msg): self.loginfo("Received a list of connected nodes.") for node in msg.arg: self.__handleNewNode(node) if self.autoscan.get(): self.scanregistry(node) self.rebuildNodeMenu() if isinstance(msg, Message): if msg.sender == self.systemdispatcher: if msg.func == "listgateways": __handleGatewayList(msg) if msg.sender == self.systemregistry and not msg.error: if msg.func == "createComponent": __handleCreateComponent(msg) if msg.func == "listRegisteredComponents": __handleRegisteredComponents(msg) elif msg.func == "listRegisteredTemplates": __handleListRegisteredTemplates(msg) if msg.func == "getComponentInfo": if not msg.error: __handleComponentInfo(msg) if msg.func in ("renderArea", "renderCoord"): if not msg.error: if self.MapViewer: self.MapViewer.drawMap(msg.arg) else: self.MapViewer = TkMapDialog(msg.arg) self.MapViewer.activate() def scanlinetest(self): polygon = [[50, 5], [100, 270], [150, 270], [220, 30]] ScanlineTestDialog = TkScanlineTestDialog(polygon) def quit(self): self.logcritical("Shutting down hard.") try: import cherrypy self.loginfo("WebGate running. Stopping cherrypy first.") cherrypy.engine.stop() except ImportError: self.loginfo("WebGate not running. Not killing cherrypy.") Scheduler.scheduler.run.stop() def setupWindow(self): self.logdebug("Setting up TkAdmin GUI") Pmw.initialise(self.window) self.window.title(self.title) ### Menu ### self.__FrameMenu = Frame(self.window) self.__FrameMenu.pack(anchor='n', side='top') self.__Menu = Menu(self.window) self.__MenuFile = Menu(self.__Menu) self.__MenuEdit = Menu(self.__Menu) self.__MenuMessage = Menu(self.__Menu) self.__MenuSettings = Menu(self.__Menu) self.__MenuSystem = Menu(self.__Menu) self.__Menu.add_cascade(menu=self.__MenuFile, label="File") self.__Menu.add_cascade(menu=self.__MenuEdit, label="Edit") self.__Menu.add_cascade(menu=self.__MenuMessage, label="Message") self.__Menu.add_cascade(menu=self.__MenuSettings, label="Settings") self.__Menu.add_cascade(menu=self.__MenuSystem, label="System") self.window.config(menu=self.__Menu) self.__MenuFile.add_command(label="Update Message Log", command=self.updateMessageLog) self.__MenuFile.add_command(label="Quit", command=self.quit) self.autoscan = BooleanVar() self.fixsender = BooleanVar() self.autoclear = BooleanVar() self.showresponses = BooleanVar() self.__MenuMessage.add_command(label="View", command=self.showMessage) self.__MenuMessage.add_command(label="Compose New", command=self.composeMessage) self.__MenuSettings.add_checkbutton(label="Fix sender", onvalue=True, offvalue=False, variable=self.fixsender) self.__MenuSettings.add_checkbutton(label="Autoscan", onvalue=True, offvalue=False, variable=self.autoscan) self.__MenuSettings.add_checkbutton(label="Autoclear", onvalue=True, offvalue=False, variable=self.autoclear) self.__MenuSettings.add_checkbutton(label="Show responses", onvalue=True, offvalue=False, variable=self.showresponses) self.__MenuSystem.add_command(label="View/Edit identity", command=self.editidentity) self.__MenuTemplates = Menu(self.__MenuSystem) self.__MenuSystem.add_cascade(label='Create Component', menu=self.__MenuTemplates) self.__MenuNodes = Menu(self.__Menu) self.__MenuNodes.add_command(label="Update connected nodes", command=self.scangateways) self.__MenuNodes.add_command(label="Scan Local", command=self.scanregistry) self.__MenuNodes.add_command(label="Dump Nodelist", command=self.dumpnodelist) self.__MenuNodes.add_separator() self.__Menu.add_cascade(menu=self.__MenuNodes, label="Nodes") ### /Menu ### ### Output ### self.__FrameOutput = Frame(self.window) self.__FrameOutput.pack(side='top', fill='both', expand='yes') self.__NotebookOutput = Pmw.NoteBook(self.__FrameOutput) self.__NotebookOutput.pack(fill='both', expand=1) self.__PageMessages = self.__NotebookOutput.add('Messages') self.__PageMap = self.__NotebookOutput.add('Map') self.__PageResponses = self.__NotebookOutput.add('Responses') #self.__PageLog = self.__NotebookOutput.add('Log') # Needs a loggercomponent and revised logging first self.__MessageLog = Pmw.ScrolledListBox(self.__PageMessages) self.__MessageLog.pack(expand='yes', fill='both') self.__NotebookOutput.tab('Messages').focus_set() self.__FrameInput = Frame(self.window, borderwidth=2) self.__FrameInput.pack(anchor='s', expand='no', fill='x', side='top') self.__FrameStatusbar = Frame(self.window, relief='raised') self.__FrameStatusbar.pack(anchor='sw', side='top') # ,fill='x' self.__LabelStatus = Label(self.__FrameStatusbar, text='Ready.') self.__LabelStatus.pack(anchor='w', expand='yes', side='top') # ,fill='both' self.__FrameResponses = Frame(self.__PageResponses, background="yellow") self.__FrameResponsesHeader = Frame(self.__FrameResponses) self.__LabelResponses = Label(self.__FrameResponsesHeader, text='Responses') self.__LabelResponses.pack(anchor='e', side='right', fill='x') self.__ButtonClearResponses = Button(self.__FrameResponsesHeader, text='Clear') self.__ButtonClearResponses.pack(anchor='w', side='left') self.__FrameResponsesHeader.pack(anchor='n', fill='x', side=TOP) self.__TextResponses = Pmw.ScrolledText(self.__FrameResponses) self.__TextResponses.pack(expand=1, fill='both', side=BOTTOM) self.__FrameResponses.pack(expand=1, fill="both") #self.__FrameLog = Frame(self.__PageLog) #self.__FrameLog.pack(side='left', expand=1, fill="both") #self.__FrameLogHeader = Frame(self.__FrameLog) #self.__FrameLogHeader.pack(anchor='n',expand='yes', fill='x', side='top') #self.__LabelLog = Label(self.__FrameLogHeader,text='Log') #self.__LabelLog.pack(anchor='e',side='right', fill='both') #self.__ButtonClearLog = Button(self.__FrameLogHeader, text='Clear') #self.__ButtonClearLog.pack(anchor='w',side='left') #self.__TextLog = Pmw.ScrolledText(self.__FrameLog) #self.__TextLog.pack(expand=1,fill='both') self.__MapCanvas = Canvas(self.__PageMap) self.__MapCanvas.pack(expand=1, fill='both') self.__NotebookOutput.setnaturalsize() ### /Output ### ### Input ### self.__FrameInputEntry = Frame(self.__FrameInput) self.__EntryInput = Entry(self.__FrameInput) self.__EntryInput.pack(expand='yes', fill='both', side='left') self.__FrameTransmitButton = Frame(self.__FrameInput) self.__FrameTransmitButton.pack(anchor='w', side='left') self.__ButtonTransmit = Button(self.__FrameTransmitButton, text='Transmit') self.__ButtonTransmit.pack(expand='yes', fill='both', side='top') self.__FrameClearButton = Frame(self.__FrameInput) self.__FrameClearButton.pack(anchor='w', side='left') self.__ButtonClear = Button(self.__FrameClearButton, text='Clear') self.__ButtonClear.pack(expand='yes', fill='both', side='top') self.__FrameInputEntry.pack(side='left') ### /Input ### ### Bindings ### self.__MessageLog._listbox.bind("<Double-Button-1>", self.showMessage) self.__ButtonClearResponses.bind('<ButtonRelease-1>', self.__on_ButtonClearResponses_Press) self.__ButtonTransmit.bind('<ButtonRelease-1>', self.__on_ButtonTransmit_Release) self.__ButtonClear.bind('<ButtonPress-1>', self.__on_ButtonClear_Press) self.__EntryInput.bind('<Control-Return>', self.__on_EntryInput_Enter__C) self.defaultcolors = { 'bg': self.window['bg'], 'fg': self.__EntryInput['fg'] } def main(self): """ Main loop. Stub method, reimplement with your own functionality. Must regularly call self.tkupdate() to ensure tk event processing happens. """ if self.autoscan.get(): self.loginfo("Local autoscan initiated.") self.scanregistry() while not self.isDestroyed(): yield 1 if self.dataReady("control"): msg = self.recv("control") if isinstance(msg, producerFinished) or isinstance( msg, shutdownMicroprocess): self.send(msg, "signal") self.window.destroy() if self.dataReady("inbox"): msg = self.recv("inbox") self.logdebug("Received message '%s'" % msg) self.handleRPC(msg) if self.showresponses.get(): self.__TextResponses.insert(END, "%s\n" % msg) self.tkupdate()
class SerialTerm(Tk): def __init__(self, serial_queue, serial_thread): Tk.__init__(self) self.title("Foss SerialTerminal for Multi") self.serial_queue = serial_queue self.serial_thread = serial_thread menu_bar = Menu(self) file_menu = Menu(menu_bar, tearoff=0) file_menu.add_command(label="Save as...") file_menu.add_command(label="Exit", command=self.quit) menu_bar.add_cascade(label="File", menu=file_menu) self.parser_menu = Menu(menu_bar, tearoff=0) self.serial_parser_enabled = IntVar() self.serial_parser_enabled.set(1) self.parser_menu.add_checkbutton( label="Serial parser enabled", variable=self.serial_parser_enabled ) self.parser_menu.add_command(label="Edit parser rules", command=self.open_conditionals_editor) menu_bar.add_cascade(label="Parser", menu=self.parser_menu) self.config(menu=menu_bar) main_frame = Frame(self) output_frame = Frame(main_frame) input_frame = Frame(main_frame) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) main_frame.grid(column=0, row=0, padx=3, pady=3, sticky=(N, W, E, S)) main_frame.grid_columnconfigure(0, weight=1) main_frame.grid_rowconfigure(0, weight=1) output_text_vertical_scrollbar = Scrollbar(output_frame, orient=VERTICAL) output_text_horizontal_scrollbar = Scrollbar(output_frame, orient=HORIZONTAL) self.output_text = Text( output_frame, wrap=NONE, xscrollcommand=output_text_horizontal_scrollbar.set, yscrollcommand=output_text_vertical_scrollbar.set ) self.output_text.configure(bg="white", state="disabled") self.output_text.grid(column=0, row=0, sticky=(N, S, E, W)) output_text_vertical_scrollbar.grid(column=1, row=0, sticky=(N, S)) output_text_vertical_scrollbar.config(command=self.output_text.yview) output_text_horizontal_scrollbar.grid(column=0, row=1, sticky=(E, W)) output_text_horizontal_scrollbar.config(command=self.output_text.xview) output_frame.grid(column=0, row=0, sticky=(N, S, E, W)) output_frame.grid_columnconfigure(0, weight=1) output_frame.grid_rowconfigure(0, weight=1) self.input_string = StringVar() input_entry = Entry(input_frame, textvariable=self.input_string) input_entry.grid(column=0, row=0, sticky=(E, W)) line_end_selection_items = ["CR&NL", "NL", "CR", "None"] self.line_end_selection = Combobox( input_frame, values=line_end_selection_items, state="readonly", width=len(max(line_end_selection_items, key=len)) ) self.line_end_selection.current(newindex=0) self.line_end_selection.grid(column=1, row=0) serial_port_names = ["Port"] serial_port_names.extend([s.name for s in serial.tools.list_ports.comports()]) self.port_name_selection = Combobox( input_frame, values = serial_port_names, state="readonly", width=len(max(serial_port_names, key=len)) ) self.port_name_selection.current(newindex=0) self.port_name_selection_index = 0 self.port_name_selection.grid(column=2, row=0) baudrates = [ "300 baud", "1200 baud", "2400 baud", "4800 baud", "9600 baud", "19200 baud", "38400 baud", "57600 baud", "74880 baud", "115200 baud", "230400 baud", "250000 baud" ] self.baudrate_selection = Combobox( input_frame, values = baudrates, state="readonly", width=len(max(baudrates, key=len)) ) self.baudrate_selection.current(newindex=9) self.baudrate_selection.grid(column=3, row=0) input_frame.grid(column=0, row=1, sticky=(E, W)) input_frame.grid_columnconfigure(0, weight=1) self.port_name_selection.bind("<<ComboboxSelected>>", self.port_name_selected) self.baudrate_selection.bind("<<ComboboxSelected>>", self.baudrate_selected) self.after(100, self.serial_tick) # TODO Load from pickle file. self.conditionals = [ ["Enabled", "line.startswith(\"Hello\")", "Python", "print 'Fooobaaaaar. Jibb.'"], ["Enabled", "line.startswith(\"Foo\")", "Debugger", "halt\nreset"], ] self.counter = 0 def open_conditionals_editor(self): self.conditionals_editor = Toplevel(master=self) self.parser_menu.entryconfig("Edit parser rules", state="disabled") ConditionalsEditor(self.conditionals_editor, self.conditionals, self.closing_conditionals_editor) def closing_conditionals_editor(self): self.parser_menu.entryconfig("Edit parser rules", state="normal") def update_output_text(self, line): self.output_text.configure(state="normal") self.output_text.insert(END, line) self.output_text.configure(state="disabled") self.output_text.see(END) def evaluate_conditionals(self, line): if self.serial_parser_enabled.get() == 1: for condition in self.conditionals: if condition[0] == "Enabled": if eval(condition[1]): if condition[2] == "Python": exec(condition[3], locals()) elif condition[2] == "Debugger": print "Send to debugger: %s"%condition[3] def serial_tick(self): while True: try: line = self.serial_queue.get_nowait() self.update_output_text(line) self.evaluate_conditionals(line) except Queue.Empty: break self.after(100, self.serial_tick) def port_name_selected(self, event): port_name = event.widget.selection_get() if port_name == "Port": event.widget.current(newindex=self.port_name_selection_index) return self.port_name_selection_index = event.widget.current() self.serial_thread.set_port(port_name) def baudrate_selected(self, event): self.serial_thread.set_baudrate(event.widget.selection_get())
def __init__(self, master, visible=True): self.root = master Menu.__init__(self, master.root) self.sc3_plugins = BooleanVar() self.sc3_plugins.set(SC3_PLUGINS) # Set font self.config(font="CodeFont") # 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.selectall, 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="Toggle Menu", command=self.root.toggle_menu, accelerator="Ctrl+M") self.add_cascade(label="Edit", menu=editmenu) # Code menu codemenu = Menu(self, tearoff=0) codemenu.add_command(label="Evaluate Block", command=self.root.exec_block, accelerator="Ctrl+Return") 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="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) self.add_cascade(label="Code", menu=codemenu) # Settings ## settingsmenu = Menu(self, tearoff=0) ## settingsmenu.add_command(label="Preferences...", command=self.root.toggleMenu) ## settingsmenu.add_command(label="Change Colours...", command=self.root.toggleMenu) ## settingsmenu.add_command(label="Open Samples Folder", command=self.root.toggleMenu) ## self.add_cascade(label="Settings", menu=settingsmenu) # Help helpmenu = Menu(self, tearoff=0) helpmenu.add_command(label="Visit FoxDot Homepage", command=self.root.openhomepage) helpmenu.add_command(label="Documentation", command=self.root.opendocumentation) self.add_cascade(label="Help", menu=helpmenu) # Add to root self.visible = visible if self.visible: master.root.config(menu=self)
def __init__(self, master, visible=True): self.root = master Menu.__init__(self, master.root) # File menu filemenu = Menu(self, tearoff=0) filemenu.add_command(label="New Document", command=self.new_file, accelerator="Ctrl+N") filemenu.add_command(label="Save", command=self.save_file, accelerator="Ctrl+S") filemenu.add_command(label="Open", command=self.open_file, accelerator="Ctrl+O") filemenu.add_separator() filemenu.add_command(label="Start logging performance", command=lambda: "break") filemenu.add_command(label="Import logged performance", command=self.root.ImportLog) self.add_cascade(label="File", menu=filemenu) # Edit menu editmenu = Menu(self, tearoff=0) editmenu.add_command(label="Cut", command=self.root.cut, accelerator="Ctrl+X") editmenu.add_command(label="Copy", command=self.root.copy, accelerator="Ctrl+C") editmenu.add_command(label="Paste", command=self.root.paste, accelerator="Ctrl+V") editmenu.add_command(label="Select All", command=self.root.select_all, accelerator="Ctrl+/") editmenu.add_separator() editmenu.add_command(label="Increase Font Size", command=self.root.increase_font_size, accelerator="Ctrl+=") editmenu.add_command(label="Decrease Font Size", command=self.root.decrease_font_size, accelerator="Ctrl+-") editmenu.add_separator() editmenu.add_command(label="Toggle Menu", command=self.toggle, accelerator="Ctrl+M") editmenu.add_separator() editmenu.add_command(label="Edit Colours", command=self.root.edit_colours) editmenu.add_checkbutton(label="Toggle Window Transparency", command=self.root.toggle_transparency, variable=self.root.transparent) self.add_cascade(label="Edit", menu=editmenu) # Code menu codemenu = Menu(self, tearoff=0) codemenu.add_command(label="Evaluate Code", command=self.root.evaluate, accelerator="Ctrl+Return") codemenu.add_command(label="Evaluate Single Line", command=self.root.single_line_evaluate, accelerator="Alt+Return") codemenu.add_command(label="Stop All Sound", command=self.root.stop_sound, accelerator="Ctrl+.") codemenu.add_command(label="Font colour merge", command=self.root.text.merge.start) # Constraints constmenu = Menu(self, tearoff=0) for i, name in self.root.text.constraint.items(): constmenu.add_checkbutton( label=str(name).title(), command=partial(self.root.set_constraint, i), variable=self.root.text.constraint.using[i]) codemenu.add_cascade(label="Set Constraint", menu=constmenu) codemenu.add_separator() # Allow choice of interpreter langmenu = Menu(self, tearoff=0) for name, interpreter in langnames.items(): langmenu.add_checkbutton(label=langtitles[name], command=partial(self.root.set_interpreter, interpreter), variable=self.root.interpreters[name]) codemenu.add_cascade(label="Choose language", menu=langmenu) self.add_cascade(label="Code", menu=codemenu) # Help helpmenu = Menu(self, tearoff=0) helpmenu.add_command(label="Documentation", command=self.root.OpenGitHub) self.add_cascade(label="Help", menu=helpmenu) # Add to root self.visible = visible if self.visible: master.root.config(menu=self)
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 view_menu(): menu = Menu(menubar, tearoff=0) menu.add_checkbutton(label="Auto-render", variable=self.render_auto) # menu.add_command(label="Filter threads", command=None) return menu
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)
class CellularAutomataMain(Tk): GRID_WIDTH_PX = DisplayConfiguration.CA_CANVAS_MAX_PIX_X GRID_HEIGHT_PX = DisplayConfiguration.CA_CANVAS_MAX_PIX_Y def __init__(self, width_cells=DisplayConfiguration.DEFAULT_WIDTH, *args, **kwargs): Tk.__init__(self, *args, **kwargs) self.resizable(width=False, height=False) self.state = {'rules': None, 'rules_file': None, 'grid': None} self.random_start = BooleanVar(self) self.random_start.trace('w', self.random_start_callback) #Load blank grid self.width_cells = width_cells self.height_cells = width_cells # Default setting should probably have the grid be square. canvas_width = self.GRID_WIDTH_PX-80 canvas_height = self.GRID_HEIGHT_PX-80 self.state['grid'] = build_blank_grid(width_cells, width_cells) self.grid_display = GridDisplay(self, self.state['grid'], self.GRID_WIDTH_PX, self.GRID_HEIGHT_PX, width=canvas_width, height=canvas_height, relief=GROOVE, bd=4) self.grid_display.grid(row=0, column=0, padx=20, pady=20) #Build top menus self.menubar = Menu(self) try: self.config(menu=self.Menu) except AttributeError: self.tk.call(self, 'config', '-menu', self.menubar) self.file_menu = Menu(self, tearoff=False) self.file_menu.add_command(label="Load Ruleset", command=self.load_dialogue) self.file_menu.add_separator() self.file_menu.add_command(label="Save Automata (Image)", command=self.save_image_dialogue) self.file_menu.add_separator() self.file_menu.add_command(label="Quit", command=self.quit) self.menubar.add_cascade(menu=self.file_menu, label='File') self.config_menu = Menu(self, tearoff=False) self.config_menu.add_command(label='Set Dimensions', command=self.config_dimensions) self.config_menu.add_checkbutton(label='Set Grid Wrap') self.config_menu.add_checkbutton(label='Random Start Row', variable=self.random_start) self.bg_color_menu = self.build_selector_menu(GridDisplay.ALLOWED_COLORS, self.grid_display.set_bg_color, lambda: self.grid_display.draw_grid(self.state['grid']), 'white') self.fill_color_menu = self.build_selector_menu(GridDisplay.ALLOWED_COLORS, self.grid_display.set_fill_color, lambda: self.grid_display.draw_grid(self.state['grid']), 'black') self.config_menu.add_cascade(menu=self.bg_color_menu, label="Set Background Color...") self.config_menu.add_cascade(menu=self.fill_color_menu, label="Set Fill Color...") self.config_menu.add_separator() self.config_menu.add_command(label='Configure Plug-ins') self.plugin_menu = Menu(self) self.config_menu.add_cascade(menu=self.plugin_menu, label="Plugins...") self.menubar.add_cascade(menu=self.config_menu, label='Configure') self.menubar.add_command(label="About", command=self.about) #Load status bar self.status_bar_var = StringVar(self) self.status_bar_var.set('Initialized.') self.status_bar = Label(self, textvar=self.status_bar_var, relief=SUNKEN, justify=LEFT, anchor=W) self.status_bar.grid(row=1, column=0, sticky="EW", padx=2, pady=2) #Build plugin manager disp_logger.info('Loading plug-in manager') self.status_bar_var.set('Loading plug-in manager...') self.plugin_manager = PluginManager() self.plugin_manager.setPluginPlaces(['../plugins/']) self.plugin_manager.collectPlugins() disp_logger.info('Plug-in manager loaded. {} plug-ins were loaded.' ''.format(len(self.plugin_manager.getAllPlugins()))) def load_dialogue(self): new_rule_filename = tkFileDialog.askopenfilename(parent=self, title='Open Rule File', defaultextension=".txt", filetypes=[('Rules Files', '*.txt'), ('All Files', '*')]) if not new_rule_filename: return try: self.load(new_rule_filename) except: disp_logger.exception('Faulted loading rules file!') def save_image_dialogue(self): automata_image_filename = tkFileDialog.asksaveasfilename(parent=self, title='Save Automata Image', defaultextension='.eps', filetypes=[('Postscript', '.eps'), ('PNG', '.png'), ('JPEG', '.jpg')]) if not automata_image_filename: return try: #TODO: Should we be converting, or should I have a local image representation instead? if not automata_image_filename.endswith('.eps'): self.grid_display.postscript(file='tmp.eps') img = Image.open('tmp.eps') img.save(automata_image_filename) os.remove('tmp.eps') else: self.grid_display.postscript(file=automata_image_filename) self.status_bar_var.set('Saved automata image file as: {}'.format(automata_image_filename)) except: disp_logger.exception('Faulted saving automata image!') def load(self, rule_file): disp_logger.info('Attempting to load new rules file: {}'.format(rule_file)) rules = load_rules(rule_file) self.state['rules'] = rules self.state['rules_file'] = rule_file self._build_grid(rules) self.status_bar_var.set('Loaded rules file: {}'.format(rule_file)) def _build_grid(self, rules): grid = [] if self.random_start.get(): start_row = build_random_start_row(self.width_cells) else: start_row = build_default_start_row(self.width_cells) grid.append(start_row) grid.extend(evolve_system_multi(start_row, rules, self.height_cells)) self.state['grid'] = grid self.grid_display.draw_grid(grid) def config_dimensions(self): new_width, new_height = DimensionsDialog(self, title='Set Automata Dimensions', prompt='Set Automata Dimensions', x_name='Width', y_name='Height', x_default=self.width_cells, y_default=self.height_cells) if not new_width or not new_height: return disp_logger.info('Resizing automata to new width: {}, height: {}'.format(new_width, new_height)) self.width_cells = new_width self.height_cells = new_height self._build_grid(self.state['rules']) def random_start_callback(self, *args): self._build_grid(self.state['rules']) @staticmethod def about(): tkMessageBox.showinfo('About', '{app} ({ver})\nby {auth}, 2014' ''.format(ver=__version__, auth=__author__, app=__application_name__)) 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