Browse Source

Added Table to TTkDesigner

pull/283/head
Eugenio Parodi 1 year ago
parent
commit
18a12bbec8
  1. 66
      TermTk/TTkUiTools/properties/table.py
  2. 6
      TermTk/TTkUiTools/uiproperties.py
  3. 2
      TermTk/TTkWidgets/TTkModelView/tablewidget.py
  4. 4
      TermTk/TTkWidgets/TTkTerminal/terminalhelper.py
  5. 3
      docs/source/index.rst
  6. 64
      tools/ttkDesigner/app/propertyeditor.py
  7. 15
      tools/ttkDesigner/app/superobj/superobj.py
  8. 2
      tools/ttkDesigner/app/superobj/superwidgetabstractscrollarea.py
  9. 3
      tools/ttkDesigner/app/widgetbox.py

66
TermTk/TTkUiTools/properties/table.py

@ -0,0 +1,66 @@
# MIT License
#
# Copyright (c) 2024 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# 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.
__all__ = ['TTkTableProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.TTkModelView.table import TTkTable
from TermTk.TTkWidgets.TTkModelView.tablewidget import TTkTableWidget
TTkTableProperties = {
'properties' : {
'H-Separator' : {
'init': {'name':'hSeparator', 'type':bool } ,
'get': { 'cb':TTkTableWidget.hSeparatorVisibility, 'type':bool, 'fw_obj':TTkTable.viewport } ,
'set': { 'cb':TTkTableWidget.setHSeparatorVisibility, 'type':bool, 'fw_obj':TTkTable.viewport } },
'V-Separator' : {
'init': {'name':'vSeparator', 'type':bool } ,
'get': { 'cb':TTkTableWidget.vSeparatorVisibility, 'type':bool, 'fw_obj':TTkTable.viewport } ,
'set': { 'cb':TTkTableWidget.setVSeparatorVisibility, 'type':bool, 'fw_obj':TTkTable.viewport } },
'Sorting' : {
'init': {'name':'sortingEnabled', 'type':bool } ,
'get': { 'cb':TTkTableWidget.isSortingEnabled, 'type':bool, 'fw_obj':TTkTable.viewport } ,
'set': { 'cb':TTkTableWidget.setSortingEnabled, 'type':bool, 'fw_obj':TTkTable.viewport } },
},'signals' : {
'cellChanged(int,int)' : {'name' : 'cellChanged' , 'type':(int, int)},
'cellClicked(int,int)' : {'name' : 'cellClicked' , 'type':(int, int)},
'cellDoubleClicked(int,int)' : {'name' : 'cellDoubleClicked' , 'type':(int, int)},
'cellEntered(int,int)' : {'name' : 'cellEntered' , 'type':(int, int)},
'currentCellChanged(int,int,int,int)' : {'name' : 'currentCellChanged', 'type':(int, int, int, int)},
},'slots' : {
'undo()' : {'name' : 'undo' , 'type': None },
'redo()' : {'name' : 'redo' , 'type': None },
'copy()' : {'name' : 'copy' , 'type': None },
'cut()' : {'name' : 'cut' , 'type': None },
'paste()' : {'name' : 'paste' , 'type': None },
'setSortingEnabled(bool)' : {'name' : 'copy' , 'type': bool },
'sortByColumn(int,SortOrder)' : {'name' : 'copy' , 'type': (int,TTkK.SortOrder), },
'setColumnWidth(int,int)' : {'name' : 'copy' , 'type': (int,int) },
'resizeColumnToContents(int)' : {'name' : 'copy' , 'type': int },
'resizeColumnsToContents()' : {'name' : 'copy' , 'type': None },
'setRowHeight(int,int)' : {'name' : 'copy' , 'type': (int,int) },
'resizeRowToContents(int)' : {'name' : 'copy' , 'type': int },
'resizeRowsToContents()' : {'name' : 'copy' , 'type': None },
}
}

6
TermTk/TTkUiTools/uiproperties.py

@ -53,6 +53,10 @@ from .properties.texedit import *
from .properties.widget import *
from .properties.window import *
from .properties.table import *
# from .properties.tree import *
# from .properties.terminal import *
# Pickers
from .properties.colorpicker import *
from .properties.filepicker import *
@ -84,4 +88,6 @@ TTkUiProperties = {
TTkFileButtonPicker.__name__ : TTkFileButtonPickerProperties,
# Layouts
TTkLayout.__name__: TTkLayoutProperties,
# Models
TTkTable.__name__: TTkTableProperties,
}

2
TermTk/TTkWidgets/TTkModelView/tablewidget.py

@ -819,7 +819,7 @@ class TTkTableWidget(TTkAbstractScrollView):
self.update()
return super().leaveEvent(evt)
@pyTTkSlot(int)
@pyTTkSlot(int,int)
def setColumnWidth(self, column:int, width: int) -> None:
'''
Sets the width of the given column.

4
TermTk/TTkWidgets/TTkTerminal/terminalhelper.py

@ -198,9 +198,9 @@ class TTkTerminalHelper():
TTkTerminal
pty
C:\ --[ KeyPresses, MouseEvents, ResizeSignal, ... ]-->
C:\ --[ KeyPresses, MouseEvents, ResizeSignal, ... ]-->
<---------[ Output, Ansi escape codes, ... ]------- bash, sh, ...
.. caution:: Do not touch this! (unless you know what you are doing)
'''

3
docs/source/index.rst

@ -107,7 +107,8 @@ API Reference
.. # :toctree: _autosummary
.. # :template: custom-class-template.01.rst
.. #
.. # TTkCore.TTkK
.. # TTkCore.pyTTkSignal
.. # TTkCore.pyTTkSlot
.. #
.. # TTkWidgets.TTkAppTemplate
.. # TTkWidgets.TTkMenuBar

64
tools/ttkDesigner/app/propertyeditor.py

@ -41,7 +41,7 @@ class PropertyEditor(ttk.TTkGridLayout):
self._makeDetail(widget, *superWidget.getSuperProperties())
def _makeDetail(self, domw, additions, exceptions, exclude):
def _makeDetail(self, domwBase, additions, exceptions, exclude):
def _boundValue(_f,_w,_v):
def _ret():
_f(_w,_v)
@ -77,7 +77,7 @@ class PropertyEditor(ttk.TTkGridLayout):
# • Text │[X] 0x0001
# • Number │[ ] 0x0002
# • Password │[ ] 0x0004
def _processMultiFlag(name, prop):
def _processMultiFlag(name, prop, domw):
flags = prop['get']['flags']
ret = ttk.TTkTreeWidgetItem([name,f" - (0x{prop['get']['cb'](domw):04X})"],expanded=True)
# value = ttk.TTkFrame(layout=ttk.TTkVBoxLayout(), height=len(flags), border=False)
@ -99,7 +99,7 @@ class PropertyEditor(ttk.TTkGridLayout):
# ││Unchecked │ │
# ││Partially Checked │ │
# │└───────────────────┘ │
def _processSingleFlag(name, prop):
def _processSingleFlag(name, prop, domw):
flags = prop['get']['flags']
items = [(k,v) for k,v in flags.items()]
if 'set' in prop:
@ -123,7 +123,7 @@ class PropertyEditor(ttk.TTkGridLayout):
# { 'name': 'x', 'type':int } ,
# { 'name': 'y', 'type':int } ] } },
#
def _processList(name, prop):
def _processList(name, prop, domw):
def _getter(_i, _p):
def _ret(_w):
return _p['get']['cb'](_w)[_i]
@ -146,42 +146,42 @@ class PropertyEditor(ttk.TTkGridLayout):
'set' : { 'cb': _setter(_i, prop), 'type':_prop['type'] }
}
# ret.addChild(ttk.TTkTreeWidgetItem([_prop['name'],f"{curVal[_i]}"]))
ret.addChild(_processProp(_prop['name'], _newProp))
ret.addChild(_processProp(_prop['name'], _newProp, domw))
return ret
# Dict Fields
def _processDict(name, prop):
def _processDict(name, prop, domw):
curVal = prop['get']['cb'](domw)
value = ttk.TTkLabel(text=f"{curVal} - TBD")
ret = ttk.TTkTreeWidgetItem([name,value])
return ret
# Boolean Fields
def _processBool(name, prop):
def _processBool(name, prop, domw):
getval = prop['get']['cb'](domw)
value = ttk.TTkCheckbox(text=f" {p}", checked=getval, height=1)
value.stateChanged.connect(_bound(prop['set']['cb'],domw, lambda v:v==ttk.TTkK.Checked))
return ttk.TTkTreeWidgetItem([name,value])
# Integer Fields
def _processInt(name, prop):
def _processInt(name, prop, domw):
getval = prop['get']['cb'](domw)
value = ttk.TTkSpinBox(value=getval, height=1, maximum=0x10000, minimum=-0x10000)
value.valueChanged.connect(_bound(prop['set']['cb'],domw,lambda v:v))
return ttk.TTkTreeWidgetItem([name,value])
# String Fields
def _processStr(name, prop):
def _processStr(name, prop, domw):
getval = prop['get']['cb'](domw)
value = ttk.TTkLineEdit(text=getval, height=len(getval.split('\n')))
value.textChanged.connect(_boundLineEdit(prop['set']['cb'],domw,value))
return ttk.TTkTreeWidgetItem([name,value])
# String Fields
def _processTTkString(name, prop, multiLine=True):
def _processTTkString(name, prop, domw, multiLine=True):
getval = prop['get']['cb'](domw)
value = ttk.TTkTextPicker(text=getval, height=len(getval.split('\n')), autoSize=True, multiLine=multiLine)
value.textChanged.connect(_boundTextEdit(prop['set']['cb'],domw,value))
return ttk.TTkTreeWidgetItem([name,value])
# Color Fields
def _processTTkColor(name, prop):
def _processTTkColor(name, prop, domw):
getval = prop['get']['cb'](domw)
value = ttk.TTkContainer(layout=ttk.TTkHBoxLayout(), height=1)
value.layout().addWidget(_cb := ttk.TTkColorButtonPicker(color=getval, height=1))
@ -191,19 +191,19 @@ class PropertyEditor(ttk.TTkGridLayout):
_rc.clicked.connect(lambda :_cb.setColor(ttk.TTkColor.RST))
return ttk.TTkTreeWidgetItem([name,value])
# Layout field
def _processTTkLayout(name, prop):
def _processTTkLayout(name, prop, domw):
value = ttk.TTkComboBox(list=['TTkLayout','TTkGridLayout','TTkHBoxLayout','TTkVBoxLayout'], height=1)
value.setCurrentText(prop['get']['cb'](domw).__class__.__name__)
value.currentTextChanged.connect(_bound(prop['set']['cb'],domw, lambda v:globals()[v]()))
return ttk.TTkTreeWidgetItem([name,value])
# Add a button Control
def _processButton(name, prop):
def _processButton(name, prop, domw):
value = ttk.TTkButton(text=f" {prop['get']['text']}", border=False)
value.clicked.connect(lambda :prop['get']['cb'](domw))
return ttk.TTkTreeWidgetItem([name,value])
# Unrecognised Field
def _processUnknown(name, prop):
def _processUnknown(name, prop, domw):
getval = prop['get']['cb'](domw)
if type(prop['get']['type']) == str:
getval = f"{prop['get']['type']} = {getval}"
@ -212,38 +212,40 @@ class PropertyEditor(ttk.TTkGridLayout):
value = ttk.TTkLabel(minSize=(30,1), maxHeight=1, text=f"{getval}", height=1)
return ttk.TTkTreeWidgetItem([name,value])
def _processProp(name, prop):
def _processProp(name, prop, domw):
if 'fw_obj' in prop['get']:
domw = prop['get']['fw_obj'](domw)
if 'get' in prop:
if prop['get']['type'] == 'multiflags':
return _processMultiFlag(name, prop)
return _processMultiFlag(name, prop, domw)
elif prop['get']['type'] == 'singleflag':
return _processSingleFlag(name, prop)
return _processSingleFlag(name, prop, domw)
elif prop['get']['type'] == bool and 'set' in prop:
return _processBool(name, prop)
return _processBool(name, prop, domw)
elif prop['get']['type'] == int and 'set' in prop:
return _processInt(name, prop)
return _processInt(name, prop, domw)
elif prop['get']['type'] == str and 'set' in prop:
return _processStr(name, prop)
return _processStr(name, prop, domw)
elif prop['get']['type'] == ttk.TTkString and 'set' in prop:
return _processTTkString(p,prop,multiLine=True)
return _processTTkString(p,prop,domw,multiLine=True)
elif prop['get']['type'] == 'singleLineTTkString':
return _processTTkString(p,prop,multiLine=False)
return _processTTkString(p,prop,domw,multiLine=False)
elif prop['get']['type'] == ttk.TTkColor and 'set' in prop:
return _processTTkColor(name, prop)
return _processTTkColor(name, prop, domw)
elif prop['get']['type'] == ttk.TTkLayout and 'set' in prop:
return _processTTkLayout(name, prop)
return _processTTkLayout(name, prop, domw)
elif type(prop['get']['type']) == list:
return _processList(name, prop)
return _processList(name, prop, domw)
elif type(prop['get']['type']) == dict:
return _processDict(name, prop)
return _processDict(name, prop, domw)
elif prop['get']['type'] == 'button':
return _processButton(p,prop)
return _processButton(p, prop, domw)
else:
return _processUnknown(name, prop)
return _processUnknown(name, prop, domw)
proplist = exclude
self._detail.clear()
for cc in reversed(type(domw).__mro__):
for cc in reversed(type(domwBase).__mro__):
# if hasattr(cc,'_ttkProperties'):
if issubclass(cc, ttk.TTkWidget) or issubclass(cc, ttk.TTkLayout):
ccName = cc.__name__
@ -254,7 +256,7 @@ class PropertyEditor(ttk.TTkGridLayout):
for p in additions[ccName]:
if p not in proplist:
proplist.append(p)
classItem.addChild(_processProp(p, additions[ccName][p]))
classItem.addChild(_processProp(p, additions[ccName][p], domwBase))
for p in ttk.TTkUiProperties[ccName]['properties']:
if p in exceptions:
prop = exceptions[p]
@ -262,4 +264,4 @@ class PropertyEditor(ttk.TTkGridLayout):
prop = ttk.TTkUiProperties[ccName]['properties'][p]
if p not in proplist:
proplist.append(p)
classItem.addChild(_processProp(p, prop))
classItem.addChild(_processProp(p, prop, domwBase))

