SOLVED observer for adding new glyph to the font
-
Hi,
I started to create a script that marks every added glyph with a specific colour.To do that I used defcon observer
font.addObserver(self, 'glyphOrderChangedCallback', 'Font.GlyphOrderChanged')
, but somehow it doesn't work.here is the method for that observer:
def glyphOrderChangedCallback(self, info): oldValue = info['oldValue'] newValue = info['newValue'] newGlyphNames = list(set(oldValue)-set(newValue)) for name in newGlyphNames: self.font[name].colorMark = (1,0,0,1)
Maybe there is a better way to track the names of added glyph objects to the font?
Thanks in advance for any advice on how to make it work.
-
Keep a reference of the font in your class otherwise the observer will be gone after the script is finished.
Thats why the examples have an open window, so its the font and observers stays alive!
good luck
-
@RafaŁ-Buchner haven’t tried to run the code, but there’s a typo:
addObsever
→addObserver
-
@frederik said in observer for adding new glyph to the font:
font = CurrentFont()
defconFont = font.naked()
defconFont.dispatcher.addObsever(observer=self, methodName="glyphAdded", notification="Layer.GlyphAdded", observable=None)class Test(object): def __init__(self, *args): font = CurrentFont() defconFont = font.naked() defconFont.dispatcher.addObsever(observer=self, methodName="glyphAdded", notification="Layer.GlyphAdded", observable=None) def glyphAdded(self, notification): print(notification) Test()
Traceback (most recent call last): File "<untitled>", line 9, in <module> File "<untitled>", line 5, in __init__ AttributeError: 'NotificationCenter' object has no attribute 'addObsever'
Am I doing something wrong? I will check also Defcon source code, but I think it should work
-
There are defcon notifications for different actions see the source.
You can even set a global font wise observer (only with defcon objects)
font = CurrentFont() defconFont = font.naked() defconFont.dispatcher.addObsever(observer=self, methodName="glyphAdded", notification="Layer.GlyphAdded", observable=None)
when
observable
isNone
the notification center sends out a notification for each call, not only for the object its observinggood luck
-
@RafaŁ-Buchner thanks for asking good questions here, it helps to improve the docs :)
this example is super valuable because it shows how to use RoboFont and defcon notifications together. thanks @frederik!
-
@gferreira said in observer for adding new glyph to the font:
from vanilla import FloatingWindow from mojo.events import addObserver, removeObserver class NewGlyphMarker: def __init__(self): ### for debugging only self.w = FloatingWindow((200, 50), "mark new glyphs") self.w.bind("close", self.windowCloseCallback) self.w.open() ### end debugging self.font = None addObserver(self, "currentFontChanged", "fontBecameCurrent") self.subscribeFont(CurrentFont()) def __del__(self): self.unsubscribeFont() def windowCloseCallback(self, sender): removeObserver(self, "fontBecameCurrent") self.unsubscribeFont() def subscribeFont(self, font): self.unsubscribeFont() if font is not None: self.font = font self.font.addObserver(self, "glyphOrderChanged", "Font.GlyphOrderChanged") def unsubscribeFont(self): if self.font is not None: self.font.removeObserver(self, "Font.GlyphOrderChanged") self.font = None def currentFontChanged(self, notification): print('current font changed') # a robofont event notification self.subscribeFont(notification["font"]) print(notification['font']) def glyphOrderChanged(self, notification): print('glyph order changed') # a defcon notification font = notification.object font = RFont(font) oldGlyphOrder = notification.data['oldValue'] newGlyphOrder = notification.data['newValue'] newGlyphNames = list(set(newGlyphOrder) - set(oldGlyphOrder)) for glyphName in newGlyphNames: self.font[glyphName].markColor = 1, 0, 0, 1 NewGlyphMarker()
Gustavo, You're the best !!! Big Thanks!!!
I messed up with getting data in the callback. Somehow nothing appeared in the output window (it is set to show every possible error).
-
hi @RafaŁ-Buchner,
I gave it a try — this seems to work:
from vanilla import FloatingWindow from mojo.events import addObserver, removeObserver class NewGlyphMarker: def __init__(self): ### for debugging only self.w = FloatingWindow((200, 50), "mark new glyphs") self.w.bind("close", self.windowCloseCallback) self.w.open() ### end debugging self.font = None addObserver(self, "currentFontChanged", "fontBecameCurrent") self.subscribeFont(CurrentFont()) def __del__(self): self.unsubscribeFont() def windowCloseCallback(self, sender): removeObserver(self, "fontBecameCurrent") self.unsubscribeFont() def subscribeFont(self, font): self.unsubscribeFont() if font is not None: self.font = font self.font.addObserver(self, "glyphOrderChanged", "Font.GlyphOrderChanged") def unsubscribeFont(self): if self.font is not None: self.font.removeObserver(self, "Font.GlyphOrderChanged") self.font = None def currentFontChanged(self, notification): print('current font changed') # a robofont event notification self.subscribeFont(notification["font"]) print(notification['font']) def glyphOrderChanged(self, notification): print('glyph order changed') # a defcon notification font = notification.object font = RFont(font) oldGlyphOrder = notification.data['oldValue'] newGlyphOrder = notification.data['newValue'] newGlyphNames = list(set(newGlyphOrder) - set(oldGlyphOrder)) for glyphName in newGlyphNames: self.font[glyphName].markColor = 1, 0, 0, 1 NewGlyphMarker()
(based on an older example script by @frederik)
I hope this does what you need… cheers!