File indexing completed on 2024-04-28 04:18:50
0001 // vim: set tabstop=4 shiftwidth=4 expandtab: 0002 /* 0003 Gwenview: an image viewer 0004 Copyright 2008 Aurélien Gâteau <agateau@kde.org> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. 0019 0020 */ 0021 // Self 0022 #include "graphicswidgetfloater.h" 0023 0024 // Qt 0025 #include <QApplication> 0026 #include <QEvent> 0027 #include <QGraphicsWidget> 0028 #include <QPointer> 0029 #include <QStyle> 0030 0031 // Local 0032 0033 namespace Gwenview 0034 { 0035 struct GraphicsWidgetFloaterPrivate { 0036 QGraphicsWidget *mParent = nullptr; 0037 QPointer<QGraphicsWidget> mChild; 0038 Qt::Alignment mAlignment; 0039 0040 int mHorizontalMargin; 0041 int mVerticalMargin; 0042 bool mInsideUpdateChildGeometry; 0043 0044 void updateChildGeometry() 0045 { 0046 if (!mChild) { 0047 return; 0048 } 0049 if (mInsideUpdateChildGeometry) { 0050 return; 0051 } 0052 0053 int posX, posY; 0054 int childWidth, childHeight; 0055 int parentWidth, parentHeight; 0056 0057 childWidth = mChild->size().width(); 0058 childHeight = mChild->size().height(); 0059 0060 parentWidth = mParent->size().width(); 0061 parentHeight = mParent->size().height(); 0062 0063 if (parentWidth == 0 || parentHeight == 0) { 0064 return; 0065 } 0066 0067 if (mAlignment & Qt::AlignLeft) { 0068 posX = mHorizontalMargin; 0069 } else if (mAlignment & Qt::AlignHCenter) { 0070 posX = (parentWidth - childWidth) / 2; 0071 } else if (mAlignment & Qt::AlignJustify) { 0072 posX = mHorizontalMargin; 0073 childWidth = parentWidth - 2 * mHorizontalMargin; 0074 } else { 0075 posX = parentWidth - childWidth - mHorizontalMargin; 0076 } 0077 0078 if (mAlignment & Qt::AlignTop) { 0079 posY = mVerticalMargin; 0080 } else if (mAlignment & Qt::AlignVCenter) { 0081 posY = (parentHeight - childHeight) / 2; 0082 } else { 0083 posY = parentHeight - childHeight - mVerticalMargin; 0084 } 0085 0086 mInsideUpdateChildGeometry = true; 0087 mChild->setGeometry(posX, posY, childWidth, childHeight); 0088 mInsideUpdateChildGeometry = false; 0089 } 0090 }; 0091 0092 GraphicsWidgetFloater::GraphicsWidgetFloater(QGraphicsWidget *parent) 0093 : QObject(parent) 0094 , d(new GraphicsWidgetFloaterPrivate) 0095 { 0096 Q_ASSERT(parent); 0097 d->mParent = parent; 0098 d->mParent->installEventFilter(this); 0099 d->mChild = nullptr; 0100 d->mAlignment = Qt::AlignCenter; 0101 // TODO 0102 d->mHorizontalMargin = 0; 0103 d->mVerticalMargin = d->mHorizontalMargin; 0104 d->mInsideUpdateChildGeometry = false; 0105 } 0106 0107 GraphicsWidgetFloater::~GraphicsWidgetFloater() 0108 { 0109 delete d; 0110 } 0111 0112 void GraphicsWidgetFloater::setChildWidget(QGraphicsWidget *child) 0113 { 0114 if (d->mChild) { 0115 d->mChild->removeEventFilter(this); 0116 disconnect(d->mChild, nullptr, this, nullptr); 0117 } 0118 d->mChild = child; 0119 d->mChild->setParent(d->mParent); 0120 d->mChild->installEventFilter(this); 0121 connect(d->mChild.data(), &QGraphicsObject::visibleChanged, this, &GraphicsWidgetFloater::slotChildVisibilityChanged); 0122 d->updateChildGeometry(); 0123 // d->mChild->raise(); 0124 d->mChild->show(); 0125 } 0126 0127 void GraphicsWidgetFloater::setAlignment(Qt::Alignment alignment) 0128 { 0129 d->mAlignment = alignment; 0130 d->updateChildGeometry(); 0131 } 0132 0133 bool GraphicsWidgetFloater::eventFilter(QObject *, QEvent *event) 0134 { 0135 if (event->type() == QEvent::GraphicsSceneResize) { 0136 d->updateChildGeometry(); 0137 } 0138 return false; 0139 } 0140 0141 void GraphicsWidgetFloater::slotChildVisibilityChanged() 0142 { 0143 if (d->mChild->isVisible()) { 0144 d->updateChildGeometry(); 0145 } 0146 } 0147 0148 void GraphicsWidgetFloater::setHorizontalMargin(int value) 0149 { 0150 d->mHorizontalMargin = value; 0151 d->updateChildGeometry(); 0152 } 0153 0154 int GraphicsWidgetFloater::horizontalMargin() const 0155 { 0156 return d->mHorizontalMargin; 0157 } 0158 0159 void GraphicsWidgetFloater::setVerticalMargin(int value) 0160 { 0161 d->mVerticalMargin = value; 0162 d->updateChildGeometry(); 0163 } 0164 0165 int GraphicsWidgetFloater::verticalMargin() const 0166 { 0167 return d->mVerticalMargin; 0168 } 0169 0170 } // namespace 0171 0172 #include "moc_graphicswidgetfloater.cpp"