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.

from vanilla import *
from mojo.events import addObserver, removeObserver
from defconAppKit.windows.baseWindow import BaseWindowController

class ListLayersTool(BaseWindowController):

    padding = 10
    textHeight = 20

    def __init__(self):

        # create a floating window
        self.w = FloatingWindow((200, 300), "layers", minSize=(123, 200))

        # name of the current font
        x = y = self.padding
        self.w.fontName = TextBox((x, y, -self.padding, self.textHeight), '')

        y += self.textHeight + self.padding
        # create a list for font layers
        self.w.list = List((x, y, -self.padding, -self.padding), [])

        # observe the 'fontBecameCurrent' event:
        # that is, call a method every time the current font changes
        addObserver(self, 'fontBecameCurrentCallback', "fontBecameCurrent")
        addObserver(self, 'fontWillCloseCallback', "fontWillClose")

        # setup window behaviour
        self.setUpBaseWindowBehavior()

        # set current font layer names
        self.setFont(CurrentFont())

        # open the dialog
        self.w.open()

    def windowCloseCallback(self, sender):
        # disconnect observers when the tool is closed
        removeObserver(self, 'fontBecameCurrent')
        removeObserver(self, 'fontWillClose')
        super(ListLayersTool, self).windowCloseCallback(sender)

    def fontBecameCurrentCallback(self, notification):
        # get the current font
        font = notification['font']
        self.setFont(font)

    def fontWillCloseCallback(self, notitication):
        # get all open fonts
        fonts = AllFonts()
        font = None
        if len(fonts) > 1:
            # this font that 'will' close is still open
            # so check if the fonts list is bigger then 1
            font = fonts[1]
        else:
            font = None
        self.setFont(font)

    def setFont(self, font):
        # font could be none
        if font is None:
            self.w.list.set([])
            self.w.fontName.set("")
        else:
            # update layers list
            self.w.list.set(font.layerOrder)

            # update font name
            fontName = '%s %s' % (font.info.familyName, font.info.styleName)
            self.w.fontName.set(fontName)


# open the dialog
ListLayersTool()

  • load font name and layers when the dialog is opened
  • remove font name and layers when all fonts are closed
Last edited on 27/03/2018