Browse Source

fix(combobox): add widget if editable (#567)

pull/570/head
slook 3 months ago committed by GitHub
parent
commit
648189fde2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 64
      libs/pyTermTk/TermTk/TTkWidgets/combobox.py

64
libs/pyTermTk/TermTk/TTkWidgets/combobox.py

@ -81,12 +81,12 @@ class _TTkComboBoxPopup(TTkResizableFrame):
class TTkComboBox(TTkContainer): class TTkComboBox(TTkContainer):
''' TTkComboBox: ''' TTkComboBox:
Editable = False editable = False
:: ::
[ - select - ^] [ - select - ^]
Editable = True editable = True
:: ::
[ Text [^] [ Text [^]
@ -102,7 +102,7 @@ class TTkComboBox(TTkContainer):
'borderColor': TTkColor.fg("#ffff00") + TTkColor.BOLD}, 'borderColor': TTkColor.fg("#ffff00") + TTkColor.BOLD},
} }
__slots__ = ('_list', '_id', '_lineEdit', '_editable', '_insertPolicy', '_textAlign', '_popupFrame', __slots__ = ('_list', '_id', '_lineEdit', '_insertPolicy', '_textAlign', '_popupFrame',
#signals #signals
'currentIndexChanged', 'currentTextChanged', 'editTextChanged') 'currentIndexChanged', 'currentTextChanged', 'editTextChanged')
@ -154,20 +154,20 @@ class TTkComboBox(TTkContainer):
:type editable: bool, optional :type editable: bool, optional
''' '''
# Define Sub-Widgets
self._lineEdit = None # TTkLineEdit created only when required, if editable
self._popupFrame = None # TTkList created only when required, on _pressEvent()
# Define Signals # Define Signals
self.currentIndexChanged = pyTTkSignal(int) self.currentIndexChanged = pyTTkSignal(int)
self.currentTextChanged = pyTTkSignal(str) self.currentTextChanged = pyTTkSignal(str)
self.editTextChanged = pyTTkSignal(str) self.editTextChanged = pyTTkSignal(str)
# self.checked = pyTTkSignal()
self._lineEdit = TTkLineEdit()
super().__init__(**kwargs) super().__init__(**kwargs)
self._lineEdit.setParent(self)
self._lineEdit.returnPressed.connect(self._lineEditChanged)
self._list = list if list else [] self._list = list if list else []
self._insertPolicy = insertPolicy self._insertPolicy = insertPolicy
self._textAlign = textAlign self._textAlign = textAlign
self._id = index self._id = index
self._popupFrame = None
self.setEditable(editable) self.setEditable(editable)
self.setMinimumSize(5, 1) self.setMinimumSize(5, 1)
self.setMaximumHeight(1) self.setMaximumHeight(1)
@ -244,7 +244,8 @@ class TTkComboBox(TTkContainer):
pyTTkSlot() pyTTkSlot()
def clear(self) -> None: def clear(self) -> None:
'''Remove all the items.''' '''Remove all the items.'''
self._lineEdit.setText("") if self._lineEdit is not None:
self._lineEdit.setText("")
self._list = [] self._list = []
self._id = -1 self._id = -1
self.update() self.update()
@ -256,10 +257,11 @@ class TTkComboBox(TTkContainer):
:return: the line edit if available, None otherwise :return: the line edit if available, None otherwise
:rtype: :py:class:`TTkLineEdit` | None :rtype: :py:class:`TTkLineEdit` | None
''' '''
return self._lineEdit if self._editable else None return self._lineEdit
def resizeEvent(self, width: int, height: int) -> None: def resizeEvent(self, width: int, height: int) -> None:
self._lineEdit.setGeometry(1,0,width-4,height) if self._lineEdit is not None:
self._lineEdit.setGeometry(1,0,width-4,height)
def paintEvent(self, canvas: TTkCanvas) -> None: def paintEvent(self, canvas: TTkCanvas) -> None:
style = self.currentStyle() style = self.currentStyle()
@ -275,10 +277,10 @@ class TTkComboBox(TTkContainer):
canvas.drawTTkString(pos=(1,0), text=TTkString(text), width=w-3, alignment=self._textAlign, color=color) canvas.drawTTkString(pos=(1,0), text=TTkString(text), width=w-3, alignment=self._textAlign, color=color)
canvas.drawText(pos=(0,0), text="[", color=borderColor) canvas.drawText(pos=(0,0), text="[", color=borderColor)
if self._editable: if self._lineEdit is not None:
canvas.drawText(pos=(w-3,0), text="[^]", color=borderColor) canvas.drawText(pos=(w-3,0), text="[]", color=borderColor)
else: else:
canvas.drawText(pos=(w-2,0), text="^]", color=borderColor) canvas.drawText(pos=(w-2,0), text="]", color=borderColor)
def currentText(self) -> str: def currentText(self) -> str:
''' '''
@ -287,7 +289,7 @@ class TTkComboBox(TTkContainer):
:return: the current text :return: the current text
:rtype: str :rtype: str
''' '''
if self._editable: if self._lineEdit is not None:
return self._lineEdit.text().toAscii() return self._lineEdit.text().toAscii()
elif self._id >= 0: elif self._id >= 0:
return self._list[self._id] return self._list[self._id]
@ -314,7 +316,7 @@ class TTkComboBox(TTkContainer):
if index > len(self._list)-1: return if index > len(self._list)-1: return
if self._id == index: return if self._id == index: return
self._id = index self._id = index
if self._editable: if self._lineEdit is not None:
self._lineEdit.setText(self._list[self._id]) self._lineEdit.setText(self._list[self._id])
else: else:
self.currentTextChanged.emit(self._list[self._id]) self.currentTextChanged.emit(self._list[self._id])
@ -329,7 +331,7 @@ class TTkComboBox(TTkContainer):
:param text: :param text:
:type text: str :type text: str
''' '''
if self._editable: if self._lineEdit is not None:
self.setEditText(text) self.setEditText(text)
else: else:
if text not in self._list: if text not in self._list:
@ -346,7 +348,7 @@ class TTkComboBox(TTkContainer):
:param text: :param text:
:type text: :py:class:`TTkString` :type text: :py:class:`TTkString`
''' '''
if self._editable: if self._lineEdit is not None:
self._lineEdit.setText(text) self._lineEdit.setText(text)
def insertPolicy(self) -> TTkK.InsertPolicy: def insertPolicy(self) -> TTkK.InsertPolicy:
@ -369,31 +371,36 @@ class TTkComboBox(TTkContainer):
def isEditable(self) -> bool: def isEditable(self) -> bool:
''' '''
This field holds the editable status of this widget. This tells if an editable :py:class:`TTkLineEdit` exists within this widget or not.
:return: True if editable, False otherwise :return: True if editable, False otherwise
:rtype: bool :rtype: bool
''' '''
return self._editable return bool(self._lineEdit is not None)
def setEditable(self, editable:bool) -> None: def setEditable(self, editable:bool) -> None:
''' '''
Set the editable status of this widget. Create or destroy the editable :py:class:`TTkLineEdit` inside this widget.
:param editable: :param editable:
:type editable: bool :type editable: bool
''' '''
self._editable = editable
if editable: if editable:
self._lineEdit.show() if self._lineEdit is None:
self._lineEdit = TTkLineEdit(parent=self)
self._lineEdit.returnPressed.connect(self._lineEditChanged)
self.setFocusPolicy(TTkK.ClickFocus) self.setFocusPolicy(TTkK.ClickFocus)
else: else:
self._lineEdit.hide() if self._lineEdit is not None:
self._lineEdit.returnPressed.disconnect(self._lineEditChanged)
self.layout().removeWidget(self._lineEdit)
self._lineEdit.close()
self._lineEdit = None
self.setFocusPolicy(TTkK.ClickFocus | TTkK.TabFocus) self.setFocusPolicy(TTkK.ClickFocus | TTkK.TabFocus)
@pyTTkSlot(str) @pyTTkSlot(str)
def _callback(self, label:str) -> None: def _callback(self, label:str) -> None:
if self._editable: if self._lineEdit is not None:
self._lineEdit.setText(label) self._lineEdit.setText(label)
self.setCurrentIndex(self._list.index(label)) self.setCurrentIndex(self._list.index(label))
TTkHelper.removeOverlayAndChild(self._popupFrame) TTkHelper.removeOverlayAndChild(self._popupFrame)
@ -438,12 +445,13 @@ class TTkComboBox(TTkContainer):
return True return True
def keyEvent(self, evt:TTkKeyEvent) -> bool: def keyEvent(self, evt:TTkKeyEvent) -> bool:
if ( evt.type == TTkK.Character and evt.key==" " ) or \ if ((evt.type == TTkK.SpecialKey and evt.key==TTkK.Key_Down) or
( evt.type == TTkK.SpecialKey and evt.key in [TTkK.Key_Enter,TTkK.Key_Down] ): self._lineEdit is None and (evt.type == TTkK.Character and evt.key==" " or
evt.type == TTkK.SpecialKey and evt.key==TTkK.Key_Enter)):
self._pressEvent() self._pressEvent()
return True return True
return super().keyEvent(evt=evt) return super().keyEvent(evt=evt)
def focusInEvent(self) -> None: def focusInEvent(self) -> None:
if self._editable: if self._lineEdit is not None:
self._lineEdit.setFocus() self._lineEdit.setFocus()

Loading…
Cancel
Save