File indexing completed on 2024-05-12 05:37:13
0001 /* 0002 SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "itemcontainer.h" 0008 #include "configoverlay.h" 0009 #include "containmentlayoutmanager_debug.h" 0010 0011 #include <QGuiApplication> 0012 #include <QQmlContext> 0013 #include <QQmlEngine> 0014 #include <QQuickWindow> 0015 #include <QStyleHints> 0016 #include <QTimer> 0017 #include <cmath> 0018 0019 #include <PlasmaQuick/AppletQuickItem> 0020 #include <chrono> 0021 0022 using namespace std::chrono_literals; 0023 0024 ItemContainer::ItemContainer(QQuickItem *parent) 0025 : QQuickItem(parent) 0026 { 0027 setFiltersChildMouseEvents(true); 0028 setFlags(QQuickItem::ItemIsFocusScope); 0029 setActiveFocusOnTab(true); 0030 setAcceptedMouseButtons(Qt::LeftButton); 0031 0032 setLayout(qobject_cast<AppletsLayout *>(parent)); 0033 0034 m_editModeTimer = new QTimer(this); 0035 m_editModeTimer->setSingleShot(true); 0036 0037 connect(this, &QQuickItem::parentChanged, this, [this]() { 0038 setLayout(qobject_cast<AppletsLayout *>(parentItem())); 0039 }); 0040 0041 connect(m_editModeTimer, &QTimer::timeout, this, [this]() { 0042 setEditMode(true); 0043 }); 0044 0045 setKeepMouseGrab(true); 0046 m_sizeHintAdjustTimer = new QTimer(this); 0047 m_sizeHintAdjustTimer->setSingleShot(true); 0048 m_sizeHintAdjustTimer->setInterval(0); 0049 0050 connect(m_sizeHintAdjustTimer, &QTimer::timeout, this, &ItemContainer::sizeHintsChanged); 0051 } 0052 0053 ItemContainer::~ItemContainer() 0054 { 0055 disconnect(this, &QQuickItem::parentChanged, this, nullptr); 0056 0057 if (m_contentItem) { 0058 m_contentItem->setEnabled(true); 0059 } 0060 } 0061 0062 QString ItemContainer::key() const 0063 { 0064 return m_key; 0065 } 0066 0067 void ItemContainer::setKey(const QString &key) 0068 { 0069 if (m_key == key) { 0070 return; 0071 } 0072 0073 m_key = key; 0074 0075 Q_EMIT keyChanged(); 0076 } 0077 0078 bool ItemContainer::editMode() const 0079 { 0080 return m_editMode; 0081 } 0082 0083 bool ItemContainer::dragActive() const 0084 { 0085 return m_dragActive; 0086 } 0087 0088 void ItemContainer::cancelEdit() 0089 { 0090 m_editModeTimer->stop(); 0091 m_mouseDown = false; 0092 setEditMode(false); 0093 } 0094 0095 void ItemContainer::setEditMode(bool editMode) 0096 { 0097 if (m_editMode == editMode) { 0098 return; 0099 } 0100 0101 if (editMode && editModeCondition() == Locked) { 0102 return; 0103 } 0104 0105 m_editMode = editMode; 0106 0107 if (m_contentItem && (m_editModeCondition != AfterMouseOver || (m_layout && m_layout->editMode()))) { 0108 m_contentItem->setEnabled(!editMode); 0109 } 0110 0111 if (editMode) { 0112 setZ(1); 0113 } else { 0114 setZ(0); 0115 } 0116 0117 if (m_mouseDown) { 0118 sendUngrabRecursive(m_contentItem); 0119 QMouseEvent ev(QEvent::MouseButtonPress, mapFromScene(m_mouseDownPosition), m_mouseDownPosition, QPointF(), Qt::LeftButton, {}, {}); 0120 ev.setExclusiveGrabber(ev.point(0), this); 0121 QCoreApplication::sendEvent(this, &ev); 0122 } 0123 0124 if (m_dragActive != editMode && m_mouseDown) { 0125 m_dragActive = editMode && m_mouseDown; 0126 Q_EMIT dragActiveChanged(); 0127 } 0128 0129 setConfigOverlayVisible(editMode); 0130 0131 Q_EMIT editModeChanged(editMode); 0132 } 0133 0134 ItemContainer::EditModeCondition ItemContainer::editModeCondition() const 0135 { 0136 if (m_layout && m_layout->editModeCondition() == AppletsLayout::Locked) { 0137 return Locked; 0138 } 0139 0140 return m_editModeCondition; 0141 } 0142 0143 void ItemContainer::setEditModeCondition(EditModeCondition condition) 0144 { 0145 if (condition == m_editModeCondition) { 0146 return; 0147 } 0148 0149 if (condition == Locked) { 0150 setEditMode(false); 0151 } 0152 0153 m_editModeCondition = condition; 0154 0155 setAcceptHoverEvents(condition == AfterMouseOver || (m_layout && m_layout->editMode())); 0156 0157 Q_EMIT editModeConditionChanged(); 0158 } 0159 0160 AppletsLayout::PreferredLayoutDirection ItemContainer::preferredLayoutDirection() const 0161 { 0162 return m_preferredLayoutDirection; 0163 } 0164 0165 void ItemContainer::setPreferredLayoutDirection(AppletsLayout::PreferredLayoutDirection direction) 0166 { 0167 if (direction == m_preferredLayoutDirection) { 0168 return; 0169 } 0170 0171 m_preferredLayoutDirection = direction; 0172 0173 Q_EMIT preferredLayoutDirectionChanged(); 0174 } 0175 0176 void ItemContainer::setLayout(AppletsLayout *layout) 0177 { 0178 if (m_layout == layout) { 0179 return; 0180 } 0181 0182 if (m_layout) { 0183 disconnect(m_layout, &AppletsLayout::editModeConditionChanged, this, nullptr); 0184 disconnect(m_layout, &AppletsLayout::editModeChanged, this, nullptr); 0185 0186 if (m_editMode) { 0187 m_layout->hidePlaceHolder(); 0188 } 0189 } 0190 0191 m_layout = layout; 0192 0193 if (!layout) { 0194 Q_EMIT layoutChanged(); 0195 return; 0196 } 0197 0198 if (parentItem() != layout) { 0199 setParentItem(layout); 0200 } 0201 0202 connect(m_layout, &AppletsLayout::editModeConditionChanged, this, [this]() { 0203 if (m_layout->editModeCondition() == AppletsLayout::Locked) { 0204 setEditMode(false); 0205 } 0206 if ((m_layout->editModeCondition() == AppletsLayout::Locked) != (m_editModeCondition == ItemContainer::Locked)) { 0207 Q_EMIT editModeConditionChanged(); 0208 } 0209 }); 0210 connect(m_layout, &AppletsLayout::editModeChanged, this, [this]() { 0211 setAcceptHoverEvents(m_editModeCondition == AfterMouseOver || m_layout->editMode()); 0212 }); 0213 Q_EMIT layoutChanged(); 0214 } 0215 0216 AppletsLayout *ItemContainer::layout() const 0217 { 0218 return m_layout; 0219 } 0220 0221 void ItemContainer::onConfigOverlayComponentStatusChanged(QQmlComponent::Status status, QQmlComponent *component) 0222 { 0223 if (status == QQmlComponent::Loading) { 0224 return; 0225 } 0226 if (!component) { 0227 component = static_cast<QQmlComponent *>(sender()); 0228 } 0229 if (status != QQmlComponent::Ready) { 0230 delete component; 0231 return; 0232 } 0233 0234 Q_ASSERT(!m_configOverlay); 0235 m_configOverlay = static_cast<ConfigOverlay *>(component->beginCreate(QQmlEngine::contextForObject(this))); 0236 0237 m_configOverlay->setVisible(false); 0238 m_configOverlay->setItemContainer(this); 0239 m_configOverlay->setParentItem(this); 0240 m_configOverlay->setTouchInteraction(m_mouseSynthetizedFromTouch); 0241 m_configOverlay->setZ(999); 0242 m_configOverlay->setPosition(QPointF(0, 0)); 0243 m_configOverlay->setSize(size()); 0244 0245 component->completeCreate(); 0246 component->deleteLater(); 0247 0248 connect(m_configOverlay, &ConfigOverlay::openChanged, this, &ItemContainer::configOverlayVisibleChanged); 0249 0250 Q_EMIT configOverlayItemChanged(); 0251 0252 m_configOverlay->setOpen(m_configOverlayVisible); 0253 } 0254 0255 void ItemContainer::syncChildItemsGeometry(const QSizeF &size) 0256 { 0257 if (m_contentItem) { 0258 m_contentItem->setPosition(QPointF(m_leftPadding, m_topPadding)); 0259 0260 m_contentItem->setSize(QSizeF(size.width() - m_leftPadding - m_rightPadding, size.height() - m_topPadding - m_bottomPadding)); 0261 } 0262 0263 if (m_backgroundItem) { 0264 m_backgroundItem->setPosition(QPointF(0, 0)); 0265 m_backgroundItem->setSize(size); 0266 } 0267 0268 if (m_configOverlay) { 0269 m_configOverlay->setPosition(QPointF(0, 0)); 0270 m_configOverlay->setSize(size); 0271 } 0272 } 0273 0274 QUrl ItemContainer::configOverlaySource() const 0275 { 0276 return m_configOverlaySource; 0277 } 0278 0279 void ItemContainer::setConfigOverlaySource(const QUrl &url) 0280 { 0281 if (url == m_configOverlaySource || !url.isValid()) { 0282 return; 0283 } 0284 0285 m_configOverlaySource = url; 0286 if (m_configOverlay) { 0287 m_configOverlay->deleteLater(); 0288 m_configOverlay = nullptr; 0289 } 0290 Q_EMIT configOverlaySourceChanged(); 0291 0292 if (m_configOverlayVisible) { 0293 loadConfigOverlayItem(); 0294 } 0295 } 0296 0297 ConfigOverlay *ItemContainer::configOverlayItem() const 0298 { 0299 return m_configOverlay; 0300 } 0301 0302 QSizeF ItemContainer::initialSize() const 0303 { 0304 return m_initialSize; 0305 } 0306 0307 void ItemContainer::setInitialSize(const QSizeF &size) 0308 { 0309 if (m_initialSize == size) { 0310 return; 0311 } 0312 0313 m_initialSize = size; 0314 0315 Q_EMIT initialSizeChanged(); 0316 } 0317 0318 bool ItemContainer::configOverlayVisible() const 0319 { 0320 return m_configOverlay && m_configOverlay->open(); 0321 } 0322 0323 void ItemContainer::setConfigOverlayVisible(bool visible) 0324 { 0325 if (!m_configOverlaySource.isValid() || visible == m_configOverlayVisible) { 0326 return; 0327 } 0328 0329 m_configOverlayVisible = visible; 0330 0331 if (visible && !m_configOverlay) { 0332 loadConfigOverlayItem(); 0333 } else if (m_configOverlay) { 0334 m_configOverlay->setVisible(visible); 0335 } 0336 } 0337 0338 void ItemContainer::contentData_append(QQmlListProperty<QObject> *prop, QObject *object) 0339 { 0340 ItemContainer *container = static_cast<ItemContainer *>(prop->object); 0341 if (!container) { 0342 return; 0343 } 0344 0345 // QQuickItem *item = qobject_cast<QQuickItem *>(object); 0346 container->m_contentData.append(object); 0347 } 0348 0349 qsizetype ItemContainer::contentData_count(QQmlListProperty<QObject> *prop) 0350 { 0351 ItemContainer *container = static_cast<ItemContainer *>(prop->object); 0352 if (!container) { 0353 return 0; 0354 } 0355 0356 return container->m_contentData.count(); 0357 } 0358 0359 QObject *ItemContainer::contentData_at(QQmlListProperty<QObject> *prop, qsizetype index) 0360 { 0361 ItemContainer *container = static_cast<ItemContainer *>(prop->object); 0362 if (!container) { 0363 return nullptr; 0364 } 0365 0366 if (index < 0 || index >= container->m_contentData.count()) { 0367 return nullptr; 0368 } 0369 return container->m_contentData.value(index); 0370 } 0371 0372 void ItemContainer::contentData_clear(QQmlListProperty<QObject> *prop) 0373 { 0374 ItemContainer *container = static_cast<ItemContainer *>(prop->object); 0375 if (!container) { 0376 return; 0377 } 0378 0379 return container->m_contentData.clear(); 0380 } 0381 0382 QQmlListProperty<QObject> ItemContainer::contentData() 0383 { 0384 return QQmlListProperty<QObject>(this, nullptr, contentData_append, contentData_count, contentData_at, contentData_clear); 0385 } 0386 0387 void ItemContainer::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) 0388 { 0389 syncChildItemsGeometry(newGeometry.size()); 0390 QQuickItem::geometryChange(newGeometry, oldGeometry); 0391 Q_EMIT contentWidthChanged(); 0392 Q_EMIT contentHeightChanged(); 0393 } 0394 0395 void ItemContainer::componentComplete() 0396 { 0397 if (!m_contentItem) { 0398 // qWarning()<<"Creating default contentItem"; 0399 m_contentItem = new QQuickItem(this); 0400 syncChildItemsGeometry(size()); 0401 } 0402 0403 for (auto *o : std::as_const(m_contentData)) { 0404 QQuickItem *item = qobject_cast<QQuickItem *>(o); 0405 if (item) { 0406 item->setParentItem(m_contentItem); 0407 } 0408 } 0409 0410 // Search for the Layout attached property 0411 // Qt6: this should become public api 0412 // https://bugreports.qt.io/browse/QTBUG-77103 0413 for (auto *o : children()) { 0414 if (o->inherits("QQuickLayoutAttached")) { 0415 m_layoutAttached = o; 0416 } 0417 } 0418 0419 if (m_layoutAttached) { 0420 // NOTE: new syntax cannot be used because we don't have access to the QQuickLayoutAttached class 0421 connect(m_layoutAttached, SIGNAL(minimumHeightChanged()), m_sizeHintAdjustTimer, SLOT(start())); 0422 connect(m_layoutAttached, SIGNAL(minimumWidthChanged()), m_sizeHintAdjustTimer, SLOT(start())); 0423 0424 connect(m_layoutAttached, SIGNAL(preferredHeightChanged()), m_sizeHintAdjustTimer, SLOT(start())); 0425 connect(m_layoutAttached, SIGNAL(preferredWidthChanged()), m_sizeHintAdjustTimer, SLOT(start())); 0426 0427 connect(m_layoutAttached, SIGNAL(maximumHeightChanged()), m_sizeHintAdjustTimer, SLOT(start())); 0428 connect(m_layoutAttached, SIGNAL(maximumWidthChanged()), m_sizeHintAdjustTimer, SLOT(start())); 0429 } 0430 QQuickItem::componentComplete(); 0431 } 0432 0433 void ItemContainer::sendUngrabRecursive(QQuickItem *item) 0434 { 0435 if (!item || !item->window()) { 0436 return; 0437 } 0438 0439 for (auto *child : item->childItems()) { 0440 sendUngrabRecursive(child); 0441 } 0442 0443 QEvent ev(QEvent::UngrabMouse); 0444 0445 QCoreApplication::sendEvent(item, &ev); 0446 } 0447 0448 void ItemContainer::loadConfigOverlayItem() 0449 { 0450 Q_ASSERT(!m_configOverlay); 0451 constexpr QQmlComponent::CompilationMode mode = QQmlComponent::Asynchronous; 0452 QQmlContext *context = QQmlEngine::contextForObject(this); 0453 auto component = new QQmlComponent(context->engine(), context->resolvedUrl(m_configOverlaySource), mode, this); 0454 if (!component->isLoading()) { 0455 onConfigOverlayComponentStatusChanged(component->status(), component); 0456 } else { 0457 connect(component, 0458 &QQmlComponent::statusChanged, 0459 this, 0460 std::bind(&ItemContainer::onConfigOverlayComponentStatusChanged, this, std::placeholders::_1, nullptr)); 0461 } 0462 } 0463 0464 bool ItemContainer::childMouseEventFilter(QQuickItem *item, QEvent *event) 0465 { 0466 // Don't filter the configoverlay 0467 if (item == m_configOverlay || (m_configOverlay && m_configOverlay->isAncestorOf(item)) || (!m_editMode && m_editModeCondition == Manual)) { 0468 if (m_closeEditModeTimer && m_closeEditModeTimer->isActive()) { 0469 m_closeEditModeTimer->setInterval(2s); 0470 m_closeEditModeTimer->start(); 0471 } 0472 return QQuickItem::childMouseEventFilter(item, event); 0473 } 0474 0475 // give more time before closing 0476 if (m_closeEditModeTimer && m_closeEditModeTimer->isActive()) { 0477 m_closeEditModeTimer->setInterval(500ms); 0478 m_closeEditModeTimer->start(); 0479 } 0480 if (event->type() == QEvent::MouseButtonPress) { 0481 QMouseEvent *me = static_cast<QMouseEvent *>(event); 0482 if (me->button() != Qt::LeftButton && !(me->buttons() & Qt::LeftButton)) { 0483 return QQuickItem::childMouseEventFilter(item, event); 0484 } 0485 forceActiveFocus(Qt::MouseFocusReason); 0486 m_mouseDown = true; 0487 m_mouseSynthetizedFromTouch = me->source() == Qt::MouseEventSynthesizedBySystem || me->source() == Qt::MouseEventSynthesizedByQt; 0488 if (m_configOverlay) { 0489 m_configOverlay->setTouchInteraction(m_mouseSynthetizedFromTouch); 0490 } 0491 0492 const bool wasEditMode = m_editMode; 0493 if (m_layout && m_layout->editMode()) { 0494 setEditMode(true); 0495 } else if (m_editModeCondition == AfterPressAndHold) { 0496 m_editModeTimer->start(QGuiApplication::styleHints()->mousePressAndHoldInterval()); 0497 } 0498 m_lastMousePosition = me->scenePosition(); 0499 m_mouseDownPosition = me->scenePosition(); 0500 0501 if (m_editMode && !wasEditMode) { 0502 event->accept(); 0503 return true; 0504 } 0505 0506 } else if (event->type() == QEvent::MouseMove) { 0507 QMouseEvent *me = static_cast<QMouseEvent *>(event); 0508 0509 if (!m_editMode && QPointF(me->scenePosition() - m_mouseDownPosition).manhattanLength() >= QGuiApplication::styleHints()->startDragDistance()) { 0510 m_editModeTimer->stop(); 0511 } else if (m_editMode) { 0512 event->accept(); 0513 } 0514 0515 } else if (event->type() == QEvent::MouseButtonRelease) { 0516 m_editModeTimer->stop(); 0517 m_mouseDown = false; 0518 m_mouseSynthetizedFromTouch = false; 0519 if (auto mouseEvent = static_cast<QMouseEvent *>(event); mouseEvent->exclusiveGrabber(mouseEvent->point(0)) == this) { 0520 mouseEvent->setExclusiveGrabber(mouseEvent->point(0), nullptr); 0521 } 0522 event->accept(); 0523 m_dragActive = false; 0524 if (m_editMode) { 0525 Q_EMIT dragActiveChanged(); 0526 } 0527 } 0528 0529 return QQuickItem::childMouseEventFilter(item, event); 0530 } 0531 0532 void ItemContainer::mousePressEvent(QMouseEvent *event) 0533 { 0534 forceActiveFocus(Qt::MouseFocusReason); 0535 0536 if (!m_editMode && m_editModeCondition == Manual) { 0537 return; 0538 } 0539 0540 m_mouseDown = true; 0541 m_mouseSynthetizedFromTouch = event->source() == Qt::MouseEventSynthesizedBySystem || event->source() == Qt::MouseEventSynthesizedByQt; 0542 if (m_configOverlay) { 0543 m_configOverlay->setTouchInteraction(m_mouseSynthetizedFromTouch); 0544 } 0545 0546 if (m_layout && m_layout->editMode()) { 0547 setEditMode(true); 0548 } 0549 0550 if (m_editMode) { 0551 event->setExclusiveGrabber(event->point(0), this); 0552 setCursor(Qt::ClosedHandCursor); 0553 m_dragActive = true; 0554 Q_EMIT dragActiveChanged(); 0555 } else if (m_editModeCondition == AfterPressAndHold) { 0556 m_editModeTimer->start(QGuiApplication::styleHints()->mousePressAndHoldInterval()); 0557 } 0558 0559 m_lastMousePosition = event->scenePosition(); 0560 m_mouseDownPosition = event->scenePosition(); 0561 event->accept(); 0562 } 0563 0564 void ItemContainer::mouseReleaseEvent(QMouseEvent *event) 0565 { 0566 Q_UNUSED(event); 0567 0568 if (!m_layout || (!m_editMode && m_editModeCondition == Manual)) { 0569 return; 0570 } 0571 0572 m_mouseDown = false; 0573 m_mouseSynthetizedFromTouch = false; 0574 m_editModeTimer->stop(); 0575 if (event->exclusiveGrabber(event->point(0)) == this) { 0576 event->setExclusiveGrabber(event->point(0), nullptr); 0577 } 0578 0579 if (m_editMode && !m_layout->itemIsManaged(this)) { 0580 m_layout->hidePlaceHolder(); 0581 m_layout->positionItem(this); 0582 } 0583 0584 m_dragActive = false; 0585 if (m_editMode) { 0586 Q_EMIT dragActiveChanged(); 0587 setCursor(Qt::OpenHandCursor); 0588 } 0589 event->accept(); 0590 } 0591 0592 void ItemContainer::mouseMoveEvent(QMouseEvent *event) 0593 { 0594 if ((event->button() == Qt::NoButton && event->buttons() == Qt::NoButton) || (!m_editMode && m_editModeCondition == Manual)) { 0595 return; 0596 } 0597 0598 if (!m_editMode && QPointF(event->scenePosition() - m_mouseDownPosition).manhattanLength() >= QGuiApplication::styleHints()->startDragDistance()) { 0599 if (m_editModeCondition == AfterPress) { 0600 setEditMode(true); 0601 } else { 0602 m_editModeTimer->stop(); 0603 } 0604 } 0605 0606 if (!m_editMode) { 0607 return; 0608 } 0609 0610 if (m_layout && m_layout->itemIsManaged(this)) { 0611 m_layout->releaseSpace(this); 0612 event->setExclusiveGrabber(event->point(0), this); 0613 m_dragActive = true; 0614 Q_EMIT dragActiveChanged(); 0615 0616 } else { 0617 setPosition(QPointF(x() + event->scenePosition().x() - m_lastMousePosition.x(), y() + event->scenePosition().y() - m_lastMousePosition.y())); 0618 0619 if (m_layout) { 0620 m_layout->showPlaceHolderForItem(this); 0621 } 0622 0623 Q_EMIT userDrag(QPointF(x(), y()), event->pos()); 0624 } 0625 m_lastMousePosition = event->scenePosition(); 0626 event->accept(); 0627 } 0628 0629 void ItemContainer::mouseUngrabEvent() 0630 { 0631 m_mouseDown = false; 0632 m_mouseSynthetizedFromTouch = false; 0633 m_editModeTimer->stop(); 0634 0635 if (m_layout && m_editMode && !m_layout->itemIsManaged(this)) { 0636 m_layout->hidePlaceHolder(); 0637 m_layout->positionItem(this); 0638 } 0639 0640 m_dragActive = false; 0641 if (m_editMode) { 0642 Q_EMIT dragActiveChanged(); 0643 } 0644 } 0645 0646 void ItemContainer::hoverEnterEvent(QHoverEvent *event) 0647 { 0648 Q_UNUSED(event); 0649 0650 if (m_editModeCondition != AfterMouseOver && !m_layout->editMode()) { 0651 return; 0652 } 0653 0654 if (m_closeEditModeTimer) { 0655 m_closeEditModeTimer->stop(); 0656 } 0657 0658 if (m_layout->editMode()) { 0659 setCursor(Qt::OpenHandCursor); 0660 setEditMode(true); 0661 } else { 0662 m_editModeTimer->start(QGuiApplication::styleHints()->mousePressAndHoldInterval()); 0663 } 0664 } 0665 0666 void ItemContainer::hoverLeaveEvent(QHoverEvent *event) 0667 { 0668 Q_UNUSED(event); 0669 0670 if (m_editModeCondition != AfterMouseOver && !m_layout->editMode()) { 0671 return; 0672 } 0673 0674 m_editModeTimer->stop(); 0675 if (!m_closeEditModeTimer) { 0676 m_closeEditModeTimer = new QTimer(this); 0677 m_closeEditModeTimer->setSingleShot(true); 0678 connect(m_closeEditModeTimer, &QTimer::timeout, this, [this]() { 0679 setEditMode(false); 0680 }); 0681 } 0682 m_closeEditModeTimer->setInterval(500ms); 0683 m_closeEditModeTimer->start(); 0684 } 0685 0686 QQuickItem *ItemContainer::contentItem() const 0687 { 0688 return m_contentItem; 0689 } 0690 0691 void ItemContainer::setContentItem(QQuickItem *item) 0692 { 0693 if (m_contentItem == item) { 0694 return; 0695 } 0696 0697 m_contentItem = item; 0698 item->setParentItem(this); 0699 0700 item->setVisible(true); 0701 m_contentItem->setPosition(QPointF(m_leftPadding, m_topPadding)); 0702 m_contentItem->setSize(QSizeF(width() - m_leftPadding - m_rightPadding, height() - m_topPadding - m_bottomPadding)); 0703 0704 Q_EMIT contentItemChanged(); 0705 } 0706 0707 QQuickItem *ItemContainer::background() const 0708 { 0709 return m_backgroundItem; 0710 } 0711 0712 void ItemContainer::setBackground(QQuickItem *item) 0713 { 0714 if (m_backgroundItem == item) { 0715 return; 0716 } 0717 0718 m_backgroundItem = item; 0719 m_backgroundItem->setParentItem(this); 0720 m_backgroundItem->setPosition(QPointF(0, 0)); 0721 m_backgroundItem->setSize(size()); 0722 0723 Q_EMIT backgroundChanged(); 0724 } 0725 0726 int ItemContainer::leftPadding() const 0727 { 0728 return m_leftPadding; 0729 } 0730 0731 void ItemContainer::setLeftPadding(int padding) 0732 { 0733 if (m_leftPadding == padding) { 0734 return; 0735 } 0736 0737 m_leftPadding = padding; 0738 syncChildItemsGeometry(size()); 0739 Q_EMIT leftPaddingChanged(); 0740 Q_EMIT contentWidthChanged(); 0741 } 0742 0743 int ItemContainer::topPadding() const 0744 { 0745 return m_topPadding; 0746 } 0747 0748 void ItemContainer::setTopPadding(int padding) 0749 { 0750 if (m_topPadding == padding) { 0751 return; 0752 } 0753 0754 m_topPadding = padding; 0755 syncChildItemsGeometry(size()); 0756 Q_EMIT topPaddingChanged(); 0757 Q_EMIT contentHeightChanged(); 0758 } 0759 0760 int ItemContainer::rightPadding() const 0761 { 0762 return m_rightPadding; 0763 } 0764 0765 void ItemContainer::setRightPadding(int padding) 0766 { 0767 if (m_rightPadding == padding) { 0768 return; 0769 } 0770 0771 m_rightPadding = padding; 0772 syncChildItemsGeometry(size()); 0773 Q_EMIT rightPaddingChanged(); 0774 Q_EMIT contentWidthChanged(); 0775 } 0776 0777 int ItemContainer::bottomPadding() const 0778 { 0779 return m_bottomPadding; 0780 } 0781 0782 void ItemContainer::setBottomPadding(int padding) 0783 { 0784 if (m_bottomPadding == padding) { 0785 return; 0786 } 0787 0788 m_bottomPadding = padding; 0789 syncChildItemsGeometry(size()); 0790 Q_EMIT bottomPaddingChanged(); 0791 Q_EMIT contentHeightChanged(); 0792 } 0793 0794 int ItemContainer::contentWidth() const 0795 { 0796 return width() - m_leftPadding - m_rightPadding; 0797 } 0798 0799 int ItemContainer::contentHeight() const 0800 { 0801 return height() - m_topPadding - m_bottomPadding; 0802 } 0803 0804 #include "moc_itemcontainer.cpp"