def _callback_goto_glyph(self, sender=None): newGlyphName = sender.get()[sender.getSelection()[0]]["Name"] if CurrentGlyphWindow(): CurrentGlyphWindow().setGlyphByName(newGlyphName) else: # TODO: open glyph window? pass
def setDarkMode(w, darkMode): if darkMode: appearance = NSAppearance.appearanceNamed_('NSAppearanceNameVibrantDark') if hasattr(w, "accordionView"): w.accordionView.setBackgroundColor(NSColor.colorWithCalibratedRed_green_blue_alpha_(.08, .08, .08, 1)) else: appearance = NSAppearance.appearanceNamed_('NSAppearanceNameAqua') if hasattr(w, "accordionView"): w.accordionView.setBackgroundColor(NSColor.colorWithCalibratedRed_green_blue_alpha_(1, 1, 1, 1)) w.getNSWindow().setAppearance_(appearance) if CurrentGlyphWindow(): CurrentGlyphWindow().window().getNSWindow().setAppearance_(appearance)
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 glyphWindowWillClose(self, notification): start = time.time() self.roboCJKView.setglyphState(self.currentGlyph) self.openedGlyphName = "" if self.glyphInspectorWindow is not None: self.glyphInspectorWindow.closeWindow() self.glyphInspectorWindow = None try: posSize = CurrentGlyphWindow().window().getPosSize() setExtensionDefault(blackrobocjk_glyphwindowPosition, posSize) self.glyphWindowPosSize = getExtensionDefault( blackrobocjk_glyphwindowPosition) except: pass if self.currentGlyph.type != "atomicElement": self.window.removeGlyphEditorSubview(self.glyphView) self.drawer.refGlyph = None self.drawer.refGlyphPos = [0, 0] self.drawer.refGlyphScale = [1, 1] self.currentFont.fontLib.update(self.currentFont._RFont.lib.asDict()) self.currentFont._fullRFont.lib.update(self.currentFont._RFont.lib) if not self.mysql: self.currentFont.save() if self.currentGlyph is not None: self.currentFont.getGlyph(self.currentGlyph) self.currentFont.clearRFont() else: self.currentFont.saveGlyph(self.currentGlyph) self.currentFont.saveFontlib() self.currentFont.batchUnlockGlyphs([self.currentGlyph.name]) stop = time.time() print(stop - start, "to close %s" % self.currentGlyph.name)
def update(self): self.glyph_window = CurrentGlyphWindow() if self.glyph_window is not None: self.glyph = CurrentGlyph() self.font = self.glyph.getParent() self.glyph_index = self.font.glyphOrder.index(self.glyph.name) self.font_index = self.all_fonts.index(self.font) self._update_text_box() return True else: f = CurrentFont() if f is not None: self.font = f self.font_index = self.all_fonts.index(self.font) glyph_names = get_glyphs(f) if len(glyph_names) > 0: self.glyph = self.font[glyph_names[0]] self.glyph_index = self.font.glyphOrder.index( self.glyph.name) self.glyph_window = OpenGlyphWindow(self.glyph, newWindow=False) self._update_text_box() return True else: print(no_glyph_selected) return False else: print(no_font_open) return False
def layer_up(self): try: self.glyph_window.layerUp() except AttributeError: self.glyph_window = CurrentGlyphWindow() self.glyph_window.layerUp() self.update()
def __init__(self): glyphWindow = getActiveGlyphWindow() if glyphWindow is None: return self.w = ActionWindow((1, 1), centerInView=CurrentGlyphWindow().getGlyphView()) self.w.responderWillBecomeFirstCallback = self.responderWillBecomeFirstCallback # There is probably a better way to set # the escape key to close the window but # I am lazy so I'm using a hidden button. self.w._closeButton = vanilla.ImageButton( (0, 0, 0, 0), bordered=False, callback=self._closeButtonCallback) self.w._closeButton.bind("\u001B", []) # Build the interface self.metrics = dict( margin=15, iconPadding=5, iconButtonWidth=30, iconButtonHeight=30, groupPadding=15, ) rules = self.buildInterface(self.w) if rules is not None: self.w.addAutoPosSizeRules(rules, self.metrics) # Bind close. self.w.bind("close", self.windowCloseCallback) # Go self.w.open()
def getGlyphs(self): glyphs = [] # font window selection if self.w.selectedGlyphs.get(): font = CurrentFont() if font is not None: glyphs += font.selectedGlyphs # current glyph window if self.w.currentGlyph.get(): glyphWindow = CurrentGlyphWindow() if glyphWindow is not None: g = glyphWindow.getGlyph() if g is not None and g not in glyphs: glyphs += [RGlyph(g)] # space center selection if self.w.spaceCenter.get(): spaceCenter = CurrentSpaceCenter(currentFontOnly=True) if spaceCenter is not None: g = spaceCenter.glyphLineView.getSelected() if g is not None and g not in glyphs: glyphs += [RGlyph(g)] return glyphs
def previous_glyph(self): prev = previous_glyph(self.font, self.glyph_index) try: self.glyph_window.setGlyphByName(prev) except AttributeError: self.glyph_window = CurrentGlyphWindow() self.glyph_window.setGlyphByName(prev) self.update()
def next_glyph(self): next = next_glyph(self.font, self.glyph_index) try: self.glyph_window.setGlyphByName(next) except AttributeError: self.glyph_window = CurrentGlyphWindow() self.glyph_window.setGlyphByName(next) self.update()
def show_dist_textbox(self, info): window = CurrentGlyphWindow() view = window.getGlyphView() vanillaView = ShowDistTextBox(view, (20, 22, 120, 22), "", alignment="left", sizeStyle="mini") window.addGlyphEditorSubview(vanillaView)
def _glyphset_List_doubleClickCallback(self, sender): sel = sender.getSelection() if not sel: return if self.ui.glyph is None: return OpenGlyphWindow(self.ui.glyph) gw = CurrentGlyphWindow() appearance = NSAppearance.appearanceNamed_( 'NSAppearanceNameVibrantDark') gw.window().getNSWindow().setAppearance_(appearance)
def mouseDown(self, info): if info["clickCount"] == 2: if not self.currentGlyph == None: mouseLoc = (info["point"].x, info["point"].y) if not self.previousGlyph == None: # There's a previous glyph being drawn, check to see if the double click is in its bouds if self.inBounds(mouseLoc, self.previousGlyph.bounds, self.currentGlyph.width): cgw = CurrentGlyphWindow() cgw.setGlyphByName(self.previousGlyph.name) else: # Check the components for c in self.currentGlyph.components: if c.selected: # First click should select it if self.inBounds(mouseLoc, c.bounds): self.didSwitch = True cgw = CurrentGlyphWindow() cgw.setGlyphByName(c.baseGlyph)
def getWindowPostition(self): # Code from Tal # https://forum.robofont.com/topic/573/automatic-statusinteractivepopupwindow-positioning if not CurrentGlyphWindow(): return nsWindow = CurrentGlyphWindow().w.getNSWindow() scrollView = CurrentGlyphWindow().getGlyphView().enclosingScrollView() rectInWindowCoords = scrollView.convertRect_toView_(scrollView.frame(), None) rectInScreenCoords = nsWindow.convertRectToScreen_(rectInWindowCoords) (x, y), (w, h) = rectInScreenCoords y = -(y + h) if getGlyphViewDisplaySettings()['Rulers']: offset = 30 else: offset = 10 return x + offset, y + offset
def getActiveGlyphWindow(): window = CurrentGlyphWindow() # there is no glyph window if window is None: return None # the editor is not the first responder if not window.getGlyphView().isFirstResponder(): return None return window
def glyphChanged(self, info): # Reset the glyph info self.glyph0.clear() self.glyph1.clear() self.compatibilityReport = None self.window = CurrentGlyphWindow() self.interpolatedGlyph.clear() # Remove any observers on the older CurrentGLyph and add them to the new one if self.currentGlyph: self.currentGlyph.removeObserver(self, "Glyph.Changed") self.currentGlyph.removeObserver(self, "Glyph.ContoursChanged") self.currentGlyph = CurrentGlyph() if self.currentGlyph: self.currentGlyph.addObserver(self, "optionsChanged", "Glyph.Changed") self.currentGlyph.addObserver(self, "optionsChanged", "Glyph.ContoursChanged") if not self.currentGlyph == None: # Update the glyph info glyphName = self.currentGlyph.name master0idx = self.w.font0.get() master1idx = self.w.font1.get() master0 = self.fonts[master0idx] master1 = self.fonts[master1idx] if glyphName in master0: self.glyph0.clear() pen = DecomposingPen(master0, self.glyph0.getPen()) master0[glyphName].draw(pen) if glyphName in master1: self.glyph1.clear() pen = DecomposingPen(master1, self.glyph1.getPen()) master1[glyphName].draw(pen) # Update the interp compatibility report self.testCompatibility() # Adjust the frame of the window to fit the interpolation # (Thanks Frederik!) if self.window: widths = [] if self.glyph0: widths.append(self.glyph0.width) if self.glyph1: widths.append(self.glyph1.width) if len(widths): widths.sort() view = self.window.getGlyphView() scale = view.scale() (x, y), (w, h) = view.frame() ox, oy = view.offset() extraWidth = widths[-1] * scale view.setOffset((ox, oy)) view.setFrame_(((x, y), (w + extraWidth, h))) # Update the view self.optionsChanged(None)
def drawPoints(self, info): newPoints = self.getValues(None) if newPoints != None: glyph = CurrentGlyph() onCurveSize = getDefault("glyphViewOncurvePointsSize") * 5 offCurveSize = getDefault("glyphViewOncurvePointsSize") * 3 fillColor = tuple([i for i in getDefault("glyphViewCurvePointsFill")]) upmScale = (glyph.font.info.unitsPerEm/1000) scale = info["scale"] oPtSize = onCurveSize * scale fPtSize = offCurveSize * scale d.save() # thanks Erik! textLoc = newPoints[0][3][0] + math.cos(self.returnAngle(newPoints)) * (scale*.25*120) * 2, newPoints[0][3][1] + math.sin(self.returnAngle(newPoints)) * (scale*.25*120) * 2 for b in newPoints: for a in b: if a == newPoints[1][0] or a == newPoints[0][-1]: d.oval(a[0]-oPtSize/2,a[1]-oPtSize/2, oPtSize, oPtSize) else: d.oval(a[0]-fPtSize/2,a[1]-fPtSize/2, fPtSize, fPtSize) d.fill(fillColor[0],fillColor[1],fillColor[2],fillColor[3]) d.stroke(fillColor[0],fillColor[1],fillColor[2],fillColor[3]) d.strokeWidth(scale) d.line(newPoints[0][2],newPoints[1][1]) d.restore() # https://robofont.com/documentation/building-tools/toolspace/observers/draw-info-text-in-glyph-view/?highlight=draw%20text glyphWindow = CurrentGlyphWindow() if not glyphWindow: return glyphView = glyphWindow.getGlyphView() textAttributes = { AppKit.NSFontAttributeName: AppKit.NSFont.userFixedPitchFontOfSize_(11), } glyphView.drawTextAtPoint( f'{round(abs(math.degrees(self.returnAngle(newPoints)))%180,4)}°\n{str(round(self.returnRatio(newPoints),4))}', textAttributes, textLoc, yOffset=0, drawBackground=True, centerX=True, centerY=True, roundBackground=False,) UpdateCurrentGlyphView()
def getImageForView(self, viewName): if viewName == "Glyph View": window = CurrentGlyphWindow() if window is None: return None view = window.getGlyphView().enclosingScrollView() elif viewName == "Space Center": window = CurrentSpaceCenter() if window is None: return None view = window.glyphLineView.getNSScrollView() data = self._getImageForView(view) data = data.bytes() if isinstance(data, memoryview): data = data.tobytes() return data
def setInFontCallback(self, sender): if self.w.fontSelection.get() == 0: if CurrentFont() is not None: fonts = [CurrentFont()] else: fonts = [] else: fonts = AllFonts() for f in fonts: with f.undo('italicBowtie'): f.info.italicAngle = self.getItalicAngle() f.lib[self.italicSlantOffsetKey] = self.getItalicSlantOffset() try: window = CurrentGlyphWindow() window.setGlyph(CurrentGlyph().naked()) except Exception: print(self.DEFAULTKEY, 'error resetting window, please refresh it') self.updateBowtie()
def setInFontCallback(self, sender): view = self.getView() if view.fontSelection.get() == 0: if CurrentFont() is not None: fonts = [CurrentFont()] else: fonts = [] else: fonts = AllFonts() for f in fonts: f.prepareUndo() f.info.italicAngle = self.getItalicAngle() f.lib[self.italicSlantOffsetKey] = self.getItalicSlantOffset() f.performUndo() try: window = CurrentGlyphWindow() window.setGlyph(CurrentGlyph().naked()) except: print(self.DEFAULTKEY, 'error resetting window, please refresh it') self.updateView()
def applyCallback(self, sender): self._holdGlyphUpdates = True font = CurrentFont() attrValues = self.getAttributes() selection = [] if CurrentGlyphWindow(): selection = [CurrentGlyph().name] else: selection = font.selectedGlyphNames for name in selection: glyph = font[name] glyph.prepareUndo("Shifter") outGlyph = self.getGlyph(glyph, *attrValues) glyph.clear() glyph.appendGlyph(outGlyph) glyph.performUndo() self._holdGlyphUpdates = False
def gotoselectedDC(self, sender): g = self.currentGlyph selectedDCName = g._deepComponents[g.selectedElement[0]].name CurrentGlyphWindow().close() self.currentGlyph = self.currentFont[selectedDCName] roboCJKView.openGlyphWindowIfLockAcquired(self, self.currentGlyph)
def wwwindow(self): return CurrentGlyphWindow()
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 updateComp(self, g, viewScale): if len(g.selectedComponents) == 1: cf = g.font cg = g selected_component = cg.selectedComponents[0] selected_component_name = cg.selectedComponents[0].baseGlyph constructions = self.constructions glyph_constructor = self.glyph_constructor glyphWindow = CurrentGlyphWindow() glyphView = glyphWindow.getGlyphView() if not glyphWindow: return for line in glyph_constructor.split("\n"): if len(line) > 0: composed_glyph = line.split("=")[0] recipee = line.split("=")[1] new_base_glyph = recipee.split("+")[0] if new_base_glyph == cg.components[ 0].baseGlyph and cg.name == composed_glyph: construction = f"{composed_glyph}={recipee}" constructionGlyph = GlyphConstructionBuilder( construction, cf) if constructionGlyph.name == cg.name: for component_index, c in enumerate( constructionGlyph.components): c = list(c)[0] if c == selected_component_name: baseGlyphName = constructionGlyph.components[ component_index - 1][0] baseGlyph = cf[baseGlyphName] recipee = construction.split("=")[1] for diacritic_and_anchor in recipee.split( "+")[1:]: diacritic = diacritic_and_anchor.split( "@")[0] anchor = diacritic_and_anchor.split( "@")[1] if diacritic == selected_component_name: selected_component_anchor_name = "_%s" % anchor for baseGlyph_anchor in baseGlyph.anchors: if baseGlyph_anchor.name == anchor: x_baseGlyph_anchor = baseGlyph_anchor.x y_baseGlyph_anchor = baseGlyph_anchor.y selected_comp_baseGlyph = cf[ selected_component_name] for selectedComponent_anchor in selected_comp_baseGlyph.anchors: if selected_component_anchor_name == selectedComponent_anchor.name: x_offset = 0 y_offset = 0 for previous_components in constructionGlyph.components[ 1: component_index]: for cg_component in cg.components: if cg_component.baseGlyph == previous_components[ 0]: x_offset += cg_component.offset[ 0] y_offset += cg_component.offset[ 1] new_x_baseGlyph_anchor = selectedComponent_anchor.x + selected_component.offset[ 0] - x_offset new_y_baseGlyph_anchor = selectedComponent_anchor.y + selected_component.offset[ 1] - y_offset self.drawInfos( new_x_baseGlyph_anchor, new_y_baseGlyph_anchor, viewScale, glyphView, baseGlyph_anchor ) ### Update baseGlyph anchor baseGlyph_anchor.x = new_x_baseGlyph_anchor baseGlyph_anchor.y = new_y_baseGlyph_anchor if self.SettingsWindow.w.updateComposites.get( ) == 1: self.updateRelatedComposites( glyph_constructor, cg, cf, new_base_glyph, baseGlyph_anchor, composed_glyph )
def mouseDownCB(self, point): if point['clickCount'] == 2: if self.isCursorAbove: CurrentGlyphWindow().setGlyphByName(self.glyphBelowName)
def updateSelfWindow(self, notification): self.window = CurrentGlyphWindow() self.buildMatchBase() self.updateValues()
def gotoGlyph(self, sender=None, glyph=None): newGlyphName = sender.get()[sender.getSelection()[0]]["Name"] #print("Goto Glyph:", newGlyphName) CurrentGlyphWindow().setGlyphByName(newGlyphName)
self = super(PasteGlyphComboBoxDataSource, self).init() self._glyphNames = [] return self def setGlyphNames_(self, names): self._glyphNames = names def comboBox_completedString_(self, comboBox, text): if text in self._glyphNames: return text for name in self._glyphNames: if name.startswith(text): return name return text def comboBox_indexOfItemWithStringValue_(self, comboBox, text): if text not in self._glyphNames: return -1 return self._glyphNames.index(text) def comboBox_objectValueForItemAtIndex_(self, comboBox, index): return self._glyphNames[index] def numberOfItemsInComboBox_(self, comboBox): return len(self._glyphNames) if __name__ == "__main__": from mojo.UI import CurrentGlyphWindow glyphWindow = CurrentGlyphWindow() PasteGlyphWindowController(glyphWindow)
def addSubView(self): self.window = CurrentGlyphWindow() if self.window is None: return self.glyphView.show(True) self.window.addGlyphEditorSubview(self.glyphView) self.glyphView.setSelectedSource()