mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 19:02:53 +00:00
299 lines
8.8 KiB
C++
299 lines
8.8 KiB
C++
/*
|
|
* Copyright (C) 2007, 2008, 2009, 2010 Ivan Cukic <ivan.cukic(at)kde.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser/Library General Public License version 2,
|
|
* or (at your option) any later version, as published by the Free
|
|
* Software Foundation
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser/Library General Public License for more details
|
|
*
|
|
* You should have received a copy of the GNU Lesser/Library General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "FullBorderLayout.h"
|
|
|
|
#include <QGraphicsWidget>
|
|
|
|
#include <lancelot/lancelot.h>
|
|
|
|
namespace Lancelot {
|
|
|
|
class FullBorderLayout::Private {
|
|
public:
|
|
FullBorderLayout * q;
|
|
|
|
explicit Private(FullBorderLayout * parent = 0)
|
|
: q(parent)
|
|
{
|
|
sizes[FullBorderLayout::LeftBorder] = -1;
|
|
sizes[FullBorderLayout::RightBorder] = -1;
|
|
sizes[FullBorderLayout::TopBorder] = -1;
|
|
sizes[FullBorderLayout::BottomBorder] = -1;
|
|
}
|
|
|
|
virtual ~Private()
|
|
{
|
|
}
|
|
|
|
QMap < FullBorderLayout::Place, QGraphicsLayoutItem * > itemPositions;
|
|
QMap < FullBorderLayout::Border, qreal > sizes;
|
|
|
|
void calculateBorderSizes(qreal & top, qreal & bottom, qreal & left, qreal & right) // const
|
|
{
|
|
// top
|
|
top = sizes[FullBorderLayout::TopBorder];
|
|
if (top < 0) {
|
|
top = 0;
|
|
if (itemPositions[FullBorderLayout::TopLeft]) {
|
|
top = qMax(top, itemPositions[FullBorderLayout::TopLeft]->preferredSize().height());
|
|
}
|
|
if (itemPositions[FullBorderLayout::Top]) {
|
|
top = qMax(top, itemPositions[FullBorderLayout::Top]->preferredSize().height());
|
|
}
|
|
if (itemPositions[FullBorderLayout::TopRight]) {
|
|
top = qMax(top, itemPositions[FullBorderLayout::TopRight]->preferredSize().height());
|
|
}
|
|
}
|
|
|
|
// bottom
|
|
bottom = sizes[FullBorderLayout::BottomBorder];
|
|
if (bottom < 0) {
|
|
bottom = 0;
|
|
if (itemPositions[FullBorderLayout::BottomLeft]) {
|
|
bottom = qMax(bottom, itemPositions[FullBorderLayout::BottomLeft]->preferredSize().height());
|
|
}
|
|
if (itemPositions[FullBorderLayout::Bottom]) {
|
|
bottom = qMax(bottom, itemPositions[FullBorderLayout::Bottom]->preferredSize().height());
|
|
}
|
|
if (itemPositions[FullBorderLayout::BottomRight]) {
|
|
bottom = qMax(bottom, itemPositions[FullBorderLayout::BottomRight]->preferredSize().height());
|
|
}
|
|
}
|
|
|
|
// left
|
|
left = sizes[FullBorderLayout::LeftBorder];
|
|
if (left < 0) {
|
|
left = 0;
|
|
if (itemPositions[FullBorderLayout::TopLeft]) {
|
|
left = qMax(left, itemPositions[FullBorderLayout::TopLeft]->preferredSize().width());
|
|
}
|
|
if (itemPositions[FullBorderLayout::Left]) {
|
|
left = qMax(left, itemPositions[FullBorderLayout::Left]->preferredSize().width());
|
|
}
|
|
if (itemPositions[FullBorderLayout::BottomLeft]) {
|
|
left = qMax(left, itemPositions[FullBorderLayout::BottomLeft]->preferredSize().width());
|
|
}
|
|
}
|
|
|
|
// right
|
|
right = sizes[FullBorderLayout::RightBorder];
|
|
if (right < 0) {
|
|
right = 0;
|
|
if (itemPositions[FullBorderLayout::TopRight]) {
|
|
right = qMax(right, itemPositions[FullBorderLayout::TopRight]->preferredSize().width());
|
|
}
|
|
if (itemPositions[FullBorderLayout::Right]) {
|
|
right = qMax(right, itemPositions[FullBorderLayout::Right]->preferredSize().width());
|
|
}
|
|
if (itemPositions[FullBorderLayout::BottomRight]) {
|
|
right = qMax(right, itemPositions[FullBorderLayout::BottomRight]->preferredSize().width());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
FullBorderLayout::FullBorderLayout(QGraphicsLayoutItem * parent) :
|
|
QGraphicsLayout(parent), d(new Private(this))
|
|
{
|
|
}
|
|
|
|
FullBorderLayout::~FullBorderLayout()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void FullBorderLayout::setGeometry(const QRectF & rect)
|
|
{
|
|
QGraphicsLayout::setGeometry(rect);
|
|
|
|
QRectF effectiveRect = geometry();
|
|
qreal left = 0, top = 0, right = 0, bottom = 0;
|
|
getContentsMargins(&left, &top, &right, &bottom);
|
|
effectiveRect.adjust(+left, +top, -right, -bottom);
|
|
|
|
qreal topBorder, bottomBorder, leftBorder, rightBorder;
|
|
d->calculateBorderSizes(topBorder, bottomBorder, leftBorder, rightBorder);
|
|
|
|
QRectF itemRect;
|
|
|
|
itemRect = effectiveRect;
|
|
itemRect.setSize(QSizeF(leftBorder, topBorder));
|
|
|
|
if (d->itemPositions[TopLeft]) {
|
|
d->itemPositions[TopLeft]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect.setLeft(effectiveRect.left() + leftBorder);
|
|
itemRect.setWidth(effectiveRect.width() - leftBorder - rightBorder);
|
|
|
|
if (d->itemPositions[Top]) {
|
|
d->itemPositions[Top]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect.setWidth(rightBorder);
|
|
itemRect.moveRight(effectiveRect.right());
|
|
|
|
if (d->itemPositions[TopRight]) {
|
|
d->itemPositions[TopRight]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect.setTop(effectiveRect.top() + topBorder);
|
|
itemRect.setHeight(effectiveRect.height() - topBorder - bottomBorder);
|
|
|
|
if (d->itemPositions[Right]) {
|
|
d->itemPositions[Right]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect.setHeight(bottomBorder);
|
|
itemRect.moveBottom(effectiveRect.bottom());
|
|
|
|
if (d->itemPositions[BottomRight]) {
|
|
d->itemPositions[BottomRight]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect.setLeft(effectiveRect.left() + leftBorder);
|
|
itemRect.setWidth(effectiveRect.width() - leftBorder - rightBorder);
|
|
|
|
if (d->itemPositions[Bottom]) {
|
|
d->itemPositions[Bottom]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect.setLeft(effectiveRect.left());
|
|
itemRect.setWidth(leftBorder);
|
|
|
|
if (d->itemPositions[BottomLeft]) {
|
|
d->itemPositions[BottomLeft]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect.setTop(effectiveRect.top() + topBorder);
|
|
itemRect.setHeight(effectiveRect.height() - topBorder - bottomBorder);
|
|
|
|
if (d->itemPositions[Left]) {
|
|
d->itemPositions[Left]->setGeometry(itemRect);
|
|
}
|
|
|
|
itemRect = effectiveRect;
|
|
itemRect.adjust(
|
|
leftBorder, topBorder,
|
|
- rightBorder, - bottomBorder
|
|
);
|
|
|
|
if (d->itemPositions[Center]) {
|
|
d->itemPositions[Center]->setGeometry(itemRect);
|
|
}
|
|
}
|
|
|
|
QSizeF FullBorderLayout::sizeHint(Qt::SizeHint which,
|
|
const QSizeF & constraint) const
|
|
{
|
|
if (which == Qt::MaximumSize) {
|
|
return MAX_WIDGET_SIZE;
|
|
}
|
|
|
|
qreal topMargin, bottomMargin, leftMargin, rightMargin;
|
|
d->calculateBorderSizes(topMargin, bottomMargin, leftMargin, rightMargin);
|
|
|
|
qreal hintHeight = topMargin + bottomMargin;
|
|
qreal hintWidth = leftMargin + rightMargin;
|
|
|
|
if (d->itemPositions[Center]) {
|
|
hintHeight += d->itemPositions[Center]
|
|
->effectiveSizeHint(which, constraint).height();
|
|
hintWidth += d->itemPositions[Center]
|
|
->effectiveSizeHint(which, constraint).width();
|
|
}
|
|
|
|
QSizeF result = QSizeF(hintWidth, hintHeight);
|
|
if (constraint.isValid()) {
|
|
result = result.boundedTo(constraint);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void FullBorderLayout::addItem(QGraphicsLayoutItem * item)
|
|
{
|
|
FullBorderLayout::addItem (item, Center);
|
|
}
|
|
|
|
void FullBorderLayout::addItem(QGraphicsLayoutItem * item, Place position)
|
|
{
|
|
d->itemPositions[position] = item;
|
|
updateGeometry();
|
|
}
|
|
|
|
int FullBorderLayout::count() const
|
|
{
|
|
int count = 0;
|
|
foreach (QGraphicsLayoutItem * i, d->itemPositions) {
|
|
if (i) {
|
|
++count;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
QGraphicsLayoutItem * FullBorderLayout::itemAt(int index) const
|
|
{
|
|
int count = 0;
|
|
foreach (QGraphicsLayoutItem * i, d->itemPositions) {
|
|
if (i) {
|
|
if (index == count) {
|
|
return i;
|
|
}
|
|
count++;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void FullBorderLayout::setSize(qreal size, Border border)
|
|
{
|
|
d->sizes[border] = size;
|
|
updateGeometry();
|
|
}
|
|
|
|
void FullBorderLayout::setAutoSize(Border border)
|
|
{
|
|
d->sizes[border] = -1;
|
|
updateGeometry();
|
|
}
|
|
|
|
qreal FullBorderLayout::size(Border border) const
|
|
{
|
|
return d->sizes[border];
|
|
}
|
|
|
|
void FullBorderLayout::removeAt(int index)
|
|
{
|
|
QMutableMapIterator < Place, QGraphicsLayoutItem * > i(d->itemPositions);
|
|
int count = 0;
|
|
while (i.hasNext()) {
|
|
i.next();
|
|
if (i.value()) {
|
|
if (index == count++) {
|
|
i.remove();
|
|
}
|
|
}
|
|
}
|
|
updateGeometry();
|
|
}
|
|
|
|
} // namespace Lancelot
|
|
|