From 5bed31985774d251180768b150f8ca03ea82f2bf Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sat, 2 Mar 2024 21:31:47 +0000 Subject: [PATCH] Added import/export in the dumb paint tool --- tools/dumb.paint.tool.py | 122 +--------- tools/dumb_paint_lib/__init__.py | 1 + tools/dumb_paint_lib/maintemplate.py | 263 ++++++++++++++++++++++ tools/dumb_paint_lib/paintarea.py | 54 ++++- tools/dumb_paint_lib/palette.py | 2 +- tools/dumb_paint_lib/quickImport.tui.json | 134 +++++++++++ ttkDesigner/app/designer.py | 1 + 7 files changed, 450 insertions(+), 127 deletions(-) create mode 100644 tools/dumb_paint_lib/maintemplate.py create mode 100644 tools/dumb_paint_lib/quickImport.tui.json diff --git a/tools/dumb.paint.tool.py b/tools/dumb.paint.tool.py index 9f70e364..2c1cd39d 100755 --- a/tools/dumb.paint.tool.py +++ b/tools/dumb.paint.tool.py @@ -27,135 +27,17 @@ import sys, os, argparse sys.path.append(os.path.join(sys.path[0],'..')) import TermTk as ttk -from dumb_paint_lib import * +from dumb_paint_lib import PaintTemplate ttk.TTkTheme.loadTheme(ttk.TTkTheme.NERD) -class LeftPanel(ttk.TTkVBoxLayout): - __slots__ = ('_palette', - # Signals - 'toolSelected') - def __init__(self, *args, **kwargs): - self.toolSelected = ttk.pyTTkSignal(PaintArea.Tool) - super().__init__(*args, **kwargs) - self._palette = Palette(maxHeight=12) - self.addWidget(self._palette) - - # Layout for the toggle buttons - lToggleFgBg = ttk.TTkHBoxLayout() - cb_p_fg = ttk.TTkCheckbox(text="-FG-", checked=ttk.TTkK.Checked) - cb_p_bg = ttk.TTkCheckbox(text="-BG-", checked=ttk.TTkK.Checked) - lToggleFgBg.addWidgets([cb_p_fg,cb_p_bg]) - lToggleFgBg.addItem(ttk.TTkLayout()) - cb_p_fg.toggled.connect(self._palette.enableFg) - cb_p_bg.toggled.connect(self._palette.enableBg) - self.addItem(lToggleFgBg) - - # Toolset - lTools = ttk.TTkGridLayout() - ra_brush = ttk.TTkRadioButton(radiogroup="tools", text="Brush", checked=True) - ra_line = ttk.TTkRadioButton(radiogroup="tools", text="Line", enabled=False) - ra_rect = ttk.TTkRadioButton(radiogroup="tools", text="Rect") - ra_oval = ttk.TTkRadioButton(radiogroup="tools", text="Oval", enabled=False) - - ra_rect_f = ttk.TTkRadioButton(radiogroup="toolsRectFill", text="Fill" , enabled=False, checked=True) - ra_rect_e = ttk.TTkRadioButton(radiogroup="toolsRectFill", text="Empty", enabled=False) - - @ttk.pyTTkSlot(bool) - def _emitTool(checked): - if not checked: return - tool = PaintArea.Tool.BRUSH - if ra_brush.isChecked(): - tool = PaintArea.Tool.BRUSH - elif ra_rect.isChecked(): - if ra_rect_e.isChecked(): - tool = PaintArea.Tool.RECTEMPTY - else: - tool = PaintArea.Tool.RECTFILL - self.toolSelected.emit(tool) - - ra_rect.toggled.connect(ra_rect_f.setEnabled) - ra_rect.toggled.connect(ra_rect_e.setEnabled) - - ra_brush.toggled.connect( _emitTool) - ra_line.toggled.connect( _emitTool) - ra_rect.toggled.connect( _emitTool) - ra_rect_f.toggled.connect( _emitTool) - ra_rect_e.toggled.connect( _emitTool) - ra_oval.toggled.connect( _emitTool) - - lTools.addWidget(ra_brush,0,0) - lTools.addWidget(ra_line,1,0) - lTools.addWidget(ra_rect,2,0) - lTools.addWidget(ra_rect_f,2,1) - lTools.addWidget(ra_rect_e,2,2) - lTools.addWidget(ra_oval,3,0) - self.addItem(lTools) - - # brush - # line - # rettangle [empty,fill] - # oval [empty,fill] - self.addItem(ttk.TTkLayout()) - - - - def palette(self): - return self._palette - - -class PaintTemplate(ttk.TTkAppTemplate): - def __init__(self, border=False, **kwargs): - super().__init__(border, **kwargs) - parea = PaintArea() - ptoolkit = PaintToolKit() - tarea = TextArea() - - leftPanel = LeftPanel() - palette = leftPanel.palette() - - self.setItem(leftPanel , self.LEFT, size=16*2) - self.setWidget(parea , self.MAIN) - self.setItem(ptoolkit , self.TOP, size=3, fixed=True) - self.setItem(tarea , self.RIGHT, size=50) - - self.setMenuBar(appMenuBar:=ttk.TTkMenuBarLayout(), self.TOP) - fileMenu = appMenuBar.addMenu("&File") - buttonOpen = fileMenu.addMenu("&Open") - buttonClose = fileMenu.addMenu("&Save") - buttonClose = fileMenu.addMenu("Save &As...") - fileMenu.addSpacer() - fileMenu.addMenu("Load Palette") - fileMenu.addMenu("Save Palette") - fileMenu.addSpacer() - buttonExit = fileMenu.addMenu("E&xit") - buttonExit.menuButtonClicked.connect(ttk.TTkHelper.quit) - - # extraMenu = appMenuBar.addMenu("E&xtra") - # extraMenu.addMenu("Scratchpad").menuButtonClicked.connect(self.scratchpad) - # extraMenu.addSpacer() - - helpMenu = appMenuBar.addMenu("&Help", alignment=ttk.TTkK.RIGHT_ALIGN) - helpMenu.addMenu("About ...").menuButtonClicked - helpMenu.addMenu("About tlogg").menuButtonClicked - - palette.colorSelected.connect(parea.setGlyphColor) - palette.colorSelected.connect(ptoolkit.setColor) - ptoolkit.updatedColor.connect(parea.setGlyphColor) - tarea.charSelected.connect(ptoolkit.glyphFromString) - tarea.charSelected.connect(parea.glyphFromString) - leftPanel.toolSelected.connect(parea.setTool) - - parea.setGlyphColor(palette.color()) - ptoolkit.setColor(palette.color()) - root = ttk.TTk( title="Dumb Paint Tool", layout=ttk.TTkGridLayout(), mouseTrack=True, sigmask=( - # ttk.TTkTerm.Sigmask.CTRL_C | + ttk.TTkTerm.Sigmask.CTRL_C | ttk.TTkTerm.Sigmask.CTRL_Q | ttk.TTkTerm.Sigmask.CTRL_S | ttk.TTkTerm.Sigmask.CTRL_Z )) diff --git a/tools/dumb_paint_lib/__init__.py b/tools/dumb_paint_lib/__init__.py index 2083f789..9a2ea381 100644 --- a/tools/dumb_paint_lib/__init__.py +++ b/tools/dumb_paint_lib/__init__.py @@ -1,3 +1,4 @@ +from .maintemplate import * from .paintarea import * from .textarea import * from .palette import * \ No newline at end of file diff --git a/tools/dumb_paint_lib/maintemplate.py b/tools/dumb_paint_lib/maintemplate.py new file mode 100644 index 00000000..24b08611 --- /dev/null +++ b/tools/dumb_paint_lib/maintemplate.py @@ -0,0 +1,263 @@ +# MIT License +# +# Copyright (c) 2024 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. + +__all__ = ['PaintTemplate'] + +import sys, os + +sys.path.append(os.path.join(sys.path[0],'../..')) +import TermTk as ttk + +from .paintarea import PaintArea, PaintToolKit +from .palette import Palette +from .textarea import TextArea + +class LeftPanel(ttk.TTkVBoxLayout): + __slots__ = ('_palette', + # Signals + 'toolSelected') + def __init__(self, *args, **kwargs): + self.toolSelected = ttk.pyTTkSignal(PaintArea.Tool) + super().__init__(*args, **kwargs) + self._palette = Palette(maxHeight=12) + self.addWidget(self._palette) + + # Layout for the toggle buttons + lToggleFgBg = ttk.TTkHBoxLayout() + cb_p_fg = ttk.TTkCheckbox(text="-FG-", checked=ttk.TTkK.Checked) + cb_p_bg = ttk.TTkCheckbox(text="-BG-", checked=ttk.TTkK.Checked) + lToggleFgBg.addWidgets([cb_p_fg,cb_p_bg]) + lToggleFgBg.addItem(ttk.TTkLayout()) + cb_p_fg.toggled.connect(self._palette.enableFg) + cb_p_bg.toggled.connect(self._palette.enableBg) + self.addItem(lToggleFgBg) + + # Toolset + lTools = ttk.TTkGridLayout() + ra_brush = ttk.TTkRadioButton(radiogroup="tools", text="Brush", checked=True) + ra_line = ttk.TTkRadioButton(radiogroup="tools", text="Line", enabled=False) + ra_rect = ttk.TTkRadioButton(radiogroup="tools", text="Rect") + ra_oval = ttk.TTkRadioButton(radiogroup="tools", text="Oval", enabled=False) + + ra_rect_f = ttk.TTkRadioButton(radiogroup="toolsRectFill", text="Fill" , enabled=False, checked=True) + ra_rect_e = ttk.TTkRadioButton(radiogroup="toolsRectFill", text="Empty", enabled=False) + + @ttk.pyTTkSlot(bool) + def _emitTool(checked): + if not checked: return + tool = PaintArea.Tool.BRUSH + if ra_brush.isChecked(): + tool = PaintArea.Tool.BRUSH + elif ra_rect.isChecked(): + if ra_rect_e.isChecked(): + tool = PaintArea.Tool.RECTEMPTY + else: + tool = PaintArea.Tool.RECTFILL + self.toolSelected.emit(tool) + + ra_rect.toggled.connect(ra_rect_f.setEnabled) + ra_rect.toggled.connect(ra_rect_e.setEnabled) + + ra_brush.toggled.connect( _emitTool) + ra_line.toggled.connect( _emitTool) + ra_rect.toggled.connect( _emitTool) + ra_rect_f.toggled.connect( _emitTool) + ra_rect_e.toggled.connect( _emitTool) + ra_oval.toggled.connect( _emitTool) + + lTools.addWidget(ra_brush,0,0) + lTools.addWidget(ra_line,1,0) + lTools.addWidget(ra_rect,2,0) + lTools.addWidget(ra_rect_f,2,1) + lTools.addWidget(ra_rect_e,2,2) + lTools.addWidget(ra_oval,3,0) + self.addItem(lTools) + + # brush + # line + # rettangle [empty,fill] + # oval [empty,fill] + self.addItem(ttk.TTkLayout()) + + + + def palette(self): + return self._palette + +class ExportArea(ttk.TTkGridLayout): + __slots__ = ('_paintArea', '_te') + def __init__(self, paintArea, **kwargs): + self._paintArea = paintArea + super().__init__(**kwargs) + self._te = ttk.TTkTextEdit(lineNumber=True, readOnly=False) + btn_ex = ttk.TTkButton(text="Export") + self.addWidget(btn_ex ,0,0) + self.addWidget(self._te,1,0,1,3) + + btn_ex.clicked.connect(self._export) + + @ttk.pyTTkSlot() + def _export(self): + # Don't try this at home + pw,ph = self._paintArea._canvasSize + data = self._paintArea._canvasArea['data'] + colors = self._paintArea._canvasArea['colors'] + # get the bounding box + xa,xb,ya,yb = pw,0,ph,0 + for y,row in enumerate(data): + for x,d in enumerate(row): + c = colors[y][x] + if d != ' ' or c.background(): + xa = min(x,xa) + xb = max(x,xb) + ya = min(y,ya) + yb = max(y,yb) + + if xa>xb or ya>yb: + self._te.setText("No Picture Found!!!") + return + + out = "data = {'data': [\n" + outData = {'data':[], 'colors':[]} + for row in data[ya:yb+1]: + out += " [" + outData['data'].append(row[xa:xb+1]) + for c in row[xa:xb+1]: + out += f"'{c}'," + out += "],\n" + out += " ],\n" + out += " 'colors': [\n" + for row in colors[ya:yb+1]: + out += " [" + outData['colors'].append([]) + for c in row[xa:xb+1]: + fg = f"{c.getHex(ttk.TTkK.Foreground)}" if c.foreground() else None + bg = f"{c.getHex(ttk.TTkK.Background)}" if c.background() else None + out += f"('{fg}','{bg}')," + outData['colors'][-1].append((fg,bg)) + out += "],\n" + out += " ]}\n" + + self._te.setText(out) + + self._te.append('\n# Compressed Data:') + self._te.append('data = TTkUtil.base64_deflate_2_obj(') + b64str = ttk.TTkUtil.obj_inflate_2_base64(outData) + b64list = ' "' + '" +\n "'.join([b64str[i:i+128] for i in range(0,len(b64str),128)]) + '")' + self._te.append(b64list) + + + +class PaintTemplate(ttk.TTkAppTemplate): + def __init__(self, border=False, **kwargs): + super().__init__(border, **kwargs) + self._parea = PaintArea() + ptoolkit = PaintToolKit() + tarea = TextArea() + expArea = ExportArea(self._parea) + + leftPanel = LeftPanel() + palette = leftPanel.palette() + + rightPanel = ttk.TTkSplitter(orientation=ttk.TTkK.VERTICAL) + rightPanel.addWidget(tarea) + rightPanel.addItem(expArea, title="Export") + rightPanel.setSizes([None,5]) + + self.setItem(leftPanel , self.LEFT, size=16*2) + self.setWidget(self._parea , self.MAIN) + self.setItem(ptoolkit , self.TOP, size=3, fixed=True) + self.setItem(rightPanel , self.RIGHT, size=50) + + self.setMenuBar(appMenuBar:=ttk.TTkMenuBarLayout(), self.TOP) + fileMenu = appMenuBar.addMenu("&File") + buttonOpen = fileMenu.addMenu("&Open") + buttonClose = fileMenu.addMenu("&Save") + buttonClose = fileMenu.addMenu("Save &As...") + fileMenu.addSpacer() + fileMenu.addMenu("&Import").menuButtonClicked.connect(self.importDictWin) + fileMenu.addSpacer() + fileMenu.addMenu("Load Palette") + fileMenu.addMenu("Save Palette") + fileMenu.addSpacer() + buttonExit = fileMenu.addMenu("E&xit") + buttonExit.menuButtonClicked.connect(ttk.TTkHelper.quit) + + # extraMenu = appMenuBar.addMenu("E&xtra") + # extraMenu.addMenu("Scratchpad").menuButtonClicked.connect(self.scratchpad) + # extraMenu.addSpacer() + + helpMenu = appMenuBar.addMenu("&Help", alignment=ttk.TTkK.RIGHT_ALIGN) + helpMenu.addMenu("About ...").menuButtonClicked + helpMenu.addMenu("About tlogg").menuButtonClicked + + palette.colorSelected.connect(self._parea.setGlyphColor) + palette.colorSelected.connect(ptoolkit.setColor) + ptoolkit.updatedColor.connect(self._parea.setGlyphColor) + ptoolkit.updatedTrans.connect(self._parea.setTrans) + tarea.charSelected.connect(ptoolkit.glyphFromString) + tarea.charSelected.connect(self._parea.glyphFromString) + leftPanel.toolSelected.connect(self._parea.setTool) + + self._parea.setGlyphColor(palette.color()) + ptoolkit.setColor(palette.color()) + + @ttk.pyTTkSlot() + def importDictWin(self): + newWindow = ttk.TTkUiLoader.loadFile(os.path.join(os.path.dirname(os.path.abspath(__file__)),"quickImport.tui.json")) + te = newWindow.getWidgetByName("TextEdit") + + @ttk.pyTTkSlot() + def _importDict(te=te): + def _probeCompressedText(_text): + import re + ret = "" + for _t in _text.split('\n'): + if m := re.match(r'^ *["\']([A-Za-z0-9+/]+[=]{0,2})["\' +]*$',_t): + ret += m.group(1) + elif not re.match(r'^ *$',_t): # exclude empty lines + return "" + return ret + text = te.toPlainText() + if compressed := _probeCompressedText(text): + dd = ttk.TTkUtil.base64_deflate_2_obj(compressed) + else: + try: + dd = eval(text) + except Exception as e: + ttk.TTkLog.error(str(e)) + messageBox = ttk.TTkMessageBox(text= str(e),icon=ttk.TTkMessageBox.Icon.Warning) + ttk.TTkHelper.overlay(None, messageBox, 5, 5, True) + return + + if type(dd) is not dict: + messageBox = ttk.TTkMessageBox(text= f"Input is {type(dd)}\nImport data must be a dict or \ncompressed String definition",icon=ttk.TTkMessageBox.Icon.Warning) + ttk.TTkHelper.overlay(None, messageBox, 5, 5, True) + return + + self._parea.importLayer(dd) + + newWindow.close() + + newWindow.getWidgetByName("BtnDict" ).clicked.connect(_importDict) + ttk.TTkHelper.overlay(None, newWindow, 10, 4, modal=True) + diff --git a/tools/dumb_paint_lib/paintarea.py b/tools/dumb_paint_lib/paintarea.py index 77e93e8f..287eaf08 100644 --- a/tools/dumb_paint_lib/paintarea.py +++ b/tools/dumb_paint_lib/paintarea.py @@ -31,14 +31,17 @@ import TermTk as ttk class PaintToolKit(ttk.TTkGridLayout): - __slots__ = ('_rSelect', '_rPaint', '_lgliph', '_cbFg', '_cbBg', '_bpFg', '_bpBg', + __slots__ = ('_rSelect', '_rPaint', '_lgliph', + '_cbFg', '_cbBg', + '_bpFg', '_bpBg', '_bpDef', '_glyph', #Signals - 'updatedColor') + 'updatedColor', 'updatedTrans') def __init__(self, *args, **kwargs): self._glyph = 'X' - super().__init__(*args, **kwargs) self.updatedColor = ttk.pyTTkSignal(ttk.TTkColor) + self.updatedTrans = ttk.pyTTkSignal(ttk.TTkColor) + super().__init__(*args, **kwargs) self._rSelect = ttk.TTkRadioButton(text='Select ' , maxWidth=10) self._rPaint = ttk.TTkRadioButton(text='Paint ' ) self._lgliph = ttk.TTkLabel(text="" , maxWidth=8) @@ -46,6 +49,7 @@ class PaintToolKit(ttk.TTkGridLayout): self._cbBg = ttk.TTkCheckbox(text="Bg" ) self._bpFg = ttk.TTkColorButtonPicker(enabled=False, maxWidth= 6) self._bpBg = ttk.TTkColorButtonPicker(enabled=False, ) + self._bpDef = ttk.TTkColorButtonPicker(color=ttk.TTkColor.bg('#FF00FF'), maxWidth=6) self.addWidget(self._rSelect ,0,0) self.addWidget(self._rPaint ,1,0) self.addWidget(self._lgliph ,0,1,2,1) @@ -53,7 +57,10 @@ class PaintToolKit(ttk.TTkGridLayout): self.addWidget(self._cbBg ,1,2) self.addWidget(self._bpFg ,0,3) self.addWidget(self._bpBg ,1,3) - self.addItem(ttk.TTkLayout() ,0,4,3,1) + + self.addWidget(ttk.TTkLabel(text=" Trans:", maxWidth=7) ,1,4) + self.addWidget(self._bpDef ,1,5) + self.addItem(ttk.TTkLayout() ,0,6,3,1) self._cbFg.toggled.connect(self._bpFg.setEnabled) self._cbBg.toggled.connect(self._bpBg.setEnabled) @@ -62,11 +69,10 @@ class PaintToolKit(ttk.TTkGridLayout): self._bpFg.colorSelected.connect(self._refreshColor) self._bpBg.colorSelected.connect(self._refreshColor) + self._bpDef.colorSelected.connect(self.updatedTrans.emit) self._refreshColor(emit=False) - - @ttk.pyTTkSlot() def _refreshColor(self, emit=True): color =self.color() @@ -145,6 +151,37 @@ class PaintArea(ttk.TTkWidget): self._canvasArea['colors'][i] = (self._canvasArea['colors'][i] + [ttk.TTkColor.RST for _ in range(w)])[:w] self.update() + def clean(self): + w,h = self._canvasSize + for i in range(h): + self._canvasArea['data'][i] = [' ']*w + self._canvasArea['colors'][i] = [ttk.TTkColor.RST]*w + + def importLayer(self, dd): + w,h = self._canvasSize + w = len(dd['data'][0]) + 10 + h = len(dd['data']) + 4 + x,y=5,2 + + self.resizeCanvas(w,h) + self.clean() + + for i,rd in enumerate(dd['data']): + for ii,cd in enumerate(rd): + self._canvasArea['data'][i+y][ii+x] = cd + for i,rd in enumerate(dd['colors']): + for ii,cd in enumerate(rd): + fg,bg = cd + if fg and bg: + self._canvasArea['colors'][i+y][ii+x] = ttk.TTkColor.fg(fg)+ttk.TTkColor.bg(bg) + elif fg: + self._canvasArea['colors'][i+y][ii+x] = ttk.TTkColor.fg(fg) + elif bg: + self._canvasArea['colors'][i+y][ii+x] = ttk.TTkColor.bg(bg) + else: + self._canvasArea['colors'][i+y][ii+x] = ttk.TTkColor.RST + self.update() + def leaveEvent(self, evt): self._mouseMove = None self.update() @@ -220,6 +257,11 @@ class PaintArea(ttk.TTkWidget): def setGlyphColor(self, color): self._glyphColor = color + @ttk.pyTTkSlot(ttk.TTkColor) + def setTrans(self, color): + self._transparentColor = color + self.update() + def _placeFill(self): if not self._mouseFill: return False w,h = self._canvasSize diff --git a/tools/dumb_paint_lib/palette.py b/tools/dumb_paint_lib/palette.py index de1ff017..f036fb43 100644 --- a/tools/dumb_paint_lib/palette.py +++ b/tools/dumb_paint_lib/palette.py @@ -39,7 +39,7 @@ _defaultPalette = [ [( 0, 64, 32),( 0,102, 51),( 0,140, 70),( 0,178, 89),( 0,217,108),( 0,255,128),( 51,255,153),(102,255,178),( 64, 0, 16),(102, 0, 26), (140, 0, 35),(178, 0, 45),(217, 0, 54),(255, 0, 64),(255, 51,102),(255,102,140)], [( 0, 64, 48),( 0,102, 77),( 0,140,105),( 0,178,134),( 0,217,163),( 0,255,191),( 51,255,204),(102,255,217),( 26, 26, 26),( 51, 51, 51), ( 77, 77, 77),(102,102,102),(128,128,128),(158,158,158),(191,191,191),(222,222,222)], [( 0, 64, 64),( 0,102,102),( 0,140,140),( 0,178,178),( 0,217,217),( 0,255,255),( 51,255,255),(102,255,255),( 26, 20, 13),( 51, 41, 26), ( 77, 61, 38),(102, 82, 51),(128,102, 64),(158,134,100),(191,171,143),(222,211,195)], - [( 0, 48, 64),( 0, 77,102),( 0,105,140),( 0,134,178),( 0,163,217),( 0,191,255),( 51,204,255),(102,217,255),( 0, 0, 0),( 0, 0, 0), ( 0, 0, 0),( 0, 0, 0),(255,255,255),(255,255,255),(255,255,255),(255,255,255)]] + [( 0, 48, 64),( 0, 77,102),( 0,105,140),( 0,134,178),( 0,163,217),( 0,191,255),( 51,204,255),(102,217,255),( 0, 0, 0),(255,255,255), (0x33,0x32,0x38),(0x63,0x68,0x7B),(0x85,0x84,0x94),(0x96,0x94,0xA1),(0xAF,0xAE,0xBC),(0xB3,0xB2,0xC0)]] class Palette(ttk.TTkWidget): __slots__ = ('_bg', '_fg', '_mouseMove', '_palette', diff --git a/tools/dumb_paint_lib/quickImport.tui.json b/tools/dumb_paint_lib/quickImport.tui.json new file mode 100644 index 00000000..578ff8d1 --- /dev/null +++ b/tools/dumb_paint_lib/quickImport.tui.json @@ -0,0 +1,134 @@ +{ + "version": "2.0.0", + "tui": { + "class": "TTkWindow", + "params": { + "Name": "MainWindow", + "Position": [ + 4, + 2 + ], + "Size": [ + 84, + 26 + ], + "Min Width": 0, + "Min Height": 0, + "Max Width": 65536, + "Max Height": 65536, + "Visible": true, + "Enabled": true, + "ToolTip": "", + "Padding": [ + 3, + 1, + 1, + 1 + ], + "Layout": "TTkGridLayout", + "Border": true, + "Title": "Mr Import \ud83c\udf81", + "Window Flags": 134250496 + }, + "layout": { + "class": "TTkGridLayout", + "params": { + "Geometry": [ + 0, + 0, + 82, + 22 + ] + }, + "children": [ + { + "class": "TTkButton", + "params": { + "Name": "BtnDict", + "Position": [ + 0, + 0 + ], + "Size": [ + 82, + 3 + ], + "Min Width": 13, + "Min Height": 3, + "Max Width": 65536, + "Max Height": 3, + "Visible": true, + "Enabled": true, + "ToolTip": "", + "Text": "Import Dict", + "Border": true, + "Checkable": false, + "Checked": false + }, + "row": 0, + "col": 0, + "rowspan": 1, + "colspan": 1 + }, + { + "class": "TTkTextEdit", + "params": { + "Name": "TextEdit", + "Position": [ + 0, + 4 + ], + "Size": [ + 82, + 18 + ], + "Min Width": 0, + "Min Height": 0, + "Max Width": 65536, + "Max Height": 65536, + "Visible": true, + "Enabled": true, + "ToolTip": "", + "Line Number": true, + "Line Number Starting": 0, + "Read Only": false, + "Multi Line": true + }, + "row": 2, + "col": 0, + "rowspan": 1, + "colspan": 1 + }, + { + "class": "TTkLabel", + "params": { + "Name": "TTkLabel", + "Position": [ + 0, + 3 + ], + "Size": [ + 82, + 1 + ], + "Min Width": 30, + "Min Height": 1, + "Max Width": 65536, + "Max Height": 1, + "Visible": true, + "Enabled": true, + "ToolTip": "", + "Text": "Paste here the Dict definition", + "Color": "\u001b[0m", + "Alignment": 0 + }, + "row": 1, + "col": 0, + "rowspan": 1, + "colspan": 1 + } + ] + } + }, + "connections": [] +} \ No newline at end of file diff --git a/ttkDesigner/app/designer.py b/ttkDesigner/app/designer.py index 30d7e1cc..3dd3b9c6 100644 --- a/ttkDesigner/app/designer.py +++ b/ttkDesigner/app/designer.py @@ -391,6 +391,7 @@ class TTkDesigner(TTkAppTemplate): return ret newWindow = TTkUiLoader.loadFile(os.path.join(os.path.dirname(os.path.abspath(__file__)),"../tui/quickImport.tui.json")) te = newWindow.getWidgetByName("TextEdit") + @pyTTkSlot() def _importDict(te=te): text = te.toPlainText() if compressed := _probeCompressedText(text):