diff --git a/TermTk/TTkCore/canvas.py b/TermTk/TTkCore/canvas.py index 5a156db9..76e7a9bf 100644 --- a/TermTk/TTkCore/canvas.py +++ b/TermTk/TTkCore/canvas.py @@ -71,6 +71,14 @@ class TTkCanvas: self._height = h TTkHelper.addPaintBuffer(self) + def clean(self, pos=(0, 0), size=None): + x,y = pos + w,h = size if size is not None else (self._width, self._height) + for iy in range(y,y+h): + for ix in range(x,x+w): + self._data[iy][ix] = ' ' + self._colors[iy][ix] = TTkColor.RST + def zTop(self): # TODO: Figure out how to use this pass diff --git a/TermTk/TTkCore/helper.py b/TermTk/TTkCore/helper.py index b2d6338d..5ba3c900 100644 --- a/TermTk/TTkCore/helper.py +++ b/TermTk/TTkCore/helper.py @@ -28,6 +28,7 @@ from TermTk.TTkCore.cfg import * class TTkHelper: # TODO: Add Setter/Getter + _focusWidget = None _rootCanvas = None _updateWidget = [] _paintBuffer = [] @@ -76,5 +77,18 @@ class TTkHelper: return (0, 0) return TTkHelper.absPos(widget.parentWidget()) + @staticmethod + def setFocus(widget): + TTkHelper._focusWidget = widget + + @staticmethod + def getFocus(): + return TTkHelper._focusWidget + + @staticmethod + def clearFocus(): + TTkHelper._focusWidget = None + + class Color(lbt.Color): pass class Mv(lbt.Mv): pass diff --git a/TermTk/TTkCore/ttk.py b/TermTk/TTkCore/ttk.py index 9948e087..7113ffc7 100644 --- a/TermTk/TTkCore/ttk.py +++ b/TermTk/TTkCore/ttk.py @@ -78,8 +78,13 @@ class TTk(TTkWidget): evt = self.events.get() if evt is TTk.MOUSE_EVENT: mevt = self.mouse_events.get() - self.mouseEvent(mevt) - # TTkLog.info(f"Mouse Event: {mevt}") + focusWidget = TTkHelper.getFocus() + if focusWidget is not None: + x,y = TTkHelper.absPos(focusWidget) + nmevt = mevt.clone(pos=(mevt.x-x, mevt.y-y)) + focusWidget.mouseEvent(nmevt) + else: + self.mouseEvent(mevt) elif evt is TTk.KEY_EVENT: kevt = self.key_events.get() self.keyEvent(kevt) diff --git a/TermTk/TTkWidgets/__init__.py b/TermTk/TTkWidgets/__init__.py index b4ee4ee3..b180b170 100644 --- a/TermTk/TTkWidgets/__init__.py +++ b/TermTk/TTkWidgets/__init__.py @@ -2,4 +2,5 @@ from .frame import * from .button import * from .layout import * from .widget import * +from .window import * from .testwidget import * \ No newline at end of file diff --git a/TermTk/TTkWidgets/button.py b/TermTk/TTkWidgets/button.py index 30e80a9f..015887f5 100644 --- a/TermTk/TTkWidgets/button.py +++ b/TermTk/TTkWidgets/button.py @@ -37,7 +37,7 @@ class TTkButton(TTkWidget): self._padl = 1 self._padr = 1 self._pressed = False - self.update() + self.setFocusPolicy(TTkWidget.ClickFocus) def paintEvent(self): if self._pressed: diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index 0f352105..f455f2bc 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -28,6 +28,19 @@ from TermTk.TTkCore.cfg import * from TermTk.TTkWidgets.layout import * class TTkWidget: + # Focus Policies + NoFocus = 0x0000 + ClickFocus = 0x0001 + WheelFocus = 0x0002 + TabFocus = 0x0004 + + # positions + NONE = 0x0000 + TOP = 0x0001 + BOTTOM = 0x0002 + LEFT = 0x0004 + RIGHT = 0x0008 + ''' Terminal ┌─────────────────────────────────────────┐ @@ -46,18 +59,27 @@ class TTkWidget: self._childs = [] self._name = kwargs.get('name', None ) self._parent = kwargs.get('parent', None ) + self._x = kwargs.get('x', 0 ) self._y = kwargs.get('y', 0 ) + self._x, self._y = kwargs.get('pos', (self._x, self._y)) self._width = kwargs.get('width' , 0 ) self._height = kwargs.get('height', 0 ) + self._width, self._height = kwargs.get('size', (self._width, self._height)) + self._padt = kwargs.get('paddingTop', 0 ) self._padb = kwargs.get('paddingBottom', 0 ) self._padl = kwargs.get('paddingLeft', 0 ) self._padr = kwargs.get('paddingRight', 0 ) + self._maxw = 0x10000 self._maxh = 0x10000 self._minw = 0x00000 self._minh = 0x00000 + + self._focus = False + self._focus_policy = TTkWidget.NoFocus + self._canvas = TTkCanvas( widget = self, width = self._width , @@ -89,6 +111,8 @@ class TTkWidget: def paintNotifyParent(self): parent = self._parent while parent is not None: + parent._canvas.clean() + parent.paintEvent() parent.paintChildCanvas() parent = parent._parent @@ -114,6 +138,17 @@ class TTkWidget: self.resize(w, h) self.move(x, y) + def setPadding(self, top, bottom, left, right): + self._padt = top + self._padb = bottom + self._padl = left + self._padr = right + if self._layout is not None: + self._layout.setGeometry( + self._padl, self._padt, + self._width - self._padl - self._padr, + self._height - self._padt - self._padb) + def mouseDoubleClickEvent(self, evt): pass def mouseMoveEvent(self, evt): pass def mouseDragEvent(self, evt): pass @@ -145,11 +180,7 @@ class TTkWidget: wx,wy,ww,wh = widget.geometry() # Skip the mouse event if outside this widget if x >= wx and x=wy and y +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.frame import TTkFrame +from TermTk.TTkWidgets.widget import TTkWidget + + +class TTkWindow(TTkWidget): + def __init__(self, *args, **kwargs): + TTkWidget.__init__(self, *args, **kwargs) + self._title = kwargs.get('title' , 0 ) + self.setPadding(3,1,1,1) + self._mouseDelta = (0,0) + self.setFocusPolicy(TTkWidget.ClickFocus) + self._draggable = False + self._resizable = TTkWidget.NONE + + def paintEvent(self): + if self.hasFocus(): + color = TTkColor.fg("#ffff55") + else: + color = TTkColor.RST + self._canvas.drawBox(pos=(0,0), color=color, size=(self._width,3)) + self._canvas.drawBox(pos=(0,2), color=color, size=(self._width,self._height-2)) + self._canvas.drawText(pos=(0,2), color=color, text="╟"+("─"*(self._width-2))+"╢") + self._canvas.drawText(pos=(2,1),text=self._title) + + def mousePressEvent(self, evt): + self._mouseDelta = (evt.x, evt.y) + w,h = self.size() + x,y = evt.x, evt.y + # If the mouse position is inside the header box enable the dragging feature + if x >= 1 and y>=1 and x +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import sys, os + +sys.path.append(os.path.join(sys.path[0],'..')) +import TermTk as ttk + +ttk.TTkLog.use_default_file_logging() + +root = ttk.TTk() + +win1 = ttk.TTkWindow(parent=root,pos = (1,1), size=(60,30), title="Test Window 1", border=True) + +win2 = ttk.TTkWindow(parent=win1,pos = (3,3), size=(40,20), title="Test Window 2", border=True) +win2.setLayout(ttk.TTkHBoxLayout()) +ttk.TTkTestWidget(parent=win2, border=False) + +win3 = ttk.TTkWindow(parent=root,pos = (20,5), size=(60,20), title="Test Window 3", border=True) +win3.setLayout(ttk.TTkHBoxLayout()) + +ttk.TTkTestWidget(parent=win3,border=True) +rightFrame = ttk.TTkFrame(parent=win3,border=True) +rightFrame.setLayout(ttk.TTkVBoxLayout()) + +ttk.TTkTestWidget(parent=rightFrame,border=True) +ttk.TTkFrame(parent=rightFrame,border=True) + +root.mainloop() \ No newline at end of file