Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 def controlChanged(self, info):
     
     # Make sure the RoboControlInput notificaiton is for the desired control name:
     if info["name"] == self.controlName:
         
         # Figure out some info about the current glyph, and current glyph window
         glyph = CurrentGlyph()
         font = CurrentFont()
         glyphOrder = []
         if font:
             glyphOrder = font.lib["public.glyphOrder"]
         
         # If there's a glyph window open:
         w = CurrentGlyphWindow()
         if w:
             # Find this glyph's index in the glyphOrder
             thisGlyphIndex = glyphOrder.index(glyph.name)
             prevGlyphIndex = thisGlyphIndex - 1
             nextGlyphIndex = thisGlyphIndex + 1
             if nextGlyphIndex == len(glyphOrder):
                 nextGlyphIndex = 0
             elif prevGlyphIndex < 0:
                 prevGlyphIndex = len(glyphOrder) - 1
             # Then, find the previous/next glyph names
             prevGlyphName = glyphOrder[prevGlyphIndex]
             nextGlyphName = glyphOrder[nextGlyphIndex]
             
             # Now that we know something about the current glyph and its neighbors:
             if info["value"] == "cw":
                 # Move clockwise, next glypyh
                 w.setGlyphByName(nextGlyphName)
             elif info["value"] == "ccw":
                 # Counter-clockwise, prev glyph
                 w.setGlyphByName(prevGlyphName)
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 8
0
 def controlChanged(self, info):
     
     # Check that the control that changed has the name were looking for:
     if info["name"] == self.controlName:
         
         # If there's a glyph window open
         w = CurrentGlyphWindow()
         if w:
             # Set the zoom scale of the window.
             # Scale the incoming "value" of the control to somewhere between 0.15% and 3000%
             scale = (info["value"] * 30) + 0.15
             w.setGlyphViewScale(scale)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
    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()
Ejemplo n.º 11
0
 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
Ejemplo n.º 12
0
 def layer_up(self):
     try:
         self.glyph_window.layerUp()
     except AttributeError:
         self.glyph_window = CurrentGlyphWindow()
         self.glyph_window.layerUp()
     self.update()
Ejemplo n.º 13
0
 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()
Ejemplo n.º 14
0
    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()
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
 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()
Ejemplo n.º 17
0
 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()
Ejemplo n.º 18
0
 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 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
Ejemplo n.º 20
0
 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()
Ejemplo n.º 21
0
 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()
Ejemplo n.º 22
0
 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()
Ejemplo n.º 23
0
 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)
Ejemplo n.º 24
0
    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
Ejemplo n.º 25
0
    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
Ejemplo n.º 26
0
 def addSubView(self):
     self.window = CurrentGlyphWindow()
     if self.window is None: return
     self.glyphView.show(True)
     self.window.addGlyphEditorSubview(self.glyphView)
     self.glyphView.setSelectedSource()
Ejemplo n.º 27
0
    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
                                                                )
