Tela Plugin

Purpose

Tela is a Krita plugin for Quick Settings.

Link

Features

  • Canvas Settings:
    • Rotation.
    • Zoom.
    • Mirror.
    • Wrap.
  • Document:
    • Width.
    • Height.
    • Resolution.
    • Reference & Deltas.
    • Guides Horizontal.
    • Guides Vertical.
    • Sort Mode.
    • Mirror Mode.
    • Guides Visible.
    • Guides Lock.
  • View:
    • Brush Blending Mode.
    • Brush Size.
    • Brush Opacity.
    • Brush Flow.
    • SOF quick save.
    • View Exposure.
    • View Gamma.

Preview



6 Likes

Tela translated means canvas as in a painting canvas or computer monitor. I thought it to be appropriate since I was trying to make sort of little UI for certain features I find a bit far between clicks but still needs work though, since it is a bit odd of collection of features it needs some usage to mature and opinions are also welcomed. However the features I wanted to create to begin with are done for my current needs for how simple they might be.

So what does it do?

well I cant say I am inventing the wheel or anything for the most part it is just a tiny UI for already made stuff that are honestly better but needed to calculate what I really wanted that was the Guides in the Document section but then I sprinkled some more stuff around too because I was walking by and made something in the end I was not quite expecting.

  • When eraser mode is active the panels invert colors so the eraser now has a big display when it’s on.
  • Canvas mode is like a simpler version of Overview. Needs some work on where to go perhaps.
  • View mode is a quick settings for the brush. clicking on the panel changes Opacity and Flow. Displays brush size in real scale. Has a little search and display of the brush blending mode (miss spelling will give you normal mode). Exposure and Gamma will need a bug fix within Krita 5 I think it has been reported and fixed so I am just waiting to reach stable now.
  • Document mode detects the current document size and resolution and can edit it too. Pressing the REF checker will memorize those values and then you can apply a delta size to that document enabling you to expand the size of your document in real time, but as soon as the document closes or Tela is closed the document reverts back to it’s previous REF size, I must warn that editing the delta size with the mouse wheel for too long might tilt them a numerical input is better. Below it there is the list of the Horizontal and Vertical guides in the scene, double clicking will allow you to edit the value for it’s location. Sort mode will organize them by values and if they are sorted you can activate Mirror mode that allows you to have mirrored Guides considering the REF size.
  • Sliders react pretty much like pigmento.
    • ALT click add and subtracts 1.
    • Shift set the default or saved value.
    • Ctrl clamps to percentual values.
    • SOF values can be saved by clicking the white bar with Ctrl, and double clicking or with Shift to Apply the saved values again. And Alt resets the default values.
    • A new thing is that the sliders now say what they are and display what is their default value as the double spin box displays the current value being used.

Guides Edit Preview:

2 Likes

Update:

  • UI and Bug fixes

Link:

I did a bit of shuffling around for the interface and I think I arrived in a organization that pleases me more. Now it will only have 1 panel to display things, still a bit WIP there as to how to incorporate all the options I want it to have. I decided to use check-boxes on the bottom right here too to open and close the options underneath the panel.

In terms of bugs while using “Reference Size” occasionally Tela would drop a value on a guide due to decimals when editing too fast as I had too much faith in the system to work. I kinda made a approach that handles everything and then gives Krita the correct values after they are sorted not relying on Krita to work them properly on their positioning, and even if it goes so fast that it manages to mess up, the next cycle it will correct itself to the correct values ensuring the guides are properly managed.

Also guides now have a visual indicator that they are present even if they are not visible in the canvas.

Despite the Panel still not being very interactive you an rotate the canvas by clicking on the circle around the document square. Pressing Ctrl will snap the rotation to 10º increments.
panel_rotate

I want to add pan and zoom and canvas display to it but I haven’t found the API references to it yet. But I believe Tela has much space to grow as a plugin still.

6 Likes

Hello @EyeOdin!

For me, at first glance, it looks like the update is working. The only thing I noticed on quick review was the perceived slightly slower rotation of large images (very many layers, effects, ~10 GB according to Krita), compared to the plugin being turned off.
Since you deleted your post so quickly, I’d like to know, is there a reason not to use it?
So far tested on Windows 10 with the current 4.4.5 and the 5.0 prealpha b4a6f80.

Michelist

Not a big issue it was snapping to the wrong point when the Reference size was active so the image was stuck to the side. I fixed it already. but let me slow it down then too.

Thanks for the quick reply!
Take your time, I do not need it necessarily - I just always “have to” try everything immediately. :rofl: I’m like a big child. It’s like a compulsion. :joy:

Michelist

I did a small update where it displays the image your working with and it updates pretty fast by the looks of it. I am a bit unsure it will cause any lag on other systems but for me it is working.

image_preview

1 Like

Now I am readding this better. Tela is eating 10gb of your ram when on?

