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 );
|
||||
layoutBox->setDefaultAlignment( Qt::AlignLeft );
|
||||
layoutBox->setMargins( 5 );
|
||||
layoutBox->setMargins( 20 );
|
||||
layoutBox->setSpacing( 10 );
|
||||
layoutBox->addItem( buttonBox );
|
||||
layoutBox->addItem( tabView );
|
||||
|
|
|
@ -959,13 +959,9 @@ QRectF QskControl::focusIndicatorRect() const
|
|||
return contentsRect();
|
||||
}
|
||||
|
||||
bool QskControl::hasFocusIndicatorClip() const
|
||||
QRectF QskControl::focusIndicatorClipRect() const
|
||||
{
|
||||
/*
|
||||
Often we want to clip the focus indicator,
|
||||
when the control is clipped.
|
||||
*/
|
||||
return clip();
|
||||
return clipRect();
|
||||
}
|
||||
|
||||
void QskControl::updateLayout()
|
||||
|
|
|
@ -93,7 +93,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
|
|||
virtual QRectF gestureRect() const;
|
||||
|
||||
virtual QRectF focusIndicatorRect() const;
|
||||
virtual bool hasFocusIndicatorClip() const;
|
||||
virtual QRectF focusIndicatorClipRect() const;
|
||||
|
||||
QRectF subControlRect( QskAspect::Subcontrol ) const;
|
||||
QRectF subControlRect( const QSizeF&, QskAspect::Subcontrol ) const;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "QskEvent.h"
|
||||
#include "QskQuick.h"
|
||||
|
||||
#include <qpointer.h>
|
||||
#include <qquickwindow.h>
|
||||
|
||||
QSK_SUBCONTROL( QskFocusIndicator, Panel )
|
||||
|
@ -24,6 +25,21 @@ static inline QRectF qskFocusIndicatorRect( const QQuickItem* 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
|
||||
{
|
||||
public:
|
||||
|
@ -35,6 +51,7 @@ class QskFocusIndicator::PrivateData
|
|||
connections.clear();
|
||||
}
|
||||
|
||||
QPointer< QQuickItem > clippingItem;
|
||||
QVector< QMetaObject::Connection > connections;
|
||||
};
|
||||
|
||||
|
@ -55,6 +72,19 @@ bool QskFocusIndicator::contains( const QPointF& ) const
|
|||
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()
|
||||
{
|
||||
updateFocusFrame();
|
||||
|
@ -78,64 +108,34 @@ void QskFocusIndicator::onFocusItemChanged()
|
|||
if ( window() == nullptr )
|
||||
return;
|
||||
|
||||
const auto focusItem = window()->activeFocusItem();
|
||||
|
||||
if ( ( focusItem == nullptr ) || ( focusItem == window()->contentItem() ) )
|
||||
{
|
||||
/*
|
||||
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 ???
|
||||
setParentItem( window()->contentItem() );
|
||||
setZ( 10e-6 );
|
||||
|
||||
setZ( item->z() + 10e-6 );
|
||||
break;
|
||||
const auto focusItem = window()->activeFocusItem();
|
||||
QQuickItem* clippingItem = nullptr;
|
||||
|
||||
if ( focusItem && ( focusItem != window()->contentItem() ) )
|
||||
{
|
||||
auto item = focusItem;
|
||||
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->connections += connectItem( item );
|
||||
}
|
||||
}
|
||||
|
||||
m_data->clippingItem = clippingItem;
|
||||
updateFocusFrame();
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,9 @@ void QskFocusIndicator::updateFocusFrame()
|
|||
{
|
||||
r = r.marginsAdded( marginsHint( Panel | QskAspect::Padding ) );
|
||||
setGeometry( r );
|
||||
|
||||
const auto clipRect = qskFocusIndicatorClipRect( m_data->clippingItem );
|
||||
setClip( !clipRect.isEmpty() );
|
||||
}
|
||||
|
||||
update();
|
||||
|
|
|
@ -23,6 +23,7 @@ class QSK_EXPORT QskFocusIndicator : public QskControl
|
|||
~QskFocusIndicator() override;
|
||||
|
||||
bool contains( const QPointF& ) const override;
|
||||
QRectF clipRect() const override;
|
||||
|
||||
protected:
|
||||
void windowChangeEvent( QskWindowChangeEvent* ) override;
|
||||
|
|
|
@ -124,11 +124,6 @@ class QskScrollAreaClipItem final : public QskControl, public QQuickItemChangeLi
|
|||
return scrollArea()->subControlRect( QskScrollView::Viewport );
|
||||
}
|
||||
|
||||
bool hasFocusIndicatorClip() const override
|
||||
{
|
||||
return scrollArea()->hasFocusIndicatorClip();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool event( QEvent* event ) override;
|
||||
|
||||
|
@ -405,11 +400,6 @@ void QskScrollArea::adjustItem()
|
|||
}
|
||||
}
|
||||
|
||||
bool QskScrollArea::hasFocusIndicatorClip() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void QskScrollArea::setItemResizable( bool on )
|
||||
{
|
||||
if ( on != m_data->isItemResizable )
|
||||
|
|
|
@ -30,8 +30,6 @@ class QSK_EXPORT QskScrollArea : public QskScrollView
|
|||
void setItemResizable( bool on );
|
||||
bool isItemResizable() const;
|
||||
|
||||
bool hasFocusIndicatorClip() const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void scrolledItemChanged();
|
||||
void itemResizableChanged( bool );
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "QskAnimationHint.h"
|
||||
#include "QskQuick.h"
|
||||
|
||||
#include <qquickwindow.h>
|
||||
|
||||
QSK_SUBCONTROL( QskTabBar, Panel )
|
||||
|
||||
static inline Qt::Orientation qskOrientation( int position )
|
||||
|
@ -71,11 +73,28 @@ namespace
|
|||
enableAutoTranslation( true );
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue