diff --git a/TermTk/TTkUiTools/uiloader.py b/TermTk/TTkUiTools/uiloader.py index 9b045216..b9a4cec9 100644 --- a/TermTk/TTkUiTools/uiloader.py +++ b/TermTk/TTkUiTools/uiloader.py @@ -48,7 +48,7 @@ class TTkUiLoader(): kwargs = {} # Init params to be configured with the setter setters = [] - layout = _getLayout(widProp['layout']) + layout = _getLayout(widProp['layout']) if 'layout' in widProp else TTkLayout() for pname in widProp['params']: if 'init' in properties[pname]: initp = properties[pname]['init'] diff --git a/ttkDesigner/app/designer.py b/ttkDesigner/app/designer.py index 84719adc..0f625811 100644 --- a/ttkDesigner/app/designer.py +++ b/ttkDesigner/app/designer.py @@ -195,9 +195,9 @@ class TTkDesigner(TTkGridLayout): @pyTTkSlot() def open(self): - # self._openFile('tmp/pippo.003.json') + # self._openFile('tmp/pippo.008.json') # return - filePicker = TTkFileDialogPicker(pos = (3,3), size=(75,24), caption="Open", path=".", fileMode=TTkK.FileMode.AnyFile ,filter="Json Files (*.json);;All Files (*)") + filePicker = TTkFileDialogPicker(pos = (3,3), size=(75,24), caption="Open", path="tmp", fileMode=TTkK.FileMode.AnyFile ,filter="Json Files (*.json);;All Files (*)") filePicker.pathPicked.connect(self._openFile) TTkHelper.overlay(None, filePicker, 5, 5, True) diff --git a/ttkDesigner/app/propertyeditor.py b/ttkDesigner/app/propertyeditor.py index dacba409..43b21f65 100644 --- a/ttkDesigner/app/propertyeditor.py +++ b/ttkDesigner/app/propertyeditor.py @@ -38,29 +38,10 @@ class PropertyEditor(ttk.TTkGridLayout): # TBD # Override: 'name', 'radiogroup', # ro geometry if grid layout - exceptions = { - 'Layout' : { - 'get': { 'cb': lambda _: superWidget._superLayout.layout().__class__ , 'type':'singleflag', - 'flags': { - 'TTkLayout' : ttk.TTkLayout , - 'TTkGridLayout' : ttk.TTkGridLayout , - 'TTkVBoxLayout' : ttk.TTkVBoxLayout , - 'TTkHBoxLayout' : ttk.TTkHBoxLayout } }, - 'set': { 'cb': lambda _,l: superWidget.changeSuperLayout(l) , 'type':'singleflag', - 'flags': { - 'TTkLayout' : ttk.TTkLayout , - 'TTkGridLayout' : ttk.TTkGridLayout , - 'TTkVBoxLayout' : ttk.TTkVBoxLayout , - 'TTkHBoxLayout' : ttk.TTkHBoxLayout } }, - }, - 'RadioGroup' : { - 'init': {'name':'radiogroup', 'type':str } , - 'get': {'cb':ttk.TTkRadioButton.radioGroup, 'type':str } , - 'set': {'cb':lambda w,l: setattr(w,'_radiogroup',l), 'type':str } }, - } - self._makeDetail(widget, exceptions) - def _makeDetail(self, domw, exceptions): + self._makeDetail(widget, *superWidget.getSuperProperties()) + + def _makeDetail(self, domw, exceptions, exclude): def _bound(_f,_w,_l): def _ret(_v): _f(_w,_l(_v)) @@ -244,7 +225,7 @@ class PropertyEditor(ttk.TTkGridLayout): else: return _processUnknown(name, prop) - proplist = [] + proplist = exclude self._detail.clear() for cc in reversed(type(domw).__mro__): # if hasattr(cc,'_ttkProperties'): @@ -258,6 +239,6 @@ class PropertyEditor(ttk.TTkGridLayout): prop = exceptions[p] else: prop = ttk.TTkUiProperties[ccName]['properties'][p] - if prop not in proplist: - proplist.append(prop) + if p not in proplist: + proplist.append(p) classItem.addChild(_processProp(p, prop)) diff --git a/ttkDesigner/app/superobj/__init__.py b/ttkDesigner/app/superobj/__init__.py index 844c391d..0c3b16e3 100644 --- a/ttkDesigner/app/superobj/__init__.py +++ b/ttkDesigner/app/superobj/__init__.py @@ -22,8 +22,12 @@ # SOFTWARE. from .supercontrol import SuperControlWidget -from .superwidget import SuperWidget -from .superlayout import SuperLayout + +from .superwidget import SuperWidget +from .superwidgettextedit import SuperWidgetTextEdit +from .superwidgetradiobutton import SuperWidgetRadioButton + +from .superlayout import SuperLayout from .superlayoutgrid import SuperLayoutGrid from .superlayoutvbox import SuperLayoutVBox from .superlayouthbox import SuperLayoutHBox \ No newline at end of file diff --git a/ttkDesigner/app/superobj/superlayout.py b/ttkDesigner/app/superobj/superlayout.py index d0bbb821..7ce3aa46 100644 --- a/ttkDesigner/app/superobj/superlayout.py +++ b/ttkDesigner/app/superobj/superlayout.py @@ -179,7 +179,7 @@ class SuperLayout(ttk.TTkWidget): sw.move(evt.x-hsx, evt.y-hsy) sw.show() elif issubclass(type(data),ttk.TTkWidget): - self.addSuperWidget(sw := so.SuperWidget(wid=data, weModified=self.weModified, thingSelected=self.thingSelected, pos=(evt.x-hsx, evt.y-hsy))) + self.addSuperWidget(sw := so.SuperWidget.swFromWidget(wid=data, weModified=self.weModified, thingSelected=self.thingSelected, pos=(evt.x-hsx, evt.y-hsy))) self._lay.addWidget(data) sw.move(evt.x-hsx, evt.y-hsy) sl = sw._superLayout diff --git a/ttkDesigner/app/superobj/superobj.py b/ttkDesigner/app/superobj/superobj.py index e359cdbd..c7a8b37e 100644 --- a/ttkDesigner/app/superobj/superobj.py +++ b/ttkDesigner/app/superobj/superobj.py @@ -24,7 +24,7 @@ import TermTk as ttk class SuperObject(): @staticmethod - def dumpParams(obj): + def dumpParams(obj,exclude=[]): def _dumpPrimitive(val): return val def _dumpTTkString(val): @@ -61,6 +61,7 @@ class SuperObject(): ccName = cc.__name__ if ccName in ttk.TTkUiProperties: for p in ttk.TTkUiProperties[ccName]['properties']: + if p in exclude: continue prop = ttk.TTkUiProperties[ccName]['properties'][p] propType = prop['get']['type'] propCb = prop['get']['cb'] diff --git a/ttkDesigner/app/superobj/superwidget.py b/ttkDesigner/app/superobj/superwidget.py index bd8829e0..ba867195 100644 --- a/ttkDesigner/app/superobj/superwidget.py +++ b/ttkDesigner/app/superobj/superwidget.py @@ -59,6 +59,26 @@ class SuperWidget(ttk.TTkWidget): _showLayout = False toggleHighlightLayout = ttk.pyTTkSignal(bool) + def getSuperProperties(self): + 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 } }, + } + } + exclude = [] + return exceptions, exclude + @ttk.pyTTkSlot(bool) def _toggleHighlightLayout(self, state): SuperWidget._showLayout = state @@ -74,39 +94,19 @@ class SuperWidget(ttk.TTkWidget): return ret @staticmethod - def swFromWidget(wid, *args, **kwargs): - # layout = wid.layout() - #newLayout = ttk.TTkLayout() - ## copy layout compatible properties - #for att in newLayout.__slots__: - # if hasattr(layout,att): - # setattr(newLayout,att,getattr(layout,att)) - #wid.setLayout(newLayout) - - #if issubclass(type(data),ttk.TTkVBoxLayout): - # sl = so.SuperLayoutVBox(pos=(x,y), size=(w,h), lay=lay, weModified=self.weModified, thingSelected=self.thingSelected, selectable=True) - #elif issubclass(type(data),ttk.TTkHBoxLayout): - # sl = so.SuperLayoutHBox(pos=(x,y), size=(w,h), lay=lay, weModified=self.weModified, thingSelected=self.thingSelected, selectable=True) - #elif issubclass(type(data),ttk.TTkGridLayout): - # sl = so.SuperLayoutGrid(pos=(x,y), size=(w,h), lay=lay, weModified=self.weModified, thingSelected=self.thingSelected, selectable=True) - #else: - # sl = so.SuperLayout( pos=(x,y), size=(w,h), lay=lay, weModified=self.weModified, thingSelected=self.thingSelected, selectable=True) - - layout = wid.layout() + def _swFromWidget(wid, *args, **kwargs): sw = so.SuperWidget(wid=wid, *args, **kwargs) - sw.changeSuperLayout(type(layout)) - for ch in layout.children(): - x,y,w,h = ch.geometry() - if ch.layoutItemType == ttk.TTkK.WidgetItem: - sch = so.SuperWidget.swFromWidget(ch.widget(), *args, **(kwargs|{'pos':(x,y),'size':(w,h)})) - else: - sch = so.SuperLayout.slFromLayout(ch, *args, **(kwargs|{'pos':(x,y),'size':(w,h),'selectable':True})) - if issubclass(type(layout),ttk.TTkGridLayout): - sw._superLayout.layout().addWidget(sch,ch._row,ch._col,ch._rowspan,ch._colspan) - else: - sw._superLayout.layout().addWidget(sch) + sw.changeSuperLayout(type(wid.layout())) return sw + @staticmethod + def swFromWidget(wid, *args, **kwargs): + swClass = { + ttk.TTkTextEdit: so.SuperWidgetTextEdit, + ttk.TTkRadioButton: so.SuperWidgetRadioButton, + }.get(type(wid),so.SuperWidget) + return swClass._swFromWidget(wid=wid, *args, **kwargs) + @staticmethod def loadDict(parent, widProp): ttkClass = getattr(ttk,widProp['class']) @@ -125,24 +125,25 @@ class SuperWidget(ttk.TTkWidget): sl = sup = so.SuperLayout.slFromLayout(layout=layout, lay=ttk.TTkLayout(), pos=(x,y), size=(w,h), weModified=parent.weModified, thingSelected=parent.thingSelected, selectable=True) children = widProp['children'] else: + setLayout = 'layout' in widProp + tui = { + 'class' : widProp['class'], + 'params' : widProp['params'] } + tui |= { + 'layout': { + 'class' : widProp['layout']['class'], + 'params' : widProp['layout']['params'], + 'children' : [] + } } if setLayout else {} demiProp = { 'version':'1.0.0', - 'tui':{ - 'class' : widProp['class'], - 'params' : widProp['params']|{'Layout':'TTkLayout'}, - 'layout': { - 'class' : 'TTkLayout', - 'params' : widProp['layout']['params'], - 'children' : [] - } - }, + 'tui': tui, 'connections':[] } wid = ttk.TTkUiLoader.loadDict(demiProp) - sup = so.SuperWidget(wid=wid, pos=wid.pos(), weModified=parent.weModified, thingSelected=parent.thingSelected) - sup.changeSuperLayout(getattr(ttk,widProp['layout']['class'])) + sup = so.SuperWidget.swFromWidget(wid=wid, pos=wid.pos(), weModified=parent.weModified, thingSelected=parent.thingSelected) sl = sup._superLayout - children = widProp['layout']['children'] + children = widProp['layout']['children'] if setLayout else [] for ch in children: sch = SuperWidget.loadDict(parent, ch) diff --git a/ttkDesigner/app/superobj/superwidgetradiobutton.py b/ttkDesigner/app/superobj/superwidgetradiobutton.py new file mode 100644 index 00000000..e2788a87 --- /dev/null +++ b/ttkDesigner/app/superobj/superwidgetradiobutton.py @@ -0,0 +1,34 @@ +# 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. + +import TermTk as ttk +import ttkDesigner.app.superobj as so + +class SuperWidgetRadioButton(so.SuperWidget): + def getSuperProperties(self): + exceptions, exclude = super().getSuperProperties() + exceptions |= { + 'RadioGroup' : { + 'init': {'name':'radiogroup', 'type':str } , + 'get': {'cb':ttk.TTkRadioButton.radioGroup, 'type':str } , + 'set': {'cb':lambda w,l: setattr(w,'_radiogroup',l), 'type':str } } } + return exceptions, exclude \ No newline at end of file diff --git a/ttkDesigner/app/superobj/superwidgettextedit.py b/ttkDesigner/app/superobj/superwidgettextedit.py new file mode 100644 index 00000000..fff4695d --- /dev/null +++ b/ttkDesigner/app/superobj/superwidgettextedit.py @@ -0,0 +1,44 @@ +# 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. + +import TermTk as ttk +import ttkDesigner.app.superobj as so +from .superobj import SuperObject + + +class SuperWidgetTextEdit(so.SuperWidget): + @staticmethod + def _swFromWidget(wid, *args, **kwargs): + return so.SuperWidgetTextEdit(wid=wid, *args, **kwargs) + + def getSuperProperties(self): + exceptions, exclude = super().getSuperProperties() + exclude += ['Layout'] + return exceptions, exclude + + def dumpDict(self): + wid = self._wid + ret = { + 'class' : wid.__class__.__name__, + 'params' : SuperObject.dumpParams(wid,exclude=['Layout']), + } + return ret \ No newline at end of file diff --git a/ttkDesigner/app/windoweditor.py b/ttkDesigner/app/windoweditor.py index fce4f607..75d7e1fe 100644 --- a/ttkDesigner/app/windoweditor.py +++ b/ttkDesigner/app/windoweditor.py @@ -79,7 +79,7 @@ class WindowEditor(ttk.TTkAbstractScrollArea): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setViewport(wev := WindowEditorView()) - wev.importWidget(ttk.TTkWidget(name = 'TTk')) + # wev.importWidget(ttk.TTkWidget(name = 'TTk')) # Forward Methods self.getTTk = wev.getTTk self.dumpDict = wev.dumpDict