QskControl::focusIndicatorClipRect added
This commit is contained in:
parent
b1c3c11984
commit
6ea56cdf30
|
@ -99,7 +99,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
auto layoutBox = new QskLinearBox( Qt::Vertical );
|
auto layoutBox = new QskLinearBox( Qt::Vertical );
|
||||||
layoutBox->setDefaultAlignment( Qt::AlignLeft );
|
layoutBox->setDefaultAlignment( Qt::AlignLeft );
|
||||||
layoutBox->setMargins( 5 );
|
layoutBox->setMargins( 20 );
|
||||||
layoutBox->setSpacing( 10 );
|
layoutBox->setSpacing( 10 );
|
||||||
layoutBox->addItem( buttonBox );
|
layoutBox->addItem( buttonBox );
|
||||||
layoutBox->addItem( tabView );
|
layoutBox->addItem( tabView );
|
||||||
|
|
|
@ -959,13 +959,9 @@ QRectF QskControl::focusIndicatorRect() const
|
||||||
return contentsRect();
|
return contentsRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskControl::hasFocusIndicatorClip() const
|
QRectF QskControl::focusIndicatorClipRect() const
|
||||||
{
|
{
|
||||||
/*
|
return clipRect();
|
||||||
Often we want to clip the focus indicator,
|
|
||||||
when the control is clipped.
|
|
||||||
*/
|
|
||||||
return clip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskControl::updateLayout()
|
void QskControl::updateLayout()
|
||||||
|
|
|
@ -93,7 +93,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
|
||||||
virtual QRectF gestureRect() const;
|
virtual QRectF gestureRect() const;
|
||||||
|
|
||||||
virtual QRectF focusIndicatorRect() const;
|
virtual QRectF focusIndicatorRect() const;
|
||||||
virtual bool hasFocusIndicatorClip() const;
|
virtual QRectF focusIndicatorClipRect() const;
|
||||||
|
|
||||||
QRectF subControlRect( QskAspect::Subcontrol ) const;
|
QRectF subControlRect( QskAspect::Subcontrol ) const;
|
||||||
QRectF subControlRect( const QSizeF&, QskAspect::Subcontrol ) const;
|
QRectF subControlRect( const QSizeF&, QskAspect::Subcontrol ) const;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "QskEvent.h"
|
#include "QskEvent.h"
|
||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
|
|
||||||
|
#include <qpointer.h>
|
||||||
#include <qquickwindow.h>
|
#include <qquickwindow.h>
|
||||||
|
|
||||||
QSK_SUBCONTROL( QskFocusIndicator, Panel )
|
QSK_SUBCONTROL( QskFocusIndicator, Panel )
|
||||||
|
@ -24,6 +25,21 @@ static inline QRectF qskFocusIndicatorRect( const QQuickItem* item )
|
||||||
return qskItemRect( item );
|
return qskItemRect( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline QRectF qskFocusIndicatorClipRect( const QQuickItem* item )
|
||||||
|
{
|
||||||
|
QRectF rect( 0.0, 0.0, -1.0, -1.0 );
|
||||||
|
|
||||||
|
if ( item )
|
||||||
|
{
|
||||||
|
if ( auto control = qskControlCast( item ) )
|
||||||
|
rect = control->focusIndicatorClipRect();
|
||||||
|
else
|
||||||
|
rect = item->clipRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
class QskFocusIndicator::PrivateData
|
class QskFocusIndicator::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -35,6 +51,7 @@ class QskFocusIndicator::PrivateData
|
||||||
connections.clear();
|
connections.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPointer< QQuickItem > clippingItem;
|
||||||
QVector< QMetaObject::Connection > connections;
|
QVector< QMetaObject::Connection > connections;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,6 +72,19 @@ bool QskFocusIndicator::contains( const QPointF& ) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRectF QskFocusIndicator::clipRect() const
|
||||||
|
{
|
||||||
|
if ( m_data->clippingItem )
|
||||||
|
{
|
||||||
|
auto rect = qskFocusIndicatorClipRect( m_data->clippingItem );
|
||||||
|
rect = mapRectFromItem( m_data->clippingItem, rect );
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::clipRect();
|
||||||
|
}
|
||||||
|
|
||||||
void QskFocusIndicator::onFocusItemGeometryChanged()
|
void QskFocusIndicator::onFocusItemGeometryChanged()
|
||||||
{
|
{
|
||||||
updateFocusFrame();
|
updateFocusFrame();
|
||||||
|
@ -78,64 +108,34 @@ void QskFocusIndicator::onFocusItemChanged()
|
||||||
if ( window() == nullptr )
|
if ( window() == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// We want to be on top, but do we cover all corner cases ???
|
||||||
|
setParentItem( window()->contentItem() );
|
||||||
|
setZ( 10e-6 );
|
||||||
|
|
||||||
const auto focusItem = window()->activeFocusItem();
|
const auto focusItem = window()->activeFocusItem();
|
||||||
|
QQuickItem* clippingItem = nullptr;
|
||||||
|
|
||||||
if ( ( focusItem == nullptr ) || ( focusItem == window()->contentItem() ) )
|
if ( focusItem && ( focusItem != window()->contentItem() ) )
|
||||||
{
|
{
|
||||||
/*
|
auto item = focusItem;
|
||||||
We might get here, when the previously focused item was destroyed.
|
|
||||||
Might happen in common situations, like when a subwindow
|
|
||||||
was closed. We put ourself below the root item then.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( parentItem() != window()->contentItem() )
|
|
||||||
setParentItem( window()->contentItem() );
|
|
||||||
|
|
||||||
updateFocusFrame();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_data->connections += connectItem( focusItem );
|
|
||||||
|
|
||||||
const QQuickItem* item = focusItem;
|
|
||||||
while ( item->parentItem() )
|
|
||||||
{
|
|
||||||
auto itemParent = item->parentItem();
|
|
||||||
|
|
||||||
bool doReparent = ( itemParent == window()->contentItem() );
|
|
||||||
|
|
||||||
if ( !doReparent )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
When the focus item is clipped - maybe because of being at the
|
|
||||||
border of a scrollarea - the focus indicator might need to be
|
|
||||||
clipped as well. The easiest way to have this is to put us
|
|
||||||
below the item having the clip.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( auto control = qskControlCast( itemParent ) )
|
|
||||||
doReparent = control->hasFocusIndicatorClip();
|
|
||||||
else
|
|
||||||
doReparent = itemParent->clip();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( doReparent )
|
|
||||||
setParentItem( itemParent );
|
|
||||||
|
|
||||||
if ( itemParent == parentItem() )
|
|
||||||
{
|
|
||||||
// We want to be on top, but do we cover all corner cases ???
|
|
||||||
|
|
||||||
setZ( item->z() + 10e-6 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
item = itemParent;
|
|
||||||
|
|
||||||
m_data->connections += connectItem( item );
|
m_data->connections += connectItem( item );
|
||||||
|
|
||||||
|
while ( auto itemParent = item->parentItem() )
|
||||||
|
{
|
||||||
|
m_data->connections += connectItem( itemParent );
|
||||||
|
|
||||||
|
if ( clippingItem == nullptr && itemParent->clip() )
|
||||||
|
{
|
||||||
|
const auto clipRect = qskFocusIndicatorClipRect( itemParent );
|
||||||
|
if ( !clipRect.isEmpty() )
|
||||||
|
clippingItem = itemParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = itemParent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_data->clippingItem = clippingItem;
|
||||||
updateFocusFrame();
|
updateFocusFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +148,9 @@ void QskFocusIndicator::updateFocusFrame()
|
||||||
{
|
{
|
||||||
r = r.marginsAdded( marginsHint( Panel | QskAspect::Padding ) );
|
r = r.marginsAdded( marginsHint( Panel | QskAspect::Padding ) );
|
||||||
setGeometry( r );
|
setGeometry( r );
|
||||||
|
|
||||||
|
const auto clipRect = qskFocusIndicatorClipRect( m_data->clippingItem );
|
||||||
|
setClip( !clipRect.isEmpty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -23,6 +23,7 @@ class QSK_EXPORT QskFocusIndicator : public QskControl
|
||||||
~QskFocusIndicator() override;
|
~QskFocusIndicator() override;
|
||||||
|
|
||||||
bool contains( const QPointF& ) const override;
|
bool contains( const QPointF& ) const override;
|
||||||
|
QRectF clipRect() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void windowChangeEvent( QskWindowChangeEvent* ) override;
|
void windowChangeEvent( QskWindowChangeEvent* ) override;
|
||||||
|
|
|
@ -124,11 +124,6 @@ class QskScrollAreaClipItem final : public QskControl, public QQuickItemChangeLi
|
||||||
return scrollArea()->subControlRect( QskScrollView::Viewport );
|
return scrollArea()->subControlRect( QskScrollView::Viewport );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasFocusIndicatorClip() const override
|
|
||||||
{
|
|
||||||
return scrollArea()->hasFocusIndicatorClip();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool event( QEvent* event ) override;
|
bool event( QEvent* event ) override;
|
||||||
|
|
||||||
|
@ -405,11 +400,6 @@ void QskScrollArea::adjustItem()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskScrollArea::hasFocusIndicatorClip() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskScrollArea::setItemResizable( bool on )
|
void QskScrollArea::setItemResizable( bool on )
|
||||||
{
|
{
|
||||||
if ( on != m_data->isItemResizable )
|
if ( on != m_data->isItemResizable )
|
||||||
|
|
|
@ -30,8 +30,6 @@ class QSK_EXPORT QskScrollArea : public QskScrollView
|
||||||
void setItemResizable( bool on );
|
void setItemResizable( bool on );
|
||||||
bool isItemResizable() const;
|
bool isItemResizable() const;
|
||||||
|
|
||||||
bool hasFocusIndicatorClip() const override;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void scrolledItemChanged();
|
void scrolledItemChanged();
|
||||||
void itemResizableChanged( bool );
|
void itemResizableChanged( bool );
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "QskAnimationHint.h"
|
#include "QskAnimationHint.h"
|
||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
|
|
||||||
|
#include <qquickwindow.h>
|
||||||
|
|
||||||
QSK_SUBCONTROL( QskTabBar, Panel )
|
QSK_SUBCONTROL( QskTabBar, Panel )
|
||||||
|
|
||||||
static inline Qt::Orientation qskOrientation( int position )
|
static inline Qt::Orientation qskOrientation( int position )
|
||||||
|
@ -71,11 +73,28 @@ namespace
|
||||||
enableAutoTranslation( true );
|
enableAutoTranslation( true );
|
||||||
|
|
||||||
setFocusPolicy( Qt::NoFocus );
|
setFocusPolicy( Qt::NoFocus );
|
||||||
|
|
||||||
|
connect( this, &ScrollBox::scrollPosChanged,
|
||||||
|
this, &QskControl::focusIndicatorRectChanged );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasFocusIndicatorClip() const override
|
QRectF focusIndicatorClipRect() const override
|
||||||
{
|
{
|
||||||
return false;
|
auto r = clipRect();
|
||||||
|
|
||||||
|
if ( window() )
|
||||||
|
{
|
||||||
|
if ( auto focusItem = window()->activeFocusItem() )
|
||||||
|
{
|
||||||
|
const auto itemRect = mapRectFromItem(
|
||||||
|
focusItem, focusItem->boundingRect() );
|
||||||
|
|
||||||
|
if ( r.intersects( itemRect ) )
|
||||||
|
return QRectF();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
QskAnimationHint flickHint() const override
|
QskAnimationHint flickHint() const override
|
||||||
|
|
Loading…
Reference in New Issue