def _checkForUpdatesCallback(self, url, data, error): if error: # cannot get the contents of the info.plist file logger.error("Cannot read '%s' for '%s'" % (url, self.extensionName())) logger.error(error) try: # try to parse the info.plist from string # and fail silently with a custom message info = plistlib.loads(data) except Exception as e: # cannot parse the plist info = {} logger.error("Cannot parse '%s' for '%s'" % (url, self.extensionName())) logger.error(e) # set the version self._remoteVersion = info.get("version", None) if self._remoteVersion is not None: # flag the extension as needing an update extensionVersion = self.extensionVersion() if extensionVersion is None: self._needsUpdate = False else: self._needsUpdate = extensionVersion < self._remoteVersion postEvent(EXTENSION_DID_CHECK_FOR_UPDATES_EVENT_KEY, item=self)
def fillCallback(self, sender): """ Change the fill status """ setExtensionDefault(DEFAULTKEY_FILL, sender.get()) postEvent(f"{DEFAULTKEY}.fillCheckBoxDidChange")
def _processExtensionIcon(self, url, data, error): if error is None and len(data) > 0: image = NSImage.alloc().initWithData_(data) self._extensionIcon = image postEvent(EXTENSION_ICON_DID_LOAD_EVENT_KEY, item=self, iconURL=self.extensionIconURL())
def strokeCallback(self, sender): """ Change the stroke status """ setExtensionDefault(DEFAULTKEY_STROKE, sender.get()) postEvent(f"{DEFAULTKEY}.strokeCheckBoxDidChange")
def checkForUpdates(self): if self.remoteVersion() is not None: # flag the extension as needing an update extensionVersion = self.extensionVersion() if extensionVersion is None: self._needsUpdate = False else: self._needsUpdate = extensionVersion < self.remoteVersion() postEvent(EXTENSION_DID_CHECK_FOR_UPDATES_EVENT_KEY, item=self)
def accuracySliderCB(self, sender): """ When slider changes, write setting and post event. Reverse slider value by subtracting from maxValue because we're tracking tolerance """ toleranceValue = round(self.maxValue - sender.get(), 2) hf.writeSetting(settingDir, toleranceValue) postEvent("com.ToleranceSettingChanged")
def extensionUninstall(self): bundle = self.extensionBundle() if bundle.bundleExists(): if self.extensionIconURL(): CachingURLReader.invalidate_cache_for_url( self.extensionIconURL()) self._extensionIcon = None bundle.deinstall() self.resetRemembered() postEvent(EXTENSION_DID_UNINSTALL_EVENT_KEY, item=self)
def colorCallback(self, sender): """ Change the color """ r, g, b, a = NSColorToRgba(sender.get()) self.fillColor = r, g, b, a self.strokeColor = r, g, b, 1 setExtensionDefault(DEFAULTKEY_FILLCOLOR, (r, g, b, a)) setExtensionDefault(DEFAULTKEY_STROKECOLOR, self.strokeColor) postEvent(f"{DEFAULTKEY}.colorDidChange")
def controlChanged(self, info): if info["name"] == self.sensorName: # Turn the value into a position in degrees between 0 and 180 pos = info["value"] * 180 # Update the interface newText = str(info["value"]) + ", " + str(pos) + chr(176) self.w.knobValue.set(newText) # Make the servo motor move to this position by sending it a notification postEvent("RoboControlOutput", name="Servo", position=pos)
def okCB(self, sender): """ Get everything from fields, save in self.editedProofGroup dict, post event, pass the edited group to observer, and close window """ self.editedProofGroup["name"] = self.w.groupNameEdit.get().strip() self.editedProofGroup["typeSize"] = self.w.typeSizeEdit.get() self.editedProofGroup["leading"] = self.w.leadingEdit.get() self.editedProofGroup["print"] = self.proofGroup[ "print"] # just pass this back for now self.editedProofGroup["contents"] = hf.makeCleanListFromStr( self.w.contentsEdit.get()) postEvent("com.ProofGroupEdited", editedProofGroup=self.editedProofGroup) self.w.close()
def _remoteInstallCallback(self, url, data, error): if error: message = "Could not download the extension zip file for: '%s' at url: '%s'" % ( self.extensionName(), url) logger.error(message) logger.error(error) raise ExtensionRepoError(message) # create a temp folder tempFolder = tempfile.mkdtemp() try: # try to extract the zip # and fail silently with a custom message with zipfile.ZipFile(io.BytesIO(data.bytes())) as z: z.extractall(tempFolder) except Exception as e: message = "Could not extract the extension zip file for: '%s' at url: '%s'" % ( self.extensionName(), url) logger.error(message) logger.error(e) raise ExtensionRepoError(message) # find the extension path extensionPath = findExtensionInRoot( os.path.basename(self.extensionPath), tempFolder) if extensionPath: # if found get the bundle and install it bundle = ExtensionBundle(path=extensionPath) bundle.install(showMessages=self._showMessages) self.resetRemembered() else: # raise an custom error when the extension is not found in the zip message = "Could not find the extension: '%s'" % self.extensionPath logger.error(message) raise ExtensionRepoError(message) # remove the temp folder with the extracted zip shutil.rmtree(tempFolder) # clear the cache for this extension icon so it may be reloaded if self.extensionIconURL(): CachingURLReader.invalidate_cache_for_url(self.extensionIconURL()) self._extensionIcon = None self._needsUpdate = False postEvent(EXTENSION_DID_REMOTE_INSTALL_EVENT_KEY, item=self)
def fontListCallback(self, sender): """ If there is a selection, toggle the status of these fonts """ # Avoid recursive loop because of changing font selection if not self._selectionChanging: for selectedIndex in sender.getSelection(): item = sender.get()[selectedIndex] if item["status"]: item["status"] = "" else: item["status"] = SELECTED_SYMBOL self._selectionChanging = True # Avoid recursive loop because of changing font selection sender.setSelection([]) self._selectionChanging = False postEvent(f"{DEFAULTKEY}.displayedFontsDidChange")
def currentGlyphDidChange(self, info): """ Post events only for interesting glyph cutting non-useful notifications """ glyph = info["glyph"] editorGlyphNames = [ editor.getGlyph().name for editor in AllGlyphWindows() ] if glyph.name in editorGlyphNames: postEvent(f"{DEFAULTKEY}.displayedGlyphDidChange", glyph=glyph) contextNames = [ self.controller.w.contextBefore.getFirstName(font=glyph.font), self.controller.w.contextCurrent.getFirstName(font=glyph.font), self.controller.w.contextAfter.getFirstName(font=glyph.font), ] if glyph.name in contextNames: postEvent(f"{DEFAULTKEY}.displayedGlyphDidChange", glyph=glyph)
def showProgress(self, sender): import time totalSteps = 100 self.w.bar.set(0) for i in range(totalSteps): self.w.bar.increment(1) if i/totalSteps < 0.8: # The progress is less than 80% of the way through. # Use two numbers for the "value", to set the hue and brightness of the LED. postEvent("ControlBoardOutput", name="Status Light", state="on", value=(i/totalSteps, 1)) else: # It's within the last 80% of the progress, switch over to blinking at 100/ms postEvent("ControlBoardOutput", name="Status Light", state="blink", value=100) time.sleep(.05) # Progress is done, be sure to turn the LED off! postEvent("ControlBoardOutput", name="Status Light", state="off")
def updateMark(self, sender=None): if self.glyph: if self.glyph.mark: postEvent("ControlBoardOutput", name=self.ledName, state="on", value=self.glyph.mark[0:3]) else: postEvent("ControlBoardOutput", name=self.ledName, state="off")
# menuTitle : multiview back # shortCut : command+arrowup # command+shift+control+alt+<input> # character space tab backtab arrowup arrowdown arrowleft arrowright f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31 f32 f33 f34 f35 enter backspace delete home end pageup pagedown from mojo.events import postEvent postEvent('multiviewKey', trigger='history')
def reportValueCallback(self): # The setInterval timer will call back to this method at a regular interval. # Check to see if there are any new values to report, if there are post the most current value and reset the list if self.values: postEvent("ControlBoardInput", name=self.name, state="changed", value=self.values[-1], type=self.type) del self.values[:]
def viewCurrentCallback(self, sender): postEvent(f"{DEFAULTKEY}.alwaysCurrentViewDidChange")
def _postCloseEvent(self, sender): postEvent("com.InspectorClosed")
def fontDocumentDidOpen(self, info): font = info.get("font") if font: self.controller.fonts.append(font) postEvent(f"{DEFAULTKEY}.openedFontsDidChange")
def fontDocumentWillClose(self, info): path = info["font"].path if path: self.removeFromFonts(path) postEvent(f"{DEFAULTKEY}.openedFontsDidChange")
def launchWindow(self): postEvent("PenBallWizardSubscribeFilter", subscribeFilter=self.addExternalFilter)
def __call__(self, tense): postEvent(self.name(tense), **{self.subject: self.object})
# menuTitle : multiview wordo # shortCut : command+arrowdown # command+shift+control+alt+<input> # character space tab backtab arrowup arrowdown arrowleft arrowright f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31 f32 f33 f34 f35 enter backspace delete home end pageup pagedown from mojo.events import postEvent postEvent('multiviewKey', trigger='wordo')
# menuTitle : multiview previous line # shortCut : command+arrowleft # command+shift+control+alt+<input> # character space tab backtab arrowup arrowdown arrowleft arrowright f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31 f32 f33 f34 f35 enter backspace delete home end pageup pagedown from mojo.events import postEvent postEvent('multiviewKey', trigger='previous')
# menuTitle : multiview in context # shortCut : command+alt+shift+arrowdown # command+shift+control+alt+<input> # character space tab backtab arrowup arrowdown arrowleft arrowright f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31 f32 f33 f34 f35 enter backspace delete home end pageup pagedown from mojo.events import postEvent postEvent('multiviewKey', trigger='context')
def windowClosed(self, sender): removeObserver(self, "currentGlyphChanged") removeObserver(self, "drawInactive") postEvent("ControlBoardOutput", name=self.ledName, state="off")
def reportValueCallback(self): if self.values: postEvent("ControlBoardInput", name=self.name, state="changed", value=self.values[0], type=self.type) self.values = self.values[1:]
def alignCallback(self, sender): """ Change the alignment status """ postEvent(f"{DEFAULTKEY}.alignmentDidChange")
from mojo.events import postEvent """ ControlBoard "RGB LED" component demo """ # Send "ControlBoardOutput" notifications to board components to change their state. # The "name" of the RGB LED is the name that's set in the Control Board window. # To turn a RGB LED on, change its state to "on". It will turn on as a fully bright white: postEvent("ControlBoardOutput", name="My RGB LED", state="on") # Turn the RGB LED off postEvent("ControlBoardOutput", name="My RGB LED", state="off") # If the legs of the RGB LED are attached to pins that are capable of "Pulse Width Modulation", # which is sometimes noted with the letters "PWM" or a "~" next to the pin number on the board, # you can also set the color when you turn the LED on. # Set the color to a (R, G, B) value: postEvent("ControlBoardOutput", name="My RGB LED", state="on", value=(1, 0, 0.5)) # Set the color of the LED to a color name: postEvent("ControlBoardOutput", name="My RGB LED", state="on", value="red") postEvent("ControlBoardOutput", name="My RGB LED", state="on", value="turquoise") postEvent("ControlBoardOutput", name="My RGB LED", state="on", value="dark green") postEvent("ControlBoardOutput", name="My RGB LED", state="on", value="white") # ...etc. # A LRGB ED can also "toggle" between states, where it will switch between being on or off. # Note: Currently, it will only turn the LED completely on to white and off. postEvent("ControlBoardOutput", name="My RGB LED", state="toggle")
def contextEditCallback(self, sender): postEvent(f"{DEFAULTKEY}.contextDidChange", position=sender.title)
from mojo.events import postEvent """ ControlBoard "LED" component demo """ # Send "ControlBoardOutput" notifications to board components to change their state. # The "name" of the LED is the name that's set in the Control Board window. # To turn an LED on, change its state to "on". postEvent("ControlBoardOutput", name="My LED", state="on") # Turn the LED off postEvent("ControlBoardOutput", name="My LED", state="off") # If the LED is attached to a pin that's capable of "Pulse Width Modulation", # which is sometimes noted with the letters "PWM" or a "~" next to the pin number on the board, # you can also set the brightness when you turn the LED on. Use a "value" between 0 and 1. postEvent("ControlBoardOutput", name="My LED", state="on", value=0.5) # A LED can also "toggle" between states, where it will switch between being on or off postEvent("ControlBoardOutput", name="My LED", state="toggle") # Or, a LED can blink. This time the "value" is the blinking frequency in milliseconds (1000 = 1 sec) postEvent("ControlBoardOutput", name="My LED", state="blink", value="500")