diff --git a/TermTk/TTkCore/canvas.py b/TermTk/TTkCore/canvas.py index 2d2780ef..f28ecee6 100644 --- a/TermTk/TTkCore/canvas.py +++ b/TermTk/TTkCore/canvas.py @@ -153,9 +153,14 @@ class TTkCanvas(): fyb = min(h,fyb) fillCh = [char]*(fxb-fxa) - fillColor = [color]*(fxb-fxa) for iy in range(fya,fyb): self._data[iy][fxa:fxb] = fillCh + if color.colorType() & TTkK.Modifier: + for iy in range(fya,fyb): + for ix in range(fxa,fxb): + self._colors[iy][ix] = color.mod(fxa+ix,fya+iy) + else: + fillColor = [color]*(fxb-fxa) self._colors[iy][fxa:fxb] = fillColor def drawVLine(self, pos, size, color=TTkColor.RST): diff --git a/TermTk/TTkUiTools/properties/colorpicker.py b/TermTk/TTkUiTools/properties/colorpicker.py index 8af3ed3a..90e7f0da 100644 --- a/TermTk/TTkUiTools/properties/colorpicker.py +++ b/TermTk/TTkUiTools/properties/colorpicker.py @@ -23,16 +23,33 @@ __all__ = ['TTkColorButtonPickerProperties'] from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.TTkPickers.colorpicker import TTkColorButtonPicker +from TermTk.TTkWidgets.TTkPickers.colorpicker import TTkColorButtonPicker,TTkColorDialogPicker TTkColorButtonPickerProperties = { 'properties' : { 'Color' : { 'init': {'name':'color', 'type':TTkColor }, 'get': {'cb':TTkColorButtonPicker.color, 'type':TTkColor } , - 'set': {'cb':TTkColorButtonPicker.setColor, 'type':TTkColor } }, }, + 'set': {'cb':TTkColorButtonPicker.setColor, 'type':TTkColor } }, + 'Return Type' : { + 'init': {'name':'returnType', 'type':'singleflag', + 'flags': { + 'Default' : TTkColorDialogPicker.ColorReturnType.Default , + 'Foreground' : TTkColorDialogPicker.ColorReturnType.Foreground , + 'Background' : TTkColorDialogPicker.ColorReturnType.Background } }, + 'get': {'cb':TTkColorButtonPicker.returnType, 'type':'singleflag', + 'flags': { + 'Default' : TTkColorDialogPicker.ColorReturnType.Default , + 'Foreground' : TTkColorDialogPicker.ColorReturnType.Foreground , + 'Background' : TTkColorDialogPicker.ColorReturnType.Background } } , + 'set': {'cb':TTkColorButtonPicker.setReturnType, 'type':'singleflag', + 'flags': { + 'Default' : TTkColorDialogPicker.ColorReturnType.Default , + 'Foreground' : TTkColorDialogPicker.ColorReturnType.Foreground , + 'Background' : TTkColorDialogPicker.ColorReturnType.Background } } } }, 'signals' : { 'colorSelected(TTkColor)' : {'name': 'colorSelected', 'type' : TTkColor}, + 'colorSelectedFG(TTkColor)' : {'name': 'colorSelectedFG', 'type' : TTkColor}, 'colorSelectedBG(TTkColor)' : {'name': 'colorSelectedBG', 'type' : TTkColor}, }, 'slots' : { diff --git a/TermTk/TTkUiTools/properties/label.py b/TermTk/TTkUiTools/properties/label.py index 59848ea5..5e6e2e5c 100644 --- a/TermTk/TTkUiTools/properties/label.py +++ b/TermTk/TTkUiTools/properties/label.py @@ -62,6 +62,7 @@ TTkLabelProperties = { },'signals' : { },'slots' : { 'setText(str)' : {'name': 'setText', 'type':str}, + 'setColor(TTkColor)' : {'name': 'setColor', 'type':TTkColor}, 'setAlignment(Alignment)' : {'name': 'setAlignment', 'type':TTkK.Alignment}, } } diff --git a/TermTk/TTkWidgets/TTkPickers/colorpicker.py b/TermTk/TTkWidgets/TTkPickers/colorpicker.py index 50b93b9a..b120f6d3 100644 --- a/TermTk/TTkWidgets/TTkPickers/colorpicker.py +++ b/TermTk/TTkWidgets/TTkPickers/colorpicker.py @@ -31,6 +31,8 @@ from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor from TermTk.TTkCore.string import TTkString from TermTk.TTkCore.helper import TTkHelper +from TermTk.TTkCore.canvas import TTkCanvas +from TermTk.TTkCore.TTkTerm.inputmouse import TTkMouseEvent from TermTk.TTkWidgets.widget import TTkWidget from TermTk.TTkWidgets.window import TTkWindow from TermTk.TTkWidgets.button import TTkButton @@ -42,11 +44,11 @@ from TermTk.TTkLayouts.gridlayout import TTkGridLayout class _TTkHueCanvas(TTkWidget): __slots__ = ('_hueList', '_selected', 'colorPicked') - def __init__(self, *args, **kwargs) -> None: + def __init__(self, **kwargs) -> None: # signals self.colorPicked=pyTTkSignal(int) - TTkWidget.__init__(self, *args, **kwargs) + TTkWidget.__init__(self, **kwargs) self.setMaximumHeight(1) self.setMinimumSize(6,1) @@ -55,20 +57,20 @@ class _TTkHueCanvas(TTkWidget): self.setFocusPolicy(TTkK.ClickFocus) - def resizeEvent(self, w, h): + def resizeEvent(self, width: int, height: int) -> None: self._selected = -1 - def mousePressEvent(self, evt): + def mousePressEvent(self, evt: TTkMouseEvent) -> bool: self._selected = evt.x if evt.x < len(self._hueList): self.colorPicked.emit(self._hueList[evt.x]) self.update() return True - def mouseDragEvent(self, evt): + def mouseDragEvent(self, evt: TTkMouseEvent) -> bool: return self.mousePressEvent(evt) - def paintEvent(self, canvas): + def paintEvent(self, canvas: TTkCanvas) -> None: w,_ = self.size() self._hueList = [0x00]*(w+1) def _linInt(a,b,x): @@ -96,20 +98,20 @@ class _TTkHueCanvas(TTkWidget): class _TTkColorCanvas(TTkWidget): __slots__ = ('_hue', 'colorPicked', '_selected') - def __init__(self, *args, **kwargs) -> None: + def __init__(self, **kwargs) -> None: # signals self.colorPicked=pyTTkSignal(int) self._selected=(-1,-1) - TTkWidget.__init__(self, *args, **kwargs) + TTkWidget.__init__(self, **kwargs) self._hue = 0xff0000 self.setFocusPolicy(TTkK.ClickFocus) @pyTTkSlot(int) - def setHue(self, hue): + def setHue(self, hue:int): self._hue = hue self.update() - def mousePressEvent(self, evt): + def mousePressEvent(self, evt: TTkMouseEvent) -> bool: w,h = self.size() x,y = evt.x, evt.y self._selected = (x,y) @@ -117,7 +119,7 @@ class _TTkColorCanvas(TTkWidget): self.update() return True - def mouseDragEvent(self, evt): + def mouseDragEvent(self, evt: TTkMouseEvent) -> bool: return self.mousePressEvent(evt) def _colorAt(self,x,y,w,h): @@ -136,7 +138,7 @@ class _TTkColorCanvas(TTkWidget): b = _linInt(b,0,y/h)&0x0000ff return r|g|b - def paintEvent(self, canvas): + def paintEvent(self, canvas: TTkCanvas) -> None: w,h = self.size() for x in range(w): for y in range(h): @@ -154,94 +156,174 @@ class _TTkShowColor(TTkWidget): self._color = color TTkWidget.__init__(self, **kwargs) - def color(self): + def color(self) -> TTkColor: return self._color @pyTTkSlot(TTkColor) - def setColor(self, color): + def setColor(self, color:TTkColor) -> None: if self._color != color: self._color = color self.update() @pyTTkSlot(int) - def setRGBColor(self, color): + def setRGBColor(self, color:int) -> None: self.setColor(TTkColor.bg( f"#{color:06x}" )) self.update() - def paintEvent(self, canvas): + def paintEvent(self, canvas: TTkCanvas) -> None: w,h = self.size() for y in range(h): canvas.drawText(pos=(0,y),text=" "*w, color=self._color) class _TTkColorButton(TTkButton): lastClicked = None - __slots__ = ('colorClicked','_custom','_color') + + colorClicked:pyTTkSignal + ''' + This signal is emitted when a color is selected + + :param color: + :type color: :py:class:`TTkColor` + ''' + __slots__ = ('colorClicked','_custom','_color','_returnType') def __init__(self, *, color:TTkColor=TTkColor.RST, + returnType=0x00, custom:bool=False, **kwargs) -> None: # Signals self.colorClicked = pyTTkSignal(TTkColor) - self._color = color - self._custom = custom + self._color:TTkColor=color if color and color!=TTkColor.RST else TTkColor.BLACK + self._custom=custom + self._returnType=returnType super().__init__(**kwargs) self.clicked.connect(self._clicked) self.setColor(self._color) @pyTTkSlot(TTkColor) - def setColor(self, color): + def setColor(self, color:TTkColor) -> None: + self._color:TTkColor=color if color and color!=TTkColor.RST else TTkColor.BLACK style = self.style() - self._color = color for t in style: if 'color' in style[t]: - style[t]['color'] = color + if fg := color.foreground(): + style[t]['color'] = fg.invertFgBg() + elif bg := color.background(): + style[t]['color'] = bg + else: + style[t]['color'] = TTkColor.BG_BLACK self.setStyle(style) + self.update() - def color(self): + def color(self) -> TTkColor: + fg = self._color.foreground() + bg = self._color.background() + if self._returnType==TTkColorDialogPicker.ColorReturnType.Foreground: + return fg if fg else bg.invertFgBg() if bg else TTkColor.RST + if self._returnType==TTkColorDialogPicker.ColorReturnType.Background: + return bg if bg else fg.invertFgBg() if fg else TTkColor.RST return self._color - def isCustom(self): + def isCustom(self) -> bool: return self._custom @pyTTkSlot() - def _clicked(self): + def _clicked(self) -> None: if self._custom: _TTkColorButton.lastClicked = self - self.colorClicked.emit(self._color) + self.colorClicked.emit(self.color()) class TTkColorDialogPicker(TTkWindow): - ''' Color Picker Layout sizes: + ''' + :py:class:`TTkColorDialogPicker` is a Color Picker Dialog, normally spawned from :py:class:`TTkColorButtonPicker` :: - Terminal window (More or less, It is too annoying to redraw this) - ┌────────────────────────────────────────────────┐ - │┌──────[Palette]───────┐┌────[Color]───────────┐│ - ││┌──────┐┌─────┐┌─────┐││┌────────────────────┐││ - │││RED ││Green││Blue ││││ │││ - ││└──────┘└─────┘└─────┘│││ │││ - ││┌──────┐┌─────┐┌─────┐│││ │││ - │││Purple││White││Black││││ │││ - ││└──────┘└─────┘└─────┘│││ Color Canvas │││ - ││┌──────┐┌─────┐┌─────┐│││ │││ - │││... ││ ││ ││││ │││ - ││└──────┘└─────┘└─────┘││└────────────────────┘││ - ││┌──────┐┌─────┐┌─────┐││┌────────────────────┐││ - │││ ││ ││ ││││ HUE Canvas │││ - ││└──────┘└─────┘└─────┘││└────────────────────┘││ - │└──────────────────────┘└──────────────────────┘│ - │┌───────[Custom]───────┐┌───────[Control]──────┐│ - ││┌──────┐┌─────┐┌─────┐││┌────┐ ┌──────┐││ - │││ ││ ││ ││││ │ Red: └──────┘││ - ││└──────┘└─────┘└─────┘│││ │ ┌──────┐││ - ││┌──────┐┌─────┐┌─────┐│││ │ Green:└──────┘││ - │││ ││ ││ ││││ │ ┌──────┐││ - ││└──────┘└─────┘└─────┘││└────┘ Blue: └──────┘││ - ││ ││ ┌──────────────┐││ - ││ ││HTML: └──────────────┘││ - │└──────────────────────┘└──────────────────────┘│ - └────────────────────────────────────────────────┘ + + ╔═════════════════════════════════════════════════════════════════════════╗ + ║ Color Picker [^][x]║ + ╟────┤ Basic colors ├────┬────────────────────────────────────────────────╢ + ║┌──────┐┌──────┐┌──────┐│ ║ + ║│ ││ ││ ││ ║ + ║╘══════╛╘══════╛╘══════╛│ ║ + ║┌──────┐┌──────┐┌──────┐│ ║ + ║│ ││ ││ ││ ║ + ║╘══════╛╘══════╛╘══════╛│ ║ + ║┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐│ ║ + ║│ ││ ││ ││ ││ ││ ││ [Color Gradient] ║ + ║╘══╛╘══╛╘══╛╘══╛╘══╛╘══╛│ ║ + ╟───┤ Custom colors ├────┤ ║ + ║┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐│ ║ + ║│ ││ ││ ││ ││ ││ ││ ││ ││ ║ + ║╘═╛╘═╛╘═╛╘═╛╘═╛╘═╛╘═╛╘═╛│ ║ + ║[ Add to Custom Colors ]│ ║ + ╟──────┤ Conrols ├───────┤ ║ + ║ rgb: 136▲▼255▲▼ 255▲▼ │ ║ + ║ HTML: #88FFFF │ ║ + ║ ┌────┐ ┌────────┐ │ ║ + ║ │ OK │ │ CANCEL │ │ ║ + ║ ╘════╛ ╘════════╛ │ ║ + ╚════════════════════════╧════════════════════════════════════════════════╝ + + Quickstart: + + .. code-block:: python + + from TermTk import TTk,TTkColor,TTkColorDialogPicker,TTkLabel + + root = TTk() + + cdp = TTkColorDialogPicker( + parent=root, + pos=(3,3), size=(75,24), border=True, + color=TTkColor.RED, + title="Test Color Picker") + + lfg = TTkLabel(parent=root, pos=(0,0), text="Test Color") + + cdp.colorSelected.connect(lfg.setColor) + + root.mainloop() + ''' + # Terminal window (More or less, It is too annoying to redraw this) + # ┌────────────────────────────────────────────────┐ + # │┌──────[Palette]───────┐┌────[Color]───────────┐│ + # ││┌──────┐┌─────┐┌─────┐││┌────────────────────┐││ + # │││RED ││Green││Blue ││││ │││ + # ││└──────┘└─────┘└─────┘│││ │││ + # ││┌──────┐┌─────┐┌─────┐│││ │││ + # │││Purple││White││Black││││ │││ + # ││└──────┘└─────┘└─────┘│││ Color Canvas │││ + # ││┌──────┐┌─────┐┌─────┐│││ │││ + # │││... ││ ││ ││││ │││ + # ││└──────┘└─────┘└─────┘││└────────────────────┘││ + # ││┌──────┐┌─────┐┌─────┐││┌────────────────────┐││ + # │││ ││ ││ ││││ HUE Canvas │││ + # ││└──────┘└─────┘└─────┘││└────────────────────┘││ + # │└──────────────────────┘└──────────────────────┘│ + # │┌───────[Custom]───────┐┌───────[Control]──────┐│ + # ││┌──────┐┌─────┐┌─────┐││┌────┐ ┌──────┐││ + # │││ ││ ││ ││││ │ Red: └──────┘││ + # ││└──────┘└─────┘└─────┘│││ │ ┌──────┐││ + # ││┌──────┐┌─────┐┌─────┐│││ │ Green:└──────┘││ + # │││ ││ ││ ││││ │ ┌──────┐││ + # ││└──────┘└─────┘└─────┘││└────┘ Blue: └──────┘││ + # ││ ││ ┌──────────────┐││ + # ││ ││HTML: └──────────────┘││ + # │└──────────────────────┘└──────────────────────┘│ + # └────────────────────────────────────────────────┘ + + class ColorReturnType(int): + ''' + This class identify the return color type + ''' + Default=0x00 + '''The color type returned (fg or bg) is compliant of the type used in the initialization or 'Foreground' in case is missing or :py:class:`TTKColor.RST`''' + Foreground=0x01 + '''The color type returned is Foreground''' + Background=0x02 + '''The color type returned is Background''' classStyle = { 'default': {'color': TTkColor.RST, @@ -256,19 +338,37 @@ class TTkColorDialogPicker(TTkWindow): } customButtons = None + + colorSelected:pyTTkSignal + ''' + This signal is emitted when a color is selected or the cancel button is pressed + + :param color: the current color + :type color: :py:class:`TTkColor` + ''' __slots__ = ( - '_color', + '_color', '_returnType', '_colorCanvas', '_hueCanvas', + '_isForeground', # '_redLE', '_greenLE', '_blueRE', '_htmlLE', # Signals 'colorSelected' ) def __init__(self, *, color:TTkColor=TTkColor.RST, + returnType:ColorReturnType=ColorReturnType.Default, **kwargs) -> None: + ''' + :param color: the current color + :type color: :py:class:`TTkColor` + :param returnType: the type of the returuning color + :type returnType: :py:class:`TTkColorDialogPicker.ColorReturnType` + ''' # Signals self.colorSelected = pyTTkSignal(TTkColor) - self._color = color + self._returnType=returnType + self._color:TTkColor=color if color and color!=TTkColor.RST else TTkColor.BLACK + self._isForeground:bool = not (color.colorType()&TTkK.Background)!=0 super().__init__(**kwargs) self.setWindowFlag(TTkK.WindowFlag.WindowMaximizeButtonHint | TTkK.WindowFlag.WindowCloseButtonHint) self.setLayout(TTkGridLayout()) @@ -303,22 +403,23 @@ class TTkColorDialogPicker(TTkWindow): controlLayout.addWidget( TTkLabel(pos=(3,20), text="Seriously?") ) @pyTTkSlot() - def _okPressed(): - self.setColor(sc.color()) - self.colorSelected.emit(self._color) + def _okPressed() -> None: + color = sc.color().invertFgBg() if self._isForeground else sc.color() + # self.setColor(color) + self.colorSelected.emit(color) self.close() okButton.clicked.connect(_okPressed) @pyTTkSlot() - def _cancelPressed(): + def _cancelPressed() -> None: self.colorSelected.emit(self._color) self.close() cancelButton.clicked.connect(_cancelPressed) @pyTTkSlot(int) - def _controlSetRGBColor(color): + def _controlSetRGBColor(color:int) -> None: sc.setRGBColor(color) leR.setValue((color&0xff0000)>>16) leG.setValue((color&0x00ff00)>> 8) @@ -326,13 +427,13 @@ class TTkColorDialogPicker(TTkWindow): leHTML.setText(f"#{color:06X}") @pyTTkSlot(TTkColor) - def _controlSetColor(color): - r,g,b = color.bgToRGB() + def _controlSetColor(color:TTkColor) -> None: + r,g,b = color.fgToRGB() numColor = r<<16|g<<8|b _controlSetRGBColor(numColor) @pyTTkSlot() - def _leHTMLChanged(): + def _leHTMLChanged() -> None: text = leHTML.text() if re.match('#[a-f0-9]{6}', str(text).lower()): _controlSetRGBColor(int(str(text)[1:], 16)) @@ -340,7 +441,7 @@ class TTkColorDialogPicker(TTkWindow): leHTML.returnPressed.connect(_leHTMLChanged) @pyTTkSlot(int) - def _leRGBChanged(value): + def _leRGBChanged(value:int) -> None: r = leR.value() g = leG.value() b = leB.value() @@ -351,47 +452,47 @@ class TTkColorDialogPicker(TTkWindow): leG.valueChanged.connect(_leRGBChanged) leB.valueChanged.connect(_leRGBChanged) - _controlSetColor(self._color) + _controlSetColor(self._color if self._isForeground else self._color.invertFgBg()) # Palette Layout Widgets - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#ff0000'), border=True, maxSize=(8,3)),0,0,1,2) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#ff0000'), border=True, maxSize=(8,3)),0,0,1,2) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#ffff00'), border=True, maxSize=(8,3)),0,2,1,2) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#ffff00'), border=True, maxSize=(8,3)),0,2,1,2) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#00ff00'), border=True, maxSize=(8,3)),0,4,1,2) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#00ff00'), border=True, maxSize=(8,3)),0,4,1,2) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#00ffff'), border=True, maxSize=(8,3)),1,0,1,2) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#00ffff'), border=True, maxSize=(8,3)),1,0,1,2) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#0000ff'), border=True, maxSize=(8,3)),1,2,1,2) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#0000ff'), border=True, maxSize=(8,3)),1,2,1,2) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#ff00ff'), border=True, maxSize=(8,3)),1,4,1,2) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#ff00ff'), border=True, maxSize=(8,3)),1,4,1,2) b.colorClicked.connect(_controlSetColor) # Shades of Grey - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#ffffff'), border=True, maxSize=(4,3)),2,0) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#ffffff'), border=True, maxSize=(4,3)),2,0) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#dddddd'), border=True, maxSize=(4,3)),2,1) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#dddddd'), border=True, maxSize=(4,3)),2,1) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#aaaaaa'), border=True, maxSize=(4,3)),2,2) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#aaaaaa'), border=True, maxSize=(4,3)),2,2) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#666666'), border=True, maxSize=(4,3)),2,3) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#666666'), border=True, maxSize=(4,3)),2,3) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#333333'), border=True, maxSize=(4,3)),2,4) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#333333'), border=True, maxSize=(4,3)),2,4) b.colorClicked.connect(_controlSetColor) - paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.bg('#000000'), border=True, maxSize=(4,3)),2,5) + paletteLayout.addWidget(b:=_TTkColorButton(color=TTkColor.fg('#000000'), border=True, maxSize=(4,3)),2,5) b.colorClicked.connect(_controlSetColor) # Custom frame if TTkColorDialogPicker.customButtons is None: TTkColorDialogPicker.customButtons = ( - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , - _TTkColorButton(color=TTkColor.bg('#ffffff'), custom=True, border=True, maxSize=(3,3)) ) + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) , + _TTkColorButton(color=TTkColor.fg('#ffffff'), custom=True, border=True, maxSize=(3,3)) ) customLayout.addWidget(b:=TTkColorDialogPicker.customButtons[0],0,0) @@ -411,17 +512,19 @@ class TTkColorDialogPicker(TTkWindow): customLayout.addWidget(b:=TTkColorDialogPicker.customButtons[7],0,7) b.colorClicked.connect(_controlSetColor) + _TTkColorButton.lastClicked = TTkColorDialogPicker.customButtons[0] + customLayout.addWidget(b:=TTkButton(border=False, text='Add to Custom Colors'),1,0,1,8) customLayout.update() @pyTTkSlot() - def _addCustomPressed(): + def _addCustomPressed() -> None: btn = _TTkColorButton.lastClicked TTkLog.debug(f"{btn}") if btn is not None and \ btn.isCustom(): TTkLog.debug(f"2 {btn}") - btn.setColor(sc.color()) + btn.setColor(sc.color().invertFgBg().foreground()) b.clicked.connect(_addCustomPressed) # Events @@ -434,12 +537,40 @@ class TTkColorDialogPicker(TTkWindow): leftLayout.addItem(customLayout) leftLayout.addItem(controlLayout) - def color(self): + def _colorToBg(self) -> TTkColor: + if self._isForeground: + return self._color.invertFgBg() + else: + return self._color + + def _colorToFg(self) -> TTkColor: + if self._isForeground: + return self._color + else: + return self._color.invertFgBg() + + def color(self) -> TTkColor: + ''' + :return: the current color + :rtype: :py:class:`TTkColor` + ''' + fg = self._color.foreground() + bg = self._color.background() + if self._returnType==TTkColorDialogPicker.ColorReturnType.Foreground: + return fg if fg else bg.invertFgBg() if bg else TTkColor.RST + if self._returnType==TTkColorDialogPicker.ColorReturnType.Background: + return bg if bg else fg.invertFgBg() if fg else TTkColor.RST return self._color - def setColor(self, color): + def setColor(self, color:TTkColor) -> None: + ''' + Set the current color + + :param color: + :type color: :py:class:`TTkColor` + ''' if self._color != color: - self._color = color + self._color:TTkColor=color if color and color!=TTkColor.RST else TTkColor.BLACK self.update() def paintEvent(self, canvas): @@ -461,17 +592,78 @@ class TTkColorDialogPicker(TTkWindow): canvas.drawBoxTitle(pos=(0,17), size=(26,0), text=TTkString(" Conrols "), align=TTkK.CENTER_ALIGN, color=color, colorText=titleColor) class TTkColorButtonPicker(_TTkColorButton): - __slots__ = ('_type', 'colorSelected', 'colorSelectedBG') + ''' + :py:class:`TTkColorButtonPicker` is a button widget that spawn, if pressed, a :py:class:`TTkColorDialogPicker` can be used to choose a :py:class:`TTkColor`. + + Quickstart: + + .. code-block:: python + + import TermTk as ttk + + root = ttk.TTk() + + btn = ttk.TTkColorButtonPicker( + parent=root, + size=(8,3), + border=True, + color=ttk.TTkColor.RED ) + + lfg = ttk.TTkLabel(parent=root, pos=(0,3), text="Test FG") + lbg = ttk.TTkLabel(parent=root, pos=(0,4), text="Test BG") + + btn.colorSelectedFG.connect(lfg.setColor) + btn.colorSelectedBG.connect(lbg.setColor) + + root.mainloop() + + ''' + + colorSelected:pyTTkSignal + ''' + This signal is emitted when a color is chosen (with the "OK" button in the :py:class:`TTkColorDialogPicker`) + + :param color: the Color + :type color: :py:class:`TTkColor` + ''' + colorSelectedFG:pyTTkSignal + ''' + This signal is emitted when a color is chosen (with the "OK" button in the :py:class:`TTkColorDialogPicker`) + + :param fgColor: the Foreground Color + :type fgColor: :py:class:`TTkColor` + ''' + colorSelectedBG:pyTTkSignal + ''' + This signal is emitted when a color is chosen (with the "OK" button in the :py:class:`TTkColorDialogPicker`) + + This is a convenience signal that mrrors :py:class:`colorSelectedFG` providing a background color instead. + + :param bgColor: the Background Color + :type bgColor: :py:class:`TTkColor` + ''' + + __slots__ = ('colorSelected','colorSelectedFG', 'colorSelectedBG') def __init__(self, **kwargs) -> None: + ''' + :param color: the current color + :type color: :py:class:`TTkColor` + :param returnType: the type of the returuning color + :type returnType: :py:class:`TTkColorDialogPicker.ColorReturnType` + ''' # Signals self.colorSelected = pyTTkSignal(TTkColor) + self.colorSelectedFG = pyTTkSignal(TTkColor) self.colorSelectedBG = pyTTkSignal(TTkColor) super().__init__(**kwargs) self._custom = False self.clicked.connect(self._colorClicked) - self._type = self.color().colorType() - hexColor = self.color().getHex(self._type) - self.setColor(TTkColor.bg(hexColor)) + + def returnType(self) -> TTkColorDialogPicker.ColorReturnType: + return self._returnType + + def setReturnType(self, returnType:TTkColorDialogPicker.ColorReturnType) -> None: + self._returnType = returnType @pyTTkSlot() def _colorClicked(self): @@ -482,16 +674,14 @@ class TTkColorButtonPicker(_TTkColorButton): @pyTTkSlot(TTkColor) def _processColorSelected(self, color:TTkColor): - self.colorSelected.emit(color) - self.colorSelectedBG.emit(color.invertFgBg()) - - def setFocus(self): - lastFocus = TTkHelper.getFocus() - return super().setFocus() + if fg := self.color().foreground(): + bg = fg.invertFgBg() + elif bg := self.color().background(): + fg = bg.invertFgBg() + else: + fg = TTkColor.BLACK + bg = TTkColor.BG_BLACK - def clearFocus(self): - lastFocus = TTkHelper.getFocus() - return super().clearFocus() - - def paintEvent(self, canvas): - return super().paintEvent(canvas) + self.colorSelected.emit(color) + self.colorSelectedFG.emit(fg) + self.colorSelectedBG.emit(bg) diff --git a/TermTk/TTkWidgets/TTkPickers/filepicker.py b/TermTk/TTkWidgets/TTkPickers/filepicker.py index 638089b6..f68f1d9b 100644 --- a/TermTk/TTkWidgets/TTkPickers/filepicker.py +++ b/TermTk/TTkWidgets/TTkPickers/filepicker.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -__all__ = ['TTkFileDialog', 'TTkFileDialogPicker', 'TTkFileButtonPicker'] +__all__ = ['TTkFileDialogPicker', 'TTkFileButtonPicker'] import os import re @@ -58,7 +58,8 @@ from TermTk.TTkWidgets.TTkModelView.filetreewidgetitem import TTkFileTreeWidgetI ''' class TTkFileDialogPicker(TTkWindow): - ''' TTkFileDialogPicker: + ''' + :py:class:`TTkFileDialogPicker` is a File/Folder Picker Dialog, normally spawned from :py:class:`TTkFileButtonPicker` :: @@ -87,10 +88,10 @@ class TTkFileDialogPicker(TTkWindow): ║Files of type:[All Files (*) ^][Cancel]║ ╚═════════════════════════════════════════════════════════════════════════╝ - Demo: `formwidgets.py `_ + Demo: `filepicker.py `_ (`Try Online `__) - `ttkdesigner Tutorial `_ + :ref:`ttkdesigner Tutorial ` :param path: the current path used in the file dialog, defaults to "." :type path: str, optional @@ -257,17 +258,17 @@ class TTkFileDialogPicker(TTkWindow): def acceptMode(self) -> TTkK.AcceptMode: return self._acceptMode - def setAcceptMode(self, mode:TTkK.AcceptMode): + def setAcceptMode(self, mode:TTkK.AcceptMode) -> None: self._acceptMode = mode self._btnOpen.setText("Open" if mode == TTkK.AcceptMode.AcceptOpen else "Save") @pyTTkSlot(str) - def _cbFileTypeChanged(self, type): + def _cbFileTypeChanged(self, type:str) -> None: self._filter = re.match(r".*\((.*)\)",type).group(1) self._fileTree.setFilter(self._filter) @pyTTkSlot(str) - def _checkFileName(self, fileName): + def _checkFileName(self, fileName:str) -> None: fileName = str(fileName) valid = False if self._fileMode == TTkK.FileMode.ExistingFile: @@ -284,7 +285,7 @@ class TTkFileDialogPicker(TTkWindow): self._btnOpen.setDisabled() @pyTTkSlot() - def _open(self): + def _open(self) -> None: fileName = str(self._leFileName.text()) if self._fileMode != TTkK.FileMode.AnyFile and not os.path.exists(fileName): return if self._fileMode == TTkK.FileMode.ExistingFile and not os.path.isfile(fileName): return @@ -297,7 +298,7 @@ class TTkFileDialogPicker(TTkWindow): self.pathPicked.emit(fileName) @pyTTkSlot(TTkFileTreeWidgetItem, int) - def _selectedItem(self, item, _): + def _selectedItem(self, item:TTkFileTreeWidgetItem, _:int) -> None: path = item.path() if os.path.isdir(path) and path[-1]!='/': path = path+'/'+self._fileName @@ -306,20 +307,20 @@ class TTkFileDialogPicker(TTkWindow): self._leFileName.setText(path) @pyTTkSlot(TTkFileTreeWidgetItem, int) - def _activatedItem(self, item, _): + def _activatedItem(self, item:TTkFileTreeWidgetItem, _:int) -> None: path = str(item.path()) if os.path.isdir(path): self._openNewPath(path, True) elif os.path.isfile(path): self._open() - def filemode(self): + def filemode(self) -> TTkK.FileMode: return self._fileMode - def setFileMode(self, fileMode): + def setFileMode(self, fileMode:TTkK.FileMode) -> None: self._fileMode = fileMode - def _openPrev(self): + def _openPrev(self) -> None: if self._recentPathId<=0 or self._recentPathId>=len(self._recentPath): self._btnPrev.setDisabled() return @@ -329,7 +330,7 @@ class TTkFileDialogPicker(TTkWindow): self._btnPrev.setDisabled() self._btnNext.setEnabled() - def _openNext(self): + def _openNext(self) -> None: if self._recentPathId<0 or self._recentPathId>=len(self._recentPath)-1: self._btnNext.setDisabled() return @@ -339,13 +340,13 @@ class TTkFileDialogPicker(TTkWindow): self._btnNext.setDisabled() self._btnPrev.setEnabled() - def _openUp(self): + def _openUp(self) -> None: path = os.path.abspath(self._recentPath[self._recentPathId]) path, e = os.path.split(path) if e: self._openNewPath(path, True) - def _openNewPath(self, path, addToRecent=True): + def _openNewPath(self, path:str, addToRecent:bool=True) -> None: self._path = path if addToRecent: self._recentPathId = len(self._recentPath) @@ -361,7 +362,7 @@ class TTkFileDialogPicker(TTkWindow): self._lookPath.currentTextChanged.connect(self._openNewPath) @staticmethod - def _getListLook(path): + def _getListLook(path:str) -> list[str]: path = os.path.abspath(path) ret = [path] while True: @@ -371,10 +372,11 @@ class TTkFileDialogPicker(TTkWindow): if not path or path=='/' or path[1:]==":\\": break return ret -class TTkFileDialog: - @staticmethod - def getOpenFileName(caption, dir=".", filter="All Files (*)", options=None): - pass + +# class TTkFileDialog: +# @staticmethod +# def getOpenFileName(caption, dir=".", filter="All Files (*)", options=None): +# pass class TTkFileButtonPicker(TTkButton): ''' @@ -486,11 +488,11 @@ class TTkFileButtonPicker(TTkButton): self._acceptMode = acceptMode self.clicked.connect(self._fileButtonClicked) - def filter(self): return self._filter - def setFilter(self, filter): self._filter = filter + def filter(self) -> str: return self._filter + def setFilter(self, filter:str) -> None: self._filter = filter - def caption(self): return self._caption - def setCaption(self, caption): self._caption = caption + def caption(self) -> str: return self._caption + def setCaption(self, caption:str) -> None: self._caption = caption def acceptMode(self) -> TTkK.AcceptMode: return self._acceptMode def setAcceptMode(self, mode:TTkK.AcceptMode): self._acceptMode = mode @@ -498,11 +500,11 @@ class TTkFileButtonPicker(TTkButton): def fileMode(self) -> TTkK.FileMode: return self._fileMode def setFileMode(self, fm:TTkK.FileMode): self._fileMode = fm - def path(self): return self._path - def setPath(self, path): self._path = path + def path(self) -> str: return self._path + def setPath(self, path:str) -> None: self._path = path @pyTTkSlot() - def _fileButtonClicked(self): + def _fileButtonClicked(self) -> None: filePicker = TTkFileDialogPicker(pos = (3,3), size=(80,30), caption=self._caption, path=self._path, diff --git a/TermTk/TTkWidgets/TTkPickers/textpicker.py b/TermTk/TTkWidgets/TTkPickers/textpicker.py index b61221da..401194d6 100644 --- a/TermTk/TTkWidgets/TTkPickers/textpicker.py +++ b/TermTk/TTkWidgets/TTkPickers/textpicker.py @@ -47,7 +47,7 @@ from TermTk.TTkWidgets.checkbox import TTkCheckbox from TermTk.TTkWidgets.window import TTkWindow from TermTk.TTkWidgets.TTkModelView.filetree import TTkFileTree from TermTk.TTkWidgets.TTkModelView.filetreewidgetitem import TTkFileTreeWidgetItem -from TermTk.TTkWidgets.TTkPickers.colorpicker import TTkColorButtonPicker +from TermTk.TTkWidgets.TTkPickers.colorpicker import TTkColorButtonPicker, TTkColorDialogPicker class _superSimpleHorizontalLine(TTkWidget): def paintEvent(self, canvas): @@ -141,10 +141,10 @@ class TTkTextDialogPicker(TTkWindow): fontLayout = TTkGridLayout(columnMinWidth=1) # Char Fg/Bg buttons fontLayout.addWidget(cb_fg := TTkCheckbox(text=" FG"),0,0) - fontLayout.addWidget(btn_fgColor := TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), minSize=(7,3)),1,0) + fontLayout.addWidget(btn_fgColor := TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), minSize=(7,3), returnType=TTkColorDialogPicker.ColorReturnType.Foreground),1,0) fontLayout.addWidget(cb_bg := TTkCheckbox(text=" BG"),0,2) - fontLayout.addWidget(btn_bgColor := TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), minSize=(7,3)),1,2) + fontLayout.addWidget(btn_bgColor := TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), minSize=(7,3), returnType=TTkColorDialogPicker.ColorReturnType.Background),1,2) # Char style buttons fontLayout.addWidget(btn_bold := TTkButton(border=True, maxSize=(5,3), minSize=(5,3), checkable=True, text=TTkString( 'a' , TTkColor.BOLD) ),1,4) @@ -172,11 +172,11 @@ class TTkTextDialogPicker(TTkWindow): btn_emoji.clicked.connect(_showEmojiPicker) @pyTTkSlot(TTkColor) - def _currentColorChangedCB(format): + def _currentColorChangedCB(format:TTkColor): if fg := format.foreground(): cb_fg.setCheckState(TTkK.Checked) btn_fgColor.setEnabled() - btn_fgColor.setColor(fg.invertFgBg()) + btn_fgColor.setColor(fg) else: cb_fg.setCheckState(TTkK.Unchecked) btn_fgColor.setDisabled() @@ -195,12 +195,14 @@ class TTkTextDialogPicker(TTkWindow): btn_strikethrough.setChecked(format.strikethrough()) # TTkLog.debug(f"{fg=} {bg=} {bold=} {italic=} {underline=} {strikethrough= }") + _currentColorChangedCB(self._textEdit.textCursor().positionColor()) self._textEdit.currentColorChanged.connect(_currentColorChangedCB) + def _setStyle(): color = TTkColor() if cb_fg.checkState() == TTkK.Checked: - color += btn_fgColor.color().invertFgBg() + color += btn_fgColor.color() if cb_bg.checkState() == TTkK.Checked: color += btn_bgColor.color() if btn_bold.isChecked(): diff --git a/TermTk/TTkWidgets/frame.py b/TermTk/TTkWidgets/frame.py index 486f1d52..bf719bf4 100644 --- a/TermTk/TTkWidgets/frame.py +++ b/TermTk/TTkWidgets/frame.py @@ -47,8 +47,10 @@ class TTkFrame(TTkContainer): ''' classStyle = { 'default': {'color': TTkColor.fg("#dddddd")+TTkColor.bg("#222222"), + 'fillColor': TTkColor.RST, 'borderColor': TTkColor.RST}, 'disabled': {'color': TTkColor.fg('#888888'), + 'fillColor': TTkColor.RST, 'borderColor':TTkColor.fg('#888888')} } @@ -180,8 +182,11 @@ class TTkFrame(TTkContainer): def paintEvent(self, canvas): style = self.currentStyle() color = style['color'] + fillColor = style['fillColor'] borderColor = style['borderColor'] + if fillColor != TTkColor.RST: + canvas.fill(color=fillColor) if self._border: canvas.drawBox(pos=(0,0),size=(self._width,self._height), color=borderColor) if len(self._title) != 0: diff --git a/TermTk/TTkWidgets/label.py b/TermTk/TTkWidgets/label.py index a14eaf87..c55efa76 100644 --- a/TermTk/TTkWidgets/label.py +++ b/TermTk/TTkWidgets/label.py @@ -68,6 +68,7 @@ class TTkLabel(TTkWidget): '''color''' return self.style()['default']['color'] + @pyTTkSlot(TTkColor) def setColor(self, color): '''setColor''' self.mergeStyle({'default':{'color':color}}) diff --git a/demo/demo.py b/demo/demo.py index ab5254f7..5b6a6211 100755 --- a/demo/demo.py +++ b/demo/demo.py @@ -45,6 +45,7 @@ from showcase.list import demoList from showcase.menubar import demoMenuBar from showcase.filepicker import demoFilePicker from showcase.colorpicker import demoColorPicker +from showcase.textpicker import demoTextPicker from showcase.tree import demoTree from showcase.table import demoTTkTable from showcase.fancytable import demoFancyTable @@ -183,6 +184,7 @@ def demoShowcase(root=None, border=True): tabPickers = ttk.TTkTabWidget(parent=mainFrame, border=False, visible=False) tabPickers.addTab(demoFilePicker(), " File Picker ", 'showcase/filepicker.py') tabPickers.addTab(demoColorPicker(), " Color Picker ", 'showcase/colorpicker.py') + tabPickers.addTab(demoTextPicker(), " Text Picker ", 'showcase/textpicker.py') tabPickers.addMenu("sources", ttk.TTkK.RIGHT, tabPickers).menuButtonClicked.connect(lambda _menuButton : showSource(_menuButton.data().currentData())) listMenu.addItem(f"Graphs") diff --git a/demo/showcase/colorpicker.py b/demo/showcase/colorpicker.py index b84c23ac..41c00750 100755 --- a/demo/showcase/colorpicker.py +++ b/demo/showcase/colorpicker.py @@ -31,20 +31,35 @@ import TermTk as ttk def demoColorPicker(root=None): frame = ttk.TTkFrame(parent=root, border=False) - winCP = ttk.TTkWindow(parent=frame,pos = (0,0), size=(30,16), title="Test Color Pickers", border=True) - ttk.TTkColorButtonPicker(parent=winCP, pos=( 0,0), size=(8,3), border=True, color=ttk.TTkColor.bg('#88ffff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=( 0,3), size=(8,3), border=True, color=ttk.TTkColor.bg('#ff88ff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=( 0,6), size=(8,3), border=True, color=ttk.TTkColor.bg('#ffff88') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=( 0,9), size=(8,3), border=True, color=ttk.TTkColor.bg('#8888ff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(10,0), size=(8,3), border=True, color=ttk.TTkColor.fg('#00ffff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(10,3), size=(8,3), border=True, color=ttk.TTkColor.fg('#ff00ff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(10,6), size=(8,3), border=True, color=ttk.TTkColor.fg('#ffff00') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(10,9), size=(8,3), border=True, color=ttk.TTkColor.fg('#0000ff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(20,0), size=(8,3), border=True, color=ttk.TTkColor.bg('#ffffff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(20,3), size=(8,3), border=True, color=ttk.TTkColor.bg('#ffffff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(20,6), size=(8,3), border=True, color=ttk.TTkColor.bg('#ffffff') ) - ttk.TTkColorButtonPicker(parent=winCP, pos=(20,9), size=(8,3), border=True, color=ttk.TTkColor.bg('#ffffff') ) + lcol = ttk.TTkLabel(parent=frame, pos=(0,0), text="Test ░▒▓█▁▂▃▄▅▆▇█ Color") + lfg = ttk.TTkLabel(parent=frame, pos=(0,1), text="Test ░▒▓█▁▂▃▄▅▆▇█ Color FG") + lbg = ttk.TTkLabel(parent=frame, pos=(0,2), text="Test ░▒▓█▁▂▃▄▅▆▇█ Color BG") + winCP = ttk.TTkWindow(parent=frame,pos = (0,3), size=(30,17), title="Test Color Pickers", border=True) + ttk.TTkLabel(parent=winCP, pos=( 1,0), text="BG") + ttk.TTkLabel(parent=winCP, pos=(11,0), text="FG") + cbp01 = ttk.TTkColorButtonPicker(parent=winCP, pos=( 0, 1), size=(8,3), border=True, color=ttk.TTkColor.bg('#88ffff') ) + cbp02 = ttk.TTkColorButtonPicker(parent=winCP, pos=( 0, 4), size=(8,3), border=True, color=ttk.TTkColor.bg('#ff88ff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Default) + cbp03 = ttk.TTkColorButtonPicker(parent=winCP, pos=( 0, 7), size=(8,3), border=True, color=ttk.TTkColor.fg('#ffff88') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Background) + cbp04 = ttk.TTkColorButtonPicker(parent=winCP, pos=( 0,10), size=(8,3), border=True, color=ttk.TTkColor.bg('#8888ff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Background) + + cbp05 = ttk.TTkColorButtonPicker(parent=winCP, pos=(10, 1), size=(8,3), border=True, color=ttk.TTkColor.fg('#00ffff') ) + cbp06 = ttk.TTkColorButtonPicker(parent=winCP, pos=(10, 4), size=(8,3), border=True, color=ttk.TTkColor.fg('#ff00ff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Default) + cbp07 = ttk.TTkColorButtonPicker(parent=winCP, pos=(10, 7), size=(8,3), border=True, color=ttk.TTkColor.fg('#ffff00') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Foreground) + cbp08 = ttk.TTkColorButtonPicker(parent=winCP, pos=(10,10), size=(8,3), border=True, color=ttk.TTkColor.bg('#0000ff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Foreground) + + cbp09 = ttk.TTkColorButtonPicker(parent=winCP, pos=(20, 1), size=(8,3), border=True, color=ttk.TTkColor.fg('#ffffff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Foreground) + cbp10 = ttk.TTkColorButtonPicker(parent=winCP, pos=(20, 4), size=(8,3), border=True, color=ttk.TTkColor.bg('#ffffff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Foreground) + cbp11 = ttk.TTkColorButtonPicker(parent=winCP, pos=(20, 7), size=(8,3), border=True, color=ttk.TTkColor.fg('#ffffff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Background) + cbp12 = ttk.TTkColorButtonPicker(parent=winCP, pos=(20,10), size=(8,3), border=True, color=ttk.TTkColor.bg('#ffffff') ,returnType=ttk.TTkColorDialogPicker.ColorReturnType.Background) + + def _register(cbp:ttk.TTkColorButtonPicker): + cbp.colorSelected.connect(lcol.setColor) + cbp.colorSelectedFG.connect(lfg.setColor) + cbp.colorSelectedBG.connect(lbg.setColor) + + for cbp in [cbp01,cbp02,cbp03,cbp04,cbp05,cbp06,cbp07,cbp08,cbp09,cbp10,cbp11,cbp12]: + _register(cbp) # win2_1 = ttk.TTkColorDialogPicker(parent=frame,pos = (3,3), size=(110,40), title="Test Color Picker", border=True) diff --git a/demo/showcase/textedit.py b/demo/showcase/textedit.py index 1d66a4ac..6c17a8f1 100755 --- a/demo/showcase/textedit.py +++ b/demo/showcase/textedit.py @@ -130,10 +130,10 @@ def demoTextEdit(root=None, document=None): # Char Fg/Bg buttons fontLayout.addWidget(cb_fg := ttk.TTkCheckbox(text=" FG"),0,0) - fontLayout.addWidget(btn_fgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3)),1,0) + fontLayout.addWidget(btn_fgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), returnType=ttk.TTkColorDialogPicker.ColorReturnType.Foreground),1,0) fontLayout.addWidget(cb_bg := ttk.TTkCheckbox(text=" BG"),0,2) - fontLayout.addWidget(btn_bgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7 ,3)),1,2) + fontLayout.addWidget(btn_bgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), returnType=ttk.TTkColorDialogPicker.ColorReturnType.Background),1,2) fontLayout.addWidget(cb_linenumber := ttk.TTkCheckbox(text=" LineNumber", checked=True),0,4,1,3) fontLayout.addWidget(sb_linenumber := ttk.TTkSpinBox(value=1, maxWidth=5, maximum=10000, minimum=-10000, enabled=True),0,7,1,1) @@ -161,7 +161,7 @@ def demoTextEdit(root=None, document=None): if fg := format.foreground(): cb_fg.setCheckState(ttk.TTkK.Checked) btn_fgColor.setEnabled() - btn_fgColor.setColor(fg.invertFgBg()) + btn_fgColor.setColor(fg) else: cb_fg.setCheckState(ttk.TTkK.Unchecked) btn_fgColor.setDisabled() @@ -185,7 +185,7 @@ def demoTextEdit(root=None, document=None): def _setStyle(): color = ttk.TTkColor() if cb_fg.checkState() == ttk.TTkK.Checked: - color += btn_fgColor.color().invertFgBg() + color += btn_fgColor.color() if cb_bg.checkState() == ttk.TTkK.Checked: color += btn_bgColor.color() if btn_bold.isChecked(): diff --git a/demo/showcase/textpicker.py b/demo/showcase/textpicker.py index fa0cbd91..20c73b89 100755 --- a/demo/showcase/textpicker.py +++ b/demo/showcase/textpicker.py @@ -28,13 +28,15 @@ sys.path.append(os.path.join(sys.path[0],'../..')) import TermTk as ttk def demoTextPicker(root=None): - frame = ttk.TTkFrame(parent=root, border=False) + frame = ttk.TTkFrame( + parent=root, border=False, + addStyle={'default':{'fillColor':ttk.TTkColor.bg('#004400', modifier=ttk.TTkColorGradient(increment=-6))}}) - ttk.TTkLabel(parent=frame, pos=(0,0),text="No Autosize") + ttk.TTkLabel(parent=frame, pos=(0,0),text="[ No Autosize ]") ttk.TTkTextPicker(parent=frame, pos=( 0,1), size=(20, 1),autoSize=False, multiLine=False) - ttk.TTkLabel(parent=frame, pos=(0,2),text="Multiline") + ttk.TTkLabel(parent=frame, pos=(0,2),text="[ Multiline ]") ttk.TTkTextPicker(parent=frame, pos=( 0,3), size=(20, 1),autoSize=False, multiLine=True) - ttk.TTkLabel(parent=frame, pos=(0,4),text="Autosize") + ttk.TTkLabel(parent=frame, pos=(0,4),text="[ Autosize ]") ttk.TTkTextPicker(parent=frame, pos=( 0,5), size=(20, 1),autoSize=True, multiLine=True) ttk.TTkTextPicker(parent=frame, pos=(25,0), size=(20, 5),autoSize=True, multiLine=True) diff --git a/tools/dumbPaintTool/app/importimage.py b/tools/dumbPaintTool/app/importimage.py index 8381254d..2b0e6dac 100644 --- a/tools/dumbPaintTool/app/importimage.py +++ b/tools/dumbPaintTool/app/importimage.py @@ -404,7 +404,7 @@ class ImportImage(ttk.TTkWindow): propertiesFrame.layout().addWidget(ttk.TTkLabel(text='Resolution:',maxWidth=11), 0,0) propertiesFrame.layout().addWidget(cb_resolution := ttk.TTkComboBox(), 0,1,1,2) propertiesFrame.layout().addWidget(ttk.TTkLabel(text='AlphaColor:'), 1,0) - propertiesFrame.layout().addWidget(b_color := ttk.TTkColorButtonPicker(color=ttk.TTkColor.fg("#000000")), 1,1,1,2) + propertiesFrame.layout().addWidget(b_color := ttk.TTkColorButtonPicker(color=ttk.TTkColor.bg("#000000")), 1,1,1,2) propertiesFrame.layout().addWidget(b_export := ttk.TTkButton(text="Export"), 3,0,1,3) # propertiesFrame.layout().addItem(ttk.TTkLayout(),3,0,1,2) diff --git a/tools/dumbPaintTool/app/painttoolkit.py b/tools/dumbPaintTool/app/painttoolkit.py index a904f3db..6796a20c 100644 --- a/tools/dumbPaintTool/app/painttoolkit.py +++ b/tools/dumbPaintTool/app/painttoolkit.py @@ -136,7 +136,7 @@ class PaintToolKit(ttk.TTkContainer): def color(self): color = ttk.TTkColor() if self._cbFg.checkState() == ttk.TTkK.Checked: - color += self._bpFg.color().invertFgBg() + color += self._bpFg.color() if self._cbBg.checkState() == ttk.TTkK.Checked: color += self._bpBg.color() return color @@ -146,7 +146,7 @@ class PaintToolKit(ttk.TTkContainer): if fg := color.foreground(): self._cbFg.setCheckState(ttk.TTkK.Checked) self._bpFg.setEnabled() - self._bpFg.setColor(fg.invertFgBg()) + self._bpFg.setColor(fg) else: self._cbFg.setCheckState(ttk.TTkK.Unchecked) self._bpFg.setDisabled() diff --git a/tools/dumbPaintTool/app/textarea.py b/tools/dumbPaintTool/app/textarea.py index f591d794..7e75b98a 100644 --- a/tools/dumbPaintTool/app/textarea.py +++ b/tools/dumbPaintTool/app/textarea.py @@ -116,10 +116,10 @@ class TextArea(ttk.TTkGridLayout): # Char Fg/Bg buttons fontLayout.addWidget(cb_fg := ttk.TTkCheckbox(text=" FG"),0,0) - fontLayout.addWidget(btn_fgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3)),1,0) + fontLayout.addWidget(btn_fgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), returnType=ttk.TTkColorDialogPicker.ColorReturnType.Foreground),1,0) fontLayout.addWidget(cb_bg := ttk.TTkCheckbox(text=" BG"),0,2) - fontLayout.addWidget(btn_bgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7 ,3)),1,2) + fontLayout.addWidget(btn_bgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), returnType=ttk.TTkColorDialogPicker.ColorReturnType.Background),1,2) fontLayout.addWidget(cb_linenumber := ttk.TTkCheckbox(text=" LineNumber", checked=True),0,4,1,3) diff --git a/tools/dumbPaintTool/tui/paintToolKit.tui.json b/tools/dumbPaintTool/tui/paintToolKit.tui.json index bd922812..550f89eb 100644 --- a/tools/dumbPaintTool/tui/paintToolKit.tui.json +++ b/tools/dumbPaintTool/tui/paintToolKit.tui.json @@ -1,6 +1,6 @@ { "type": "TTkUi/Document", - "version": "2.0.2", + "version": "2.1.0", "tui": { "class": "TTkContainer", "params": { @@ -176,7 +176,8 @@ "Border": false, "Checkable": false, "Checked": false, - "Color": "\u001b[48;2;0;0;0m" + "Color": "\u001b[48;2;0;0;0m", + "Return Type": 0 }, "row": 0, "col": 0, @@ -206,7 +207,8 @@ "Border": false, "Checkable": false, "Checked": false, - "Color": "\u001b[48;2;0;0;0m" + "Color": "\u001b[48;2;0;0;0m", + "Return Type": 2 }, "row": 0, "col": 0, @@ -236,7 +238,8 @@ "Border": false, "Checkable": false, "Checked": false, - "Color": "\u001b[48;2;0;0;0m" + "Color": "\u001b[38;2;0;0;0m", + "Return Type": 1 }, "row": 0, "col": 0, diff --git a/tools/ttkDesigner/app/notepad.py b/tools/ttkDesigner/app/notepad.py index e53e33dd..336c109a 100644 --- a/tools/ttkDesigner/app/notepad.py +++ b/tools/ttkDesigner/app/notepad.py @@ -55,10 +55,10 @@ class NotePad(ttk.TTkGridLayout): # Char Fg/Bg buttons fontLayout.addWidget(cb_fg := ttk.TTkCheckbox(text=" FG"),0,0) - fontLayout.addWidget(btn_fgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3)),1,0) + fontLayout.addWidget(btn_fgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), returnType=ttk.TTkColorDialogPicker.ColorReturnType.Foreground),1,0) fontLayout.addWidget(cb_bg := ttk.TTkCheckbox(text=" BG"),0,2) - fontLayout.addWidget(btn_bgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7 ,3)),1,2) + fontLayout.addWidget(btn_bgColor := ttk.TTkColorButtonPicker(border=True, enabled=False, maxSize=(7,3), returnType=ttk.TTkColorDialogPicker.ColorReturnType.Background),1,2) fontLayout.addWidget(cb_linenumber := ttk.TTkCheckbox(text=" LineNumber", checked=True),0,4,1,3)