Browse Source

TTkTextEdit, improved selection in case of multilinme wrap and tabs

pull/34/head
Eugenio Parodi 4 years ago
parent
commit
57dfd3c3e2
  1. 76
      TermTk/TTkWidgets/texedit.py

76
TermTk/TTkWidgets/texedit.py

@ -219,12 +219,58 @@ class _TTkTextEditView(TTkAbstractScrollView):
self._lines[sy2].substring(fr=sx2)
self._lines = self._lines[:sy1+1] + self._lines[sy2+1:]
def _cursorAlign(self, x, y):
'''
Return the widget position of the closest editable char
in:
x,y = widget relative position
return:
x,y = widget relative position aligned to the close editable char
'''
y = max(0,min(y,len(self._lines)))
dt, (fr, to) = self._lines[y]
x = max(0,x)
s = self._dataLines[dt].substring(fr,to)
x = s.tabCharPos(x, self._tabSpaces)
x = len(s.substring(0,x).tab2spaces(self._tabSpaces))
return x, y
def _linePosFromCursor(self,x,y):
'''
return the line and the x position from the x,y cursor position relative to the widget
I assume the x,y position already normalized using the _cursorAlign function
'''
dt, (fr, to) = self._lines[y]
return self._dataLines[dt], self._dataLines[dt].tabCharPos(x+fr,self._tabSpaces)
def _cursorFromLinePos(self,liney,p):
'''
return the x,y cursor position relative to the widget from the
liney value relative to the self._lines and the
p = position value relative to the string related to self._lines[liney][0]
I know, big chink of crap
'''
# Find the bginning of the string in the "self._lines" (position from == 0)
while self._lines[liney][1][0]: liney -=1
dt = self._lines[liney][0]
while liney < len(self._lines):
dt1, (fr, to) = self._lines[liney]
if dt1 != dt:
break
if fr<=p<to:
s = self._dataLines[dt].substring(0,p).tab2spaces(self._tabSpaces)
return len(s)-fr, liney
liney += 1
liney-=1
dt, (fr, to) = self._lines[liney]
s = self._dataLines[dt].substring(fr,to)
return len(s.tab2spaces(self._tabSpaces)), liney
def mousePressEvent(self, evt) -> bool:
if self._readOnly:
return super().mousePressEvent(evt)
ox, oy = self.getViewOffsets()
y = max(0,min(evt.y + oy,len(self._lines)))
x = max(0,min(evt.x + ox,len(self._lines[y])))
x,y = self._cursorAlign(evt.x + ox, evt.y + oy)
self._cursorPos = (x,y)
self._selectionFrom = (x,y)
self._selectionTo = (x,y)
@ -236,8 +282,7 @@ class _TTkTextEditView(TTkAbstractScrollView):
if self._readOnly:
return super().mouseDragEvent(evt)
ox, oy = self.getViewOffsets()
y = max(0,min(evt.y + oy,len(self._lines)))
x = max(0,min(evt.x + ox,len(self._lines[y])))
x,y = self._cursorAlign(evt.x + ox, evt.y + oy)
cx = self._cursorPos[0]
cy = self._cursorPos[1]
@ -260,12 +305,12 @@ class _TTkTextEditView(TTkAbstractScrollView):
if self._readOnly:
return super().mouseDoubleClickEvent(evt)
ox, oy = self.getViewOffsets()
y = max(0,min(evt.y + oy,len(self._lines)))
x = max(0,min(evt.x + ox,len(self._lines[y])))
x,y = self._cursorAlign(evt.x + ox, evt.y + oy)
self._cursorPos = (x,y)
before = self._lines[y].substring(to=x)
after = self._lines[y].substring(fr=x)
l,p = self._linePosFromCursor(x,y)
before = l.substring(to=p)
after = l.substring(fr=p)
xFrom = len(before)
xTo = len(before)
@ -277,8 +322,8 @@ class _TTkTextEditView(TTkAbstractScrollView):
if m := after.search('^'+selectRE):
xTo += len(m.group(0))
self._selectionFrom = ( xFrom, y )
self._selectionTo = ( xTo, y )
self._selectionFrom = self._cursorFromLinePos(y,xFrom)
self._selectionTo = self._cursorFromLinePos(y,xTo)
self.update()
return True
@ -287,13 +332,13 @@ class _TTkTextEditView(TTkAbstractScrollView):
if self._readOnly:
return super().mouseTapEvent(evt)
ox, oy = self.getViewOffsets()
y = max(0,min(evt.y + oy,len(self._lines)))
x = max(0,min(evt.x + ox,len(self._lines[y])))
x,y = self._cursorAlign(evt.x + ox, evt.y + oy)
self._cursorPos = (x,y)
self._selectionFrom = ( 0 , y )
self._selectionTo = ( len(self._lines[y]) , y )
l,_ = self._linePosFromCursor(x,y)
self._selectionFrom = self._cursorFromLinePos(y,0)
self._selectionTo = self._cursorFromLinePos(y,len(l))
self.update()
return True
@ -301,8 +346,7 @@ class _TTkTextEditView(TTkAbstractScrollView):
if self._readOnly:
return super().mouseReleaseEvent(evt)
ox, oy = self.getViewOffsets()
y = max(0,min(evt.y + oy,len(self._lines)))
x = max(0,min(evt.x + ox,len(self._lines[y])))
x,y = self._cursorAlign(evt.x + ox, evt.y + oy)
self._cursorPos = (x,y)
self.update()
return True

Loading…
Cancel
Save