Styled custom widgets

Thomas Lübking thomas.luebking at web.de
Wed Sep 3 03:54:43 BST 2008


Am Tuesday 02 September 2008 schrieb Rafael Fernández López:
> Hi,
>
> > Another approach would be to add a SH_SupportsXXX for every PE_XXX or
> > CE_XXX. Providing a QList<int> feels very powerful but I really doubt
> > its usefulness beyond this use case (also one has to concat this list
> > with the parent style's list and all that). Instead,
> >
> > if (style()->styleHint(SH_SupportsXXX)) {
> >     style()->drawControlElement(CE_XXX);
> > } else {
> >     // fall back painting
> > }
>
> I really think this is a good solution...


The reason why i'd favor the runtime feature adding soution would be the 
question on how new items are added.
Like if say k3b needs a new styled widget, they could just implement it with a 
fallack painting routine and see whether it gets adepted by styles, while the 
compiletime solution means: first they'll have to ask for a number in a kstyle 
extension to the enums. What will follow then is presumingly a long discussion 
about whether it's usefull and worthy to be added and then (iff), with the 
next KDE release it'll be (officially) supported and styles can start to adept 
it....
That doesn't sound like much fun :-(

That said, here's a last suggestion
(as maybe the solution could be much easier than i thought...)
====================================================
On construction and every QEvent::StyleChange custom styled widgets
1. adjust their name: QObject::setObjectName("PE_MyFancyPrimitive");
2. query: d->myFancyPrimitiveID = (QStyle::PrimitiveElement) 
QStyle::styleHint(KStyle::SH_PrimitiveElement, NULL, this);
if (d->myFancyPrimitiveID < QStyle::PE_CustomBase)
    d->myFancyPrimitiveID = 0; // to avoid unlikely accidental interference on 
KStyle::SH_PrimitiveElement, hoping sane SH_ replies are <<<<<<< 0xf000000...
3. Adjust name back ;-P

In the paintevent:
if (d->myFancyPrimitiveID)
    style()->drawPrimitive(.);
else
{
    QPainter p(this);
    ...
    p.end();
}

while the style that wants to support custom widgets just has to carry a
- static QHash/QMap<QString, int> styleElements; // as widgets will please use 
PE_, CE_ and CC_ prefixes...
- static QList<QString> supportedElements; // supportedElements << 
PE_KCapacityBar << CC_AmarokAnalyzer << ...
- static int primitiveCounter = PE_CustomBase, controlCounter = CE_CustomBase, 
complexCounter = CC_CustomBase; // or 0xff00000 instead of 0xf000000...


and a styleHint implementation like
MyStyle::styleHint(.,., QWidget *widget)
{
...
    case SH_PrimitiveElement:
    if (widget)
    {
        int element = styleElements.value(widget->objectName(), 0);
        if (!element &&
            (supportedElements.contains(widget->objectName()) ||
            DaddyStyle::styleHint(KStyle::SH_PrimitiveElement, option, 
widget)))
            styleElements.insert(widget->objectName(), element = 
++primitiveCounter);
        // if (!element)
        //    qDebug() << "Unsupported primitive requested:" << widget-
>objectName();
        return element;
    }
    ....
}

That's maybe not the "most clean" solution as for abusing (?) 
QStyle::styleHint() and QWidget::objectName(), but shouldn't hurt either and 
this way we'll just need 3 (three!) additional SH_s, have runtime extension 
and not too much overhead (only at particular moments, not at common action, 
especially painting) and not the least requirement to extend anything (ok, the 
KStyle enums... if you want symbols ;-P ... maybe also a wiki to propagate new 
elements...)

Thomas




More information about the kde-core-devel mailing list