Ejemplo n.º 1
0
 def _distributeSpacing(self, index, title):
     glyph = CurrentGlyph()
     if glyph is None:
         return
     rects, selectedContours, selectedBPoints = getSelectionData(glyph)
     if len(rects) < 3:
         return
     widths = []
     heights = []
     edgeRect = None
     for rect in rects:
         xMin, yMin, xMax, yMax = rect
         widths.append(xMax - xMin)
         heights.append(yMax - yMin)
         if edgeRect is None:
             edgeRect = rect
         else:
             edgeRect = unionRect(edgeRect, rect)
     objectWidth = sum(widths)
     objectHeight = sum(heights)
     xMin, yMin, xMax, yMax = edgeRect
     overallWidth = xMax - xMin
     overallHeight = yMax - yMin
     availableXSpace = overallWidth - objectWidth
     availableYSpace = overallHeight - objectHeight
     xSpace = availableXSpace / (len(rects) - 1)
     ySpace = availableYSpace / (len(rects) - 1)
     spaceBetweenObjects = (xSpace, ySpace)[index]
     ordered = [(bPoint.anchor[index], (bPoint.anchor[0], bPoint.anchor[1],
                                        bPoint.anchor[0], bPoint.anchor[1]),
                 bPoint) for bPoint in selectedBPoints]
     ordered += [(contour.bounds[index], contour.bounds, contour)
                 for contour in selectedContours]
     ordered.sort()
     glyph.prepareUndo(title)
     prevEdge = None
     for pos, bounds, obj in ordered[:-1]:
         xMin, yMin, xMax, yMax = bounds
         width = xMax - xMin
         height = yMax - yMin
         size = (width, height)[index]
         if prevEdge is None:
             newPos = (xMin, yMin)[index]
         else:
             newPos = prevEdge + spaceBetweenObjects
         d = newPos - pos
         print(d)
         if d != 0:
             if index == 0:
                 obj.moveBy((d, 0))
             else:
                 obj.moveBy((0, d))
         prevEdge = newPos + size
     for bPoint in selectedBPoints:
         bPoint.round()
     for contour in selectedContours:
         contour.round()
     glyph.changed()
     glyph.performUndo()
     UpdateCurrentGlyphView()
Ejemplo n.º 2
0
def nudgeSelected(offset):
    g = CurrentGlyph()
    for c in g.contours:
        for i, p in enumerate(c.bPoints):
            n = c.bPoints[i]
            if n.selected:
                g.prepareUndo(undoTitle='InterpolatedNudge')
                interpolateNode(i, g, c, offset)
                g.performUndo()
                g.update()
Ejemplo n.º 3
0
def nudgeSelected(x):
    g = CurrentGlyph()
    for c in g.contours:
        i = 0
        for p in c.bPoints:
            n = c.bPoints[i]
            if n.selected:
                g.prepareUndo(undoTitle='InterpolatedNudge')
                interpolateNode(i, g, c, x)
                g.performUndo()
                g.update()
            i = i + 1
Ejemplo n.º 4
0
def nudgeSelected(x):
    g = CurrentGlyph()
    for c in g.contours:
        i = 0
        for p in c.bPoints:
            n = c.bPoints[i]
            if n.selected:
                g.prepareUndo(undoTitle='InterpolatedNudge')
                interpolateNode(i, g, c, x)
                g.performUndo()
                g.update()
            i = i + 1
Ejemplo n.º 5
0
 def _distribute(self, methods, title):
     glyph = CurrentGlyph()
     if glyph is None:
         return
     rects, selectedContours, selectedBPoints = getSelectionData(glyph)
     if len(rects) < 3:
         return
     glyph.prepareUndo(title)
     for method in methods:
         method(rects, selectedContours, selectedBPoints)
     for bPoint in selectedBPoints:
         bPoint.round()
     for contour in selectedContours:
         contour.round()
     glyph.changed()
     glyph.performUndo()
     UpdateCurrentGlyphView()
