Skip to content

Instantly share code, notes, and snippets.

@typemytype
Created April 10, 2024 15:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save typemytype/57de9e474aaae05d998364b2c42db151 to your computer and use it in GitHub Desktop.
Save typemytype/57de9e474aaae05d998364b2c42db151 to your computer and use it in GitHub Desktop.
RoboFont subscriber to rotate both the glyph view and space center to help out drawing Mongolian, where the letter shapes are stored in binaries 90° rotated.
"""
RoboFont subscriber to rotate both the glyph view and space center to help out drawing Mongolian,
where the letter shapes are stored in binaries 90° rotated.
"""
from AppKit import NSNotificationCenter, NSViewFrameDidChangeNotification
import ezui
from mojo.subscriber import Subscriber, registerSpaceCenterSubscriber, unregisterSpaceCenterSubscriber, registerGlyphEditorSubscriber, unregisterGlyphEditorSubscriber, WindowController
from mojo.tools import CallbackWrapper
class RotatedMixin:
rotation = -90
def subscribeView(self):
self.rotateView(self.rotatedView, self.rotation)
self._callback = CallbackWrapper(self.rotateViewFrameChanged)
NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self._callback, "action:", NSViewFrameDidChangeNotification, self.rotatedView)
def unsubscribeView(self):
NSNotificationCenter.defaultCenter().removeObserver_(self._callback)
if self.rotatedView.frameRotation() != 0:
self.rotateView(self.rotatedView, 0)
def rotateView(self, view, rotation):
(x, y), (w, h) = view.frame()
view.setFrameRotation_(rotation)
self._ignoreFrameChanges = True
if rotation == 0:
view.setFrame_(((x, y-w), (h, w)))
elif rotation == -90:
view.setFrame_(((x, h + y), (h, w)))
documentView = view.documentView()
if hasattr(documentView, "recalculateFrame"):
documentView.recalculateFrame()
self._ignoreFrameChanges = False
def rotateViewFrameChanged(self, notification):
if self._ignoreFrameChanges:
return
view = notification.object()
superview = view.superview()
bounds = superview.bounds()
self._ignoreFrameChanges = True
(x, y), (w, h) = bounds
view.setFrame_(((x + self.frameAdjustments[0], h + y + self.frameAdjustments[1]),
(h + self.frameAdjustments[2], w + self.frameAdjustments[3])))
self._ignoreFrameChanges = False
class RotateGlyphEditorSubscriber(Subscriber, RotatedMixin):
debug = True
frameAdjustments = 0, 0, 0, 0
def started(self):
glyphEditor = self.getGlyphEditor()
self.rotatedView = glyphEditor.editGlyphView.enclosingScrollView()
self.subscribeView()
def destroy(self):
self.unsubscribeView()
class RotateSpaceCenterSubscriber(Subscriber, RotatedMixin):
debug = True
frameAdjustments = 0, -40, -89, 0
def started(self):
spaceCenter = self.getSpaceCenter()
self.rotatedView = spaceCenter.glyphLineView.getNSScrollView()
self.rotatedView.setScrollerStyle_(0)
self.subscribeView()
def destroy(self):
self.unsubscribeView()
class RotateController(WindowController):
def build(self):
content = """
[X] Rotate Views @rotateViews
"""
descriptionData = dict()
self.w = ezui.EZPanel(
title="Rotator",
content=content,
descriptionData=descriptionData,
size="auto",
controller=self
)
def activate(self):
registerGlyphEditorSubscriber(RotateGlyphEditorSubscriber)
registerSpaceCenterSubscriber(RotateSpaceCenterSubscriber)
def deactivate(self):
unregisterGlyphEditorSubscriber(RotateGlyphEditorSubscriber)
unregisterSpaceCenterSubscriber(RotateSpaceCenterSubscriber)
def started(self):
self.w.open()
self.activate()
def destroy(self):
self.deactivate()
def rotateViewsCallback(self, sender):
if sender.get():
self.activate()
else:
self.deactivate()
OpenWindow(RotateController)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment