Help for Krita UI Redesign - Layers Docker

Hi there! Currently continuing work for the UI redesign, as I think it would be really cool to have a newer version working for Krita 5.0. However, I’m stumped regarding one particular thing: the separator lines in the layer docker. I think the separation really hinders the cleanliness in that particular case, but it’s been tricky to actually remove the lines.

Here’s what I’m talking about, with a before and (hopefully) after:

I’ve been looking into the source code, since I’m fairly certain that the elements are injected in run-time. However, I could not find the parts of the code that would be responsible for the UI aspect. I looked into Layerbox.cpp, but couldn’t find the right file.

Could someone from the dev team / someone who might know give me a pointer as to where to look more closely? Thanks in advance!

5 Likes

These frames are drawn in /krita/plugins/dockers/layerdocker/NodeDelegate.cpp

3 Likes

Thank you! I’ll look into it straight away!

You’re right. However, this does look like there’s no way this could be done externally via plugin, right?

I don’t really know enough about how the code works to definitively answer that myself, sorry.

By the way, in case this pertains to your plugin, most of the nonflat textless buttons you see in 5.0 have been flattened in 5.1 (with KToolButton’s autoraise property).

1 Like

Uuuh, very interesting. I’ll have a look at it, thanks!

This might be off topic, but there were discussions here on the forum for adding more information like blend modes and opacity percentages à la CSP. if you are looking for contributing to the core Krita may be this would be good to have.

2 Likes

Could you link to the discussions, please?

1 Like

I would wish this to be in native krita :slight_smile:

4 Likes

Just saw what you meant, looks quite a lot better than the default version. I already did some of the changes “manually” in the Redesign, but it’s always better when the base Krita looks better :smiley: Thanks for you contribution!

2 Likes

Yeah, this would most likely have to be done in native Krita. I at least have no idea how to do something like this in PyQT. It’s an interesting proposition :smiley: I already took a look at it, but I’m horrible at multitasking, so if I do end up taking on this task, it will probably be after the redesign UI is mostly finished.

But I’ll keep it in the back of my mind!

1 Like

In NodeDelegate.cpp, inside NodeDelegate::drawIcons function, if you change the line p->setPen(scm.gridColor(option, d->view)); to p->setPen(Qt::transparent); then those lines dissapear.

So, yes, it is hardcoded, and cannot be changed from python I guess.

The layer docker is a delicate thing (I’m sure anyone has their own opinion on how it should be improved), so maybe it is better to have a dedicated dynamic thread where opinions are given and a mockup is constantly being updated. Then, when the community arrives to a consensus (sort of), the changes can be proposed in a consistent way and be put into krita.

5 Likes

I wholeheartedly agree. Even the thread that was linked in a comment to this post is important to that discussion.

1 Like

It looks like vertical lines are hard coded in delegate, but QRgb color is taken from QStyle.SH_Table_GridLineColor, that can be overridden.

Sadly grid color can’t be set to transparent, and grid color also affects bottom line separator :cry:

from krita import (
        Krita,)

from PyQt5.QtGui import (
        qRgba,
        QPalette)

from PyQt5.QtWidgets import (
        QProxyStyle,
        QStyle,
        QTreeView)


class NinjaStyle(QProxyStyle):
    _grid_color = qRgba(255, 0, 0, 0)

    def styleHint(self, hint, option=None, widget=None, returnData=None):
        if hint == QStyle.SH_Table_GridLineColor:
            return self._grid_color  # qRgb(a) is strange in python...
        return super().styleHint(hint, option, widget, returnData)


def get_list_layers_view():
    app = Krita.instance()
    for docker in app.dockers():
        if docker.objectName() == 'KisLayerBox':
            return docker.findChild(QTreeView, 'listLayers')


view = get_list_layers_view()
color = view.palette().color(QPalette.Base)
ninja_style = NinjaStyle(view.style())
ninja_style._grid_color = qRgba(color.red(), color.green(), color.blue(), 0)
view.setStyle(ninja_style)

/AkiR

With regards to that thread, I also recently proposed there to be a button on filter layers so you can double click to access the properties of such layers in this topic: Double click on layer filter mask to edit settings? - #4 by Hologram, which could be taken into consideration as well.

2 Likes

What if you used

QRgb qRgba(int r, int g, int b, int a)

instead? It seems to have the same return value as qRgb:

QRgb qRgb(int r, int g, int b)

Source: QColor Class | Qt GUI 5.15.16

yes, it looks like qRgba(r, g, b, a=0) works nicely, as replacement for qRgb(r, g, b)
it’s just little bit strange how uint should work when returned from def styleHint(...) -> int

From Qt:s documentation…

typedef QRgb
An ARGB quadruplet on the format #AARRGGBB, equivalent to an unsigned int.

The type also holds a value for the alpha-channel. The default alpha channel is ff, i.e opaque. For more information, see the Alpha-Blended Drawing section.

alpha value FF should be opaque, but 00 must be sent from python to avoid value error.

(editing code to use qRgba(), it’s bit better, but still feels wrong :smiley: )
/AkiR

1 Like

Where are node delegates used? I did a short test on a compiled version of Krita, and it works as expected, but I don’t want to accidentally cause a regression elsewhere.

NodeDelegate is only used in NodeView for the Layers docker.

In general, UI elements defined in a plugin are not supposed to be used outside of that plugin.

1 Like

@Lynx3d I see. Then maybe I could make a small test and open a merge request? It’s basically what people told, and I’ll put the image of the image after. It’s not going to be the extensive layers redesign, but it’s a step in the right direction :smiley:

3 Likes