diff --git a/TermTk/TTkCore/canvas.py b/TermTk/TTkCore/canvas.py index 761009c7..9d6f76d6 100644 --- a/TermTk/TTkCore/canvas.py +++ b/TermTk/TTkCore/canvas.py @@ -245,7 +245,7 @@ class TTkCanvas: # TTkLog.debug("pushToTerminal") lastcolor = TTkColor.RST for y in range(0, self._height): - ansi = lbt.Mv.t(y+1,1) + ansi = TTkColor.RST+lbt.Mv.t(y+1,1) for x in range(0, self._width): ch = self._data[y][x] color = self._colors[y][x] diff --git a/TermTk/TTkCore/constant.py b/TermTk/TTkCore/constant.py index de7f61ca..aba2dda3 100644 --- a/TermTk/TTkCore/constant.py +++ b/TermTk/TTkCore/constant.py @@ -59,6 +59,11 @@ class TTkConstant: Cursor_Blinking_Bar = 0x0006 Cursor_Steady_Bar = 0x0007 + # Input types + Input_Text = 0x01 + Input_Number = 0x02 + Input_Password = 0x04 + # Alignment NONE = 0x0000 LEFT_ALIGN = 0x0001 diff --git a/TermTk/TTkLayouts/gridlayout.py b/TermTk/TTkLayouts/gridlayout.py index 1f2669e5..382c2227 100644 --- a/TermTk/TTkLayouts/gridlayout.py +++ b/TermTk/TTkLayouts/gridlayout.py @@ -107,6 +107,7 @@ class TTkGridLayout(TTkLayout): item = TTkGridWidgetItem(widget, row=row, col=col) self._gridItems[row][col] = item self.addItem(item) + widget.update(updateParent=True) def removeWidget(self, widget): TTkLayout.removeWidget(self, widget) @@ -283,3 +284,4 @@ class TTkGridLayout(TTkLayout): item.widget().update() elif isinstance(item, TTkLayout): item.update() + return True diff --git a/TermTk/TTkLayouts/layout.py b/TermTk/TTkLayouts/layout.py index 92150ab0..8cb5dfba 100644 --- a/TermTk/TTkLayouts/layout.py +++ b/TermTk/TTkLayouts/layout.py @@ -128,13 +128,15 @@ class TTkLayout(TTkLayoutItem): self._zSortItems() def update(self): + ret = False for i in self.children(): if isinstance(i, TTkWidgetItem) and not i.isEmpty(): - i.widget().update() + ret = ret or i.widget().update() # TODO: Have a look at this: # i.getCanvas().top() elif isinstance(i, TTkLayout): - i.update() + ret= ret or i.update() + return ret class TTkWidgetItem(TTkLayoutItem): slots = ('_widget','_z') diff --git a/TermTk/TTkWidgets/button.py b/TermTk/TTkWidgets/button.py index 92593539..066b38e7 100644 --- a/TermTk/TTkWidgets/button.py +++ b/TermTk/TTkWidgets/button.py @@ -42,6 +42,7 @@ class TTkButton(TTkWidget): self.setMinimumSize(2+len(self._text), 3) else: self.setMinimumSize(len(self._text)+2, 1) + self.setMaximumHeight(1) self._pressed = False self.setFocusPolicy(TTkWidget.ClickFocus) diff --git a/TermTk/TTkWidgets/lineedit.py b/TermTk/TTkWidgets/lineedit.py index 3d007208..fee77fe2 100644 --- a/TermTk/TTkWidgets/lineedit.py +++ b/TermTk/TTkWidgets/lineedit.py @@ -37,14 +37,19 @@ from TermTk.TTkWidgets.widget import * <--> Offset ''' class TTkLineEdit(TTkWidget): - __slots__ = ('_text', '_cursorPos', '_offset', '_replace') + __slots__ = ('_text', '_cursorPos', '_offset', '_replace', '_inputType') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) self._name = kwargs.get('name' , 'TTkButton' ) + self._inputType = kwargs.get('inputType' , TTkK.Input_Text ) self._text = kwargs.get('text' , '' ) - self._cursorPos = 0 + if self._inputType & TTkK.Input_Number and\ + not self._text.isdigit(): self._text = "" self._offset = 0 + self._cursorPos = 0 self._replace=False + self.setMaximumHeight(1) + self.setMinimumSize(10,1) self.setFocusPolicy(TTkWidget.ClickFocus) def _pushCursor(self): @@ -61,7 +66,10 @@ class TTkLineEdit(TTkWidget): else: color = TTkCfg.theme.lineEditTextColor w = self.width() - text = self._text[self._offset:] + if self._inputType & TTkK.Input_Password: + text = ("*"*(len(self._text)))[self._offset:] + else: + text = self._text[self._offset:] text = text[:w].ljust(w) self._canvas.drawText(pos=(0,0), text=text, color=color) @@ -106,6 +114,9 @@ class TTkLineEdit(TTkWidget): self._offset = self._cursorPos self._pushCursor() else: + if self._inputType & TTkK.Input_Number and \ + not evt.key.isdigit(): + return text = self._text pre = text[:self._cursorPos] if self._replace: diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index dd794d31..545cf9eb 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -143,12 +143,14 @@ class TTkWidget: def resizeEvent(self, w, h): pass def move(self, x, y): + if x==self._x and y==self._y: return self._x = x self._y = y self.update(repaint=False, updateLayout=False) self.moveEvent(x,y) def resize(self, w, h): + if w==self._width and h==self._height: return self._width = w self._height = h self._canvas.resize(self._width, self._height) @@ -168,6 +170,8 @@ class TTkWidget: return self._padt, self._padb, self._padl, self._padr def setPadding(self, top, bottom, left, right): + if self._padt == top and self._padb == bottom and \ + self._padl == left and self._padr == right: return self._padt = top self._padb = bottom self._padl = left @@ -423,12 +427,16 @@ class TTkWidget: def isVisible(self): return self._visible + # Event to be sent + def layoutUpdated(): pass + def update(self, repaint=True, updateLayout=False, updateParent=False): if repaint: TTkHelper.addUpdateBuffer(self) TTkHelper.addUpdateWidget(self) if updateLayout and self._layout is not None: - self._layout.update() + if self._layout.update(): + self.layoutUpdated() if updateParent and self._parent is not None: self._parent.update(updateLayout=True) diff --git a/TermTk/TTkWidgets/window.py b/TermTk/TTkWidgets/window.py index 5a66b6e1..6c216283 100644 --- a/TermTk/TTkWidgets/window.py +++ b/TermTk/TTkWidgets/window.py @@ -114,6 +114,14 @@ class TTkWindow(TTkWidget): return True return False + def layoutUpdated(self): + pass + # maxw,maxh = self.layout.maximumSize() + # minw,minh = self.layout.maximumSize() + # if + # self.resize(w+self._padl+self._padr,h+self._padt+self._padb) + + def focusInEvent(self): self.update() diff --git a/docs/BUGS.md b/docs/BUGS.md index 78e2c62c..8e294d26 100644 --- a/docs/BUGS.md +++ b/docs/BUGS.md @@ -2,4 +2,6 @@ ## Events - [Minor] ~~Overlapping widget click (below window receive the click event)~~ -- [Minor] Background color still propagate between widgets \ No newline at end of file +- [Minor] Background color still propagate between widgets +- [Minor] Window does not reshape to the max/min layout during initialization +- [Major] ~~[Canvas Paint] The Top Left corner start with the bottom right corner color~~ \ No newline at end of file diff --git a/docs/TODO.md b/docs/TODO.md index fa7d9632..1b7e1683 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -48,6 +48,65 @@ - [x] Add Show/Hide - [ ] Clean the way the parent is assigned, propagated *Widget \[setParent, addWidget, . . ], GridLayout \[addWidget]* +#### Button Widget + - [x] Basic Implementation + - [x] Events (Signal/Slots) + - [x] Themes +#### Line Edit Widget + - [x] Basic Implementation + - [ ] Events (Signal/Slots) + - [x] Themes + - [x] Input Type Numbers/Password +#### Text Edit Widget + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes + #### Table Widget + - [x] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes + #### Window Widget + - [x] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes + #### CheckBox Widget + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Radio button Widget + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Dropdown Widget + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Splitter widget + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Tab Widget + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Spin Box + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Progress Bar + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Graph Widget + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes +#### Header Menu + - [ ] Basic Implementation + - [ ] Events (Signal/Slots) + - [ ] Themes + + ### Layout - [ ] Add Weight in V and H Layout - [ ] Add addLayout method diff --git a/tests/test.ui.009.widgets.form.py b/tests/test.ui.009.widgets.form.py index e279ecf9..a25309f1 100755 --- a/tests/test.ui.009.widgets.form.py +++ b/tests/test.ui.009.widgets.form.py @@ -32,13 +32,33 @@ ttk.TTkLog.use_default_file_logging() root = ttk.TTk() win_form1 = ttk.TTkWindow(parent=root,pos=(1,1), size=(60,30), title="Test Window 1", border=True) +win_form1.setLayout(ttk.TTkGridLayout(columnMinWidth=1)) -ttk.TTkButton(parent=win_form1, pos=(1,3), size=(15,1), text='Button 1') -ttk.TTkButton(parent=win_form1, pos=(1,4), size=(15,1), text='Button 2') +win_form1.layout().addWidget(ttk.TTkButton(text='Button 1'),0,0) +win_form1.layout().addWidget(ttk.TTkButton(text='Button 2'),1,0) + +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Test 1'),2,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='Line Edit Test 1'),2,2) +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Test 2'),3,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='Line Edit Test 2'),3,2) +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Test 3'),4,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='Line Edit Test 3'),4,2) +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Test 4'),5,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='Line Edit Test 4'),5,2) +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Test 5'),6,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='Line Edit Test 5'),6,2) + +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Input Number'),7,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='123456', inputType=ttk.TTkK.Input_Number),7,2) +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Input Wrong Number'),8,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='No num Text', inputType=ttk.TTkK.Input_Number),8,2) + +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Input Password'),9,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='Password', inputType=ttk.TTkK.Input_Password),9,2) +win_form1.layout().addWidget(ttk.TTkLabel(text='Line Edit Number Password'),10,0) +win_form1.layout().addWidget(ttk.TTkLineEdit(text='Password', inputType=ttk.TTkK.Input_Password+ttk.TTkK.Input_Number),10,2) + +win_form1.layout().addWidget(ttk.TTkSpacer(),11,0) -ttk.TTkLineEdit(parent=win_form1, pos=(1,5), size=(20,1), text='Line Edit Test 1') -ttk.TTkLineEdit(parent=win_form1, pos=(1,6), size=(50,1), text='Line Edit Test 2') -ttk.TTkLineEdit(parent=win_form1, pos=(1,7), size=(50,1), text='Line Edit Test 3') -ttk.TTkLineEdit(parent=win_form1, pos=(1,8), size=(50,1), text='Line Edit Test 4') root.mainloop() \ No newline at end of file