Skip to content

Instantly share code, notes, and snippets.

@RafalBuchner
Last active July 27, 2023 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RafalBuchner/95ceb5dd044a529d490cf208d4b0c323 to your computer and use it in GitHub Desktop.
Save RafalBuchner/95ceb5dd044a529d490cf208d4b0c323 to your computer and use it in GitHub Desktop.
Subscriber, that will add additional button to Glyph Editor "Display..." menu
# ===================================
# 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)
# ===================================
# 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)
# ===================================
# 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