Added possibility to set pop up (menu, dialog or other widgets) alignment to left, center or right

Translate left and right alignment for vertical form factors
Swap right and left alignment in case of RTL layout
Use center alignment for tool tips

svn path=/trunk/KDE/kdelibs/; revision=1028983
This commit is contained in:
Michał Dutkiewicz 2009-09-28 17:28:17 +00:00
parent f99025da70
commit 4d051d8f86
5 changed files with 66 additions and 10 deletions

View File

@ -687,10 +687,16 @@ QRect Applet::mapToView(const QGraphicsView *view, const QRectF &rect) const
}
QPoint Applet::popupPosition(const QSize &s) const
{
return popupPosition(s, Qt::AlignLeft);
}
QPoint Applet::popupPosition(const QSize &s, Qt::AlignmentFlag alignment) const
{
Corona * corona = qobject_cast<Corona*>(scene());
Q_ASSERT(corona);
return corona->popupPosition(this, s);
return corona->popupPosition(this, s, alignment);
}
void Applet::updateConstraints(Plasma::Constraints constraints)

View File

@ -231,6 +231,16 @@ class PLASMA_EXPORT Applet : public QGraphicsWidget
*/
QPoint popupPosition(const QSize &s) const;
/**
* @since 4.4
* Reccomended position for a popup window like a menu or a tooltip
* given its size
* @param s size of the popup
* @param alignment alignment of the popup, valid flags are Qt::AlignLeft, Qt::AlignRight and Qt::AlignCenter
* @returns reccomended position
*/
QPoint popupPosition(const QSize &s, Qt::AlignmentFlag alignment) const;
/**
* Called when any of the geometry constraints have been updated.
* This method calls constraintsEvent, which may be reimplemented,

View File

@ -509,6 +509,14 @@ QRegion Corona::availableScreenRegion(int id) const
QPoint Corona::popupPosition(const QGraphicsItem *item, const QSize &s)
{
return popupPosition(item, s, Qt::AlignLeft);
}
QPoint Corona::popupPosition(const QGraphicsItem *item, const QSize &s, Qt::AlignmentFlag alignment)
{
// TODO: merge both methods (also these in Applet) into one (with optional alignment) when we can break compatibility
// TODO: add support for more flags in the future?
QGraphicsView *v = viewFor(item);
if (!v) {
@ -518,6 +526,15 @@ QPoint Corona::popupPosition(const QGraphicsItem *item, const QSize &s)
QPoint pos;
QTransform sceneTransform = item->sceneTransform();
//swap direction if necessary
if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) {
if (alignment == Qt::AlignRight) {
alignment == Qt::AlignLeft;
} else {
alignment == Qt::AlignRight;
}
}
//if the applet is rotated the popup position has to be un-transformed
if (sceneTransform.isRotating()) {
qreal angle = acos(sceneTransform.m11());
@ -544,9 +561,12 @@ QPoint Corona::popupPosition(const QGraphicsItem *item, const QSize &s)
switch (loc) {
case BottomEdge:
case TopEdge: {
//TODO: following line makes them centered.
//could make it better or worse, must be decided
//pos.setX(pos.x() + item->boundingRect().width()/2 - s.width()/2);
if (alignment == Qt::AlignCenter) {
pos.setX(pos.x() + item->boundingRect().width()/2 - s.width()/2);
} else if (alignment == Qt::AlignRight) {
pos.setX(pos.x() + item->boundingRect().width() - s.width());
}
if (pos.x() + s.width() > v->geometry().right()) {
pos.setX(v->geometry().right() - s.width());
} else {
@ -556,7 +576,12 @@ QPoint Corona::popupPosition(const QGraphicsItem *item, const QSize &s)
}
case LeftEdge:
case RightEdge: {
//pos.setY(pos.y() + item->boundingRect().height()/2 - s.height()/2);
if (alignment == Qt::AlignCenter) {
pos.setY(pos.y() + item->boundingRect().height()/2 - s.height()/2);
} else if (alignment == Qt::AlignRight) {
pos.setY(pos.y() + item->boundingRect().height() - s.height());
}
if (pos.y() + s.height() > v->geometry().bottom()) {
pos.setY(v->geometry().bottom() - s.height());
} else {
@ -565,6 +590,11 @@ QPoint Corona::popupPosition(const QGraphicsItem *item, const QSize &s)
break;
}
default:
if (alignment == Qt::AlignCenter) {
pos.setX(pos.x() + item->boundingRect().width()/2 - s.width()/2);
} else if (alignment == Qt::AlignRight) {
pos.setX(pos.x() + item->boundingRect().width() - s.width());
}
break;
}
switch (loc) {
@ -602,11 +632,10 @@ QPoint Corona::popupPosition(const QGraphicsItem *item, const QSize &s)
}
pos.rx() = qMax(0, pos.rx());
return pos;
}
void Corona::loadDefaultLayout()
{
}
@ -672,7 +701,7 @@ QList<Plasma::Location> Corona::freeEdges(int screen) const
<< Plasma::LeftEdge << Plasma::RightEdge;
foreach (Containment *containment, containments()) {
if (containment->screen() == screen &&
if (containment->screen() == screen &&
freeEdges.contains(containment->location())) {
freeEdges.removeAll(containment->location());
}

View File

@ -156,6 +156,17 @@ public:
*/
QPoint popupPosition(const QGraphicsItem *item, const QSize &size);
/**
* @since 4.4
* Recommended position for a popup window like a menu or a tooltip
* given its size
* @param item the item that the popup should appear adjacent to (an applet, say)
* @param size size of the popup
* @param alignment alignment of the popup, valid flags are Qt::AlignLeft, Qt::AlignRight and Qt::AlignCenter
* @returns reccomended position
*/
QPoint popupPosition(const QGraphicsItem *item, const QSize &size, Qt::AlignmentFlag alignment);
/**
* This method is useful in order to retrieve the list of available
* screen edges for panel type containments.

View File

@ -245,7 +245,7 @@ void ToolTipManager::setContent(QGraphicsWidget *widget, const ToolTipContent &d
d->tipWidget->setContent(widget, data);
d->tipWidget->prepareShowing();
if (m_corona) {
d->tipWidget->moveTo(m_corona->popupPosition(widget, d->tipWidget->size()));
d->tipWidget->moveTo(m_corona->popupPosition(widget, d->tipWidget->size(), Qt::AlignCenter));
}
}
}
@ -372,7 +372,7 @@ void ToolTipManagerPrivate::showToolTip()
tipWidget->setContent(currentWidget, tooltip.value());
tipWidget->prepareShowing();
if (q->m_corona) {
tipWidget->moveTo(q->m_corona->popupPosition(currentWidget, tipWidget->size()));
tipWidget->moveTo(q->m_corona->popupPosition(currentWidget, tipWidget->size(), Qt::AlignCenter));
}
tipWidget->show();
isShown = true; //ToolTip is visible