From ec92226730adbb042b0793dcf1aa6661511ed035 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 10 Oct 2024 11:27:45 +0200 Subject: [PATCH] initial version of QskItemAnchors introduced --- src/CMakeLists.txt | 2 + src/controls/QskItemAnchors.cpp | 145 ++++++++++++++++++++++++++++++++ src/controls/QskItemAnchors.h | 60 +++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 src/controls/QskItemAnchors.cpp create mode 100644 src/controls/QskItemAnchors.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f4412eb8..151ed18f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -219,6 +219,7 @@ list(APPEND HEADERS controls/QskGraphicLabelSkinlet.h controls/QskHintAnimator.h controls/QskItem.h + controls/QskItemAnchors.h controls/QskListView.h controls/QskListViewSkinlet.h controls/QskMenu.h @@ -325,6 +326,7 @@ list(APPEND SOURCES controls/QskInputGrabber.cpp controls/QskItem.cpp controls/QskItemPrivate.cpp + controls/QskItemAnchors.cpp controls/QskListView.cpp controls/QskListViewSkinlet.cpp controls/QskMenuSkinlet.cpp diff --git a/src/controls/QskItemAnchors.cpp b/src/controls/QskItemAnchors.cpp new file mode 100644 index 00000000..a8f126c5 --- /dev/null +++ b/src/controls/QskItemAnchors.cpp @@ -0,0 +1,145 @@ +/****************************************************************************** + * QSkinny - Copyright (C) The authors + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#include "QskItemAnchors.h" +#include "QskMargins.h" + +QSK_QT_PRIVATE_BEGIN +#include +#include +QSK_QT_PRIVATE_END + +namespace +{ + inline QQuickAnchors::Anchor toQuickAnchor( Qt::AnchorPoint edge ) + { + switch( edge ) + { + case Qt::AnchorLeft: + return QQuickAnchors::LeftAnchor; + + case Qt::AnchorHorizontalCenter: + return QQuickAnchors::HCenterAnchor; + + case Qt::AnchorRight: + return QQuickAnchors::RightAnchor; + + case Qt::AnchorTop: + return QQuickAnchors::TopAnchor; + + case Qt::AnchorVerticalCenter: + return QQuickAnchors::VCenterAnchor; + + case Qt::AnchorBottom: + return QQuickAnchors::BottomAnchor; + } + + return QQuickAnchors::InvalidAnchor; + } + + struct AnchorOperators + { + QQuickAnchorLine ( QQuickAnchors::*line ) () const; + void ( QQuickAnchors::*setLine )( const QQuickAnchorLine& ); + void ( QQuickAnchors::*resetLine )(); + }; + + const AnchorOperators& operators( Qt::AnchorPoint edge ) + { + using A = QQuickAnchors; + + static constexpr AnchorOperators table[] = + { + // in order of Qt::AnchorPoint + + { &A::left, &A::setLeft, &A::resetLeft }, + { &A::horizontalCenter, &A::setHorizontalCenter, &A::resetHorizontalCenter }, + { &A::right, &A::setRight, &A::resetRight }, + { &A::top, &A::setTop, &A::resetTop }, + { &A::verticalCenter, &A::setVerticalCenter, &A::resetVerticalCenter }, + { &A::bottom, &A::setBottom, &A::resetBottom } + }; + + return table[edge]; + } +} + +QskItemAnchors::QskItemAnchors() +{ +} + +QskItemAnchors::~QskItemAnchors() +{ +} + +QQuickItem* QskItemAnchors::item() const +{ + return m_anchors ? QQuickAnchorsPrivate::get( m_anchors )->item : nullptr; +} + +QMarginsF QskItemAnchors::margins() const +{ + if ( !isValid() ) + return QMarginsF(); + + return QMarginsF( m_anchors->leftMargin(), m_anchors->topMargin(), + m_anchors->rightMargin(), m_anchors->bottomMargin() ); +} + +void QskItemAnchors::setMargins( const QMarginsF& margins ) +{ + m_anchors->setLeftMargin( margins.left() ); + m_anchors->setRightMargin( margins.right() ); + m_anchors->setTopMargin( margins.top() ); + m_anchors->setBottomMargin( margins.bottom() ); +} + +void QskItemAnchors::addAnchor( QQuickItem* otherItem, + Qt::AnchorPoint otherEdge, Qt::AnchorPoint edge ) +{ + const auto& ops = operators( edge ); + ( m_anchors->*ops.setLine )( { otherItem, toQuickAnchor( otherEdge ) } ); +} + +void QskItemAnchors::removeAnchor( Qt::AnchorPoint edge ) +{ + const auto& ops = operators( edge ); + ( m_anchors->*ops.resetLine ) (); +} + +void QskItemAnchors::addAnchors( QQuickItem* otherItem, + Qt::Corner otherCorner, Qt::Corner corner ) +{ + auto anchorPoint = + []( Qt::Corner corner, Qt::Orientation orientation ) + { + if ( orientation == Qt::Horizontal ) + return ( corner & 0x1 ) ? Qt::AnchorRight : Qt::AnchorLeft; + else + return ( corner >= 0x2 ) ? Qt::AnchorBottom : Qt::AnchorTop; + }; + + addAnchor( otherItem, anchorPoint( otherCorner, Qt::Horizontal ), + anchorPoint( corner, Qt::Horizontal ) ); + + addAnchor( otherItem, anchorPoint( otherCorner, Qt::Vertical ), + anchorPoint( corner, Qt::Vertical ) ); +} + +void QskItemAnchors::addAnchors( QQuickItem* otherItem, Qt::Orientations orientations ) +{ + if ( orientations & Qt::Horizontal ) + { + addAnchor( otherItem, Qt::AnchorLeft, Qt::AnchorLeft ); + addAnchor( otherItem, Qt::AnchorRight, Qt::AnchorRight ); + } + + if ( orientations & Qt::Vertical ) + { + addAnchor( otherItem, Qt::AnchorTop, Qt::AnchorTop ); + addAnchor( otherItem, Qt::AnchorBottom, Qt::AnchorBottom ); + } +} + diff --git a/src/controls/QskItemAnchors.h b/src/controls/QskItemAnchors.h new file mode 100644 index 00000000..a1fb2e46 --- /dev/null +++ b/src/controls/QskItemAnchors.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * QSkinny - Copyright (C) The authors + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#ifndef QSK_ITEM_ANCHORS_H +#define QSK_ITEM_ANCHORS_H + +#include "QskGlobal.h" +#include +#include + +class QMarginsF; +class QQuickAnchors; +class QQuickItem; + +class QskItemAnchors +{ + public: + QskItemAnchors(); + ~QskItemAnchors(); + + QQuickItem* item() const; + + bool isValid() const; + + bool operator==( const QskItemAnchors& ) const noexcept; + bool operator!=( const QskItemAnchors& ) const noexcept; + + QMarginsF margins() const; + void setMargins( const QMarginsF& ); + + void addAnchor( QQuickItem*, Qt::AnchorPoint, Qt::AnchorPoint ); + void addAnchors( QQuickItem*, Qt::Corner, Qt::Corner ); + void addAnchors( QQuickItem*, Qt::Orientations = Qt::Horizontal | Qt::Vertical ); + + void removeAnchor( Qt::AnchorPoint ); + + private: + QPointer< QQuickAnchors > m_anchors; +}; + +inline bool QskItemAnchors::operator==( + const QskItemAnchors& other ) const noexcept +{ + return m_anchors.data() == other.m_anchors.data(); +} + +inline bool QskItemAnchors::operator!=( + const QskItemAnchors& other ) const noexcept +{ + return !( *this == other ); +} + +inline bool QskItemAnchors::isValid() const +{ + return !m_anchors.isNull(); +} + +#endif