Is this possible? Couldn’t find it in the docu.
unfortunately not. At least not in a sane way. Can you add a feature request to: http://bugreport.glyphsapp.com
Still the same answer here?
not sure if there’s a better way, but I do it like this:
filterContent = {"Count" : 1,
"ShallHaveCount" : 1,
"icon" : "CustomFilterListTemplate",
"isLeaf" : 1,
"list" : ["A"],
"name" : "myNewFilter"
}
filterController = Font.fontView.glyphsGroupViewController()
filters = filterController.glyphGroups()[2]["subGroup"]
filters.append(filterContent)
filterController.update()
That looks very good.
Any updates on this? It doesn’t seem to work anymore with Glyphs 3.
from Foundation import NSMutableDictionary
font = Glyphs.font
filterController = font.fontView.glyphsGroupViewController()
glyphGroups = filterController.glyphGroups()
filters = glyphGroups[3]
print(filters)
flt = NSMutableDictionary.dictionaryWithObjectsAndKeys_(
True, "isLeaf",
"MyListFilter", "name",
["A", "B"], "list",
"CustomFilterListTemplate", "icon",
None
)
# Neither of those two options work:
# filters.insertObject_inSubItemsAtIndex_(flt, 0)
# filters.insertSubItems_atIndex_([flt], 0)
filterController.update()
Alternatively, is there a way to filter the font view from within a script temporarily without adding a filter to the sidebar?
Alternatively, is there a way to filter the font view from within a script temporarily without adding a filter to the sidebar?
I have thought the same thing a few years ago:
class SearchState(object):
ALL = 0
NAME = 1
UNICODE = 2
NOTE = 3
@staticmethod
def make_key(key, searchField):
if Glyphs.versionNumber < 3.0:
return 'GlyphList{0}'.format(key)
return searchField.key_(key)
@classmethod
def set_state_in_font(cls, font, state, search=False):
controller = font.fontView
searchField = controller.glyphSearchField()
searchField.setStringValue_(state.pattern)
Glyphs.defaults[cls.make_key('SearchState', searchField)] = state.mode
Glyphs.defaults[cls.make_key('SearchStateMatchCase', searchField)] = state.match_case
Glyphs.defaults[cls.make_key('SearchStateRegex', searchField)] = state.regex
if search:
controller.filterGlyphs_(searchField)
@classmethod
def from_font(cls, font):
controller = font.fontView
searchField = controller.glyphSearchField()
return cls(
searchField.stringValue(),
Glyphs.defaults[cls.make_key('SearchState', searchField)],
bool(Glyphs.defaults[cls.make_key('SearchStateMatchCase', searchField)]),
bool(Glyphs.defaults[cls.make_key('SearchStateRegex', searchField)])
)
def __init__(self, pattern, mode=0, match_case=False, regex=False):
self.pattern = pattern
self.mode = mode if not regex else self.NAME
self.match_case = match_case
self.regex = regex
def perform_temporal_search(self, font):
prev = self.from_font(font)
try:
self.set_state_in_font(font, self, search=True)
finally:
self.set_state_in_font(font, prev, search=False)
@classmethod
def reset(cls, font):
cls.set_state_in_font(font, cls.from_font(font), search=True)
if __name__ == '__main__':
SearchState('A|B|C', mode=SearchState.NAME, match_case=True, regex=True).perform_temporal_search(Glyphs.font)
I came up with the code above. My idea at that time was to perform a regex search, and then restore only the UI state as if nothing happened.
To add a new filter:
GSSidebarItem = objc.lookUpClass("GSSidebarItem")
font = Glyphs.font
filterController = font.fontView.glyphsGroupViewController()
glyphGroups = filterController.glyphGroups()
filters = glyphGroups[3]
print(filters)
newItem = GSSidebarItem.new()
newItem.setName_("MyListFilter1")
newItem.setCoverage_(["A", "B"])
newItem.setIconName_("CustomFilterListTemplate")
newItem.setItemType_(3)
filters.insertObject_inSubItemsAtIndex_(newItem, len(filters.subItems()))
filterController.didChangeSidebarItem_(filters)
And to temporarily change the sorting in Font view:
from AppKit import NSSortDescriptor
font = Glyphs.font
glyphsArrayController = font.fontView.glyphsArrayController()
glyphsArrayController.setSortDescriptors_([NSSortDescriptor.alloc().initWithKey_ascending_("layer0.LSB", True)])
And when you like to use a predefined list of names:
GSSortDescriptorNameList = objc.lookUpClass("GSSortDescriptorNameList")
font = Glyphs.font
glyphsArrayController = font.fontView.glyphsArrayController()
sortDescriptor = GSSortDescriptorNameList.alloc().initWithKey_ascending_("name", True)
sortDescriptor.setReferenceList_(["z", "y", "x"])
glyphsArrayController.setSortDescriptors_([sortDescriptor])
Whoa. I can even set up a filter smarter than a smart filter:
newItem = GSSidebarItem.new()
newItem.setName_("MySmartFilter1")
newItem.setPredicate_(NSPredicate.predicateWithFormat_("""\
NOT (name MATCHES '[A-Z].+')
AND ((name CONTAINS 'acute') OR (name CONTAINS 'grave'))
AND (export == 1)
AND ((layer0.countOfPaths > 0) OR (layer0.countOfComponents > 0))
"""))
newItem.setIconName_('CustomFilterPredicateTemplate')
newItem.setItemType_(3)
This will be definitely a time saver for me. Thanks for the snippets!
I am trying to use this code to implement a temporarily change to the sorting in the Font view using a pre-defined list of names. I’m able to see the Font View change successfully, but after a second or two, it updates again and restores back to the standard view. This didn’t happen when I was running the plugin on Glyphs2, so that leads me to think this is something new in Glyphs3. Is there some way to prevent the fontview from updating again or to preserve the predefined sort for longer?
I used the script and the sorting is still there even after I worked on the font for some time.
But any selection in the sidebar and adding/removing glyphs will most likely reset it.
Ah, thanks! It seems one of the instances of Glyphs.font.fontView.glyphsGroupViewController().update()
in my script was being re-run for some reason, clearing the view.