Created
December 24, 2021 11:08
-
-
Save roberto-arista/11893947b9de0321b8b637f87f6849e4 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env python3 | |
from math import hypot | |
from mojo.subscriber import Subscriber, WindowController | |
from mojo.subscriber import registerGlyphEditorSubscriber, unregisterGlyphEditorSubscriber | |
from mojo.roboFont import OpenWindow | |
from vanilla import FloatingWindow, CheckBox | |
RED = 1, 0, 0, 1 | |
WHITE = 1, 1, 1, 1 | |
class PointDistanceControllerPalette(WindowController): | |
debug = True | |
def build(self): | |
self.w = FloatingWindow((200, 40), "PointDistanceController") | |
self.w.checkBox = CheckBox((10, 10, -10, 20), "Display Distances", | |
callback=self.checkBoxCallback, value=True) | |
self.w.open() | |
def started(self): | |
PointDistanceController.controller = self | |
registerGlyphEditorSubscriber(PointDistanceController) | |
def destroy(self): | |
unregisterGlyphEditorSubscriber(PointDistanceController) | |
PointDistanceController.controller = None | |
def checkBoxCallback(self, sender): | |
if sender.get(): | |
PointDistanceController.controller = self | |
registerGlyphEditorSubscriber(PointDistanceController) | |
else: | |
PointDistanceController.controller = None | |
unregisterGlyphEditorSubscriber(PointDistanceController) | |
class PointDistanceController(Subscriber): | |
debug = True | |
def build(self): | |
glyphEditor = self.getGlyphEditor() | |
self.container = glyphEditor.extensionContainer( | |
identifier="com.roboFont.PointDistanceController.foreground", | |
location="foreground", | |
clear=True | |
) | |
self.distancesLayer = self.container.appendBaseSublayer() | |
def destroy(self): | |
self.container.clearSublayers() | |
def glyphDidChangeSelection(self, info): | |
# get the glyph from the notification | |
glyph = info["glyph"] | |
# get the selection | |
selection = glyph.selection | |
# check if the selection is more than 1 and less than 6 | |
if 2 <= len(selection) <= 5: | |
self.distancesLayer.setVisible(True) | |
self.distancesLayer.clearSublayers() | |
done = [] | |
# loop over all the points in the selection | |
for p in selection: | |
# loope in a the loop again over all the points in the selection | |
for p2 in selection: | |
# check if the point is not the same | |
if p == p2: | |
continue | |
# check if we already handled the point | |
if set([p, p2]) in done: | |
continue | |
# add a line to the distances layer | |
self.distancesLayer.appendLineSublayer( | |
startPoint=(p.x, p.y), | |
endPoint=(p2.x, p2.y), | |
strokeWidth=1, | |
strokeColor=RED | |
) | |
# calculate the center point | |
cx = p.x + (p2.x - p.x) * .5 | |
cy = p.y + (p2.y - p.y) * .5 | |
# calculate the distance | |
dist = hypot(p2.x - p.x, p2.y - p.y) | |
# store connections to avoid duplicates | |
done.append(set([p, p2])) | |
# create the label layer | |
self.distancesLayer.appendTextLineSublayer( | |
position=(cx, cy), | |
backgroundColor=RED, | |
text=f"{dist:.0f}" if dist % 1 == 0 else f"{dist:.2f}", | |
font="system", | |
weight="bold", | |
pointSize=12, | |
padding=(4, 1), | |
cornerRadius=4, | |
fillColor=WHITE, | |
horizontalAlignment='center', | |
verticalAlignment='center', | |
) | |
else: | |
self.distancesLayer.setVisible(False) | |
if __name__ == '__main__': | |
OpenWindow(PointDistanceControllerPalette) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment