Subscribing to current glyph events ↩
This example shows a floating window that displays information about the current glyph. The window knows when the user has switched the current glyph and updates accordingly. The displayed information is updated when the data within the current glyph is changed.
The tool uses the Subscriber
module to subscribe to current glyph outlines, anchors, components, and guidelines. It uses merz
to render a visualization into a vanilla FloatingWindow
based on the glyph data.
"""
Window showing info about the current glyph
This example shows a floating window that displays information
about the current glyph. The window knows when the user has
switched the current glyph and updates accordingly. The displayed
information is updated when the data within the current glyph
is changed.
"""
import ezui
from mojo.subscriber import Subscriber, registerCurrentGlyphSubscriber
class CurrentGlyphWithUISubscriberDemo(Subscriber, ezui.WindowController):
debug = True
def build(self):
content = """
* VerticalStack @stackView
> * MerzView @pointsView
> name @nameTextBox
> contours @contoursTextBox
> components @componentsTextBox
> anchors @anchorsTextBox
> guidelines @guidelinesTextBox
"""
descriptionData = dict(
stackView=dict(
spacing=10,
alignment="leading"
),
pointsView=dict(
backgroundColor=(0.75, 0.75, 0.75, 1),
height=300,
gravity="top",
delegate=self
),
)
self.w = ezui.EZWindow(
title="Useless Glyph Data",
content=content,
size=(300, "auto"),
descriptionData=descriptionData,
controller=self
)
def started(self):
self.w.open()
def currentGlyphDidSetGlyph(self, info):
self.currentGlyphInfoDidChange(info)
self.currentGlyphContoursDidChange(info)
self.currentGlyphComponentsDidChange(info)
self.currentGlyphAnchorsDidChange(info)
self.currentGlyphGuidelinesDidChange(info)
def currentGlyphInfoDidChange(self, info):
glyph = info["glyph"]
text = ""
if glyph is not None:
text = f"This glyph is named {glyph.name}."
self.w.getItem("nameTextBox").set(text)
def currentGlyphContoursDidChange(self, info):
glyph = info["glyph"]
text = ""
if glyph is not None:
text = f"This glyph contains {len(glyph.contours)} contours."
self.w.getItem("contoursTextBox").set(text)
view = self.w.getItem("pointsView")
container = view.getMerzContainer()
container.clearSublayers()
if glyph is not None:
viewWidth = view.width()
viewHeight = view.height()
font = glyph.font
verticalMetrics = [
font.info.descender,
font.info.xHeight,
font.info.capHeight,
font.info.ascender
]
bottom = min(verticalMetrics)
top = max(verticalMetrics)
contentHeight = top - bottom
fitHeight = viewHeight * 0.8
scale = fitHeight / contentHeight
x = (viewWidth - (glyph.width * scale)) / 2
y = (viewHeight - fitHeight) / 2
container.addSublayerTransformation((scale, 0, 0, scale, x, y),
name="scale&translate")
glyphLayer = container.appendRectangleSublayer(
size=(glyph.width, contentHeight),
fillColor=(1, 1, 1, 1)
)
with glyphLayer.sublayerGroup():
for contour in glyph.contours:
for point in contour.points:
if point.type == "move":
glyphLayer.appendSymbolSublayer(
position=(point.x, point.y),
imageSettings=dict(
name="star",
pointCount=8,
size=(100, 100),
fillColor=(1, 1, 0, 0.5)
)
)
elif point.type == "line":
glyphLayer.appendSymbolSublayer(
position=(point.x, point.y),
imageSettings=dict(
name="rectangle",
size=(40, 40),
fillColor=(0, 0, 1, 0.2)
)
)
elif point.type == "curve":
glyphLayer.appendSymbolSublayer(
position=(point.x, point.y),
imageSettings=dict(
name="oval",
size=(50, 50),
fillColor=(0, 1, 0, 0.2)
)
)
elif point.type == "qcurve":
glyphLayer.appendSymbolSublayer(
position=(point.x, point.y),
imageSettings=dict(
name="triangle",
size=(50, 50),
fillColor=(1, 0, 0, 0.2)
)
)
elif point.type == "offcurve":
glyphLayer.appendSymbolSublayer(
position=(point.x, point.y),
imageSettings=dict(
name="oval",
size=(75, 75),
fillColor=None,
strokeColor=(0, 0, 0, 0.2),
strokeWidth=1
)
)
def currentGlyphComponentsDidChange(self, info):
glyph = info["glyph"]
text = ""
if glyph is not None:
text = f"This glyph contains {len(glyph.components)} components."
self.w.getItem("componentsTextBox").set(text)
def currentGlyphAnchorsDidChange(self, info):
glyph = info["glyph"]
text = ""
if glyph is not None:
text = f"This glyph contains {len(glyph.anchors)} anchors."
self.w.getItem("anchorsTextBox").set(text)
def currentGlyphGuidelinesDidChange(self, info):
glyph = info["glyph"]
text = ""
if glyph is not None:
text = f"This glyph contains {len(glyph.guidelines)} guidelines."
self.w.getItem("guidelinesTextBox").set(text)
registerCurrentGlyphSubscriber(CurrentGlyphWithUISubscriberDemo)