Setting Space Center display options with a script

This example shows how to set the Space Center’s input text and display options.

from mojo.UI import CurrentSpaceCenter

sp = CurrentSpaceCenter()

# set sample contents
sp.setRaw('abcdefghijklmnopqrstuvwxyz')
sp.setPre('/o/n')
sp.setAfter('/n')

# get display states
states = sp.glyphLineView.getDisplayStates()

# modify display states
states["Show Space Matrix"] = True
states["Right to Left"] = False
states["Upside Down"] = True
states["Inverse"] = True

# set display states
sp.glyphLineView.setDisplayStates(states)

Adding a custom button to the Space Center

The script below shows how to add a custom button to the Space Center interface.

from mojo.UI import CurrentSpaceCenter
from vanilla import Button

class AddButtonToSpaceCenter:

    def __init__(self):
        buttonWidth = 40
        padding = 10

        # get the current space center
        sp = CurrentSpaceCenter()

        # shift pre input to the right
        x, y, w, h = sp.top.glyphLinePreInput.getPosSize()
        x += buttonWidth + padding
        sp.top.glyphLinePreInput.setPosSize((x, y, w, h))

        # shift text input to the right
        x, y, w, h = sp.top.glyphLineInput.getPosSize()
        x += buttonWidth + padding
        sp.top.glyphLineInput.setPosSize((x, y, w, h))

        # add a button
        x = y = padding
        sp.myButton = Button((x, y, buttonWidth, 22), "OK", callback=self.buttonCallback)

    def buttonCallback(self, sender):
        print("Do something")

AddButtonToSpaceCenter()

Synchronizing multiple Space Centers

The following script shows a simple tool to synchronize input and display options across all open Space Centers. Once initialized, the tool will add a checkbox to the bottom right of all Space Center windows. Select/deselect the checkbox to turn synchronization on/off.

from mojo.UI import AllSpaceCenters, CurrentSpaceCenter
from mojo.events import addObserver, removeObserver
from vanilla import *

cachedSettings = {}

class SynchronizeSpaceCenters(object):

    def __init__(self):
        addObserver(self, "addSynchronizeCheckBox", "spaceCenterDidOpen")

    def removeSynchronizeCheckBox(self, sender):
        removeObserver(self, "spaceCenterDrawLineView")
        removeObserver(self, "removeSynchronizeCheckBox")

    def addSynchronizeCheckBox(self, sender):
        sp = CurrentSpaceCenter()
        if not sp:
            return
        sp.synchronizeToggle = CheckBox((-22, -22, 22, 22), title=None, callback=self.synchronizeCallback, value=True)
        addObserver(self, "synchronize", "spaceCenterDrawLineView")
        addObserver(self, "removeSynchronizeCheckBox", "spaceCenterWillClose")

    def synchronize(self, none):

        sp = CurrentSpaceCenter()

        # no space center open
        if not sp:
            return

        # space center does not have a synchronize checkbox
        if not sp.synchronizeToggle:
            return

        # space center synchronization is turned off
        if not sp.synchronizeToggle.get():
            return

        # collect new settings
        settings = {
            'text'       : sp.getRaw(),
            'before'     : sp.getPre(),
            'after'      : sp.getAfter(),
            'suffix'     : sp.getSuffix(),
            'fontSize'   : sp.getPointSize(),
            'lineHeight' : sp.getLineHeight(),
        }

        # stop if the settings haven't changed
        global cachedSettings
        if settings == cachedSettings:
            return

        # apply settings to all other space centers
        for sc in AllSpaceCenters():
            if sc == sp:
                continue
            sc.setRaw(settings['text'])
            sc.setPre(settings['before'])
            sc.setAfter(settings['after'])
            sc.setSuffix(settings['suffix'])
            sc.setPointSize(settings['fontSize'])
            sc.setLineHeight(settings['lineHeight'])

        # save settings for next time
        cachedSettings = settings

    def synchronizeCallback(self, sender):
        state = sender.get()

        # synchronize checkboxes
        for sc in AllSpaceCenters():
            sc.synchronizeToggle.set(state)

        # synchronize space centers
        if state:
            self.synchronize(True)

SynchronizeSpaceCenters()

Based on this script by Jackson Cavanaugh (Okay Type).

Exporting multipage PDFs from the Space Center

The ‘proof of concept’ script below takes the current Space Center’s content and settings, and uses them to create a multipage PDF with DrawBot.

  1. open a font
  2. open the Space Center, type some text
  3. run the script below in the DrawBot extension
'''Export SpaceCenter contents as a multipage PDF.'''

from mojo.UI import CurrentSpaceCenter

# --------
# settings
# --------

pageSize = 'A4Landscape'
margin = 40

# ------------
# calculations
# ------------

f = CurrentFont()
spaceCenter = CurrentSpaceCenter()

size(pageSize)

s = spaceCenter.getPointSize() / f.info.unitsPerEm # scale factor
L = (f.info.unitsPerEm + f.info.descender) * s # first line shift

w = width()  - margin * 2
h = height() - margin * 2
x = margin
y = height() - margin - L

# ----------
# make pages
# ----------

translate(x, y)
scale(s)
X, Y = 0, 0

for gr in spaceCenter.glyphRecords:

    # linebreak
    if (X + gr.glyph.width) * s > w:
        X = 0
        Y -= f.info.unitsPerEm * (1 + spaceCenter.getLineHeight() / 800)

    # pagebreak
    if (abs(Y * s) + L) > h:
        newPage(pageSize)
        translate(x, y)
        scale(s)
        X, Y = 0, 0

    with savedState():
        translate(X, Y)
        drawGlyph(gr.glyph)

    X += gr.glyph.width

Written in response to a question in the Forum.

Last edited on 04/07/2019