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.

import vanilla
from mojo.UI import CurrentSpaceCenter

def buttonCallback(sender):
    '''A function that does something when the button is clicked.'''
    print('button clicked!')


if __name__ == '__main__':
    # access the current space center
    w = CurrentSpaceCenter()

    # resize the top bar to create space for the new button
    w.top.setPosSize((0, 0, -100, 40))

    # add the button with the function above as callback
    w.myButton = vanilla.Button((-100, 10, -10, 22),
                                "click me",
                                callback=buttonCallback)

Adapted from this forum thread

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
from mojo.subscriber import Subscriber, registerSpaceCenterSubscriber, disableSubscriberEvents
from vanilla import CheckBox

cachedSettings = {}

class SynchronizeSpaceCenters(Subscriber):

    debug = True

    def build(self):
        sp = self.getSpaceCenter()
        sp.synchronizeToggle = CheckBox((-22, -22, 22, 22),
                                        title=None,
                                        callback=self.synchronizeCheckBoxCallback,
                                        value=True)

    def destroy(self):
        sp = self.getSpaceCenter()
        del sp.synchronizeToggle

    def spaceCenterDidChangeText(self, info):
        self.synchronize()

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

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

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

    def synchronize(self):
        sp = self.getSpaceCenter()

        # 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
        with disableSubscriberEvents():
            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


if __name__ == '__main__':
    registerSpaceCenterSubscriber(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.

Have a look at the SpaceCenter object reference for the complete list of attributes and methods.

Last edited on 01/09/2021