Last active
March 20, 2024 17:06
-
-
Save frankrolf/20493e72adfef446032dcfedcef56e8e to your computer and use it in GitHub Desktop.
Robofont: toggle current glyph window and space center window, if open
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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