15
tools/ttkDesigner/app/superobj/superobj.py

@ -65,19 +65,22 @@ class SuperObject():
prop = ttk.TTkUiProperties[ccName]['properties'][p]
propType = prop['get']['type']
propCb = prop['get']['cb']
objCb = obj
if 'fw_obj' in prop['get']:
objCb = prop['get']['fw_obj'](objCb)
# ttk.TTkLog.debug(ccName)
if propType in (int,str,float,bool):
params |= {p: _dumpPrimitive(propCb(obj))}
params |= {p: _dumpPrimitive(propCb(objCb))}
elif type(propType) in (list,tuple):
params |= {p: _dumpList(propCb(obj), propType)}
params |= {p: _dumpList(propCb(objCb), propType)}
elif propType is ttk.TTkLayout:
params |= {p: _dumpTTkLayout(propCb(obj))}
params |= {p: _dumpTTkLayout(propCb(objCb))}
elif propType in (ttk.TTkString,'singleLineTTkString'):
params |= {p: _dumpTTkString(propCb(obj))}
params |= {p: _dumpTTkString(propCb(objCb))}
elif propType is ttk.TTkColor:
params |= {p: _dumpTTkColor(propCb(obj))}
params |= {p: _dumpTTkColor(propCb(objCb))}
elif propType in ('singleflag','multiflags'):
params |= {p: _dumpFlag(propCb(obj))}
params |= {p: _dumpFlag(propCb(objCb))}
else:
ttk.TTkLog.warn("Type not Recognised")
return params

2
tools/ttkDesigner/app/superobj/superwidgetabstractscrollarea.py

@ -39,6 +39,6 @@ class SuperWidgetAbstractScrollArea(so.SuperWidgetContainer):
wid = self._wid
ret = {
'class' : wid.__class__.__name__,
'params' : SuperObject.dumpParams(wid,exclude=['Layout','Padding']),
'params' : SuperObject.dumpParams(obj=wid, exclude=['Layout','Padding']),
}
return ret

3
tools/ttkDesigner/app/widgetbox.py

@ -65,6 +65,9 @@ dWidgets = {
"Tab Widget" : { "class":ttk.TTkTabWidget, "params":{'size':(20,3)}, "disabled": True},
"Widget" : { "class":ttk.TTkWidget, "params":{'size':(20,5)}},
},
'Model View':{
"Table" : { "class":ttk.TTkTable, "params":{'size':( 20,5)}},
},
'Pickers':{
"Color Picker" : { "class":ttk.TTkColorButtonPicker, "params":{'size':( 6,3), 'border':True}},
"Color Picker Slim": { "class":ttk.TTkColorButtonPicker, "params":{'size':( 6,1), 'border':False}},

Loading…
Cancel
Save