| | 383 | return found |
|---|
| | 384 | |
|---|
| | 385 | def _handleDetailWindow(self, event, found, mouseDown=False, mouseMoved=False, mouseDragged=False, mouseUp=False, inDragAndDrop=False): |
|---|
| | 386 | # no window |
|---|
| | 387 | if self._glyphDetailWindow is None: |
|---|
| | 388 | return |
|---|
| | 389 | # determine show/hide |
|---|
| | 390 | shouldBeVisible = True |
|---|
| | 391 | eventLocation = event.locationInWindow() |
|---|
| | 392 | mouseLocation = self.convertPoint_fromView_(eventLocation, None) |
|---|
| | 393 | ## drag and drop |
|---|
| | 394 | if inDragAndDrop: |
|---|
| | 395 | shouldBeVisible = False |
|---|
| | 396 | ## modifiers |
|---|
| | 397 | modifiers = event.modifierFlags() |
|---|
| | 398 | for modifier in self._glyphDetailRequiredModifiers: |
|---|
| | 399 | if not modifiers & modifier: |
|---|
| | 400 | shouldBeVisible = False |
|---|
| | 401 | break |
|---|
| | 402 | ## mouse conditions |
|---|
| | 403 | haveMouseCondition = False |
|---|
| | 404 | requireMouseCondition = True in (self._glyphDetailOnMouseDown, self._glyphDetailOnMouseUp, self._glyphDetailOnMouseMoved, self._glyphDetailOnMouseDragged) |
|---|
| | 405 | if not requireMouseCondition: |
|---|
| | 406 | haveMouseCondition = True |
|---|
| | 407 | else: |
|---|
| | 408 | if self._glyphDetailOnMouseDown and mouseDown: |
|---|
| | 409 | haveMouseCondition = True |
|---|
| | 410 | elif self._glyphDetailOnMouseUp and mouseUp: |
|---|
| | 411 | haveMouseCondition = True |
|---|
| | 412 | elif self._glyphDetailOnMouseMoved and mouseMoved: |
|---|
| | 413 | haveMouseCondition = True |
|---|
| | 414 | elif self._glyphDetailOnMouseDragged and mouseDragged: |
|---|
| | 415 | haveMouseCondition = True |
|---|
| | 416 | if not haveMouseCondition: |
|---|
| | 417 | shouldBeVisible = False |
|---|
| | 418 | ## glyph hit |
|---|
| | 419 | if not found: |
|---|
| | 420 | shouldBeVisible = False |
|---|
| | 421 | ## mouse position is visible |
|---|
| | 422 | if not NSPointInRect(mouseLocation, self.visibleRect()): |
|---|
| | 423 | shouldBeVisible = False |
|---|
| | 424 | # set the position |
|---|
| | 425 | if shouldBeVisible: |
|---|
| | 426 | x, y = eventLocation |
|---|
| | 427 | windowX, windowY = event.window().frame().origin |
|---|
| | 428 | detailX = windowX + x |
|---|
| | 429 | detailY = windowY + y |
|---|
| | 430 | glyph = self._glyphs[found] |
|---|
| | 431 | self._glyphDetailWindow.setPositionNearCursor((detailX, detailY)) |
|---|
| | 432 | self._glyphDetailWindow.set(glyph) |
|---|
| | 433 | if not self._glyphDetailWindow.isVisible(): |
|---|
| | 434 | self._glyphDetailWindow.show() |
|---|
| | 435 | else: |
|---|
| | 436 | self._glyphDetailWindow.hide() |
|---|
| | 437 | |
|---|
| | 438 | def _mouseSelection(self, event, found, mouseDown=False, mouseDragged=False, mouseUp=False, mouseMoved=False): |
|---|
| | 439 | if mouseDown: |
|---|
| | 440 | self._oldSelection = set(self._selection) |
|---|
| | 441 | if found is None: |
|---|
| | 442 | return |
|---|
| 749 | | class GlyphCellView(vanilla.ScrollView): |
|---|
| 750 | | |
|---|
| 751 | | def __init__(self, posSize, |
|---|
| 752 | | selectionCallback=None, doubleClickCallback=None, deleteCallback=None, dropCallback=None, |
|---|
| 753 | | cellRepresentationName="defconAppKitGlyphCell", detailRepresentationName="defconAppKitGlyphCellDetail", |
|---|
| 754 | | autohidesScrollers=True, selfWindowDropSettings=None, selfDocumentDropSettings=None, |
|---|
| 755 | | selfApplicationDropSettings=None, otherApplicationDropSettings=None, allowDrag=False, |
|---|
| 756 | | dragAndDropType="DefconAppKitSelectedGlyphIndexesPboardType"): |
|---|
| 757 | | self._glyphCellView = DefconAppKitGlyphCellNSView.alloc().initWithFrame_cellRepresentationName_detailRepresentationName_( |
|---|
| 758 | | ((0, 0), (400, 400)), cellRepresentationName, detailRepresentationName) |
|---|
| 759 | | self._glyphCellView.vanillaWrapper = weakref.ref(self) |
|---|
| 760 | | super(GlyphCellView, self).__init__(posSize, self._glyphCellView, hasHorizontalScroller=False, autohidesScrollers=autohidesScrollers, backgroundColor=backgroundColor) |
|---|
| 761 | | self._glyphCellView.subscribeToScrollViewFrameChange_(self._nsObject) |
|---|
| 762 | | |
|---|
| 763 | | if dropCallback is not None: |
|---|
| 764 | | from warnings import warn |
|---|
| 765 | | warn(DeprecationWarning("dropCallback is deprecated. Use the new drop attributes.")) |
|---|
| 766 | | selfWindowDropSettings = dict(operation=NSDragOperationCopy, callback=self._deprecatedDropCallback) |
|---|
| 767 | | selfDocumentDropSettings = dict(operation=NSDragOperationCopy, callback=self._deprecatedDropCallback) |
|---|
| 768 | | selfApplicationDropSettings = dict(operation=NSDragOperationCopy, callback=self._deprecatedDropCallback) |
|---|
| 769 | | otherApplicationDropSettings = dict(operation=NSDragOperationCopy, callback=self._deprecatedDropCallback) |
|---|
| 770 | | for i in (selfWindowDropSettings, selfDocumentDropSettings, selfApplicationDropSettings, otherApplicationDropSettings): |
|---|
| 771 | | if i is not None: |
|---|
| 772 | | i["type"] = dragAndDropType |
|---|
| 773 | | for i in (selfWindowDropSettings, selfDocumentDropSettings, selfApplicationDropSettings, otherApplicationDropSettings): |
|---|
| 774 | | if i is not None: |
|---|
| 775 | | self._glyphCellView.registerForDraggedTypes_([dragAndDropType]) |
|---|
| 776 | | break |
|---|
| 777 | | self._selfWindowDropSettings = selfWindowDropSettings |
|---|
| 778 | | self._selfDocumentDropSettings = selfDocumentDropSettings |
|---|
| 779 | | self._otherApplicationDropSettings = selfApplicationDropSettings |
|---|
| 780 | | self._otherApplicationDropSettings = otherApplicationDropSettings |
|---|
| 781 | | self._glyphCellView.setAllowsDrag_(allowDrag) |
|---|
| 782 | | self._dragAndDropType = dragAndDropType |
|---|
| 783 | | # callbacks |
|---|
| 784 | | self._dropCallback = dropCallback |
|---|
| 785 | | self._selectionCallback = selectionCallback |
|---|
| 786 | | self._doubleClickCallback = doubleClickCallback |
|---|
| 787 | | self._deleteCallback = deleteCallback |
|---|
| 788 | | # storage |
|---|
| 789 | | self._glyphs = [] |
|---|
| 790 | | |
|---|
| 791 | | def _breakCycles(self): |
|---|
| 792 | | if hasattr(self, "_glyphCellView"): |
|---|
| 793 | | self._glyphCellView.unsubscribeToScrollViewFrameChange_(self._nsObject) |
|---|
| 794 | | del self._glyphCellView.vanillaWrapper |
|---|
| 795 | | del self._glyphCellView |
|---|
| 796 | | self._selectionCallback = None |
|---|
| 797 | | self._doubleClickCallback = None |
|---|
| 798 | | self._deleteCallback = None |
|---|
| 799 | | super(GlyphCellView, self)._breakCycles() |
|---|
| 800 | | |
|---|
| 801 | | def _removeSelection(self): |
|---|
| 802 | | if self._deleteCallback is not None: |
|---|
| 803 | | self._deleteCallback(self) |
|---|
| 804 | | |
|---|
| 805 | | def _deprecatedDropCallback(self, sender, dropInfo): |
|---|
| 806 | | source = dropInfo["source"] |
|---|
| 807 | | indexes = [int(i) for i in dropInfo["data"]] |
|---|
| 808 | | if isinstance(source, vanilla.VanillaBaseObject): |
|---|
| 809 | | glyphs = [source[i] for i in indexes] |
|---|
| 810 | | else: |
|---|
| 811 | | glyphs = source.getGlyphsAtIndexes_(indexes) |
|---|
| 812 | | return self._dropCallback(self, glyphs, not dropInfo["isProposal"]) |
|---|
| 813 | | |
|---|
| 814 | | def getGlyphCellView(self): |
|---|
| 815 | | return self._glyphCellView |
|---|
| 816 | | |
|---|
| 817 | | def __getitem__(self, index): |
|---|
| 818 | | return self._glyphs[index] |
|---|
| 819 | | |
|---|
| 820 | | def get(self): |
|---|
| 821 | | return list(self._glyphs) |
|---|
| 822 | | |
|---|
| 823 | | def set(self, glyphs): |
|---|
| 824 | | self._glyphCellView.setGlyphs_(glyphs) |
|---|
| 825 | | self._glyphs = glyphs |
|---|
| 826 | | |
|---|
| 827 | | def setCellSize(self, (width, height)): |
|---|
| 828 | | self._glyphCellView.setCellSize_((width, height)) |
|---|
| 829 | | |
|---|
| 830 | | def getSelection(self): |
|---|
| 831 | | return self._glyphCellView.getSelection() |
|---|
| 832 | | |
|---|
| 833 | | def setSelection(self, selection): |
|---|
| 834 | | self._glyphCellView.setSelection_(selection) |
|---|
| 835 | | |
|---|
| 836 | | def setCellRepresentationArguments(self, **kwargs): |
|---|
| 837 | | self._glyphCellView.setCellRepresentationArguments_(**kwargs) |
|---|
| 838 | | |
|---|
| 839 | | def getCellRepresentationArguments(self): |
|---|
| 840 | | return self._glyphCellView.getCellRepresentationArguments() |
|---|
| 841 | | |
|---|
| | 781 | # ------------------------- |
|---|
| | 782 | # Information Pop Up Window |
|---|
| | 783 | # ------------------------- |
|---|
| | 784 | |
|---|
| | 785 | |
|---|
| | 786 | class GlyphInformationPopUpWindow(InformationPopUpWindow): |
|---|
| | 787 | |
|---|
| | 788 | def __init__(self): |
|---|
| | 789 | posSize = (200, 280) |
|---|
| | 790 | super(GlyphInformationPopUpWindow, self).__init__(posSize) |
|---|
| | 791 | self.glyphView = GlyphInformationGlyphView((5, 5, -5, 145)) |
|---|
| | 792 | |
|---|
| | 793 | self.line = HUDHorizontalLine((0, 160, -0, 1)) |
|---|
| | 794 | |
|---|
| | 795 | titleWidth = 100 |
|---|
| | 796 | entryLeft = 105 |
|---|
| | 797 | self.nameTitle = HUDTextBox((0, 170, titleWidth, 17), "Name:", alignment="right") |
|---|
| | 798 | self.name = HUDTextBox((entryLeft, 170, -5, 17), "") |
|---|
| | 799 | self.unicodeTitle = HUDTextBox((0, 190, titleWidth, 17), "Unicode:", alignment="right") |
|---|
| | 800 | self.unicode = HUDTextBox((entryLeft, 190, -5, 17), "") |
|---|
| | 801 | self.widthTitle = HUDTextBox((0, 210, titleWidth, 17), "Width:", alignment="right") |
|---|
| | 802 | self.width = HUDTextBox((entryLeft, 210, -5, 17), "") |
|---|
| | 803 | self.leftMarginTitle = HUDTextBox((0, 230, titleWidth, 17), "Left Margin:", alignment="right") |
|---|
| | 804 | self.leftMargin = HUDTextBox((entryLeft, 230, -5, 17), "") |
|---|
| | 805 | self.rightMarginTitle = HUDTextBox((0, 250, titleWidth, 17), "Right Margin:", alignment="right") |
|---|
| | 806 | self.rightMargin = HUDTextBox((entryLeft, 250, -5, 17), "") |
|---|
| | 807 | |
|---|
| | 808 | def set(self, glyph): |
|---|
| | 809 | # name |
|---|
| | 810 | name = glyph.name |
|---|
| | 811 | # unicode |
|---|
| | 812 | uni = glyph.unicode |
|---|
| | 813 | if uni is None: |
|---|
| | 814 | uni = "" |
|---|
| | 815 | else: |
|---|
| | 816 | uni = hex(uni)[2:].upper() |
|---|
| | 817 | if len(uni) < 4: |
|---|
| | 818 | uni = uni.zfill(4) |
|---|
| | 819 | # width |
|---|
| | 820 | width = glyph.width |
|---|
| | 821 | if width is None: |
|---|
| | 822 | width = 0 |
|---|
| | 823 | width = round(width, 3) |
|---|
| | 824 | if width == int(width): |
|---|
| | 825 | width = int(width) |
|---|
| | 826 | # left margin |
|---|
| | 827 | leftMargin = glyph.leftMargin |
|---|
| | 828 | if leftMargin is None: |
|---|
| | 829 | leftMargin = 0 |
|---|
| | 830 | leftMargin = round(leftMargin, 3) |
|---|
| | 831 | if leftMargin == int(leftMargin): |
|---|
| | 832 | leftMargin = int(leftMargin) |
|---|
| | 833 | # right margin |
|---|
| | 834 | rightMargin = glyph.rightMargin |
|---|
| | 835 | if rightMargin is None: |
|---|
| | 836 | rightMargin = 0 |
|---|
| | 837 | rightMargin = round(rightMargin, 3) |
|---|
| | 838 | if rightMargin == int(rightMargin): |
|---|
| | 839 | rightMargin = int(rightMargin) |
|---|
| | 840 | # set |
|---|
| | 841 | self.name.set(name) |
|---|
| | 842 | self.unicode.set(uni) |
|---|
| | 843 | self.width.set(width) |
|---|
| | 844 | self.leftMargin.set(leftMargin) |
|---|
| | 845 | self.rightMargin.set(rightMargin) |
|---|
| | 846 | self.glyphView.set(glyph) |
|---|
| | 847 | self._window.invalidateShadow() |
|---|
| | 848 | |
|---|
| | 849 | |
|---|
| | 850 | class DefconAppKitGlyphInformationNSView(NSView): |
|---|
| | 851 | |
|---|
| | 852 | def setGlyph_(self, glyph): |
|---|
| | 853 | self._glyph = glyph |
|---|
| | 854 | self.setNeedsDisplay_(True) |
|---|
| | 855 | |
|---|
| | 856 | def drawRect_(self, rect): |
|---|
| | 857 | if not hasattr(self, "_glyph"): |
|---|
| | 858 | return |
|---|
| | 859 | inset = 10 |
|---|
| | 860 | bounds = self.bounds() |
|---|
| | 861 | bounds = NSInsetRect(bounds, inset, inset) |
|---|
| | 862 | vWidth, vHeight = bounds.size |
|---|
| | 863 | glyph = self._glyph |
|---|
| | 864 | font = glyph.getParent() |
|---|
| | 865 | if font is None: |
|---|
| | 866 | upm = 1000 |
|---|
| | 867 | descender = -250 |
|---|
| | 868 | else: |
|---|
| | 869 | upm = font.info.unitsPerEm |
|---|
| | 870 | descender = font.info.descender |
|---|
| | 871 | scale = vHeight / upm |
|---|
| | 872 | centerOffset = (vWidth - (glyph.width * scale)) / 2 |
|---|
| | 873 | transform = NSAffineTransform.transform() |
|---|
| | 874 | transform.translateXBy_yBy_(centerOffset+inset, inset) |
|---|
| | 875 | transform.scaleBy_(scale) |
|---|
| | 876 | transform.translateXBy_yBy_(0, -descender) |
|---|
| | 877 | transform.concat() |
|---|
| | 878 | NSColor.whiteColor().set() |
|---|
| | 879 | path = glyph.getRepresentation("NSBezierPath") |
|---|
| | 880 | path.fill() |
|---|
| | 881 | |
|---|
| | 882 | |
|---|
| | 883 | class GlyphInformationGlyphView(vanilla.VanillaBaseObject): |
|---|
| | 884 | |
|---|
| | 885 | def __init__(self, posSize): |
|---|
| | 886 | self._setupView(DefconAppKitGlyphInformationNSView, posSize) |
|---|
| | 887 | |
|---|
| | 888 | def set(self, glyph): |
|---|
| | 889 | self._nsObject.setGlyph_(glyph) |
|---|
| | 890 | |
|---|