def __init__(self, glyph, construction, decompose): self.glyph = glyph width = 350 height = 120 editorWindow = CurrentGlyphWindow() (editorX, editorY, editorW, editorH), screen = getGlyphEditorRectAndScreen(editorWindow) x = editorX + ((editorW - width) / 2) y = editorY + ((editorH - height) / 2) self.w = StatusInteractivePopUpWindow((x, y, width, height), screen=screen) self.w.constructionEditor = vanilla.EditText((15, 15, -15, 22), construction) self.w.decomposeCheckBox = vanilla.CheckBox((15, 45, -15, 22), "Decompose", value=decompose) self.w.open() self.w.line = vanilla.HorizontalLine((15, -45, -15, 1)) self.w.cancelButton = vanilla.Button( (-165, -35, 70, 20), "Cancel", callback=self.cancelButtonCallback) self.w.okButton = vanilla.Button((-85, -35, 70, 20), "OK", callback=self.okButtonCallback) self.w.setDefaultButton(self.w.okButton) self.w.cancelButton.bind(".", ["command"]) self.w.getNSWindow().makeFirstResponder_( self.w.constructionEditor.getNSTextField()) self.w.open()
def __init__(self, glyph, construction, decompose): self.glyph = glyph width = 350 height = 120 editorWindow = CurrentGlyphWindow() (editorX, editorY, editorW, editorH), screen = getGlyphEditorRectAndScreen(editorWindow) x = editorX + ((editorW - width) / 2) y = editorY + ((editorH - height) / 2) self.w = StatusInteractivePopUpWindow((x, y, width, height), screen=screen) self.w.constructionEditor = vanilla.EditText( "auto", construction ) self.w.decomposeCheckBox = vanilla.CheckBox( "auto", "Decompose", value=decompose ) self.w.open() self.w.line = vanilla.HorizontalLine("auto") self.w.flex = vanilla.Group("auto") self.w.cancelButton = vanilla.Button( "auto", "Cancel", callback=self.cancelButtonCallback ) self.w.buildButton = vanilla.Button( "auto", "Build", callback=self.buildButtonCallback ) metrics = dict( margin=15, padding=10, buttonWidth=80 ) rules = [ "H:|-margin-[constructionEditor]-margin-|", "H:|-margin-[line]-margin-|", "H:|-margin-[decomposeCheckBox][flex(>=100)]-[cancelButton(==buttonWidth)]-padding-[buildButton(==buttonWidth)]-margin-|", "V:|" "-margin-" "[constructionEditor]" "-padding-" "[line]" "-padding-" "[decomposeCheckBox]" "-margin-" "|", "V:|" "-margin-" "[constructionEditor]" "-padding-" "[line]" "-padding-" "[flex]" "-margin-" "|", "V:|" "-margin-" "[constructionEditor]" "-padding-" "[line]" "-padding-" "[cancelButton]" "-margin-" "|", "V:|" "-margin-" "[constructionEditor]" "-padding-" "[line]" "-padding-" "[buildButton]" "-margin-" "|" ] self.w.addAutoPosSizeRules(rules, metrics) self.w.setDefaultButton(self.w.buildButton) self.w.cancelButton.bind(".", ["command"]) self.w.getNSWindow().makeFirstResponder_(self.w.constructionEditor.getNSTextField()) self.w.open()
def __init__(self, glyph): self.w = StatusInteractivePopUpWindow( (250, 0), centerInView=CurrentGlyphWindow().getGlyphView()) metrics = dict( border=15, padding1=10, padding2=5, titleWidth=45, inputSpace=70, # border + title + padding killButtonWidth=20, navigateButtonWidth=30, fieldHeight=22, ) rules = [ # Left "H:|-border-[leftTitle(==titleWidth)]-padding1-[leftField]-border-|", "H:|-inputSpace-[leftButton]-padding2-[leftKillButton(==killButtonWidth)]-border-|", "V:|-border-[leftTitle(==fieldHeight)]", "V:|-border-[leftField(==fieldHeight)]", "V:[leftField]-padding2-[leftButton]", "V:[leftField]-padding2-[leftKillButton(==leftButton)]", # Right "H:|-border-[rightTitle(==titleWidth)]-padding1-[rightField]-border-|", "H:|-inputSpace-[rightButton]-padding2-[rightKillButton(==killButtonWidth)]-border-|", "V:[leftButton]-padding1-[rightTitle(==fieldHeight)]", "V:[leftButton]-padding1-[rightField(==fieldHeight)]", "V:[rightField]-padding2-[rightButton]", "V:[rightField]-padding2-[rightKillButton(==rightButton)]", # Width "H:|-border-[widthTitle(==titleWidth)]-padding1-[widthField]-border-|", "H:|-inputSpace-[widthButton]-padding2-[widthKillButton(==killButtonWidth)]-border-|", "V:[rightButton]-padding1-[widthTitle(==fieldHeight)]", "V:[rightButton]-padding1-[widthField(==fieldHeight)]", "V:[widthField]-padding2-[widthButton]", "V:[widthField]-padding2-[widthKillButton(==rightButton)]", # Bottom "H:|-inputSpace-[line]-border-|", "H:|-inputSpace-[previousGlyphButton(==navigateButtonWidth)]-padding2-[nextGlyphButton(==navigateButtonWidth)]-padding1-[doneButton(>=0)]-border-|", "V:[widthButton]-padding1-[line]", "V:[line]-padding1-[previousGlyphButton]-border-|", "V:[line]-padding1-[nextGlyphButton]-border-|", "V:[line]-padding1-[doneButton]-border-|", ] self.w.leftTitle = vanilla.TextBox("auto", "Left:", alignment="right") self.w.leftField = vanilla.EditText("auto", "", continuous=False, callback=self.fieldCallback) self.w.leftButton = vanilla.Button("auto", "", callback=self.buttonCallback) self.w.leftKillButton = vanilla.ImageButton( "auto", imageNamed=NSImageNameStopProgressFreestandingTemplate, bordered=False, callback=self.buttonCallback) self.w.rightTitle = vanilla.TextBox("auto", "Right:", alignment="right") self.w.rightField = vanilla.EditText("auto", "", continuous=False, callback=self.fieldCallback) self.w.rightButton = vanilla.Button("auto", "", callback=self.buttonCallback) self.w.rightKillButton = vanilla.ImageButton( "auto", imageNamed=NSImageNameStopProgressFreestandingTemplate, bordered=False, callback=self.buttonCallback) self.w.widthTitle = vanilla.TextBox("auto", "Width:", alignment="right") self.w.widthField = vanilla.EditText("auto", "", continuous=False, callback=self.fieldCallback) self.w.widthButton = vanilla.Button("auto", "", callback=self.buttonCallback) self.w.widthKillButton = vanilla.ImageButton( "auto", imageNamed=NSImageNameStopProgressFreestandingTemplate, bordered=False, callback=self.buttonCallback) self.controlGroups = [ dict(attr="leftMargin", field=self.w.leftField, button=self.w.leftButton, kill=self.w.leftKillButton), dict(attr="rightMargin", field=self.w.rightField, button=self.w.rightButton, kill=self.w.rightKillButton), dict(attr="width", field=self.w.widthField, button=self.w.widthButton, kill=self.w.widthKillButton), ] for group in self.controlGroups: field = group["field"] button = group["button"] button.getNSButton().setAlignment_(NSLeftTextAlignment) self.w.line = vanilla.HorizontalLine("auto") self.w.doneButton = vanilla.Button("auto", "Close", callback=self.doneCallback) self.w.doneButton.bind(escapeCharacter, []) self.w.previousGlyphButton = vanilla.Button( "auto", "←", callback=self.previousGlyphCallback) self.w.previousGlyphButton.bind("[", ["command"]) self.w.nextGlyphButton = vanilla.Button( "auto", "→", callback=self.nextGlyphCallback) self.w.nextGlyphButton.bind("]", ["command"]) self.w.addAutoPosSizeRules(rules, metrics) self.loadGlyph() self.w.open()
class GlyphEditorSpaceStationController(object): def __init__(self, glyph): self.w = StatusInteractivePopUpWindow( (250, 0), centerInView=CurrentGlyphWindow().getGlyphView()) metrics = dict( border=15, padding1=10, padding2=5, titleWidth=45, inputSpace=70, # border + title + padding killButtonWidth=20, navigateButtonWidth=30, fieldHeight=22, ) rules = [ # Left "H:|-border-[leftTitle(==titleWidth)]-padding1-[leftField]-border-|", "H:|-inputSpace-[leftButton]-padding2-[leftKillButton(==killButtonWidth)]-border-|", "V:|-border-[leftTitle(==fieldHeight)]", "V:|-border-[leftField(==fieldHeight)]", "V:[leftField]-padding2-[leftButton]", "V:[leftField]-padding2-[leftKillButton(==leftButton)]", # Right "H:|-border-[rightTitle(==titleWidth)]-padding1-[rightField]-border-|", "H:|-inputSpace-[rightButton]-padding2-[rightKillButton(==killButtonWidth)]-border-|", "V:[leftButton]-padding1-[rightTitle(==fieldHeight)]", "V:[leftButton]-padding1-[rightField(==fieldHeight)]", "V:[rightField]-padding2-[rightButton]", "V:[rightField]-padding2-[rightKillButton(==rightButton)]", # Width "H:|-border-[widthTitle(==titleWidth)]-padding1-[widthField]-border-|", "H:|-inputSpace-[widthButton]-padding2-[widthKillButton(==killButtonWidth)]-border-|", "V:[rightButton]-padding1-[widthTitle(==fieldHeight)]", "V:[rightButton]-padding1-[widthField(==fieldHeight)]", "V:[widthField]-padding2-[widthButton]", "V:[widthField]-padding2-[widthKillButton(==rightButton)]", # Bottom "H:|-inputSpace-[line]-border-|", "H:|-inputSpace-[previousGlyphButton(==navigateButtonWidth)]-padding2-[nextGlyphButton(==navigateButtonWidth)]-padding1-[doneButton(>=0)]-border-|", "V:[widthButton]-padding1-[line]", "V:[line]-padding1-[previousGlyphButton]-border-|", "V:[line]-padding1-[nextGlyphButton]-border-|", "V:[line]-padding1-[doneButton]-border-|", ] self.w.leftTitle = vanilla.TextBox("auto", "Left:", alignment="right") self.w.leftField = vanilla.EditText("auto", "", continuous=False, callback=self.fieldCallback) self.w.leftButton = vanilla.Button("auto", "", callback=self.buttonCallback) self.w.leftKillButton = vanilla.ImageButton( "auto", imageNamed=NSImageNameStopProgressFreestandingTemplate, bordered=False, callback=self.buttonCallback) self.w.rightTitle = vanilla.TextBox("auto", "Right:", alignment="right") self.w.rightField = vanilla.EditText("auto", "", continuous=False, callback=self.fieldCallback) self.w.rightButton = vanilla.Button("auto", "", callback=self.buttonCallback) self.w.rightKillButton = vanilla.ImageButton( "auto", imageNamed=NSImageNameStopProgressFreestandingTemplate, bordered=False, callback=self.buttonCallback) self.w.widthTitle = vanilla.TextBox("auto", "Width:", alignment="right") self.w.widthField = vanilla.EditText("auto", "", continuous=False, callback=self.fieldCallback) self.w.widthButton = vanilla.Button("auto", "", callback=self.buttonCallback) self.w.widthKillButton = vanilla.ImageButton( "auto", imageNamed=NSImageNameStopProgressFreestandingTemplate, bordered=False, callback=self.buttonCallback) self.controlGroups = [ dict(attr="leftMargin", field=self.w.leftField, button=self.w.leftButton, kill=self.w.leftKillButton), dict(attr="rightMargin", field=self.w.rightField, button=self.w.rightButton, kill=self.w.rightKillButton), dict(attr="width", field=self.w.widthField, button=self.w.widthButton, kill=self.w.widthKillButton), ] for group in self.controlGroups: field = group["field"] button = group["button"] button.getNSButton().setAlignment_(NSLeftTextAlignment) self.w.line = vanilla.HorizontalLine("auto") self.w.doneButton = vanilla.Button("auto", "Close", callback=self.doneCallback) self.w.doneButton.bind(escapeCharacter, []) self.w.previousGlyphButton = vanilla.Button( "auto", "←", callback=self.previousGlyphCallback) self.w.previousGlyphButton.bind("[", ["command"]) self.w.nextGlyphButton = vanilla.Button( "auto", "→", callback=self.nextGlyphCallback) self.w.nextGlyphButton.bind("]", ["command"]) self.w.addAutoPosSizeRules(rules, metrics) self.loadGlyph() self.w.open() def setFirstResponder(self, control): self.w.getNSWindow().makeFirstResponder_(control.getNSTextField()) def _getControlGroup(self, sender): for group in self.controlGroups: field = group["field"] button = group["button"] kill = group["kill"] if sender == field: return group if sender == button: return group if sender == kill: return group def doneCallback(self, sender): self.w.close() # -------- # Updaters # -------- def loadGlyph(self): self._inGlyphLoad = True self.glyph = CurrentGlyph() if self.glyph.bounds is None: self.setFirstResponder(self.w.widthField) else: self.setFirstResponder(self.w.leftField) leftField = self.w.leftField.getNSTextField() rightField = self.w.rightField.getNSTextField() leftField.setNextKeyView_(rightField) rightField.setNextKeyView_(leftField) self._updateFields() self._updateButtons() self._inGlyphLoad = False def _updateFields(self): for group in self.controlGroups: attr = group["attr"] field = group["field"] if attr in ("leftMargin", "rightMargin") and self.glyph.bounds is None: value = "" else: value = getMetricValue(self.glyph, attr) value = roundint(value) field.set(value) def _updateButtons(self): for group in self.controlGroups: attr = group["attr"] button = group["button"] formula = getFormula(self.glyph, attr) if not formula: button.setTitle("") button.enable(False) continue calculatedValue = calculateFormula(self.glyph, formula, attr) value = getMetricValue(self.glyph, attr) if roundint(value) != roundint(calculatedValue): color = outSyncButtonColor else: color = inSyncButtonColor string = NSAttributedString.alloc().initWithString_attributes_( formula, {NSForegroundColorAttributeName: color}) button.setTitle(string) button.enable(True) # --------- # Callbacks # --------- def fieldCallback(self, sender): if self._inGlyphLoad: return group = self._getControlGroup(sender) attr = group["attr"] field = group["field"] button = group["button"] value = field.get().strip() if value.startswith("="): formula = value[1:] if not formula: NSBeep() return value = calculateFormula(self.glyph, formula, attr) if value is None: NSBeep() return field.set(str(roundint(value))) setFormula(self.glyph, attr, formula) else: try: value = int(value) except: NSBeep() return self.glyph.prepareUndo("Spacing Change") setMetricValue(self.glyph, attr, value) self.glyph.performUndo() self._updateFields() self._updateButtons() def buttonCallback(self, sender): group = self._getControlGroup(sender) attr = group["attr"] field = group["field"] button = group["button"] kill = group["kill"] if sender == kill: clearFormula(self.glyph, attr) else: formula = button.getTitle() value = calculateFormula(self.glyph, formula, attr) if value is None: NSBeep() return self.glyph.prepareUndo("Spacing Change") setMetricValue(self.glyph, attr, value) self.glyph.performUndo() self._updateFields() self._updateButtons() def previousGlyphCallback(self, sender): CurrentGlyphWindow().getGlyphView().previousGlyph_() self.loadGlyph() def nextGlyphCallback(self, sender): CurrentGlyphWindow().getGlyphView().nextGlyph_() self.loadGlyph()
def __init__(self): ## Preference Files self.lastScriptFile = os.path.join( "/".join(os.path.realpath(__file__).split("/")[:-1]), "lastscript.ini") self.preferencesFile = os.path.join( "/".join(os.path.realpath(__file__).split("/")[:-1]), "preferences.ini") ## Preference Defaults self.scriptsDirectory = os.path.join( os.getenv("HOME"), "Library/Application Support/RoboFont/scripts") self.extensionsDirectory = os.path.join( os.getenv("HOME"), "Library/Application Support/RoboFont/plugins") self.rememberLast = 1 self.searchLocal = False self.searchUpDir = 3 # Storage self.scripts = {"preferences": ""} # scriptName : scriptPath ## Window width = 500 height = 200 screen = NSScreen.mainScreen() screenRect = screen.frame() (screenX, screenY), (screenW, screenH) = screenRect screenY = -(screenY + screenH) # convert to vanilla coordinate system x = screenX + ((screenW - width) / 2) y = screenY + ((screenH - height) / 2) self.w = StatusInteractivePopUpWindow((x, y, width, height), screen=screen) self.w.search_box = vanilla.EditText((10, 10, -10, 21), "", callback=self.searchScripts) """using EditText because SearchBox overrides tab and Enter buttons""" self.w.list = vanilla.List((10, 40, -10, -30), "", allowsMultipleSelection=0, doubleClickCallback=self.runScript) self.w.ok_button = vanilla.Button((10, -25, -10, 20), "Run Script", callback=self.runScript) # off Window self.w.closeWindow_button = vanilla.Button((10, 300, -10, 20), "Close Window", callback=self.closeWindow) self.w.prev_button = vanilla.Button((10, 300, -10, 20), "up", callback=self.previousScript) self.w.next_button = vanilla.Button((10, 300, -10, 20), "down", callback=self.nextScript) self.w.scriptingWindow_button = vanilla.Button( (10, 300, -10, 20), "Open in ScriptingWindow", callback=self.openScriptInScriptingWindow) # Preferences Drawer self.d = vanilla.Drawer((100, 160), self.w, preferredEdge="bottom") self.w.togglePreferencesDrawer_button = vanilla.Button( (10, 300, -10, 20), "Preferences", callback=self.togglePreferencesDrawer) self.d.title = vanilla.TextBox((10, 5, -10, 20), "Preferences") self.d.scripts_button = vanilla.Button( (10, 30, 100, 20), "Scripts", callback=self.preferencesChanged) self.d.scripts_path = vanilla.TextBox( (120, 30, -1, 20), "default: ~/Library/Application Support/RoboFont/scripts") self.d.extensions_button = vanilla.Button( (10, 60, 100, 20), "Extensions", callback=self.preferencesChanged) self.d.extensions_path = vanilla.TextBox( (120, 60, -10, 20), "default: ~/Library/Application Support/RoboFont/plugins") self.d.local_search_checkbox = vanilla.CheckBox( (10, 95, 240, 20), "Search near open fonts for scripts", value=self.searchLocal, callback=self.preferencesChanged) self.d.local_search_title = vanilla.TextBox((250, 96, 120, 20), "Search up:") self.d.local_search_count = vanilla.PopUpButton( (320, 95, 40, 22), ["0", "1", "2", "3", "4", "5", "6", "7"], callback=self.preferencesChanged) self.d.local_search_title2 = vanilla.TextBox((365, 96, -10, 20), "directories") self.d.remember_title = vanilla.TextBox((10, 130, 120, 20), "Remember Last:") self.d.remember_count = vanilla.PopUpButton( (120, 128, 40, 22), [ "0", "1", "2", "3", "4", "5", ], callback=self.preferencesChanged) self.d.remember_title2 = vanilla.TextBox((170, 130, -10, 20), "scripts") self.readPreferences() self.lastScriptRead() # Bindings self.w.prev_button.bind("uparrow", []) self.w.next_button.bind("downarrow", []) self.w.setDefaultButton(self.w.ok_button) self.w.closeWindow_button.bind(chr(27), []) # esc self.w.togglePreferencesDrawer_button.bind(',', ['command', 'option']) self.w.scriptingWindow_button.bind( 'o', ['command', 'option']) # can we bind option+enter? self.w.getNSWindow().makeFirstResponder_( self.w.search_box.getNSTextField()) self.w.open()
class scriptLauncher(object): def __init__(self): ## Preference Files self.lastScriptFile = os.path.join( "/".join(os.path.realpath(__file__).split("/")[:-1]), "lastscript.ini") self.preferencesFile = os.path.join( "/".join(os.path.realpath(__file__).split("/")[:-1]), "preferences.ini") ## Preference Defaults self.scriptsDirectory = os.path.join( os.getenv("HOME"), "Library/Application Support/RoboFont/scripts") self.extensionsDirectory = os.path.join( os.getenv("HOME"), "Library/Application Support/RoboFont/plugins") self.rememberLast = 1 self.searchLocal = False self.searchUpDir = 3 # Storage self.scripts = {"preferences": ""} # scriptName : scriptPath ## Window width = 500 height = 200 screen = NSScreen.mainScreen() screenRect = screen.frame() (screenX, screenY), (screenW, screenH) = screenRect screenY = -(screenY + screenH) # convert to vanilla coordinate system x = screenX + ((screenW - width) / 2) y = screenY + ((screenH - height) / 2) self.w = StatusInteractivePopUpWindow((x, y, width, height), screen=screen) self.w.search_box = vanilla.EditText((10, 10, -10, 21), "", callback=self.searchScripts) """using EditText because SearchBox overrides tab and Enter buttons""" self.w.list = vanilla.List((10, 40, -10, -30), "", allowsMultipleSelection=0, doubleClickCallback=self.runScript) self.w.ok_button = vanilla.Button((10, -25, -10, 20), "Run Script", callback=self.runScript) # off Window self.w.closeWindow_button = vanilla.Button((10, 300, -10, 20), "Close Window", callback=self.closeWindow) self.w.prev_button = vanilla.Button((10, 300, -10, 20), "up", callback=self.previousScript) self.w.next_button = vanilla.Button((10, 300, -10, 20), "down", callback=self.nextScript) self.w.scriptingWindow_button = vanilla.Button( (10, 300, -10, 20), "Open in ScriptingWindow", callback=self.openScriptInScriptingWindow) # Preferences Drawer self.d = vanilla.Drawer((100, 160), self.w, preferredEdge="bottom") self.w.togglePreferencesDrawer_button = vanilla.Button( (10, 300, -10, 20), "Preferences", callback=self.togglePreferencesDrawer) self.d.title = vanilla.TextBox((10, 5, -10, 20), "Preferences") self.d.scripts_button = vanilla.Button( (10, 30, 100, 20), "Scripts", callback=self.preferencesChanged) self.d.scripts_path = vanilla.TextBox( (120, 30, -1, 20), "default: ~/Library/Application Support/RoboFont/scripts") self.d.extensions_button = vanilla.Button( (10, 60, 100, 20), "Extensions", callback=self.preferencesChanged) self.d.extensions_path = vanilla.TextBox( (120, 60, -10, 20), "default: ~/Library/Application Support/RoboFont/plugins") self.d.local_search_checkbox = vanilla.CheckBox( (10, 95, 240, 20), "Search near open fonts for scripts", value=self.searchLocal, callback=self.preferencesChanged) self.d.local_search_title = vanilla.TextBox((250, 96, 120, 20), "Search up:") self.d.local_search_count = vanilla.PopUpButton( (320, 95, 40, 22), ["0", "1", "2", "3", "4", "5", "6", "7"], callback=self.preferencesChanged) self.d.local_search_title2 = vanilla.TextBox((365, 96, -10, 20), "directories") self.d.remember_title = vanilla.TextBox((10, 130, 120, 20), "Remember Last:") self.d.remember_count = vanilla.PopUpButton( (120, 128, 40, 22), [ "0", "1", "2", "3", "4", "5", ], callback=self.preferencesChanged) self.d.remember_title2 = vanilla.TextBox((170, 130, -10, 20), "scripts") self.readPreferences() self.lastScriptRead() # Bindings self.w.prev_button.bind("uparrow", []) self.w.next_button.bind("downarrow", []) self.w.setDefaultButton(self.w.ok_button) self.w.closeWindow_button.bind(chr(27), []) # esc self.w.togglePreferencesDrawer_button.bind(',', ['command', 'option']) self.w.scriptingWindow_button.bind( 'o', ['command', 'option']) # can we bind option+enter? self.w.getNSWindow().makeFirstResponder_( self.w.search_box.getNSTextField()) self.w.open() # # # # # # # # # PREFERENCES # # # # # # # # def togglePreferencesDrawer(self, sender): self.d.toggle() def readPreferences(self): # Read the preferences file which contains custom paths (scripts/extensions) and other preferential stuff. if os.path.exists(self.preferencesFile): config = configparser.ConfigParser() config.read(self.preferencesFile) if "scriptsDir" in config["PATHS"]: self.scriptsDirectory = [config["PATHS"]["scriptsDir"]][0] self.d.scripts_path.set(self.scriptsDirectory) else: self.d.scripts_path.set("default") if "extensionsDir" in config["PATHS"]: self.extensionsDirectory = [config["PATHS"]["extensionsDir"] ][0] self.d.extensions_path.set(self.extensionsDirectory) else: self.d.extensions_path.set("default") if "rememberLast" in config["REMEMBER"]: self.rememberLast = int([config["REMEMBER"]["rememberLast"] ][0]) self.d.remember_count.set(self.rememberLast) if "value" in config["SEARCHLOCAL"]: self.searchLocal = int([config["SEARCHLOCAL"]["value"]][0]) self.d.local_search_checkbox.set(self.searchLocal) if "searchUpDir" in config["SEARCHLOCAL"]: self.searchUpDir = int([config["SEARCHLOCAL"]["searchUpDir"] ][0]) self.d.local_search_count.set(self.searchUpDir) self.searchAll("sender") def preferencesChanged(self, sender): if sender.getTitle() == "Extensions": newPath = GetFolder() if newPath != None: self.extensionsDirectory = newPath self.d.extensions_path = newPath self.searchExtensionsDirectory(newPath) elif sender.getTitle() == "Scripts": newPath = GetFolder() if newPath != None: self.scriptsDirectory = newPath self.d.scripts_path = newPath self.searchScriptsDirectory(newPath) self.rememberLast = self.d.remember_count.get() self.searchLocal = self.d.local_search_checkbox.get() self.searchUpDir = self.d.local_search_count.get() self.writePreferences(sender) self.searchAll(sender) def writePreferences(self, sender): # Gets preferences from window and writes to file config = configparser.ConfigParser() config.read(self.preferencesFile) if self.d.extensions_path.get() != "default": config['PATHS']["extensionsDir"] = self.d.extensions_path.get() if self.d.scripts_path.get() != "default": config['PATHS']["scriptsDir"] = self.d.scripts_path.get() config['REMEMBER'] = {"rememberLast": self.d.remember_count.get()} config['SEARCHLOCAL'] = { "value": self.d.local_search_checkbox.get(), "searchUpDir": self.d.local_search_count.get(), } with open(self.preferencesFile, 'w') as configfile: config.write(configfile) # LAST SCRIPT # Read/Write remembers the last script that was run so it can be quickly re-run def lastScriptCreate(self): if not os.path.exists(self.lastScriptFile): config = configparser.ConfigParser() config["DEFAULT"]["lastFiles"] = "" with open(self.lastScriptFile, 'w') as configfile: config.write(configfile) def lastScriptRead(self): if os.path.exists(self.lastScriptFile): config = configparser.ConfigParser() config.read(self.lastScriptFile) l = config["DEFAULT"]["lastFiles"] l = l.split(",") self.w.list.set(l) self.w.list.setSelection([0]) else: self.lastScriptCreate() def lastScriptWrite(self, sender, file): if file != None: config = configparser.ConfigParser() config.read(self.lastScriptFile) l = config["DEFAULT"]["lastFiles"] l = l.split(",") if file.split("/")[-1] in l: l.remove(file.split("/")[-1]) l.insert(0, file.split("/")[-1]) l = l[:self.rememberLast] config["DEFAULT"]["lastFiles"] = ",".join(l) with open(self.lastScriptFile, 'w') as configfile: config.write(configfile) # # # # # # # # # FUNCTIONS # # # # # # # # def searchAll(self, sender): self.scripts = {"preferences": ""} # tabula rasa if self.searchLocal == True: self.searchNearFont(self.searchUpDir) self.searchExtensionsDirectory(self.extensionsDirectory) self.searchScriptsDirectory(self.scriptsDirectory) def searchNearFont(self, searchUpDirectories): fontDirectories = [] if len(AllFonts()) > 0: for font in AllFonts(): if font.path not in fontDirectories: fontDirectories.append(font.path) s = self.scripts for fontDirectory in fontDirectories: fontDirectoryUp = "/".join( fontDirectory.split("/")[:-(searchUpDirectories)]) for dir, subdir, files in os.walk(fontDirectoryUp): for file in files: if ".py" in file: if ".pyc" not in file: if file not in s: s[file] = os.path.join(dir, file) else: if s[file] != os.path.join( dir, file): # avoid duplicate paths # add number to scripts with idential file names count = 1 fileCount = "%s (%s).py" % ( file.split(".")[0], count) while fileCount in s: count += 1 fileCount = "%s (%s).py" % ( file.split(".")[0], count) s[fileCount] = os.path.join(dir, file) def searchScriptsDirectory(self, scriptsDirectory): if not os.path.exists(scriptsDirectory): print("scripts folder not found: %s" % (scriptsDirectory)) else: s = self.scripts for dir, subdir, files in os.walk(scriptsDirectory): for file in files: if ".py" in file: if ".pyc" not in file: if file not in s: s[file] = os.path.join(dir, file) else: if s[file] != os.path.join(dir, file): # add number to scripts with idential file names count = 1 fileCount = "%s (%s).py" % ( file.split(".")[0], count) while fileCount in s: count += 1 fileCount = "%s (%s).py" % ( file.split(".")[0], count) s[fileCount] = os.path.join(dir, file) def searchExtensionsDirectory(self, extensionsDirectory): if not os.path.exists(extensionsDirectory): print("extensions folder not found: %s" % (extensionsDirectory)) else: s = self.scripts for ext in os.listdir(extensionsDirectory): if ".roboFontExt" in ext: if os.path.exists( os.path.join(extensionsDirectory, ext, "info.plist")): with open( os.path.join(extensionsDirectory, ext, "info.plist"), 'rb') as f: pl = plistlib.load(f) if pl["launchAtStartUp"] == 0: # not launched at startup for i in pl["addToMenu"]: extName = i["preferredName"] extPath = i["path"] extFullPath = os.path.join( extensionsDirectory, ext, "lib", extPath) if not os.path.exists(extFullPath): print("%s missing path: %s" % (extName, extFullPath)) else: s[extName] = extFullPath # # # # # # # # # # # # # # # Searching/Finding/Running # # # # # # # # # # # # # # def previousScript(self, sender): if len(self.w.list) > 1: if self.w.list.getSelection() == []: self.w.list.setSelection([0]) else: i = self.w.list.getSelection()[0] if i > 0: self.w.list.setSelection([i - 1]) else: self.w.list.setSelection([len(self.w.list.get()) - 1]) def nextScript(self, sedner): if len(self.w.list) > 1: if self.w.list.getSelection() == []: self.w.list.setSelection([0]) else: i = self.w.list.getSelection()[0] if i + 1 < len(self.w.list.get()): self.w.list.setSelection([i + 1]) else: self.w.list.setSelection([0]) def searchScripts(self, sender): i = sender.get() sub_list = [] for s in self.scripts: if i.lower().replace(" ", "") in s.lower().replace(" ", ""): sub_list.append(s) sub_list.sort() self.w.list.set(sub_list) self.w.list.setSelection([0]) def executeScript(self, file, sender): with open(file) as f: try: code = compile(f.read(), file, 'exec') exec(code, globals()) except Exception as e: print("Error. Script will not run. %s" % (e)) self.lastScriptWrite(sender, file) def runScript(self, sender): if self.w.list.getSelection(): if self.w.list.get()[self.w.list.getSelection() [0]] == "preferences": self.togglePreferencesDrawer(sender) else: self.closeWindow(sender) script_file = self.w.list.get()[self.w.list.getSelection()[0]] script_path = self.scripts[script_file] if not os.path.exists(script_path): print("script not found at path:", script_path) else: self.executeScript(script_path, sender) def openScriptInScriptingWindow(self, sender): if self.w.list.getSelection(): if self.w.list.get()[self.w.list.getSelection() [0]] != "preferences": self.closeWindow(sender) script_file = self.w.list.get()[self.w.list.getSelection()[0]] script_path = self.scripts[script_file] if not os.path.exists(script_path): print("script not found at path:", script_path) else: OpenScriptWindow(script_path) def closeWindow(self, sender): self.w.close()