PDA

View Full Version : Extending QGraphicsLayout



Darkman
13th March 2009, 12:09
Hello everyone.
I'm trying to extend QGraphicsLayout to build a new layout (let's called circleLayout). the program will be a plasma applet for KDE 4.2

First of all the example found in the documentation http://doc.trolltech.com/4.4/layout.html#writing-custom-layout-managers doesn't works (i think it's because it's written to extend QLayout).
As explained in the page http://doc.trolltech.com/4.4/qgraphicslayout.html#details i extended the method setGeometry() and sizeHint(). I took a look at source code of QGraphicsGridLayout and it doesn't seems that i need to extend other methods. Obviously, my code doesn't works :D
here's my code:


void circleLayout::setGeometry(const QRectF &r)
{
kDebug()<<"Set Geometry!!";

/*setting the real geometry*/
QGraphicsLayout::setGeometry(r);
/*taking the geometry*/
QRectF effectiveRect = geometry();
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
/*adjust margins*/
effectiveRect.adjust(+left, +top, -right, -bottom);

kDebug()<<left<<","<<top<<","<<right<<","<<bottom;

/*this is how qrectf works: Qrectf (xy top left corner, width ,height)*/

/*if there are no elements in the list, view only the main element*/
/*finding the center of the rectangular*/
qreal centerX = left + (right/2);
qreal centerY = top + (bottom/2);
/*finding the radius of the circle*/
qreal radius = 0;
if(right > bottom)
radius = bottom/2;
else
radius = right/2;

/*the main element is located in the center and fill 1/3 of th space*/
/*setting the rectf for the main element*/
QRectF mainRect(centerX+radius/3, centerY+radius/3, radius*2/3, radius*2/3);
mainElement->setGeometry(mainRect);

kDebug() << "setting the main element geom";

/*if i have only one element, i'll put in the top center*/
if(list.size() == 1)
{
kDebug()<<"there is only one element";
QGraphicsLayoutItem* element = list.at(0);
/*putting this element at the top in the center*/
QRectF elementRect(centerX+radius/3, centerY+radius, radius*2/3, radius*2/3);
element->setGeometry(elementRect);
}
/*else i'll put the elements in the circle*/
else if(list.size() > 1)
{
kDebug()<<"there are more elements, "<<list.size();
for(int i=0; i<list.size(); i++)
{
/*this is the angle to rotate*/
double angle = (2*PI*i)/list.size();
/*than i made a rotation in center with the specified radius*/
QMatrix rotMatrix(cos(angle), -sin(angle),
sin(angle), cos(angle),
centerX,centerY);
/*then i multiply the matrix with the point on the top of the circle*/
qreal pointX;
qreal pointY;
/*rotation*/
rotMatrix.map(centerX,centerY+(radius*2)/3,&pointX, &pointY);

/*taking the i-esim element*/
QGraphicsLayoutItem* element = list.at(i);
/*try to put this element in the circle*/
QRectF elementRect(pointX-radius/3, pointX-radius, radius*2/3, radius*2/3);
element->setGeometry(elementRect);
}
}
}

QSizeF circleLayout :: sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
kDebug()<<"sizeHint!";

QSizeF s(0,0);
int n = list.count();
if (n > 0)
s = QSizeF(100,70); //start with a nice default size
int i = 0;
while (i < n) {
QGraphicsLayoutItem *o = list.at(i);
s = s.expandedTo(o->effectiveSizeHint(which, constraint));
++i;
}
return s ;
}

(the method sizeHint is semi-copied from QGraphicsGridLayout. i don't understand the true meaning of it)
So, here what's happens: i can compile everything without any problem, but i cannot see my object (maybe are too small?)
I'm expecting to find my objects placed around a main object (in the center)
As you may seen in the attachment, there are some dots in the center.. well, i think they're my objects! :eek:

here is the debug text i receive in my shell:


plasmoidviewer(29212) AdvancedMenuLayout::sizeHint: sizeHint!
plasmoidviewer(29212) AdvancedMenuLayout::sizeHint: sizeHint!
plasmoidviewer(29212) AdvancedMenuLayout::sizeHint: sizeHint!
plasmoidviewer(29212) AdvancedMenuLayout::setGeometry: Set Geometry!!
plasmoidviewer(29212) AdvancedMenuLayout::setGeometry: 4 , 4 , 4 , 4
plasmoidviewer(29212) AdvancedMenuLayout::setGeometry: setting the main element geom
plasmoidviewer(29212) AdvancedMenuLayout::setGeometry: there is only one element
QPainter::begin: Cannot paint on a null pixmap
QPainter::begin: Cannot paint on a null pixmap
QPainter::begin: Cannot paint on a null pixmap
QPainter::begin: Cannot paint on a null pixmap
QPainter::begin: Cannot paint on a null pixmap
QPainter::begin: Cannot paint on a null pixmap


The method setGeometry is never called!
Finally, here are my questions:
how can i extend QGraphicsLayout? what i have to do?
What i exactly have to implement inside sizeHint()? In what method i can specify where to place my elements?

thanks everyone in advance