Ejemplo n.º 6
0
class alignPointsDialog(hConstants):
    
    """Align selected points vertically or horizontally."""
    
    glyph = None
    points = []
    x_pos_list = []
    y_pos_list = []
    axis = 1
    mode = 1    
    
    def __init__(self):
        # window parameters
        self.title = 'align'
        self.width = 123
        self.column1 = 45
        self.height = (self.padding_y * 4) + self.button_height + (self.text_height * 2)
        # window
        self.w = FloatingWindow(
            (self.width, self.height),
            self.title)
        x = self.padding_x
        y = self.padding_y
        # options
        self.w.align_mode = RadioGroup(
            (x, y,
            -self.padding_x,
            self.text_height),
            [ '-', 'm', '+' ],
            isVertical=False,
            sizeStyle=self.size_style)
        self.w.align_mode.set(self.mode)
        y += (self.text_height + self.padding_y)
        # button
        x = self.padding_x
        self.w.align_button = SquareButton(
            (x, y,
            -self.padding_x,
            self.button_height),
            'apply',
            callback=self.apply_callback,
            sizeStyle=self.size_style)
        y += (self.button_height + self.padding_y)
        # axis
        self.w.axis_label = TextBox(
                    (x, y + 3,
                    self.column1,
                    self.text_height),
                    "axis",
                    sizeStyle=self.size_style)
        x = self.column1
        self.w.axis = RadioGroup(
                    (x, y,
                    -self.padding_x,
                    self.text_height),
                    ["x", "y"],
                    sizeStyle=self.size_style,
                    isVertical=False)
        self.w.axis.set(self.axis)
        # open
        self.w.open()

    def _get_parameters(self):
        self.axis = self.w.axis.get()
        self.mode = self.w.align_mode.get()

    def apply_callback(self, sender):
        # get current glyph
        self.glyph = CurrentGlyph()
        # no glyph window open
        if self.glyph is None:
            print no_glyph_open
        else:
            # collect points
            self.points = []
            for c in self.glyph:
                print c.selection
                for p in c.points:
                    if p.selected:
                        self.points.append(p)
                        self.x_pos_list.append(p.x)
                        self.y_pos_list.append(p.y)
            # not enough points selected
            if len(self.points) < 2:
                print at_least_two_points
            else:
                self._get_parameters()
                self.glyph.prepareUndo('align points')
                # select axis
                if self.axis == 0:
                    values_list = self.x_pos_list
                else:
                    values_list = self.y_pos_list
                # get aligment point
                if self.mode == 1:
                    pos = get_med(values_list)
                elif self.mode == 2:
                    pos = get_max(values_list)
                else:
                    pos = get_min(values_list)
                # align points
                for p in self.points:
                    # get delta
                    if self.axis == 0:
                        delta_x = pos - p.x
                        delta_y = 0
                    else:
                        delta_x = 0
                        delta_y = pos - p.y
                    # move points
                    p.move((delta_x, delta_y))
                # done
                self.glyph.update()
                self.glyph.performUndo()
Ejemplo n.º 7
0
class alignPointsDialog(hDialog):
    """Align selected points vertically or horizontally."""

    glyph = None
    points = []
    x_pos_list = []
    y_pos_list = []
    axis = 1
    mode = 1

    def __init__(self):
        # window parameters
        self.title = 'align'
        self.width = 123
        self.column1 = 45
        self.height = (self.padding_y *
                       4) + self.button_height + (self.text_height * 2)
        # window
        self.w = FloatingWindow((self.width, self.height), self.title)
        x = self.padding_x
        y = self.padding_y
        # options
        self.w.align_mode = RadioGroup(
            (x, y, -self.padding_x, self.text_height), ['-', 'm', '+'],
            isVertical=False,
            sizeStyle=self.size_style)
        self.w.align_mode.set(self.mode)
        y += (self.text_height + self.padding_y)
        # button
        x = self.padding_x
        self.w.align_button = SquareButton(
            (x, y, -self.padding_x, self.button_height),
            'apply',
            callback=self.apply_callback,
            sizeStyle=self.size_style)
        y += (self.button_height + self.padding_y)
        # axis
        self.w.axis_label = TextBox((x, y + 3, self.column1, self.text_height),
                                    "axis",
                                    sizeStyle=self.size_style)
        x = self.column1
        self.w.axis = RadioGroup((x, y, -self.padding_x, self.text_height),
                                 ["x", "y"],
                                 sizeStyle=self.size_style,
                                 isVertical=False)
        self.w.axis.set(self.axis)
        # open
        self.w.open()

    def _get_parameters(self):
        self.axis = self.w.axis.get()
        self.mode = self.w.align_mode.get()

    def apply_callback(self, sender):
        # get current glyph
        self.glyph = CurrentGlyph()
        # no glyph window open
        if self.glyph is None:
            print(no_glyph_open)
        else:
            # collect points
            self.points = []
            for c in self.glyph:
                print(c.selection)
                for p in c.points:
                    if p.selected:
                        self.points.append(p)
                        self.x_pos_list.append(p.x)
                        self.y_pos_list.append(p.y)
            # not enough points selected
            if len(self.points) < 2:
                print(at_least_two_points)
            else:
                self._get_parameters()
                self.glyph.prepareUndo('align points')
                # select axis
                if self.axis == 0:
                    values_list = self.x_pos_list
                else:
                    values_list = self.y_pos_list
                # get aligment point
                if self.mode == 1:
                    pos = get_med(values_list)
                elif self.mode == 2:
                    pos = get_max(values_list)
                else:
                    pos = get_min(values_list)
                # align points
                for p in self.points:
                    # get delta
                    if self.axis == 0:
                        delta_x = pos - p.x
                        delta_y = 0
                    else:
                        delta_x = 0
                        delta_y = pos - p.y
                    # move points
                    p.move((delta_x, delta_y))
                # done
                self.glyph.update()
                self.glyph.performUndo()
Ejemplo n.º 8
0
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()