class InterpolationPreviewWindow(object):
    def __init__(self):

        self.currentGlyph = None
        self.window = None

        self.fonts = []
        self.fontNames = []

        self.glyph0 = RGlyph()  #None
        self.glyph1 = RGlyph()  #None
        self.compatibilityReport = None
        self.interpolatedGlyph = RGlyph()

        self.w = vanilla.FloatingWindow((250, 155), "Interpolation Slider")
        self.w.open()
        self.w.title = vanilla.TextBox((10, 10, -10, 25),
                                       "Masters:",
                                       sizeStyle="small")
        self.w.font0 = vanilla.PopUpButton((10, 25, -10, 25), [],
                                           callback=self.glyphChanged,
                                           sizeStyle="small")
        self.w.font1 = vanilla.PopUpButton((10, 50, -10, 25), [],
                                           callback=self.glyphChanged,
                                           sizeStyle="small")
        self.w.compatibilityText = vanilla.TextBox((-105, 83, 100, 35),
                                                   u"Compatibility: ⚪️",
                                                   sizeStyle="small")
        self.w.line = vanilla.HorizontalLine((5, 110, -5, 1))
        self.w.interpValue = vanilla.Slider((10, 120, -10, 25),
                                            callback=self.optionsChanged,
                                            minValue=0,
                                            maxValue=1)
        self.w.interpValue.set(0.5)
        self.w.bind("close", self.closed)

        self.collectFonts()
        self.glyphChanged(None)

        addObserver(self, "glyphChanged", "currentGlyphChanged")
        addObserver(self, "fontsChanged", "newFontDidOpen")
        addObserver(self, "fontsChanged", "fontDidOpen")
        addObserver(self, "fontsChanged", "fontDidClose")
        addObserver(self, "drawBkgnd", "drawBackground")
        addObserver(self, "drawPreview", "drawPreview")

    def closed(self, sender):
        if self.window:
            self.window.getGlyphView().refresh()
        if self.currentGlyph:
            self.currentGlyph.removeObserver(self, "Glyph.Changed")
            self.currentGlyph.removeObserver(self, "Glyph.ContoursChanged")
        removeObserver(self, "currentGlyphChanged")
        removeObserver(self, "newFontDidOpen")
        removeObserver(self, "fontDidOpen")
        removeObserver(self, "fontDidClose")
        removeObserver(self, "drawBackground")
        removeObserver(self, "drawPreview")

    def getFontName(self, font, fonts):
        # A helper to get the font name, starting with the preferred name and working back to the PostScript name
        # Make sure that it's not the same name as another font in the fonts list
        if font.info.openTypeNamePreferredFamilyName and font.info.openTypeNamePreferredSubfamilyName:
            name = "%s %s" % (font.info.openTypeNamePreferredFamilyName,
                              font.info.openTypeNamePreferredSubfamilyName)
        elif font.info.familyName and font.info.styleName:
            name = "%s %s" % (font.info.familyName, font.info.styleName)
        elif font.info.fullName:
            name = font.info.fullName
        elif font.info.fullName:
            name = font.info.postscriptFontName
        else:
            name = "Untitled"
        # Add a number to the name if this name already exists
        if name in fonts:
            i = 2
            while name + " (%s)" % i in fonts:
                i += 1
            name = name + " (%s)" % i
        return name

    def collectFonts(self):
        # Hold aside the current font choices
        font0idx = self.w.font0.get()
        font1idx = self.w.font1.get()
        if not font0idx == -1:
            font0name = self.fontNames[font0idx]
        else:
            font0name = None
        if not font1idx == -1:
            font1name = self.fontNames[font1idx]
        else:
            font1name = None
        # Collect info on all open fonts
        self.fonts = AllFonts()
        self.fontNames = []
        for font in self.fonts:
            self.fontNames.append(self.getFontName(font, self.fontNames))
        # Update the popUpButtons
        self.w.font0.setItems(self.fontNames)
        self.w.font1.setItems(self.fontNames)
        # If there weren't any previous names, try to set the first and second items in the list
        if font0name == None:
            if len(self.fonts):
                self.w.font0.set(0)
        if font1name == None:
            if len(self.fonts) >= 1:
                self.w.font1.set(1)
        # Otherwise, if there had already been fonts choosen before new fonts were loaded,
        # try to set the index of the fonts that were already selected
        if font0name in self.fontNames:
            self.w.font0.set(self.fontNames.index(font0name))
        if font1name in self.fontNames:
            self.w.font1.set(self.fontNames.index(font1name))

    def fontsChanged(self, info):
        self.collectFonts()
        self.glyphChanged(None)

    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 testCompatibility(self):
        status = u"⚪️"
        if self.window:
            if self.glyph0 == self.glyph1:
                status = u"⚪️"
            elif len(self.interpolatedGlyph.contours) > 0:
                status = u"✅"
            else:
                status = u"❌"
        self.w.compatibilityText.set(u"Compatibility: %s" % status)

    def optionsChanged(self, sender):
        if self.glyph0 and self.glyph1:
            # Interpolate
            self.interpolatedGlyph.clear()
            self.interpolatedGlyph.interpolate(self.w.interpValue.get(),
                                               self.glyph0, self.glyph1)
        self.testCompatibility()
        # ...and refresh the window
        if self.window:
            self.window.getGlyphView().refresh()

    def addPoints(self, pt0, pt1):
        return (pt0[0] + pt1[0], pt0[1] + pt1[1])

    def subtractPoints(self, pt0, pt1):
        return (pt0[0] - pt1[0], pt0[1] - pt1[1])

    def drawBkgnd(self, info):
        # Draw the interpolated glyph outlines
        scale = info["scale"]
        ptSize = 7 * scale
        if self.interpolatedGlyph:
            # Draw the glyph outline
            pen = CocoaPen(None)
            self.interpolatedGlyph.draw(pen)
            dt.fill(r=None, g=None, b=None, a=1)
            dt.stroke(r=0, g=0, b=0, a=0.4)
            dt.strokeWidth(2 * scale)
            dt.save()
            dt.translate(self.currentGlyph.width)
            dt.drawPath(pen.path)
            dt.stroke(r=0, g=0, b=0, a=1)
            # Draw the points and handles
            for contour in self.interpolatedGlyph.contours:
                for bPoint in contour.bPoints:
                    inLoc = self.addPoints(bPoint.anchor, bPoint.bcpIn)
                    outLoc = self.addPoints(bPoint.anchor, bPoint.bcpOut)
                    dt.line(inLoc, bPoint.anchor)
                    dt.line(bPoint.anchor, outLoc)
                    dt.fill(r=1, g=1, b=1, a=1)
                    dt.oval(bPoint.anchor[0] - (ptSize * 0.5),
                            bPoint.anchor[1] - (ptSize * 0.5), ptSize, ptSize)
                    dt.fill(0)
                    # Draw an "X" over each BCP
                    if not bPoint.bcpIn == (0, 0):
                        dt.oval(inLoc[0] - (ptSize * 0.5),
                                inLoc[1] - (ptSize * 0.5), ptSize, ptSize)
                        #dt.line((inLoc[0]-(ptSize*0.5), inLoc[1]-(ptSize*0.5)), (inLoc[0]+(ptSize*0.5), inLoc[1]+(ptSize*0.5)))
                        #dt.line((inLoc[0]+(ptSize*0.5), inLoc[1]-(ptSize*0.5)), (inLoc[0]-(ptSize*0.5), inLoc[1]+(ptSize*0.5)))
                    if not bPoint.bcpOut == (0, 0):
                        dt.oval(outLoc[0] - (ptSize * 0.5),
                                outLoc[1] - (ptSize * 0.5), ptSize, ptSize)
                        #dt.line((outLoc[0]-(ptSize*0.5), outLoc[1]-(ptSize*0.5)), (outLoc[0]+(ptSize*0.5), outLoc[1]+(ptSize*0.5)))
                        #dt.line((outLoc[0]+(ptSize*0.5), outLoc[1]-(ptSize*0.5)), (outLoc[0]-(ptSize*0.5), outLoc[1]+(ptSize*0.5)))

            dt.restore()

    def drawPreview(self, info):
        # Draw a filled in version of the interpolated glyph
        scale = info["scale"]
        if self.interpolatedGlyph:
            pen = CocoaPen(None)
            self.interpolatedGlyph.draw(pen)
            dt.fill(r=0, g=0, b=0, a=0.6)
            dt.stroke(r=None, g=None, b=None, a=1)
            dt.save()
            dt.translate(self.currentGlyph.width)
            dt.drawPath(pen.path)
            dt.restore()
