New tab with glyphs of different masters?

I got two glyph names and two names of layers. Want to open a new tab with these two glyphs, each in a specified layer, like /glyphA (Bold) /glyphB (Regular)

I was only able to open a new tab with without specifying layers:

glyphnames = ‘/’ + glyphA.name + ‘/’ + glyphB.name

callAfter(Glyphs.currentDocument.windowController().addTabWithString_, glyphnames )

Help appreciated!

You need to access the current tab and its edit view controller:

currentEditViewController = Doc.windowController().activeEditViewController()
currentTab = currentEditViewController.graphicView()

To access one or many glyphs in the tab, you need to define an NSRange:

myRangeOfGlyphs = NSRange()
myRangeOfGlyphs.location = 0
myRangeOfGlyphs.length = 1

This would be the range the first glyph. Alternatively, you can get the current user selection:

myRangeOfGlyphs = currentTab.textStorage().selectedRange()

Then you define an Attribute dict with the myLayer.layerId (or the myFontMaster.id, if you only want master layers):

myLayerID = glyphA.layers[“Bold”].layerId
Attributes = { “GSLayerIdAttrib”: myLayerID }

Then you add the attributes, and force a redraw:

currentTab.textStorage().text().addAttributes_range_( Attributes, selectedRange )
currentEditViewController.forceRedraw()

Many thanks, Rainer!
Looks like there has to be a tab open, though. I’d like to create a new tab with a string and then apply layerIds to ranges of it …

Btw, where is this stuff’s documentation?

Not sure I understand what you mean. What are you missing? You know how to open a tab, and now you also know how to apply layerIds to ranges. All the steps necessary for this are on this page. This is not documented other than through Python's help() and dir() functions. And perhaps the .h files in the app package if you know your way around the PyObjC Bridge.

the you add a new tab with what glyphs you like to have and then add the ‘GSLayerIdAttrib’ to it as described.

This is my code:

from PyObjCTools.AppHelper import callAfter
f = Glyphs.font
word = 'Hello’
callAfter( Glyphs.currentDocument.windowController().addTabWithString_, word )

currentEditViewController = Glyphs.currentDocument.windowController().activeEditViewController()
currentTab = currentEditViewController.graphicView()

myRangeOfGlyphs = NSRange()
myRangeOfGlyphs.location = 0
myRangeOfGlyphs.length = 1

masterID = f.masters[2].id

Attributes = { “GSLayerIdAttrib”: masterID }

currentTab.textStorage().text().addAttributes_range_( Attributes, myRangeOfGlyphs )
currentEditViewController.forceRedraw()

When I run it in a glyphs file where no tab is open yet, I get:

Traceback (most recent call last):
File “”, line 10, in
AttributeError: ‘NoneType’ object has no attribute ‘graphicView’

When I run it again, a second tab is opened, and in the first tab the text is changed.

I’d like to achieve all this at once in one new tab. Where’s my mistake?

Thanks again!
Christoph

That is because the callAfter is still on queue when you are accessing activeEditViewController and its graphicView. Try:

Glyphs.currentDocument.windowController().addTabWithString_( word )

… instead of the callAfter line.

I expected something like that. #gefährlicheshalbwissen
Many thanks, Rainer!

In Glyphs 2, I changed the behavior of scripts a bit. As long as you don’t use dialogs the script will run in the main thread to avoid the need for callAfter().