Example #1
0
 def processArrowKey(self, evt):
     direction = evt.keysym
     if self.type is None:
         return
     elif self.type == "text":
         self.window.entryIcon.arrowAction(direction)
         return
     elif self.type == "typeover":
         self.erase()
         if direction in ("Up", "Down"):
             fromIcon = self.icon
             fromSite = fromIcon.sites.lastCursorSite()
             toIcon, toSite = self._geometricTraverse(
                 fromIcon, fromSite, direction)
             self.moveToIconSite(toIcon, toSite, evt)
         siteBefore, siteAfter, text, idx = self.icon.typeoverSites()
         if direction == 'Right':
             # Move to site after (typeover will be automatically cancelled)
             self.setToIconSite(self.icon, siteAfter)
         if direction == 'Left':
             # reset typeover and move to previous site
             self.icon.setTypeover(0, siteAfter)
             self.icon.draw()
             self.window.refresh(self.icon.rect, redraw=False, clear=False)
             siteBeforeIcon = self.icon.childAt(siteBefore)
             if siteBeforeIcon is None:
                 toIcon, toSite = self.icon, siteBefore
             else:
                 toIcon, toSite = icon.rightmostSite(siteBeforeIcon)
             self.moveToIconSite(toIcon, toSite, evt)
         return
     if self.type == "window":
         x, y = self.pos
         directions = {
             "Up": (0, -1),
             "Down": (0, 1),
             "Left": (-1, 0),
             "Right": (1, 0)
         }
         xOff, yOff = directions[direction]
         x += xOff * WINDOW_CURSOR_INCREMENT
         y += yOff * WINDOW_CURSOR_INCREMENT
         windowWidth, windowHeight = self.window.image.size
         if  WINDOW_CURSOR_MARGIN < x < windowWidth - WINDOW_CURSOR_MARGIN and \
          WINDOW_CURSOR_MARGIN < y < windowHeight - WINDOW_CURSOR_MARGIN:
             self.erase()
             self.pos = x, y
             self.draw()
         return
     elif self.type == "icon":
         self._processIconArrowKey(evt)
Example #2
0
 def backspace(self, siteId, evt):
     redrawRect = self.topLevelParent().hierRect()
     parent = self.parent()
     leftArg = self.leftArg()
     rightArg = self.rightArg()
     op = self.operator
     win = self.window
     if parent is None and leftArg is None:
         entryAttachedIcon, entryAttachedSite = None, None
     elif parent is not None and leftArg is None:
         entryAttachedIcon = parent
         entryAttachedSite = parent.siteOf(self)
     else:  # leftArg is not None, attach to that
         entryAttachedIcon, entryAttachedSite = icon.rightmostSite(
             icon.findLastAttrIcon(leftArg), ignoreAutoParens=True)
     win.entryIcon = entryicon.EntryIcon(initialString=op, window=win)
     if leftArg is not None:
         leftArg.replaceChild(None, 'output')
     if rightArg is not None:
         rightArg.replaceChild(None, 'output')
         win.entryIcon.setPendingArg(rightArg)
     if parent is None:
         if leftArg is None:
             win.replaceTop(self, win.entryIcon)
         else:
             win.replaceTop(self, leftArg)
             entryAttachedIcon.replaceChild(win.entryIcon,
                                            entryAttachedSite)
     else:
         parentSite = parent.siteOf(self)
         if leftArg is not None:
             parent.replaceChild(leftArg, parentSite)
         entryAttachedIcon.replaceChild(win.entryIcon, entryAttachedSite)
     self.replaceChild(None, 'leftArg')
     self.replaceChild(None, 'rightArg')
     win.cursor.setToEntryIcon()
     win.redisplayChangedEntryIcon(evt, redrawRect)
