Last active
July 27, 2023 15:11
-
-
Save RafalBuchner/95ceb5dd044a529d490cf208d4b0c323 to your computer and use it in GitHub Desktop.
Subscriber, that will add additional button to Glyph Editor "Display..." menu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# =================================== | |
# INFO | |
# this is file, where you define your settings. | |
# | |
# - It is important to change __myExtensionName__ part in the file's name to to the actual name of your extension. | |
# - You should change all __myExtensionName__ entries to the actual name of your extension. | |
# - Add all your custom defaults to "defaults" variable. | |
# | |
# Imports below ARE MANDATORY: | |
# =================================== | |
from mojo.extensions import ( | |
registerExtensionDefaults, | |
getExtensionDefault, | |
setExtensionDefault | |
) | |
extensionID = "com.__myName__.__myExtensionName__" | |
extensionKeyStub = extensionID + "." | |
defaults = { | |
extensionKeyStub + "isVisible": False, | |
} | |
registerExtensionDefaults(defaults) | |
def internalGetDefault(key): | |
key = extensionKeyStub + key | |
return getExtensionDefault(key) | |
def internalSetDefault(key, value): | |
key = extensionKeyStub + key | |
setExtensionDefault(key, value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# =================================== | |
# INFO | |
# this is main file, where you define your functionality. | |
# | |
# - It is important to change __myExtensionName__ part in the file's name to to the actual name of your extension. | |
# - You should change all __myExtensionName__ entries to the actual name of your extension. | |
# - You should define "title" class attribute (35 line of the code). It will show up as this in the display menu. | |
# - Your subscriber class has to have a DisplaySuscriber set as parent in order to make the whole thing work. | |
# - If you define glyphEditorDidOpen event, it has to call super() of itself (look at line no 8e of the code). | |
# | |
# Three imports below ARE MANDATORY: | |
# =================================== | |
from displaySubscriber import DisplaySuscriber | |
from mojo import subscriber | |
from __myExtensionName__Settings import ( | |
internalGetDefault, | |
internalSetDefault, | |
extensionID, | |
extensionKeyStub | |
) | |
from fontTools.pens.transformPen import TransformPointPen, TransformPen | |
from fontTools.misc.transform import Transform | |
from merz import MerzPen | |
# ==================================== | |
# Example | |
# ==================================== | |
class __myExtensionName__Subscriber(DisplaySuscriber): | |
debug = True | |
title = "My Extension Name" | |
curvaturePath = None | |
def build(self): | |
self.showMe = internalGetDefault("isVisible") | |
window = self.getGlyphEditor() | |
self.backgroundContainer = window.extensionContainer( | |
identifier=extensionKeyStub + "background", | |
location="background", | |
clear=True, | |
) | |
self.bgBaseLayer = self.backgroundContainer.appendBaseSublayer() | |
self.curvaturePath = self.bgBaseLayer.appendPathSublayer( | |
fillColor=(1, 0, 0, 0.5), visible=False | |
) | |
def toggleOn(self): | |
if self.curvaturePath is None: | |
return | |
self.curvaturePath.setVisible(True) | |
def toggleOff(self): | |
if self.curvaturePath is None: | |
return | |
self.curvaturePath.setVisible(False) | |
def glyphEditorDidKeyDown(self, info): | |
self.drawPath(info) | |
def glyphEditorDidUndo(self, info): | |
self.drawPath(info) | |
def glyphEditorDidMouseDrag(self, info): | |
self.drawPath(info) | |
def drawPath(self, info): | |
glyph = info["glyph"] | |
merzPen = MerzPen() | |
n_glyph = RGlyph() | |
n_glyphPen = n_glyph.getPen() | |
glyph.draw(n_glyphPen) | |
n_glyph.moveBy((100,100)) | |
n_glyph.draw(merzPen) | |
self.curvaturePath.setPath( merzPen.path ) | |
def glyphEditorDidOpen(self, info): | |
super().glyphEditorDidOpen(info) | |
self.drawPath(info) | |
subscriber.registerGlyphEditorSubscriber(ExampleSubscriber) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# =================================== | |
# ATTENCION!!!! | |
# dont' touch this file except __myExtensionName__ parts!!! | |
# =================================== | |
from vanilla.vanillaBase import VanillaCallbackWrapper | |
from mojo.subscriber import Subscriber | |
from AppKit import NSMenuItem | |
from __myExtensionName__Settings import ( | |
internalGetDefault, | |
internalSetDefault, | |
extensionID | |
) | |
def _getDisplayPopUpMenuFromEditWindow(editWindow): | |
if editWindow is None: | |
return | |
return editWindow.getGlyphStatusBar().displayButton | |
def _createCustomVisualizerSeparator(displayPopUp): | |
if len(displayPopUp.getItems()) == 27: | |
menu = displayPopUp.getNSPopUpButton().menu() | |
menu.addItem_(NSMenuItem.separatorItem()) | |
elif displayPopUp.getNSPopUpButton().itemArray()[27].isSeparatorItem(): | |
return | |
# ========================================= | |
# S U B S C R I B E R (with basic events) | |
# ========================================= | |
class DisplaySuscriber(Subscriber): | |
debug = True | |
title = None | |
def menuButtonWasPressed(self, nsMenuItem): | |
if self.getButtonState(): | |
self.showMe = True | |
else: | |
self.showMe = False | |
@property | |
def showMe(self): | |
return self._showMe | |
@showMe.setter | |
def showMe(self, value): | |
if value: | |
self.toggleOn() | |
else: | |
self.toggleOff() | |
internalSetDefault("isVisible", value) | |
self._showMe = value | |
def getButtonState(self): | |
return bool(self._menuItem.state()) | |
def _menuItemCallback(self, nsMenuItem): | |
self._menuItem.setState_(not self._menuItem.state()) | |
self.menuButtonWasPressed(nsMenuItem) | |
print(self.title) | |
def _appendMenuItemToDisplayMenu(self, window): | |
assert self.title is not None, "title wasn't set" | |
assert isinstance(self.title, str), "title must be a string" | |
displayPopUp = _getDisplayPopUpMenuFromEditWindow(window) | |
if displayPopUp is None: | |
return | |
# creating the separator in Display... menu | |
_createCustomVisualizerSeparator(displayPopUp) | |
self._menuItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(self.title, "", "") | |
wrapper = VanillaCallbackWrapper(self._menuItemCallback) | |
self._menuItemCallbackWrappers = [] | |
self._menuItemCallbackWrappers.append(wrapper) | |
self._menuItem.setTarget_(wrapper) | |
self._menuItem.setAction_("action:") | |
menu = displayPopUp.getNSPopUpButton().menu() | |
menu.addItem_(self._menuItem) | |
def toggleOff(self): | |
NotImplemented | |
def toggleOn(self): | |
NotImplemented | |
def glyphEditorDidOpen(self, info): | |
""" | |
Whenever you want to use glyphEditorDidOpen event in your own DisplaySuscriber class, please | |
use super method of glyphEditorDidOpen | |
""" | |
self._appendMenuItemToDisplayMenu(info["glyphEditor"]) | |
self.showMe = internalGetDefault("isVisible") | |
self._menuItem.setState_(self.showMe) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment