diff --git a/ttkDesigner/app/designer.py b/ttkDesigner/app/designer.py index d7a982b8..72566e78 100644 --- a/ttkDesigner/app/designer.py +++ b/ttkDesigner/app/designer.py @@ -36,8 +36,7 @@ from TermTk import TTkFileTree, TTkTextEdit from TermTk import TTkLayout, TTkGridLayout, TTkVBoxLayout, TTkHBoxLayout from TermTk import TTkSplitter -from TermTk import TTkLogViewer, TTkTomInspector - +from TermTk import TTkLogViewer from TermTk import TTkUiLoader, TTkUtil from .cfg import * diff --git a/ttkDesigner/app/signalsloteditor.py b/ttkDesigner/app/signalsloteditor.py index a12d6b0e..4417b6bb 100644 --- a/ttkDesigner/app/signalsloteditor.py +++ b/ttkDesigner/app/signalsloteditor.py @@ -189,7 +189,7 @@ class _SignalSlotItem(ttk.TTkTreeWidgetItem): signals[ccName] = ttk.TTkUiProperties[ccName]['signals'] return signals,slots -class SignalSlotEditor(ttk.TTkWidget): +class SignalSlotEditor(ttk.TTkContainer): __slots__ = ('_items', '_designer') def __init__(self, designer, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/ttkDesigner/app/superobj/__init__.py b/ttkDesigner/app/superobj/__init__.py index 11eaf060..97c78875 100644 --- a/ttkDesigner/app/superobj/__init__.py +++ b/ttkDesigner/app/superobj/__init__.py @@ -24,6 +24,7 @@ from .supercontrol import SuperControlWidget from .superwidget import SuperWidget +from .superwidgetcontainer import SuperWidgetContainer from .superwidgettextedit import SuperWidgetTextEdit from .superwidgetradiobutton import SuperWidgetRadioButton from .superwidgetframe import SuperWidgetFrame diff --git a/ttkDesigner/app/superobj/superlayout.py b/ttkDesigner/app/superobj/superlayout.py index 1f852d97..9ead5eb7 100644 --- a/ttkDesigner/app/superobj/superlayout.py +++ b/ttkDesigner/app/superobj/superlayout.py @@ -26,7 +26,7 @@ import TermTk as ttk import ttkDesigner.app.superobj as so from .superobj import SuperObject -class SuperLayout(ttk.TTkWidget): +class SuperLayout(ttk.TTkContainer): __slots__ = ('_lay', '_dropBorder', '_superRootWidget', '_selectable', '_designer') def __init__(self, lay, designer, *args, **kwargs): self._designer = designer @@ -183,28 +183,41 @@ class SuperLayout(ttk.TTkWidget): self._lay.addItem(sl._lay) sl.show() sl.move(evt.x-hsx, evt.y-hsy) - elif issubclass(type(data), so.SuperWidget): + elif issubclass(type(data), so.SuperWidgetContainer): sw = data self.addSuperWidget(sw) self._lay.addWidget(sw._wid) sl = sw._superLayout sw.move(evt.x-hsx, evt.y-hsy) sw.show() - elif issubclass(type(data),ttk.TTkWidget): + elif issubclass(type(data), so.SuperWidget): + sw = data + self.addSuperWidget(sw) + self._lay.addWidget(sw._wid) + sl = None + sw.move(evt.x-hsx, evt.y-hsy) + sw.show() + elif issubclass(type(data),ttk.TTkContainer): self.addSuperWidget(sw := so.SuperWidget.swFromWidget(designer=self._designer, wid=data, pos=(evt.x-hsx, evt.y-hsy))) self._lay.addWidget(data) sw.move(evt.x-hsx, evt.y-hsy) sl = sw._superLayout + elif issubclass(type(data),ttk.TTkWidget): + self.addSuperWidget(sw := so.SuperWidget.swFromWidget(designer=self._designer, wid=data, pos=(evt.x-hsx, evt.y-hsy))) + self._lay.addWidget(data) + sw.move(evt.x-hsx, evt.y-hsy) + sl = None else: return False self.layout().update() # set the Drop Border in case this layout auto resize - if issubclass(type(self.layout()),ttk.TTkGridLayout): - sl.setDropBorder(1) - else: - sl.setDropBorder(0) + if sl: + if issubclass(type(self.layout()),ttk.TTkGridLayout): + sl.setDropBorder(1) + else: + sl.setDropBorder(0) self.update() self._designer.weModified.emit() diff --git a/ttkDesigner/app/superobj/superwidget.py b/ttkDesigner/app/superobj/superwidget.py index 27d19fcc..e418c040 100644 --- a/ttkDesigner/app/superobj/superwidget.py +++ b/ttkDesigner/app/superobj/superwidget.py @@ -27,8 +27,8 @@ import TermTk as ttk import ttkDesigner.app.superobj as so from .superobj import SuperObject -class SuperWidget(ttk.TTkWidget): - __slots__ = ('_wid', '_superLayout', '_superRootWidget', '_designer', +class SuperWidget(ttk.TTkContainer): + __slots__ = ('_wid', '_superRootWidget', '_designer', 'superMoved', 'superResized') def __init__(self, designer, wid, *args, **kwargs): self.superMoved = ttk.pyTTkSignal(int,int) @@ -37,18 +37,10 @@ class SuperWidget(ttk.TTkWidget): self._wid = wid self._wid.move(*kwargs['pos']) self._wid._canvas.show() - self._superLayout = so.SuperLayout(designer=designer, lay=self._wid.layout(),) self._superRootWidget = kwargs.get('superRootWidget',False) - kwargs['layout'] = ttk.TTkGridLayout() - kwargs['layout'].addWidget(self._superLayout) kwargs['maxSize'] = wid.maximumSize() kwargs['minSize'] = wid.minimumSize() kwargs['size'] = wid.size() - padt, padb, padl, padr = wid.getPadding() - kwargs['paddingTop'] = padt - kwargs['paddingBottom'] = padb - kwargs['paddingLeft'] = padl - kwargs['paddingRight'] = padr super().__init__(*args, **kwargs) #self.resize(*self._wid.size()) h,s,l = randint(0,359),100,randint(60,80) @@ -81,20 +73,6 @@ class SuperWidget(ttk.TTkWidget): 'Name': { 'get': { 'cb':ttk.TTkWidget.name, 'type':str} , 'set': { 'cb':lambda _,n: self.setSuperName(n), 'type':str} }, - 'Layout' : { - 'get': { 'cb': lambda _: self._superLayout.layout().__class__ , 'type':'singleflag', - 'flags': { - 'TTkLayout' : ttk.TTkLayout , - 'TTkGridLayout' : ttk.TTkGridLayout , - 'TTkVBoxLayout' : ttk.TTkVBoxLayout , - 'TTkHBoxLayout' : ttk.TTkHBoxLayout } }, - 'set': { 'cb': lambda _,l: self.changeSuperLayout(l) , 'type':'singleflag', - 'flags': { - 'TTkLayout' : ttk.TTkLayout , - 'TTkGridLayout' : ttk.TTkGridLayout , - 'TTkVBoxLayout' : ttk.TTkVBoxLayout , - 'TTkHBoxLayout' : ttk.TTkHBoxLayout } }, - } } exclude = [] return additions, exceptions, exclude @@ -109,14 +87,12 @@ class SuperWidget(ttk.TTkWidget): ret = { 'class' : wid.__class__.__name__, 'params' : SuperObject.dumpParams(wid), - 'layout': self._superLayout.dumpDict() } return ret @staticmethod def _swFromWidget(wid, swClass, *args, **kwargs): sw = swClass(wid=wid, *args, **kwargs) - sw.changeSuperLayout(type(wid.layout())) return sw @staticmethod @@ -125,11 +101,12 @@ class SuperWidget(ttk.TTkWidget): for c, sc in { ttk.TTkTextEdit: so.SuperWidgetTextEdit, ttk.TTkRadioButton: so.SuperWidgetRadioButton, - ttk.TTkFrame: so.SuperWidgetFrame, # ttk.TTkResizableFrame: so.SuperWidgetFrame, # ttk.TTkWindow: so.SuperWidgetFrame, ttk.TTkSplitter: so.SuperWidgetSplitter, ttk.TTkMenuButton: so.SuperWidgetMenuButton, + ttk.TTkFrame: so.SuperWidgetFrame, + ttk.TTkContainer: so.SuperWidgetContainer, }.items(): if c in type(wid).mro(): swClass = sc @@ -153,7 +130,7 @@ class SuperWidget(ttk.TTkWidget): x,y,w,h = layout.geometry() sl = sup = so.SuperLayout.slFromLayout(designer=designer, layout=layout, lay=ttk.TTkLayout(), pos=(x,y), size=(w,h), selectable=True) children = widProp['children'] - else: + elif issubclass(ttkClass,ttk.TTkContainer): setLayout = 'layout' in widProp setMenuBar = 'menuBar' in widProp tui = { @@ -174,9 +151,22 @@ class SuperWidget(ttk.TTkWidget): 'connections':[] } wid = ttk.TTkUiLoader.loadDict(demiProp) - sup = so.SuperWidget.swFromWidget(designer=designer, wid=wid, pos=wid.pos()) + sup = so.SuperWidgetContainer.swFromWidget(designer=designer, wid=wid, pos=wid.pos()) sl = sup._superLayout children = widProp['layout']['children'] if setLayout else [] + else: + setMenuBar = 'menuBar' in widProp + tui = { + 'class' : widProp['class'], + 'params' : widProp['params'] } + demiProp = { + 'version':'1.0.0', + 'tui': tui, + 'connections':[] + } + wid = ttk.TTkUiLoader.loadDict(demiProp) + sup = so.SuperWidget.swFromWidget(designer=designer, wid=wid, pos=wid.pos()) + children = [] for ch in children: sch = SuperWidget.loadDict(designer, parent, ch) @@ -193,26 +183,9 @@ class SuperWidget(ttk.TTkWidget): schl.setDropBorder(0) return sup - def changeSuperLayout(self, layout): - sl = self._superLayout - self.layout().removeWidget(sl) - if layout == ttk.TTkVBoxLayout: - sl = so.SuperLayoutVBox(designer=self._designer, lay=self._wid.layout(), selectable=False) - elif layout == ttk.TTkHBoxLayout: - sl = so.SuperLayoutHBox(designer=self._designer, lay=self._wid.layout(), selectable=False) - elif layout == ttk.TTkGridLayout: - sl = so.SuperLayoutGrid(designer=self._designer, lay=self._wid.layout(), selectable=False) - else: - sl = so.SuperLayout( designer=self._designer, lay=self._wid.layout(), selectable=False) - self._superLayout = sl - self._wid.setLayout(layout()) - self.layout().addWidget(sl) - self._designer.weModified.emit() - def updateAll(self): self.resize(*(self._wid.size())) self.move(*(self._wid.pos())) - self.setPadding(*(self._wid.getPadding())) self.setMaximumSize(*(self._wid.maximumSize())) self.setMinimumSize(*(self._wid.minimumSize())) self.update() @@ -252,13 +225,6 @@ class SuperWidget(ttk.TTkWidget): def superChild(self): return self._wid - def dropEvent(self, evt) -> bool: - padt, padb, padl, padr = self._wid.getPadding() - # evt = evt.copy() - evt.x-=padl - evt.y-=padt - return self._superLayout.dropEvent(evt) - def move(self, x: int, y: int): self._wid.move(x,y) self.update() @@ -274,11 +240,10 @@ class SuperWidget(ttk.TTkWidget): def paintEvent(self, canvas): w,h = self.size() if SuperWidget._showLayout: - t,b,l,r = self._wid.getPadding() for y in range(h): canvas.drawText(pos=(0,y),text='',width=w,color=self._layoutColor) - for y in range(t,h-b): - canvas.drawText(pos=(l,y),text='',width=w-r-l,color=self._layoutPadColor) + for y in range(0,h): + canvas.drawText(pos=(0,y),text='',width=w,color=self._layoutPadColor) # canvas.fill(color=self._layoutColor) # canvas.fill(pos=(l,t), size=(w-r-l,h-b-t), color=self._layoutPadColor) else: diff --git a/ttkDesigner/app/superobj/superwidgetcontainer.py b/ttkDesigner/app/superobj/superwidgetcontainer.py new file mode 100644 index 00000000..d082c8c9 --- /dev/null +++ b/ttkDesigner/app/superobj/superwidgetcontainer.py @@ -0,0 +1,123 @@ +# MIT License +# +# Copyright (c) 2023 Eugenio Parodi +# +# 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 random import randint + +import TermTk as ttk + +import ttkDesigner.app.superobj as so +from .superobj import SuperObject + +class SuperWidgetContainer(so.SuperWidget): + __slots__ = ('_superLayout') + def __init__(self, designer, wid, *args, **kwargs): + + self._superLayout = so.SuperLayout(designer=designer, lay=wid.layout(),) + self._superRootWidget = kwargs.get('superRootWidget',False) + kwargs['layout'] = ttk.TTkGridLayout() + kwargs['layout'].addWidget(self._superLayout) + + padt, padb, padl, padr = wid.getPadding() + kwargs['paddingTop'] = padt + kwargs['paddingBottom'] = padb + kwargs['paddingLeft'] = padl + kwargs['paddingRight'] = padr + super().__init__(designer, wid, *args, **kwargs) + + def getSuperProperties(self): + additions, exceptions, exclude = super().getSuperProperties() + exceptions |= { + 'Layout' : { + 'get': { 'cb': lambda _: self._superLayout.layout().__class__ , 'type':'singleflag', + 'flags': { + 'TTkLayout' : ttk.TTkLayout , + 'TTkGridLayout' : ttk.TTkGridLayout , + 'TTkVBoxLayout' : ttk.TTkVBoxLayout , + 'TTkHBoxLayout' : ttk.TTkHBoxLayout } }, + 'set': { 'cb': lambda _,l: self.changeSuperLayout(l) , 'type':'singleflag', + 'flags': { + 'TTkLayout' : ttk.TTkLayout , + 'TTkGridLayout' : ttk.TTkGridLayout , + 'TTkVBoxLayout' : ttk.TTkVBoxLayout , + 'TTkHBoxLayout' : ttk.TTkHBoxLayout } }, + } + } + return additions, exceptions, exclude + + def dumpDict(self): + ret = super().dumpDict() + ret |= { + 'layout': self._superLayout.dumpDict() + } + return ret + + @staticmethod + def _swFromWidget(wid, swClass, *args, **kwargs): + sw = swClass(wid=wid, *args, **kwargs) + sw.changeSuperLayout(type(wid.layout())) + return sw + + def dropEvent(self, evt) -> bool: + padt, padb, padl, padr = self._wid.getPadding() + # evt = evt.copy() + evt.x-=padl + evt.y-=padt + return self._superLayout.dropEvent(evt) + + def changeSuperLayout(self, layout): + sl = self._superLayout + self.layout().removeWidget(sl) + if layout == ttk.TTkVBoxLayout: + sl = so.SuperLayoutVBox(designer=self._designer, lay=self._wid.layout(), selectable=False) + elif layout == ttk.TTkHBoxLayout: + sl = so.SuperLayoutHBox(designer=self._designer, lay=self._wid.layout(), selectable=False) + elif layout == ttk.TTkGridLayout: + sl = so.SuperLayoutGrid(designer=self._designer, lay=self._wid.layout(), selectable=False) + else: + sl = so.SuperLayout( designer=self._designer, lay=self._wid.layout(), selectable=False) + self._superLayout = sl + self._wid.setLayout(layout()) + self.layout().addWidget(sl) + self._designer.weModified.emit() + + def updateAll(self): + self.setPadding(*(self._wid.getPadding())) + super().updateAll() + + def paintEvent(self, canvas): + w,h = self.size() + if so.SuperWidget._showLayout: + t,b,l,r = self._wid.getPadding() + for y in range(h): + canvas.drawText(pos=(0,y),text='',width=w,color=self._layoutColor) + for y in range(t,h-b): + canvas.drawText(pos=(l,y),text='',width=w-r-l,color=self._layoutPadColor) + # canvas.fill(color=self._layoutColor) + # canvas.fill(pos=(l,t), size=(w-r-l,h-b-t), color=self._layoutPadColor) + else: + self._wid.getCanvas().updateSize() + self._wid.paintEvent(self._wid.getCanvas()) + canvas.paintCanvas( + self._wid.getCanvas(), + ( 0, 0, w, h), # geometry + ( 0, 0, w, h), # slice + ( 0, 0, w, h)) # bound \ No newline at end of file diff --git a/ttkDesigner/app/superobj/superwidgetframe.py b/ttkDesigner/app/superobj/superwidgetframe.py index 798a150c..7a02c463 100644 --- a/ttkDesigner/app/superobj/superwidgetframe.py +++ b/ttkDesigner/app/superobj/superwidgetframe.py @@ -24,7 +24,7 @@ import TermTk as ttk import ttkDesigner.app.superobj as so from ttkDesigner.app.menuBarEditor import MenuBarEditor -class SuperWidgetFrame(so.SuperWidget): +class SuperWidgetFrame(so.SuperWidgetContainer): def getSuperProperties(self): additions, exceptions, exclude = super().getSuperProperties() additions |= { diff --git a/ttkDesigner/app/superobj/superwidgetsplitter.py b/ttkDesigner/app/superobj/superwidgetsplitter.py index df6dae08..44b1149a 100644 --- a/ttkDesigner/app/superobj/superwidgetsplitter.py +++ b/ttkDesigner/app/superobj/superwidgetsplitter.py @@ -25,7 +25,7 @@ import ttkDesigner.app.superobj as so from .superobj import SuperObject -class SuperWidgetSplitter(so.SuperWidget): +class SuperWidgetSplitter(so.SuperWidgetContainer): def getSuperProperties(self): additions, exceptions, exclude = super().getSuperProperties() exclude += ['layout'] diff --git a/ttkDesigner/app/treeinspector.py b/ttkDesigner/app/treeinspector.py index 006d0d5b..cd33744f 100644 --- a/ttkDesigner/app/treeinspector.py +++ b/ttkDesigner/app/treeinspector.py @@ -23,6 +23,7 @@ import TermTk as ttk from .superobj.superwidget import SuperWidget +from .superobj.superwidgetcontainer import SuperWidgetContainer from .superobj.superlayout import SuperLayout from .superobj.superwidgetframe import SuperWidgetFrame from .superobj.superwidgetmenubutton import SuperWidgetMenuButton @@ -151,7 +152,7 @@ class TreeInspector(ttk.TTkGridLayout): elif issubclass(type(superThing), SuperLayout): thing = thing._lay expanded = True # ttk.TTkHelper.isParent(widSelected,thing) if widSelected else False - if issubclass(type(superThing), SuperWidget): + if issubclass(type(superThing), SuperWidgetContainer): top = _TTkTomTreeWidgetItem([ thing._name, thing.__class__.__name__, str(thing.isVisible()), @@ -159,6 +160,13 @@ class TreeInspector(ttk.TTkGridLayout): tomWidget=thing, tomSuperWidget=superThing, expanded=expanded) + elif issubclass(type(superThing), SuperWidget): + top = _TTkTomTreeWidgetItem([ + thing._name, thing.__class__.__name__, + str(thing.isVisible()),""], + tomWidget=thing, + tomSuperWidget=superThing, + expanded=expanded) elif issubclass(type(superThing), SuperLayout): top = _TTkTomTreeWidgetItem([ 'Layout', thing.__class__.__name__, @@ -169,7 +177,7 @@ class TreeInspector(ttk.TTkGridLayout): expanded=expanded) if issubclass(type(superThing), SuperWidgetFrame): _processMenuBars(thing, top) - if issubclass(type(superThing), SuperWidget): + if issubclass(type(superThing), SuperWidgetContainer): for c in superThing._superLayout.layout().children(): top.addChild(TreeInspector._getTomTreeItem(c,widSelected,designer)) elif issubclass(type(superThing), SuperLayout): diff --git a/ttkDesigner/app/widgetbox.py b/ttkDesigner/app/widgetbox.py index 02abce11..a37ba272 100644 --- a/ttkDesigner/app/widgetbox.py +++ b/ttkDesigner/app/widgetbox.py @@ -68,7 +68,7 @@ dWidgets = { 'Debug':{ "Log Viewer" : { "class":ttk.TTkLogViewer, "params":{'size':(60,10)}}, "Input View" : { "class":ttk.TTkKeyPressView, "params":{'size':(60,3)}}, - "Tom Inspector" : { "class":ttk.TTkTomInspector, "params":{'size':(40,10)}, "disabled": True}, + # "Tom Inspector" : { "class":ttk.TTkTomInspector, "params":{'size':(40,10)}, "disabled": True}, "Test Widget" : { "class":ttk.TTkTestWidgets, "params":{'size':(40,10)}, "disabled": True}, "Test Widget info" : { "class":ttk.TTkTestWidgetSizes, "params":{'size':(40,10)}}, } diff --git a/ttkDesigner/app/windoweditor.py b/ttkDesigner/app/windoweditor.py index a3074d9a..bdeda442 100644 --- a/ttkDesigner/app/windoweditor.py +++ b/ttkDesigner/app/windoweditor.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from .superobj import SuperWidget +from .superobj import SuperWidget,SuperWidgetContainer import TermTk as ttk @@ -40,7 +40,7 @@ class WindowEditorView(ttk.TTkAbstractScrollView): self._ttk.superResized.disconnect(self._superChanged) self._ttk.superMoved.disconnect(self._superChanged) self.layout().removeWidget(self._ttk) - self._ttk = SuperWidget(wid=ttk.TTkWindow(name = 'MainWindow'), designer=self._designer, pos=(4,2), superRootWidget=True) + self._ttk = SuperWidget.swFromWidget(wid=ttk.TTkWindow(name = 'MainWindow'), designer=self._designer, pos=(4,2), superRootWidget=True) self._ttk.resize(self.width()-8,self.height()-4) self._snapRootWidget = True self.layout().addWidget(self._ttk) @@ -53,7 +53,7 @@ class WindowEditorView(ttk.TTkAbstractScrollView): self._ttk.superResized.disconnect(self._superChanged) self._ttk.superMoved.disconnect(self._superChanged) self.layout().removeWidget(self._ttk) - self._ttk = SuperWidget(wid=ttk.TTkWidget(name = 'MainWidget'), designer=self._designer, pos=(4,2), superRootWidget=True) + self._ttk = SuperWidget.swFromWidget(wid=ttk.TTkContainer(name = 'MainWidget'), designer=self._designer, pos=(4,2), superRootWidget=True) self._ttk.resize(self.width()-8,self.height()-4) self._snapRootWidget = True self.layout().addWidget(self._ttk)