Example #3
0
 def _lexicalTraverse(self, fromIcon, fromSite, direction):
     """Return the cursor position (icon and siteId) to the left or right according
     to the "text-flow"."""
     fromSiteType = fromIcon.typeOf(fromSite)
     if direction == 'Left':
         if fromSiteType in iconsites.parentSiteTypes:
             # Cursor is on an output site.  There's probably nowhere to go (return
             # the same cursor position).  In the unlikely case that it is attached to
             # something, make a recursive call with the proper cursor site (input)
             attachedIc = fromIcon.childAt(fromSite)
             if attachedIc is None:
                 return fromIcon, fromSite
             attachedSite = attachedIc.siteOf(fromIcon)
             return self._lexicalTraverse(attachedIc, attachedSite,
                                          direction)
         elif fromSite == 'seqOut':
             if isinstance(fromIcon, icon.BlockEnd):
                 return fromIcon, "seqIn"
             return icon.rightmostSite(fromIcon)
         elif fromSite == 'seqIn':
             prevStmt = fromIcon.prevInSeq()
             if prevStmt is None:
                 return fromIcon, fromSite
             if isinstance(prevStmt, icon.BlockEnd):
                 return prevStmt, "seqIn"
             return icon.rightmostSite(prevStmt)
         # Cursor is on an input site of some sort (input, attrIn, cprhIn)
         prevSite = fromIcon.sites.prevCursorSite(fromSite)
         if prevSite is None:
             highestIc = iconsites.highestCoincidentIcon(fromIcon)
             parent = highestIc.parent()
             if parent is None:
                 if highestIc.hasCoincidentSite():
                     return iconsites.lowestCoincidentSite(
                         highestIc, highestIc.hasCoincidentSite())
                 return highestIc, self._topSite(highestIc, seqDown=False)
             parentSite = parent.siteOf(highestIc)
             if highestIc == fromIcon and fromIcon.hasCoincidentSite():
                 return self._lexicalTraverse(parent, parentSite, direction)
             return iconsites.lowestCoincidentSite(parent, parentSite)
         iconAtPrevSite = fromIcon.childAt(prevSite)
         if iconAtPrevSite is None:
             return fromIcon, prevSite
         return icon.rightmostSite(iconAtPrevSite)
     else:  # 'Right'
         if fromSiteType in iconsites.parentSiteTypes or fromSiteType == 'seqIn':
             nextSite = fromIcon.sites.firstCursorSite()
             if nextSite is None:
                 return fromIcon, self._topSite(fromIcon, seqDown=True)
             if fromSite == 'output' and nextSite == fromIcon.hasCoincidentSite(
             ):
                 return self._lexicalTraverse(fromIcon, nextSite, direction)
             return fromIcon, nextSite
         if fromSite == 'seqOut':
             nextStmt = fromIcon.nextInSeq()
             if nextStmt is None:
                 return fromIcon, fromSite
             nextSite = nextStmt.sites.firstCursorSite()
             if nextSite is None:
                 return nextStmt, 'seqOut'
             return nextStmt, nextSite
         # Start from the lowest coincident site at the cursor
         ic, site = iconsites.lowestCoincidentSite(fromIcon, fromSite)
         childIc = ic.childAt(site)
         if childIc is not None:
             # There is an icon attached to it that can accept a cursor, go there
             firstChildSite = childIc.sites.firstCursorSite()
             if firstChildSite is not None:
                 return childIc, firstChildSite
         # There is no icon attached to the site that can accept a cursor.  Iterate up
         # the hierarchy to find an icon with a site to take one.  If none is found,
         # attach to the seqOut or output site of the top icon
         nextSite = ic.sites.nextCursorSite(site)
         nextIcon = ic
         while nextSite is None or nextSite == nextIcon.hasCoincidentSite():
             parent = nextIcon.parent()
             if parent is None:
                 return nextIcon, self._topSite(nextIcon, seqDown=True)
             parentSite = parent.siteOf(nextIcon)
             nextSite = parent.sites.nextCursorSite(parentSite)
             nextIcon = parent
         return nextIcon, nextSite
