Skip to content

Instantly share code, notes, and snippets.

@frankrolf
Last active March 20, 2024 17:06
Show Gist options
  • Save frankrolf/20493e72adfef446032dcfedcef56e8e to your computer and use it in GitHub Desktop.
Save frankrolf/20493e72adfef446032dcfedcef56e8e to your computer and use it in GitHub Desktop.
Robofont: toggle current glyph window and space center window, if open
'''
TikToggle
- toggle glyph windows
- toggle the current space center to correspond to the frontmost glyph
suggested shortcut: ctrl - ↑
toggle_backward.py also exists:
suggested shortcut: ctrl - ↓
Ideas:
- could have a little UI with big “TOGGLE” buttons
- that UI could control prefs for transferring data (selection, measurement)
- that UI could control prefs for switching Space Center toggle on/off
- could toggle Metrics Machine
- could keep the layer (complexity with mismatching layer structure predicted)
update 2022/11/18
No more lost font objects! The glyph toggled away from is now inserted
into the window the new glyph came from :-)
'''
from mojo import UI
from fontParts.world import AllFonts
def get_glyph_window_for_font(my_font):
'''
'''
return next((
window for window in UI.AllGlyphWindows() if
# window.getGlyph().font.asFontParts() == my_font), None) # this toggles the glyph, but doesn’t make it “active” -- it means that a copy-paste from one glyph to another will paste into the inactive glyph window.
window.getGlyph().font == my_font), None) # xxx
def transfer_selection(g, next_g):
'''
'''
selected_point_indexes = {}
selected_component_indexes = []
selected_anchor_indexes = []
selected_contour_indexes = []
for cnt in g.selectedContours:
if len(cnt.selectedPoints) == len(cnt):
selected_contour_indexes.append(cnt.index)
for p in g.selectedPoints:
selected_point_indexes.setdefault(p.contour.index, []).append(p.index)
for c in g.selectedComponents:
selected_component_indexes.append(c.index)
for a in g.selectedAnchors:
selected_anchor_indexes.append(a.index)
if any([
selected_contour_indexes,
selected_point_indexes,
selected_component_indexes,
selected_anchor_indexes]
):
next_g.deselect()
with next_g.holdChanges():
# select whole contours in next glyph if selected in current glyph
if selected_contour_indexes:
for cnt_index in selected_contour_indexes:
if cnt_index <= len(next_g.contours) - 1:
next_g.contours[cnt_index].selected = True
# otherwise, replicate point index selection
else:
for c_index, p_index_list in selected_point_indexes.items():
try:
next_contour = next_g.contours[c_index]
filtered_p_index_list = [
i for i in p_index_list if i <= len(next_contour.points)]
for ix in filtered_p_index_list:
next_contour.points[ix].selected = True
except IndexError:
break
for c_index in selected_component_indexes:
if c_index <= len(next_g.components) - 1:
next_g.components[c_index].selected = True
for a_index in selected_anchor_indexes:
if a_index <= len(next_g.anchors) - 1:
next_g.anchors[a_index].selected = True
else:
next_g.deselect()
def toggle_window(direction=1):
try:
# Put the fonts in order of their path.
# This seems to make most sense when multiple families are open
af_sorted = sorted([f for f in AllFonts()], key=lambda x: x.path)
except TypeError:
# No path, just sort by style name
af_sorted = AllFonts(sortOptions=['styleName'])
current_window = UI.CurrentWindow()
doodle_glyph = None
if current_window.doodleWindowName == 'SpaceCenter':
sc = current_window.getSpaceCenter()
current_font = sc.font
elif current_window.doodleWindowName == 'FontWindow':
current_font = current_window.document.font
# dead end, font window is too heavy to toggle
# (editThatNextMaster can do it)
elif current_window.doodleWindowName == 'GlyphWindow':
g_window = UI.CurrentGlyphWindow()
doodle_glyph = current_window.getGlyph()
current_font = doodle_glyph.font
font_index = af_sorted.index(current_font.asFontParts())
next_font = af_sorted[(font_index + direction) % len(af_sorted)]
current_index = font_index
# toggle the glyph. This is slightly complex since the
# glyph may not exist in other fonts
tries = 0
if doodle_glyph is not None:
while doodle_glyph.name not in next_font.keys():
if tries == len(af_sorted):
print(f'{doodle_glyph.name} is not in any other font')
break
else:
current_index += direction
next_font = af_sorted[(current_index + direction) % len(af_sorted)]
# next_doodle_glyph = next_font.asDefcon()[doodle_glyph.name] # xxx
# next_doodle_glyph = next_font[doodle_glyph.name].asDefcon()
next_doodle_glyph = next_font[doodle_glyph.name].naked()
# next_doodle_glyph = next_font[doodle_glyph.name]
next_doodle_glyph.measurements = doodle_glyph.measurements
other_window = get_glyph_window_for_font(next_font)
g_window.setGlyph(next_doodle_glyph)
if other_window:
other_window.setGlyph(doodle_glyph)
transfer_selection(
doodle_glyph.asFontParts(), next_doodle_glyph.asFontParts())
# toggle the space center window
sc_window = UI.CurrentSpaceCenterWindow()
if sc_window:
sc = sc_window.getSpaceCenter()
sc.setFont(next_font)
sc.updateGlyphLineView()
sc_window.setTitle()
sc_window.setFont(next_font)
if __name__ == '__main__':
toggle_window()
import toggle
# from importlib import reload
# reload(toggle)
toggle.toggle_window(-1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment