Skip to content

Commit

Permalink
Added the ExtraSelections in the TTKTextEdit
Browse files Browse the repository at this point in the history
  • Loading branch information
ceccopierangiolieugenio committed Jan 21, 2025
1 parent d080083 commit 89939f6
Show file tree
Hide file tree
Showing 8 changed files with 467 additions and 96 deletions.
18 changes: 8 additions & 10 deletions TermTk/TTkCore/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,18 +232,16 @@ def drawTTkString(self, pos, text, width=None, color=TTkColor.RST, alignment=TTk

text = text.align(width=width, alignment=alignment, color=color)
txt, colors = text.tab2spaces().getData()
a,b = max(0,-x), min(len(txt),self._width-x)
self._data[y][x+a:x+b] = txt[a:b]
if forceColor:
colors=[color]*len(colors)
a,b = max(0,-x), min(len(txt),self._width-x)
for i in range(a,b):
#self._set(y, x+i, txt[i-x], colors[i-x])
self._data[y][x+i] = txt[i]
if colors[i] == TTkColor.RST != color:
self._colors[y][x+i] = color.mod(x+i,y)
elif (not colors[i].hasBackground()) and color.hasBackground():
self._colors[y][x+i] = (color + colors[i]).mod(x+i,y)
else:
self._colors[y][x+i] = colors[i].mod(x+i,y)
else:
for i in range(a,b):
if color != TTkColor.RST:
self._colors[y][x+i] = (colors[i] | color).mod(x+i,y)
else:
self._colors[y][x+i] = colors[i].mod(x+i,y)
# Check the full wide chars on the edge of the two canvasses
if ((0 <= (x+a) < self._width) and self._data[y][x+a] == ''):
self._data[y][x+a] = TTkCfg.theme.unicodeWideOverflowCh[0]
Expand Down
62 changes: 16 additions & 46 deletions TermTk/TTkCore/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,11 @@ def __eq__(self, other):
self._fg == other._fg and
self._bg == other._bg )

# # self | other
# def __or__(self, other):
# # TTkLog.debug("__add__")
# if other._clean:
# return other
# clean = self._clean
# fg: str = self._fg or other._fg
# bg: str = self._bg or other._bg
# colorMod = self._colorMod or other._colorMod
# return _TTkColor(
# fg=fg, bg=bg,
# colorMod=colorMod,
# clean=clean)
# self | other
def __or__(self, other):
c = self.copy()
c._clean = False
return other + c

# self + other
def __add__(self, other):
Expand Down Expand Up @@ -307,21 +299,11 @@ def __eq__(self, other):
( self._mod == (other._mod if isinstance(other,_TTkColor_mod) else 0))
)

# # self | other
# def __or__(self, other):
# # TTkLog.debug("__add__")
# if other._clean:
# return other
# otherMod = other._mod if isinstance(other,_TTkColor_mod) else 0
# clean = self._clean
# fg: str = self._fg or other._fg
# bg: str = self._bg or other._bg
# mod: str = self._mod + otherMod
# colorMod = self._colorMod or other._colorMod
# return _TTkColor_mod(
# fg=fg, bg=bg, mod=mod,
# colorMod=colorMod,
# clean=clean)
# self | other
def __or__(self, other):
c = self.copy()
c._clean = False
return other + c

# self + other
def __add__(self, other):
Expand Down Expand Up @@ -407,24 +389,12 @@ def __eq__(self, other):
( self._link == (other._link if isinstance(other,_TTkColor_mod_link) else 0))
)

# # self | other
# def __or__(self, other):
# # TTkLog.debug("__add__")
# if other._clean:
# return other
# otherMod = other._mod if isinstance(other,_TTkColor_mod) else 0
# otherLink = other._link if isinstance(other,_TTkColor_mod_link) else ''
# clean = self._clean
# fg: str = self._fg or other._fg
# bg: str = self._bg or other._bg
# mod: str = self._mod + otherMod
# link:str = self._link or otherLink
# colorMod = self._colorMod or other._colorMod
# return _TTkColor_mod_link(
# fg=fg, bg=bg, mod=mod,
# colorMod=colorMod, link=link,
# clean=clean)

# self | other
def __or__(self, other):
c = self.copy()
c._clean = False
return other + c

# self + other
def __add__(self, other):
# TTkLog.debug("__add__")
Expand Down
11 changes: 11 additions & 0 deletions TermTk/TTkCore/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ class SelectionMode(int):
# ContiguousSelection = SelectionMode.ContiguousSelection
MultiSelection = SelectionMode.MultiSelection

class SelectionFormat(int):
'''
Selection properties
.. autosummary::
FullWidthSelection
'''
FullWidthSelection = 0x06000
'''When set on the characterFormat of a selection, the whole width of the text will be shown selected.'''


# Graph types
FILLED = 0x0001
LINE = 0x0002
Expand Down
10 changes: 5 additions & 5 deletions TermTk/TTkCore/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ def replace(self, *args, **kwargs) -> Self:

return ret

def completeColor(self, color, match=None, posFrom=None, posTo=None) -> Self:
def completeColor(self, color:TTkColor, match=None, posFrom=None, posTo=None) -> Self:
''' Complete the color of the entire string or a slice of it
The Fg and/or Bg of the string is replaced with the selected Fg/Bg color only if missing
Expand All @@ -479,17 +479,17 @@ def completeColor(self, color, match=None, posFrom=None, posTo=None) -> Self:
while pos := self._text.index(match, start) if match in self._text[start:] else None:
start = pos+lenMatch
for i in range(pos, pos+lenMatch):
ret._colors[i] += color
ret._colors[i] |= color
elif posFrom == posTo == None:
ret._colors = [c+color for c in self._colors]
ret._colors = [c|color for c in self._colors]
elif posFrom < posTo:
ret._colors = self._colors.copy()
posFrom = min(len(self._text),posFrom)
posTo = min(len(self._text),posTo)
for i in range(posFrom, posTo):
ret._colors[i] += color
ret._colors[i] |= color
else:
ret._colors = [c+color for c in self._colors]
ret._colors = [c|color for c in self._colors]
return ret


Expand Down
50 changes: 33 additions & 17 deletions TermTk/TTkGui/textcursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ def anchor(self) -> _CP:

def position(self) -> _CP:
return self._properties[self._cID].position

def cursors(self) -> list[_CP]:
return self._properties

def addCursor(self, line:int, pos:int) -> None:
self._cID = 0
Expand Down Expand Up @@ -490,6 +493,7 @@ def select(self, selection:SelectionType) -> None:
xTo += len(m.group(0))
p.position.pos = xTo
p.anchor.pos = xFrom
p.anchor.line = line
self._checkCursors(notify=self.position().toNum()!=currPos)

def selectedText(self) -> TTkString:
Expand Down Expand Up @@ -577,12 +581,38 @@ def applyColor(self, color:TTkColor) -> None:
self._document._dataLines[l] = line.setColor(color=color, posFrom=pf, posTo=pt)
self._autoChanged = True
self._document.setChanged(True)
self._document._acquire()
self._document._release()
self._document.contentsChanged.emit()
# self._document.contentsChange.emit(0,0,0)
self._autoChanged = True

def getHighlightedLines(self, fr:int, to:int, color:TTkColor) -> list[TTkString]:
def _getCoveredLines(self, fr:int, to:int, lines:list[TTkColor], color:TTkColor) -> list[TTkColor]:
for p in self._properties:
selSt = p.selectionStart().line
selEn = p.selectionEnd().line
if selEn >= fr and selSt<=to:
for i in range(max(selSt,fr),min(selEn,to)+1):
lines[i-fr] = color
return lines

def _getBlinkingCursors(self, fr:int, to:int, lines, color:TTkColor) -> list[TTkString]:
ret = lines
# Add Blinking cursor
if len(self._properties)>1:
for p in self._properties:
cp = p.position
if not 0<=(cp.line-fr)<len(ret): continue
ret[cp.line-fr] = ret[cp.line-fr].setColor(color=color+TTkColor.BLINKING, posFrom=cp.pos, posTo=cp.pos+1)
if cp.pos == len(ret[cp.line-fr]):
ret[cp.line-fr] = ret[cp.line-fr]+TTkString('↵',color+TTkColor.BLINKING)
elif ret[cp.line-fr].charAt(cp.pos) == ' ':
ret[cp.line-fr].setCharAt(pos=cp.pos, char='∙')
# ret[p.line-fr].setColorAt(pos=p.pos, color=TTkCfg.theme.treeLineColor+TTkColor.BLINKING)
#elif ret[p.line-fr].charAt(p.pos) == '\t':
# ret[p.line-fr].setCharAt(pos=p.pos, char='\t')
return ret

def _getHighlightedLines(self, fr:int, to:int, lines, color:TTkColor) -> list[TTkString]:
# Create a list of cursors (filtering out the ones which
# position/selection is outside the screen boundaries)
sel = []
Expand All @@ -593,7 +623,7 @@ def getHighlightedLines(self, fr:int, to:int, color:TTkColor) -> list[TTkString]
sel.append((selSt,selEn,p))

# Retrieve the sublist of lines to be required (displayed)
ret = self._document._dataLines[fr:to+1]
ret = lines
# Apply the selection color for each of them
for s in sel:
selSt, selEn, _ = s
Expand All @@ -602,18 +632,4 @@ def getHighlightedLines(self, fr:int, to:int, color:TTkColor) -> list[TTkString]
pf = 0 if i > selSt.line else selSt.pos
pt = len(l) if i < selEn.line else selEn.pos
ret[i-fr] = l.setColor(color=color, posFrom=pf, posTo=pt)
# Add Blinking cursor
if len(self._properties)>1:
for s in sel:
_, _, prop = s
p = prop.position
ret[p.line-fr] = ret[p.line-fr].setColor(color=color+TTkColor.BLINKING, posFrom=p.pos, posTo=p.pos+1)
if p.pos == len(ret[p.line-fr]):
ret[p.line-fr] = ret[p.line-fr]+TTkString('↵',color+TTkColor.BLINKING)
elif ret[p.line-fr].charAt(p.pos) == ' ':
ret[p.line-fr].setCharAt(pos=p.pos, char='∙')
# ret[p.line-fr].setColorAt(pos=p.pos, color=TTkCfg.theme.treeLineColor+TTkColor.BLINKING)
#elif ret[p.line-fr].charAt(p.pos) == '\t':
# ret[p.line-fr].setCharAt(pos=p.pos, char='\t')

return ret
Loading

0 comments on commit 89939f6

Please sign in to comment.