Example #4
0
 def backspace(self, siteId, evt):
     win = self.window
     if siteId == 'indexIcon':
         # Cursor is on the index site.  Try to remove brackets
         if self.hasSite('upperIcon') and self.childAt('upperIcon') or \
                 self.hasSite('stepIcon') and self.childAt('stepIcon') or \
                 self.hasSite('attrIcon') and self.childAt('attrIcon'):
             # Can't remove brackets: select the icon and its children
             win._select(self, op='hier')
         elif not self.childAt('indexIcon'):
             # Icon is empty, remove
             parent = self.parent()
             win.removeIcons([self])
             if parent is not None:
                 win.cursor.setToIconSite(parent, 'attrIcon')
         else:
             # Icon has a single argument and it's in the first slot: unwrap
             # the bracket from around it.
             redrawRegion = comn.AccumRects(
                 self.topLevelParent().hierRect())
             parent = self.parent()
             content = self.childAt('indexIcon')
             if parent is None:
                 # The icon was on the top level: replace it with its content
                 self.replaceChild(None, 'indexIcon')
                 win.replaceTop(self, content)
                 win.cursor.setToBestCoincidentSite(content, 'output')
             else:
                 # The icon has a parent, but since the subscript icon sits on
                 # an attribute site we can't attach, so create an entry icon
                 # and make the content a pending argument to it.
                 parentSite = parent.siteOf(self)
                 win.entryIcon = entryicon.EntryIcon(parent,
                                                     parentSite,
                                                     window=win)
                 parent.replaceChild(win.entryIcon, parentSite)
                 win.entryIcon.setPendingArg(content)
                 win.cursor.setToEntryIcon()
                 win.redisplayChangedEntryIcon(evt, redrawRegion.get())
                 return
             redrawRegion.add(
                 win.layoutDirtyIcons(filterRedundantParens=False))
             win.refresh(redrawRegion.get())
         return
     elif siteId == 'attrIcon':
         # The cursor is on the attr site, remove the end bracket
         redrawRegion = comn.AccumRects(self.topLevelParent().hierRect())
         entryicon.reopenParen(self)
         redrawRegion.add(win.layoutDirtyIcons(filterRedundantParens=False))
         win.refresh(redrawRegion.get())
         return
     # Site is after a colon.  Try to remove it
     redrawRegion = comn.AccumRects(self.topLevelParent().hierRect())
     if siteId == 'upperIcon':
         # Remove first colon
         mergeSite1 = 'indexIcon'
         mergeSite2 = 'upperIcon'
     else:
         # Remove second colon
         mergeSite1 = 'upperIcon'
         mergeSite2 = 'stepIcon'
     mergeIcon1 = self.childAt(mergeSite1)
     mergeIcon2 = self.childAt(mergeSite2)
     if mergeIcon2 is None:
         # Site after colon is empty (no need to merge)
         cursorIc, cursorSite = icon.rightmostFromSite(self, mergeSite1)
     elif mergeIcon1 is None:
         # Site before colon is empty, move the icon after the colon to it
         self.replaceChild(None, mergeSite2)
         self.replaceChild(mergeIcon2, mergeSite1)
         cursorIc, cursorSite = self, mergeSite1
     else:
         # Both sites are occupied merge the two expressions
         rightmostIc, rightmostSite = icon.rightmostSite(mergeIcon1)
         if rightmostIc.typeOf(rightmostSite) == 'input':
             # An empty input on the right allows merge without inserting entry icon
             self.replaceChild(None, mergeSite2)
             rightmostIc.replaceChild(mergeIcon2, rightmostSite)
             reorderexpr.reorderArithExpr(mergeIcon1)
             cursorIc, cursorSite = rightmostIc, rightmostSite
         else:
             lowestIc, lowestSite = iconsites.lowestCoincidentSite(
                 self, mergeSite2)
             if lowestIc.childAt(lowestSite):
                 # Can't merge the two expressions: insert an entry icon
                 self.replaceChild(None, mergeSite2)
                 win.entryIcon = entryicon.EntryIcon('', window=win)
                 win.entryIcon.setPendingArg(mergeIcon2)
                 rightmostIc.replaceChild(win.entryIcon, rightmostSite)
                 cursorIc = cursorSite = None
             else:
                 # Empty site right of colon, merge left side in to that and reorder
                 self.replaceChild(None, mergeSite2)
                 self.replaceChild(mergeIcon2, mergeSite1)
                 lowestIc.replaceChild(mergeIcon1, lowestSite)
                 reorderexpr.reorderArithExpr(lowestIc)
                 cursorIc, cursorSite = rightmostIc, rightmostSite
     # If there is a step site that wasn't part of the merge, shift it.
     if self.hasSite('stepIcon') and mergeSite2 != 'stepIcon':
         moveIcon = self.childAt('stepIcon')
         self.replaceChild(moveIcon, 'upperIcon')
     # Remove the colon (colonectomy)
     if self.hasSite('stepIcon'):
         self.changeNumSubscripts(2)
     else:
         self.changeNumSubscripts(1)
     # Place the cursor or new entry icon, and redraw
     if win.entryIcon is None:
         win.cursor.setToIconSite(cursorIc, cursorSite)
         redrawRegion.add(win.layoutDirtyIcons())
         win.refresh(redrawRegion.get())
     else:
         win.cursor.setToEntryIcon()
         win.redisplayChangedEntryIcon(evt, redrawRegion.get())