No, I loaded an extra-large file (deliberately prepared, bloated with transform, fill and FX layers) to test Krita’s response in conjunction with Tela. For large complex images with many effects and layers etc., rotating the image with Tela seems a bit slower to me than without Tela (Tela deactivated). With my “normal” files of A3 600 PPI, with a few effects, transformations or so it is not noticeable.
These 10 GB are what Krita shows me in the title bar, nothing special, but for testing I like to challenge my PC, it is quite powerful and so I just give it “food” :wink:

Michelist

Oh a workbench file~ okay okay.

I can’t say I maximized performance yet I still don’t know where the bottle necks reside for this but I have 1 or 2 guesses. I will work to make it go faster but my focus now is to make all the features I want it too have now I just don’t know how I want it to react to the commands.

@Michelist
I did a small tweak to it so it is a bit lighter with the display.
to me I see no difference but maybe with the workbench it does make a difference?

Hello @EyeOdin!

The version from today started with a “Script error”, but then ran, that is, was usable. However, it was now completely stuttering when trying to rotate the file. But it was the prepared file! “Normal files” can be rotated with it without stuttering or noticeable delay. Only the script error remains.
The part of the error message I could not copy here as a screenshot, the rest as text:


TypeError
Python 3.8.1: c:\TC_PP\Tools\krita-x64-4.4.3\bin\krita.exe
Tue Jul  6 12:46:00 2021

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 C:\Users\Surfbrett\AppData\Roaming\krita\pykrita\tela\tela_modulo.py in paintEvent(self=<tela.tela_modulo.Panel object>, event=<PyQt5.QtGui.QPaintEvent object>)
  569     # Paint
  570     def paintEvent(self, event):
  571         self.drawColors(event)
  572     def drawColors(self, event):
  573         # Start Qpainter
self = <tela.tela_modulo.Panel object>
self.drawColors = <bound method Panel.drawColors of <tela.tela_modulo.Panel object>>
event = <PyQt5.QtGui.QPaintEvent object>

 C:\Users\Surfbrett\AppData\Roaming\krita\pykrita\tela\tela_modulo.py in drawColors(self=<tela.tela_modulo.Panel object>, event=<PyQt5.QtGui.QPaintEvent object>)
  602             # painter.scale(six,six)
  603             # Draw QImage
  604             painter.drawImage(
  605                 0,0,
  606                 self.doc_thumb)
painter = <PyQt5.QtGui.QPainter object>
painter.drawImage = <built-in method drawImage of QPainter object>
self = <tela.tela_modulo.Panel object>
self.doc_thumb = None
TypeError: arguments did not match any overloaded call:
  drawImage(self, QRectF, QImage): argument 1 has unexpected type 'int'
  drawImage(self, QRect, QImage): argument 1 has unexpected type 'int'
  drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'int'
  drawImage(self, QPoint, QImage): argument 1 has unexpected type 'int'
  drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 3 has unexpected type 'NoneType'
  drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'
  drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'
  drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'
  drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'
    __cause__ = None
    __class__ = <class 'TypeError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of TypeError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of TypeError object>
    __doc__ = 'Inappropriate argument type.'
    __eq__ = <method-wrapper '__eq__' of TypeError object>
    __format__ = <built-in method __format__ of TypeError object>
    __ge__ = <method-wrapper '__ge__' of TypeError object>
    __getattribute__ = <method-wrapper '__getattribute__' of TypeError object>
    __gt__ = <method-wrapper '__gt__' of TypeError object>
    __hash__ = <method-wrapper '__hash__' of TypeError object>
    __init__ = <method-wrapper '__init__' of TypeError object>
    __init_subclass__ = <built-in method __init_subclass__ of type object>
    __le__ = <method-wrapper '__le__' of TypeError object>
    __lt__ = <method-wrapper '__lt__' of TypeError object>
    __ne__ = <method-wrapper '__ne__' of TypeError object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of TypeError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of TypeError object>
    __repr__ = <method-wrapper '__repr__' of TypeError object>
    __setattr__ = <method-wrapper '__setattr__' of TypeError object>
    __setstate__ = <built-in method __setstate__ of TypeError object>
    __sizeof__ = <built-in method __sizeof__ of TypeError object>
    __str__ = <method-wrapper '__str__' of TypeError object>
    __subclasshook__ = <built-in method __subclasshook__ of type object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ("arguments did not match any overloaded call:\n  d....AutoColor): argument 1 has unexpected type 'int'",)
    with_traceback = <built-in method with_traceback of TypeError object>

The above is a description of an error in a Python program.  Here is
the original traceback:

Traceback (most recent call last):
  File "C:\Users\Surfbrett\AppData\Roaming\krita\pykrita\tela\tela_modulo.py", line 571, in paintEvent
    self.drawColors(event)
  File "C:\Users\Surfbrett\AppData\Roaming\krita\pykrita\tela\tela_modulo.py", line 604, in drawColors
    painter.drawImage(
TypeError: arguments did not match any overloaded call:
  drawImage(self, QRectF, QImage): argument 1 has unexpected type 'int'
  drawImage(self, QRect, QImage): argument 1 has unexpected type 'int'
  drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'int'
  drawImage(self, QPoint, QImage): argument 1 has unexpected type 'int'
  drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 3 has unexpected type 'NoneType'
  drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'
  drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'
  drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'
  drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.ImageConversionFlag.AutoColor): argument 1 has unexpected type 'int'

Michelist

Update: Image display UI performance improvement

Took me a bit to feel the weight of the lag on bigger documents but I shoot for the roof and 5k-10k images and I could see what you meant even without effects over it.

I placed threading for the image query and now even on 10k images the brush seems to be working alright with no noticable lag or with the feeling of the brush being disabled by the UI lag.

Because of this you will notice a second of adjustment time when changing the documents size.

1 Like

I did small tweeks

  1. “Brush Blend” input now can auto-complete the text your inputting.

  1. Also doing mirror to the Canvas will also mirror the display on Tela now.
    Not sure if this is something that works the best but it shows.

3 Likes

The following code appeared when I used today’s plugin. And krita cannot be opened

TypeError
Python 3.8.1: C:\GAMES\STEAM\steamapps\common\Krita\krita\bin\krita.exe
Tue Jul 13 19:37:53 2021

A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.

C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py in Krita_TIMER(self=<tela.tela.TelaDocker object>)
480 font.setBold(True)
481 self.layout.check.setText(“ON”)
482 self.Krita_2_Tela()
483 self.timer.start()
484 self.q_image = True
self = <tela.tela.TelaDocker object>
self.Krita_2_Tela = <bound method TelaDocker.Krita_2_Tela of <tela.tela.TelaDocker object>>

C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py in Krita_2_Tela(self=<tela.tela.TelaDocker object>)
634 self.SOF_1_READ(40)
635 if self.sof_2 != 100:
636 self.SOF_2_READ(100)
637 if self.sof_3 != 100:
638 self.SOF_3_READ(100)
self = <tela.tela.TelaDocker object>
self.SOF_2_READ = <bound method TelaDocker.SOF_2_READ of <tela.tela.TelaDocker object>>

C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py in SOF_2_READ(self=<tela.tela.TelaDocker object>, value=100)
1784 self.layout.sof_2_slider.update()
1785 self.layout.sof_2_value.update()
1786 self.Panel_Update()
1787 def SOF_2_Minus(self):
1788 if ((self.canvas() is not None) and (self.canvas().view() is not None)):
self = <tela.tela.TelaDocker object>
self.Panel_Update = <bound method TelaDocker.Panel_Update of <tela.tela.TelaDocker object>>

C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py in Panel_Update(self=<tela.tela.TelaDocker object>)
665 self.layout.panel.update()
666 else:
667 self.panel.Update_Panel(
668 False, False,
669 False,
self = <tela.tela.TelaDocker object>
self.panel = <tela.tela_modulo.Panel object>
self.panel.Update_Panel = <bound method Panel.Update_Panel of <tela.tela_modulo.Panel object>>
self.layout = <PyQt5.QtWidgets.QWidget object>
self.layout.panel = <PyQt5.QtWidgets.QWidget object>
self.layout.panel.width =
self.layout.panel.height =
TypeError: Update_Panel() takes 21 positional arguments but 23 were given
cause = None
class = <class ‘TypeError’>
context = None
delattr = <method-wrapper ‘delattr’ of TypeError object>
dict = {}
dir =
doc = ‘Inappropriate argument type.’
eq = <method-wrapper ‘eq’ of TypeError object>
format =
ge = <method-wrapper ‘ge’ of TypeError object>
getattribute = <method-wrapper ‘getattribute’ of TypeError object>
gt = <method-wrapper ‘gt’ of TypeError object>
hash = <method-wrapper ‘hash’ of TypeError object>
init = <method-wrapper ‘init’ of TypeError object>
init_subclass =
le = <method-wrapper ‘le’ of TypeError object>
lt = <method-wrapper ‘lt’ of TypeError object>
ne = <method-wrapper ‘ne’ of TypeError object>
new =
reduce =
reduce_ex =
repr = <method-wrapper ‘repr’ of TypeError object>
setattr = <method-wrapper ‘setattr’ of TypeError object>
setstate =
sizeof =
str = <method-wrapper ‘str’ of TypeError object>
subclasshook =
suppress_context = False
traceback =
args = (‘Update_Panel() takes 21 positional arguments but 23 were given’,)
with_traceback =

The above is a description of an error in a Python program. Here is
the original traceback:

Traceback (most recent call last):
File “C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py”, line 482, in Krita_TIMER
self.Krita_2_Tela()
File “C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py”, line 636, in Krita_2_Tela
self.SOF_2_READ(100)
File “C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py”, line 1786, in SOF_2_READ
self.Panel_Update()
File “C:\Users\123\AppData\Roaming\krita\pykrita\tela\tela.py”, line 667, in Panel_Update
self.panel.Update_Panel(
TypeError: Update_Panel() takes 21 positional arguments but 23 were given

that is weird… I re-uploaded the files. try downloading it again please.

1 Like