Ejemplo n.º 29
0
 def wwwindow(self):
     return CurrentGlyphWindow()
class GlyphMetricsUI(object):
    def __init__(self):
        # debug
        windowname = 'Debug Glyph Metrics UI'
        windows = [w for w in NSApp().orderedWindows() if w.isVisible()]
        for window in windows:
            print(window.title())
            if window.title() == windowname:
                window.close()
        if debug == True:
            self.debug = Window((333, 33), windowname)
            self.debug.bind('close', self.windowSideuiClose)
            self.debug.open()
        # setup
        self.showButtons = False
        self.sbui = None
        # add interface
        addObserver(self, 'addInterface', 'glyphWindowWillOpen')
        addObserver(self, 'updateSelfWindow', 'currentGlyphChanged')
        # toggle visibility of tool ui
        addObserver(self, 'showSideUIonDraw', 'draw')
        addObserver(self, 'hideSideUIonPreview', 'drawPreview')
        # remove UI and window manager when glyph window closes
        # addObserver(self, "observerGlyphWindowWillClose", "glyphWindowWillClose")
        # subscribe to glyph changes
        addObserver(self, "viewDidChangeGlyph", "viewDidChangeGlyph")

    # def observerGlyphWindowWillClose(self, notification):
    #     self.window = notification['window']
    #     self.cleanup(self.window)
    #     del windowViewManger[notification['window']]
    #     del lll[notification['window']]
    #     del ccc[notification['window']]
    #     del rrr[notification['window']]

    def windowSideuiClose(self, sender):
        self.window.removeGlyphEditorSubview(self.sbui)
        removeObserver(self, 'glyphWindowWillOpen')
        removeObserver(self, 'glyphWindowWillClose')
        removeObserver(self, 'glyphWindowWillClose')
        removeObserver(self, 'currentGlyphChanged')
        removeObserver(self, 'draw')
        removeObserver(self, 'drawPreview')
        removeObserver(self, 'viewDidChangeGlyph')

    def cleanup(self, w):
        try:
            w.removeGlyphEditorSubview(self.sbui)
        except:
            return

    def addInterface(self, notification):
        self.window = notification['window']
        # self.cleanup(self.window)

        # CONTAINER
        xywh = (margin, -55, -margin, height)
        self.sbui = CanvasGroup(xywh, delegate=CanvasStuff(self.window))

        # LEFT
        x, y, w, h = xywh = (0, -height, dfltLwidth, height)
        this = self.sbui.L = Group(xywh)

        # text input
        xywh = (x, y + 3, width * 1.5, height * .75)
        this.Ltext = EditText(xywh,
                              placeholder='angledLeftMargin',
                              sizeStyle='mini',
                              continuous=False,
                              callback=self.setSB)
        # quick mod buttons
        xywh = (x + width * 1.5 + (gap * 1), y, width, height)
        this.Lminus = Button(xywh,
                             iconminus,
                             sizeStyle='mini',
                             callback=self.setLminus)
        this.Lminus.getNSButton().setToolTip_('Adjust LSB -' + str(unit))
        xywh = (x + width * 2.5 + (gap * 2), y, width, height)
        this.Lplus = Button(xywh,
                            iconplus,
                            sizeStyle='mini',
                            callback=self.setLplus)
        this.Lplus.getNSButton().setToolTip_('Adjust LSB +' + str(unit))
        xywh = (x + width * 3.5 + (gap * 3), y, width, height)
        this.Lround = Button(xywh,
                             iconround,
                             sizeStyle='mini',
                             callback=self.setLround)
        this.Lround.getNSButton().setToolTip_('Round LSB to ' + str(unit))
        xywh = (x + width * 4.5 + (gap * 4), y, width, height)
        this.Lright = Button(xywh,
                             iconcopyR,
                             sizeStyle='mini',
                             callback=self.setLright)
        this.Lright.getNSButton().setToolTip_('Copy Right Value')
        # stylize
        this.Ltext.getNSTextField().setBezeled_(False)
        this.Ltext.getNSTextField().setBackgroundColor_(NSColor.clearColor())
        self.flatButt(this.Lminus)
        self.flatButt(this.Lplus)
        self.flatButt(this.Lround)
        self.flatButt(this.Lright)

        # RIGHT
        x, y, w, h = xywh = (-dfltRwidth, y, dfltRwidth, h)
        this = self.sbui.R = Group(xywh)
        # text input
        xywh = (-x - width * 1.5, y + 3, width * 1.5, height * .75)
        this.Rtext = EditText(xywh,
                              placeholder='angledRightMargin',
                              sizeStyle='mini',
                              continuous=False,
                              callback=self.setSB)
        # quick mod buttons
        xywh = (-x - width * 5.5 - (gap * 4), y, width, height)
        this.Rleft = Button(xywh,
                            iconcopyL,
                            sizeStyle='mini',
                            callback=self.setRleft)
        this.Rleft.getNSButton().setToolTip_('Copy Left Value')
        xywh = (-x - width * 4.5 - (gap * 3), y, width, height)
        this.Rround = Button(xywh,
                             iconround,
                             sizeStyle='mini',
                             callback=self.setRround)
        this.Rround.getNSButton().setToolTip_('Round RSB to ' + str(unit))
        xywh = (-x - width * 3.5 - (gap * 2), y, width, height)
        this.Rminus = Button(xywh,
                             iconminus,
                             sizeStyle='mini',
                             callback=self.setRminus)
        this.Rminus.getNSButton().setToolTip_('Adjust RSB -' + str(unit))
        xywh = (-x - width * 2.5 - (gap * 1), y, width, height)
        this.Rplus = Button(xywh,
                            iconplus,
                            sizeStyle='mini',
                            callback=self.setRplus)
        this.Rplus.getNSButton().setToolTip_('Adjust RSB +' + str(unit))
        # stylize
        this.Rtext.getNSTextField().setBezeled_(False)
        this.Rtext.getNSTextField().setBackgroundColor_(NSColor.clearColor())
        this.Rtext.getNSTextField().setAlignment_(NSTextAlignmentRight)
        self.flatButt(this.Rminus)
        self.flatButt(this.Rplus)
        self.flatButt(this.Rround)
        self.flatButt(this.Rleft)

        # CENTER
        winX, winY, winW, winH = self.window.getVisibleRect()
        winW = winW - margin * 5
        x, y, w, h = xywh = ((winW / 2) - (dfltCwidth / 2), y, dfltCwidth, h)
        this = self.sbui.C = Group(xywh)
        x = 0

        # text input
        c = (dfltCwidth / 2)
        xywh = (c - (width * .75), y + 3, width * 1.5, height * .75)
        this.Ctext = EditText(xywh,
                              placeholder='width',
                              sizeStyle='mini',
                              continuous=False,
                              callback=self.setSB)
        # quick mod buttons
        xywh = (c - (width * .75) - width * 2 - (gap * 2), y, width, height)
        this.Ccenter = Button(xywh,
                              iconcenter,
                              sizeStyle='mini',
                              callback=self.setCcenter)
        this.Ccenter.getNSButton().setToolTip_('Center on Width')
        xywh = (c - (width * .75) - width - (gap * 1), y, width, height)
        this.Cround = Button(xywh,
                             iconround,
                             sizeStyle='mini',
                             callback=self.setCround)
        this.Cround.getNSButton().setToolTip_('Round Width to ' + str(unit))
        xywh = (c + (width * .75) + (gap * 1), y, width, height)
        this.Cminus = Button(xywh,
                             iconminus,
                             sizeStyle='mini',
                             callback=self.setCminus)
        this.Cminus.getNSButton().setToolTip_('Adjust Width -' + str(2 * unit))
        xywh = (c + (width * .75) + width + (gap * 2), y, width, height)
        this.Cplus = Button(xywh,
                            iconplus,
                            sizeStyle='mini',
                            callback=self.setCplus)
        this.Cplus.getNSButton().setToolTip_('Adjust Width +' + str(2 * unit))
        # stylize
        this.Ctext.getNSTextField().setBezeled_(False)
        this.Ctext.getNSTextField().setBackgroundColor_(NSColor.clearColor())
        this.Ctext.getNSTextField().setAlignment_(NSTextAlignmentCenter)
        self.flatButt(this.Cminus)
        self.flatButt(this.Cplus)
        self.flatButt(this.Cround)
        self.flatButt(this.Ccenter)

        # hide
        self.sbui.L.Lminus.show(False)
        self.sbui.L.Lround.show(False)
        self.sbui.L.Lplus.show(False)
        self.sbui.L.Lright.show(False)
        self.sbui.R.Rminus.show(False)
        self.sbui.R.Rround.show(False)
        self.sbui.R.Rplus.show(False)
        self.sbui.R.Rleft.show(False)
        self.sbui.C.Cminus.show(False)
        self.sbui.C.Cround.show(False)
        self.sbui.C.Ccenter.show(False)
        self.sbui.C.Cplus.show(False)

        # make it real
        self.sbWatcherInitialize()
        self.window.addGlyphEditorSubview(self.sbui)
        self.updateValues()
        self.buildMatchBase()
        windowViewManger[self.window] = self.sbui

    def updateSelfWindow(self, notification):
        self.window = CurrentGlyphWindow()
        self.buildMatchBase()
        self.updateValues()

    def showSideUIonDraw(self, notification):
        self.sbWatcher()
        sbui = windowViewManger.get(self.window)
        if sbui is not None:
            sbui.show(True)

    def hideSideUIonPreview(self, notification):
        sbui = windowViewManger.get(self.window)
        if sbui is not None:
            sbui.show(False)

    def updateValues(self, notification=None):
        try:
            g = self.window.getGlyph()
            f = g.font
            sbui = windowViewManger.get(self.window)
            sbui.L.Ltext.set(str(g.angledLeftMargin))
            sbui.R.Rtext.set(str(g.angledRightMargin))
            sbui.C.Ctext.set(str(g.width))
        except Exception as e:
            # if debug == True:
            #     print('Exception updateValues', e)
            return

    # hack sidebearings changed observer
    # used when things redraw
    def sbWatcherInitialize(self):
        g = self.window.getGlyph()
        f = g.font
        if g is not None:
            lll[self.window] = g.angledLeftMargin
            ccc[self.window] = g.width
            rrr[self.window] = g.angledRightMargin

    def sbWatcher(self):
        g = CurrentGlyph()
        if g is not None:
            f = g.font
            if lll[self.window] != None and ccc[self.window] != None and rrr[
                    self.window] != None:
                if lll[self.window] != g.angledLeftMargin or ccc[
                        self.window] != g.width or rrr[
                            self.window] != g.angledRightMargin:
                    lll[self.window] = g.angledLeftMargin
                    ccc[self.window] = g.width
                    rrr[self.window] = g.angledRightMargin
                    self.updateValues()
                    self.buildMatchBase()

    def setSB(self, sender):
        changeAttribute = sender.getPlaceholder()
        g = self.window.getGlyph()
        f = g.font
        v = sender.get()
        if is_number(v):
            if debug == True:
                print('value is a number')
            g.prepareUndo('Change ' + changeAttribute + ' SB')
            setattr(g, changeAttribute, float(v))
            g.performUndo()
            self.updateValues()
        elif v in f:
            if debug == True:
                print('value is a glyph')
            g.prepareUndo('Change ' + changeAttribute + ' SB')
            sb = getattr(f[v], changeAttribute)
            setattr(g, changeAttribute, sb)
            g.performUndo()
            self.updateValues()
        else:
            if debug == True:
                print('value is not a number or a glyph')
            return

    def setLminus(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('➖ Left SB')
        g.angledLeftMargin += -1 * unit
        g.performUndo()
        self.updateValues()

    def setLround(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Round Left SB')
        g.angledLeftMargin = int(unit *
                                 round(float(g.angledLeftMargin) / unit))
        g.performUndo()
        self.updateValues()

    def setLplus(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('➕ Left SB')
        g.angledLeftMargin += unit
        g.performUndo()
        self.updateValues()

    def setLright(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Copy Right SB')
        g.angledLeftMargin = g.angledRightMargin
        g.performUndo()
        self.updateValues()

    def setLmatch(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Match Left SB')
        f = g.font
        gmatch = sender.getTitle()
        if f[gmatch] is not None:
            g.angledLeftMargin = f[gmatch].angledLeftMargin
        g.performUndo()
        self.updateValues()

    def setRminus(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('➖ Right SB')
        g.angledRightMargin += -1 * unit
        g.performUndo()
        self.updateValues()

    def setRround(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Round Right SB')
        g.angledRightMargin = int(unit *
                                  round(float(g.angledRightMargin) / unit))
        g.performUndo()
        self.updateValues()

    def setRplus(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('➕ Right SB')
        g.angledRightMargin += unit
        g.performUndo()
        self.updateValues()

    def setRmatch(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Match Right SB')
        gmatch = sender.getTitle()
        f = g.font
        if f[gmatch] is not None:
            g.angledRightMargin = f[gmatch].angledRightMargin
        g.performUndo()
        self.updateValues()

    def setRleft(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Copy Left SB')
        g.angledRightMargin = g.angledLeftMargin
        g.performUndo()
        self.updateValues()

    def setCminus(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('➖ Width')
        # use whole units, not floats
        oldwidth = g.width
        leftby = unit
        g.angledLeftMargin += -1 * leftby
        g.width = oldwidth - unit * 2
        g.performUndo()
        self.updateValues()

    def setCround(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Round Width')
        g.width = int(unit * round(float(g.width) / unit))
        g.performUndo()
        self.updateValues()

    def setCcenter(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Center on Width')
        # use whole units, not floats
        padding = g.angledLeftMargin + g.angledRightMargin
        gwidth = g.width
        g.angledLeftMargin = int(padding / 2)
        g.width = gwidth
        g.performUndo()
        self.updateValues()

    def setCplus(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('➕ Width')
        # use whole units, not floats
        oldwidth = g.width
        leftby = unit
        g.angledLeftMargin += leftby
        g.width = oldwidth + unit * 2
        g.performUndo()
        self.updateValues()

    def setCmatch(self, sender):
        g = self.window.getGlyph()
        if g is None:
            return
        g.prepareUndo('Match Width')
        f = g.font
        gmatch = sender.getTitle()
        if f[gmatch] is not None:
            g.width = f[gmatch].width
        g.performUndo()
        self.updateValues()

    def flatButt(self, this, match=False):
        this = this.getNSButton()
        this.setBezelStyle_(buttstyle)
        this.setBordered_(False)
        this.setWantsLayer_(True)
        this.setBackgroundColor_(NSColor.whiteColor())
        if match == True:
            this.setBackgroundColor_(
                NSColor.colorWithCalibratedRed_green_blue_alpha_(
                    .9, 1, .85, 1))

    def buildMatchBase(self, notification=None):
        self.newheight = height
        try:
            g = self.window.getGlyph()
            f = g.font
            # remove old buttons
            for i in range(10):
                if hasattr(self.sbui.L, 'buttobj_%s' % i):
                    delattr(self.sbui.L, 'buttobj_%s' % i)
                    delattr(self.sbui.R, 'buttobj_%s' % i)
                    delattr(self.sbui.C, 'buttobj_%s' % i)

            # add button for each component
            self.uniquecomponents = []
            for c in g.components:
                if c.baseGlyph not in self.uniquecomponents:
                    self.uniquecomponents.append(c.baseGlyph)

            for i, c in enumerate(self.uniquecomponents):
                row = i + 1
                yy = -height * (row + 1) - 3

                xywh = (0, yy, width * 5.5 + (gap * 4), height)
                buttobj = Button(xywh,
                                 c,
                                 sizeStyle='mini',
                                 callback=self.setLmatch)
                setattr(self.sbui.L, 'buttobj_%s' % i, buttobj)
                this = getattr(self.sbui.L, 'buttobj_%s' % i)
                this.getNSButton().setAlignment_(NSTextAlignmentLeft)
                this.getNSButton().setToolTip_('Match LSB of ' + c)

                xywh = (-width * 5.5 - (gap * 4), yy, width * 5.5 + (gap * 4),
                        height)
                buttobj = Button(xywh,
                                 c,
                                 sizeStyle='mini',
                                 callback=self.setRmatch)
                setattr(self.sbui.R, 'buttobj_%s' % i, buttobj)
                this = getattr(self.sbui.R, 'buttobj_%s' % i)
                this.getNSButton().setAlignment_(NSTextAlignmentRight)
                this.getNSButton().setToolTip_('Match RSB of ' + c)

                xywh = ((dfltLwidth / 2) - (width * 2.75 + (gap * 2)), yy,
                        width * 5.5 + (gap * 4), height)
                buttobj = Button(xywh,
                                 c,
                                 sizeStyle='mini',
                                 callback=self.setCmatch)
                setattr(self.sbui.C, 'buttobj_%s' % i, buttobj)
                this = getattr(self.sbui.C, 'buttobj_%s' % i)
                this.getNSButton().setToolTip_('Match Width of ' + c)

            for i, c in enumerate(self.uniquecomponents):
                try:
                    this = getattr(self.sbui.L, 'buttobj_%s' % i)
                    # hide if hidden
                    if self.showButtons == False:
                        this.show(False)
                    # check if metrics match base glyphs
                    if int(f[c].angledLeftMargin) == int(g.angledLeftMargin):
                        self.flatButt(this, True)
                    else:
                        self.flatButt(this)

                    this = getattr(self.sbui.R, 'buttobj_%s' % i)
                    if self.showButtons == False:
                        this.show(False)
                    if int(f[c].angledRightMargin) == int(g.angledRightMargin):
                        self.flatButt(this, True)
                    else:
                        self.flatButt(this)

                    this = getattr(self.sbui.C, 'buttobj_%s' % i)
                    if self.showButtons == False:
                        this.show(False)
                    if f[c].width == g.width:
                        self.flatButt(this, True)
                    else:
                        self.flatButt(this)

                except Exception as e:
                    return

            # change height of canvas to fit buttons
            self.newheight = height * (len(self.uniquecomponents) + 2)
            newy = -55 - height * (len(self.uniquecomponents))
            self.sbui.setPosSize((margin, newy, -margin, self.newheight))
            self.sbui.L.setPosSize((0, 0, dfltLwidth, self.newheight))
            self.sbui.R.setPosSize(
                (-dfltRwidth, 0, dfltRwidth, self.newheight))
            winX, winY, winW, winH = self.window.getVisibleRect()
            winW = winW - margin * 5
            offsetcenter = (winW / 2) - (width * 2.25)
            self.sbui.C.setPosSize(
                (offsetcenter, 0, width * 5 + 12, self.newheight))

        except Exception as e:
            return

    #############################################
    # watch for glyph changes
    #############################################

    def viewDidChangeGlyph(self, notification):
        self.glyph = CurrentGlyph()
        self.unsubscribeGlyph()
        self.subscribeGlyph()
        self.glyphChanged()

    def subscribeGlyph(self):
        self.glyph.addObserver(self, 'glyphChanged', 'Glyph.Changed')

    def unsubscribeGlyph(self):
        if self.glyph is None:
            return
        self.glyph.removeObserver(self, 'Glyph.Changed')

    def glyphChanged(self, notification=None):
        self.updateValues()
 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)
Ejemplo n.º 33
0
        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)
Ejemplo n.º 34
0
    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()