Example #5
0
 def backspace(self, siteId, evt):
     siteName, index = iconsites.splitSeriesSiteId(siteId)
     win = self.window
     if siteName == "values" and index == 0:
         # Cursor is on first input site.  Remove icon and replace with cursor
         text = self.op + '='
         valueIcons = [
             s.att for s in self.sites.values if s.att is not None
         ]
         targetIcon = self.childAt("targetIcon")
         if len(valueIcons) in (0, 1):
             # Zero or one argument, convert to entry icon (with pending arg if
             # there was an argument) attached to name icon
             redrawRegion = comn.AccumRects(
                 self.topLevelParent().hierRect())
             if self.parent() is not None:
                 print('AugmentedAssign has parent?????')
                 return
             if targetIcon is None:
                 win.entryIcon = entryicon.EntryIcon(initialString=text,
                                                     window=win)
                 win.replaceTop(self, win.entryIcon)
             else:
                 win.entryIcon = entryicon.EntryIcon(initialString=text,
                                                     window=win)
                 win.replaceTop(self, targetIcon)
                 targetIcon.replaceChild(win.entryIcon, 'attrIcon')
             if len(valueIcons) == 1:
                 win.entryIcon.setPendingArg(valueIcons[0])
         else:
             # Multiple remaining arguments: convert to tuple with entry icon as
             # first element
             redrawRegion = comn.AccumRects(
                 self.topLevelParent().hierRect())
             valueIcons = [
                 s.att for s in self.sites.values if s.att is not None
             ]
             newTuple = listicons.TupleIcon(window=win, noParens=True)
             if targetIcon is None:
                 win.entryIcon = entryicon.EntryIcon(initialString=text,
                                                     window=win)
                 newTuple.replaceChild(win.entryIcon, "argIcons_0")
             else:
                 win.entryIcon = entryicon.EntryIcon(initialString=text,
                                                     window=win)
                 targetIcon.replaceChild(win.entryIcon, 'attrIcon')
                 newTuple.replaceChild(targetIcon, 'argIcons_0')
             for i, arg in enumerate(valueIcons):
                 if i == 0:
                     win.entryIcon.setPendingArg(arg)
                 else:
                     self.replaceChild(None, self.siteOf(arg))
                     newTuple.insertChild(arg, "argIcons", i)
             win.replaceTop(self, newTuple)
         win.cursor.setToEntryIcon()
         win.redisplayChangedEntryIcon(evt, redrawRegion.get())
     elif siteName == "values":
         # Cursor is on comma input.  Delete if empty or previous site is empty
         prevSite = iconsites.makeSeriesSiteId(siteName, index - 1)
         childAtCursor = self.childAt(siteId)
         if childAtCursor and self.childAt(prevSite):
             cursors.beep()
             return
         topIcon = self.topLevelParent()
         redrawRegion = comn.AccumRects(topIcon.hierRect())
         if not self.childAt(prevSite):
             self.removeEmptySeriesSite(prevSite)
             win.cursor.setToIconSite(self, prevSite)
         else:
             rightmostIcon = icon.findLastAttrIcon(self.childAt(prevSite))
             rightmostIcon, rightmostSite = icon.rightmostSite(
                 rightmostIcon)
             self.removeEmptySeriesSite(siteId)
             win.cursor.setToIconSite(rightmostIcon, rightmostSite)
         redrawRegion.add(win.layoutDirtyIcons(filterRedundantParens=False))
         win.refresh(redrawRegion.get())
         win.undo.addBoundary()