Skip to content

Instantly share code, notes, and snippets.

@ryanbugden
Last active July 23, 2026 21:58
Show Gist options
  • Select an option

  • Save ryanbugden/568bf3797ac69511f029ea9f07d59811 to your computer and use it in GitHub Desktop.

Select an option

Save ryanbugden/568bf3797ac69511f029ea9f07d59811 to your computer and use it in GitHub Desktop.
# menuTitle: (Start-up) (FO) Delete Glyphs From Layer
# author: Ryan Bugden
import ezui
from mojo.subscriber import Subscriber, registerFontOverviewSubscriber
from mojo.UI import CurrentFontWindow
from mojo.extensions import getExtensionDefault, setExtensionDefault
'''
(Start-up script)
A contextual menu in the Font Overview. Right click selected glyphs
to delete them from a specified layer.
Ryan Bugden
2023.06.07
'''
class DGLayerSheet(ezui.WindowController):
def build(self, parent):
window = parent.w
self.f = RFont(parent._font)
layers = [l.name for l in self.f.layers]
self.glyphs_to_delete = self.f.templateSelectedGlyphNames
content = """
Delete selected glyph from: @label
|-----| @table
| |
|-----|
======================
(Cancel) @cancelButton
(Delete Glyph) @deleteButton
"""
button_width = 110
descriptionData=dict(
table=dict(
items=layers
),
cancelButton=dict(
keyEquivalent=chr(27),
width=button_width,
),
deleteButton=dict(
keyEquivalent=chr(13),
width=button_width,
),
)
self.w = ezui.EZSheet(
content=content,
descriptionData=descriptionData,
controller=self,
size=('auto', 300),
parent=window
)
if len(self.glyphs_to_delete) > 1:
self.w.getItem('deleteButton').setTitle("Delete Glyphs")
self.w.getItem('label').set("Delete selected glyphs from:")
if len(layers) > 1:
# Set the selection to be the second layer by default.
self.w.getItem('table').setSelectedItems([layers[1]])
def started(self):
self.w.open()
def cancelButtonCallback(self, sender):
self.w.close()
def deleteButtonCallback(self, sender):
choice = self.w.getItem("table").getSelectedItems()
chosen_layers_amount = len(choice)
total_layers_amount = len(self.w.getItem("table").get())
# Save template glyph order
glyph_order = list(self.f.templateGlyphOrder)
for layer_name in choice:
layer = self.f.getLayer(layer_name)
for g_name in self.glyphs_to_delete:
try:
del layer[g_name]
except:
pass
# Restore template glyph order, because we don't want to remove templates
self.f.templateGlyphOrder = glyph_order
print(f"Deleted the following glyphs from following layers:\n\tGlyphs: {self.glyphs_to_delete}\n\tLayers: {choice}")
self.w.close()
# Update the glyphs on the font level, to make sure the layer indicator is updated
for g_name in [g_name for g_name in self.glyphs_to_delete if g_name in self.f]:
self.f[g_name].changed()
class DeleteGlyphsFromLayer(Subscriber):
def fontOverviewWantsContextualMenuItems(self, info):
self.f = info['glyph'].font
self.fo = info['fontOverview']
if len(self.f.templateSelectedGlyphNames) > 1:
message = "Delete Glyphs from Layer..."
else:
message = "Delete Glyph from Layer..."
my_menu_items = [
(message, self.deleteGlyphsCallback)
]
info['itemDescriptions'].extend(my_menu_items)
def deleteGlyphsCallback(self, sender):
parent = CurrentFontWindow()
DGLayerSheet(parent)
#===================
if __name__ == "__main__":
registerFontOverviewSubscriber(DeleteGlyphsFromLayer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment