Warning, file /office/calligra/libs/widgets/KoPositionSelector.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2007 Thomas Zander <zander@kde.org> 0003 * Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoPositionSelector.h" 0022 0023 #include <QRadioButton> 0024 #include <QGridLayout> 0025 #include <QButtonGroup> 0026 #include <QPainter> 0027 #include <WidgetsDebug.h> 0028 #include <QStyleOption> 0029 0030 #define GAP 0 0031 0032 class Q_DECL_HIDDEN KoPositionSelector::Private 0033 { 0034 public: 0035 Private() 0036 : position(KoFlake::TopLeftCorner) 0037 { 0038 topLeft = createButton(KoFlake::TopLeftCorner); 0039 topLeft->setChecked(true); 0040 topRight = createButton(KoFlake::TopRightCorner); 0041 center = createButton(KoFlake::CenteredPosition); 0042 bottomRight = createButton(KoFlake::BottomRightCorner); 0043 bottomLeft = createButton(KoFlake::BottomLeftCorner); 0044 } 0045 0046 QRadioButton *createButton(int id) { 0047 QRadioButton *b = new QRadioButton(); 0048 buttonGroup.addButton(b, id); 0049 return b; 0050 } 0051 0052 QRadioButton *topLeft, *topRight, *center, *bottomRight, *bottomLeft; 0053 QButtonGroup buttonGroup; 0054 KoFlake::Position position; 0055 }; 0056 0057 class RadioLayout : public QLayout { 0058 Q_OBJECT 0059 public: 0060 RadioLayout(QWidget *parent) 0061 : QLayout(parent) 0062 { 0063 } 0064 0065 ~RadioLayout() override 0066 { 0067 foreach( const Item & item, items ) 0068 delete item.child; 0069 items.clear(); 0070 } 0071 0072 void setGeometry (const QRect &geom) override { 0073 QSize prefSize = calcSizes(); 0074 0075 qreal columnWidth, rowHeight; 0076 if (geom.width() <= minimum.width()) 0077 columnWidth = geom.width() / (qreal) maxCol; 0078 else 0079 columnWidth = prefSize.width() + GAP; 0080 if (geom.height() <= minimum.height()) 0081 rowHeight = geom.height() / (qreal) maxRow; 0082 else 0083 rowHeight = prefSize.height() + GAP; 0084 // padding inside row and column so that radio button is centered 0085 QPoint padding( qRound(0.5 * (columnWidth - prefSize.width())), qRound(0.5 * (rowHeight - prefSize.height()))); 0086 // offset so that all the radio button are centered within the widget 0087 qreal offsetX = 0.5 * (geom.width()- static_cast<qreal>(maxCol) * columnWidth); 0088 qreal offsetY = 0.5 * (geom.height() - static_cast<qreal>(maxRow) * rowHeight); 0089 QPoint offset( qRound(offsetX), qRound(offsetY)); 0090 foreach(const Item & item, items) { 0091 QPoint point( qRound(item.column * columnWidth), qRound(item.row * rowHeight) ); 0092 QRect rect(point + offset + padding + geom.topLeft(), prefSize); 0093 item.child->setGeometry(rect); 0094 } 0095 } 0096 0097 QSize calcSizes() { 0098 QSize prefSize; 0099 maxRow = 0; 0100 maxCol = 0; 0101 foreach(const Item & item, items) { 0102 if(prefSize.isEmpty()) { 0103 QAbstractButton *but = dynamic_cast<QAbstractButton*> (item.child->widget()); 0104 Q_ASSERT(but); 0105 QStyleOptionButton opt; 0106 opt.initFrom(but); 0107 prefSize = QSize(but->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, &opt, but), 0108 but->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight, &opt, but)); 0109 } 0110 maxRow = qMax(maxRow, item.row); 0111 maxCol = qMax(maxCol, item.column); 0112 } 0113 maxCol++; maxRow++; // due to being zero-based. 0114 preferred = QSize(maxCol * prefSize.width() + (maxCol-1) * GAP, maxRow * prefSize.height() + (maxRow-1) * GAP); 0115 minimum = QSize(maxCol * prefSize.width(), maxRow * prefSize.height()); 0116 return prefSize; 0117 } 0118 0119 QLayoutItem *itemAt (int index) const override { 0120 if( index < count() ) 0121 return items.at(index).child; 0122 else 0123 return 0; 0124 } 0125 0126 QLayoutItem *takeAt (int index) override { 0127 Q_ASSERT(index < count()); 0128 Item item = items.takeAt(index); 0129 return item.child; 0130 } 0131 0132 int count () const override { 0133 return items.count(); 0134 } 0135 0136 void addItem(QLayoutItem *) override { 0137 Q_ASSERT(0); 0138 } 0139 0140 QSize sizeHint() const override { 0141 if(preferred.isEmpty()) 0142 const_cast<RadioLayout*> (this)->calcSizes(); 0143 return preferred; 0144 } 0145 0146 QSize minimumSize() const override { 0147 if(minimum.isEmpty()) 0148 const_cast<RadioLayout*> (this)->calcSizes(); 0149 return minimum; 0150 } 0151 0152 void addWidget(QRadioButton *widget, int row, int column) { 0153 addChildWidget(widget); 0154 Item newItem; 0155 newItem.child = new QWidgetItem(widget); 0156 newItem.row = row; 0157 newItem.column = column; 0158 items.append(newItem); 0159 } 0160 0161 private: 0162 struct Item { 0163 QLayoutItem *child; 0164 int column; 0165 int row; 0166 }; 0167 QList<Item> items; 0168 QSize preferred, minimum; 0169 int maxCol, maxRow; 0170 }; 0171 0172 KoPositionSelector::KoPositionSelector(QWidget *parent) 0173 : QWidget(parent), 0174 d(new Private()) 0175 { 0176 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 0177 RadioLayout *lay = new RadioLayout(this); 0178 lay->addWidget(d->topLeft, 0, 0); 0179 lay->addWidget(d->topRight, 0, 2); 0180 lay->addWidget(d->center, 1, 1); 0181 lay->addWidget(d->bottomRight, 2, 2); 0182 lay->addWidget(d->bottomLeft, 2, 0); 0183 setLayout(lay); 0184 0185 connect(&d->buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(positionChanged(int))); 0186 } 0187 0188 KoPositionSelector::~KoPositionSelector() { 0189 delete d; 0190 } 0191 0192 KoFlake::Position KoPositionSelector::position() const { 0193 return d->position; 0194 } 0195 0196 void KoPositionSelector::setPosition(KoFlake::Position position) { 0197 d->position = position; 0198 switch(d->position) { 0199 case KoFlake::TopLeftCorner: 0200 d->topLeft->setChecked(true); 0201 break; 0202 case KoFlake::TopRightCorner: 0203 d->topRight->setChecked(true); 0204 break; 0205 case KoFlake::CenteredPosition: 0206 d->center->setChecked(true); 0207 break; 0208 case KoFlake::BottomLeftCorner: 0209 d->bottomLeft->setChecked(true); 0210 break; 0211 case KoFlake::BottomRightCorner: 0212 d->bottomRight->setChecked(true); 0213 break; 0214 } 0215 } 0216 0217 void KoPositionSelector::positionChanged(int position) { 0218 d->position = static_cast<KoFlake::Position> (position); 0219 emit positionSelected(d->position); 0220 } 0221 0222 void KoPositionSelector::paintEvent (QPaintEvent *) { 0223 QPainter painter( this ); 0224 QPen pen(Qt::black); 0225 int width; 0226 if (d->topLeft->width() %2 == 0) 0227 width = 2; 0228 else 0229 width = 3; 0230 pen.setWidth(width); 0231 painter.setPen(pen); 0232 painter.drawRect( QRect( d->topLeft->geometry().center(), d->bottomRight->geometry().center() ) ); 0233 painter.end(); 0234 } 0235 #include "KoPositionSelector.moc"