A very simple example tool: a dialog which displays a list of layers in the current font. If the current font changes, the font name and layers list in the UI are updated automatically.

fromvanillaimport*frommojo.eventsimportaddObserver,removeObserverfromdefconAppKit.windows.baseWindowimportBaseWindowControllerclassListLayersTool(BaseWindowController):padding=10textHeight=20def__init__(self):# create a floating windowself.w=FloatingWindow((200,300),"layers",minSize=(123,200))# name of the current fontx=y=self.paddingself.w.fontName=TextBox((x,y,-self.padding,self.textHeight),'')y+=self.textHeight+self.padding# create a list for font layersself.w.list=List((x,y,-self.padding,-self.padding),[])# observe the 'fontBecameCurrent' event:# that is, call a method every time the current font changesaddObserver(self,'fontBecameCurrentCallback',"fontBecameCurrent")addObserver(self,'fontWillCloseCallback',"fontWillClose")# setup window behaviourself.setUpBaseWindowBehavior()# set current font layer namesself.setFont(CurrentFont())# open the dialogself.w.open()defwindowCloseCallback(self,sender):# disconnect observers when the tool is closedremoveObserver(self,'fontBecameCurrent')removeObserver(self,'fontWillClose')super(ListLayersTool,self).windowCloseCallback(sender)deffontBecameCurrentCallback(self,notification):# get the current fontfont=notification['font']self.setFont(font)deffontWillCloseCallback(self,notitication):# get all open fontsfonts=AllFonts()font=Noneiflen(fonts)>1:# this font that 'will' close is still open# so check if the fonts list is bigger then 1font=fonts[1]else:font=Noneself.setFont(font)defsetFont(self,font):# font could be noneiffontisNone:self.w.list.set([])self.w.fontName.set("")else:# update layers listself.w.list.set(font.layerOrder)# update font namefontName='%s %s'%(font.info.familyName,font.info.styleName)self.w.fontName.set(fontName)# open the dialogListLayersTool()