Qt::FocusPolicy added. Hope this implementation does not break common
standards for mouse/wheel handling like being done in QC2
This commit is contained in:
parent
68125cfc7e
commit
2c0733182a
@ -50,7 +50,7 @@ LineEdit::LineEdit( QQuickItem* parent ):
|
||||
Q_D( LineEdit );
|
||||
d->init();
|
||||
|
||||
setActiveFocusOnTab( true );
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
#if 1
|
||||
auto skinlet = new LineEditSkinlet();
|
||||
skinlet->setOwnedBySkinnable( true );
|
||||
|
@ -56,9 +56,9 @@ QskAbstractButton::QskAbstractButton( QQuickItem* parent ):
|
||||
Inherited( parent ),
|
||||
m_data( new PrivateData() )
|
||||
{
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
setAcceptedMouseButtons( Qt::LeftButton );
|
||||
setAcceptHoverEvents( true );
|
||||
setActiveFocusOnTab( true );
|
||||
}
|
||||
|
||||
QskAbstractButton::~QskAbstractButton()
|
||||
@ -302,21 +302,15 @@ void QskAbstractButton::mouseMoveEvent( QMouseEvent* event )
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void QskAbstractButton::mousePressEvent( QMouseEvent* event )
|
||||
void QskAbstractButton::mousePressEvent( QMouseEvent* )
|
||||
{
|
||||
// QPlatformTheme::GroupBoxTitleFont
|
||||
// isSignalConnected( pressAndHold, ());
|
||||
// QGuiApplication::styleHints()->mousePressAndHoldInterval()
|
||||
// QGuiApplication::styleHints()->mousePressAndHoldInterval() ???
|
||||
setPressed( true );
|
||||
forceActiveFocus( Qt::MouseFocusReason );
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void QskAbstractButton::mouseReleaseEvent( QMouseEvent* event )
|
||||
void QskAbstractButton::mouseReleaseEvent( QMouseEvent* )
|
||||
{
|
||||
releaseButton();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void QskAbstractButton::mouseUngrabEvent()
|
||||
|
@ -175,7 +175,9 @@ QskControl::QskControl( QQuickItemPrivate& dd, QQuickItem* parent ):
|
||||
m_blockedPolish( false ),
|
||||
m_blockedImplicitSize( true ),
|
||||
m_clearPreviousNodes( false ),
|
||||
m_isInitiallyPainted( false )
|
||||
m_isInitiallyPainted( false ),
|
||||
m_focusPolicy( Qt::NoFocus ),
|
||||
m_isWheelEnabled( false )
|
||||
{
|
||||
Q_D( QskControl );
|
||||
|
||||
@ -198,7 +200,7 @@ QskControl::QskControl( QQuickItemPrivate& dd, QQuickItem* parent ):
|
||||
}
|
||||
|
||||
setFlag( QQuickItem::ItemHasContents, true );
|
||||
setActiveFocusOnTab( false );
|
||||
QQuickItem::setActiveFocusOnTab( false );
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
@ -368,6 +370,44 @@ bool QskControl::polishOnResize() const
|
||||
return m_polishOnResize;
|
||||
}
|
||||
|
||||
void QskControl::setWheelEnabled( bool on )
|
||||
{
|
||||
if ( on != m_isWheelEnabled )
|
||||
{
|
||||
m_isWheelEnabled = on;
|
||||
// Q_EMIT wheelEnabledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool QskControl::isWheelEnabled() const
|
||||
{
|
||||
return m_isWheelEnabled;
|
||||
}
|
||||
|
||||
void QskControl::setFocusPolicy( Qt::FocusPolicy policy )
|
||||
{
|
||||
if ( policy != m_focusPolicy )
|
||||
{
|
||||
m_focusPolicy = policy & ~Qt::TabFocus;
|
||||
QQuickItem::setActiveFocusOnTab( policy & Qt::TabFocus );
|
||||
|
||||
#if 0
|
||||
// we have to get rid of the hack used in playground/inputpanel
|
||||
// so that we can add additional signals !!!
|
||||
Q_EMIT ( focusPolicyChanged() );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Qt::FocusPolicy QskControl::focusPolicy() const
|
||||
{
|
||||
uint policy = m_focusPolicy;
|
||||
if ( activeFocusOnTab() )
|
||||
policy |= Qt::TabFocus;
|
||||
|
||||
return static_cast< Qt::FocusPolicy >( policy );
|
||||
}
|
||||
|
||||
void QskControl::setTabFence( bool on )
|
||||
{
|
||||
Q_D( QskControl );
|
||||
@ -1068,7 +1108,6 @@ void QskControl::itemChange( QQuickItem::ItemChange change,
|
||||
}
|
||||
case QQuickItem::ItemActiveFocusHasChanged:
|
||||
{
|
||||
// creating focus events ???
|
||||
setSkinStateFlag( Focused, hasActiveFocus() );
|
||||
break;
|
||||
}
|
||||
|
@ -44,6 +44,17 @@ class QSK_EXPORT QskControl : public QQuickItem, public QskResizable, public Qsk
|
||||
Q_PROPERTY( bool transparentForPositioners READ isTransparentForPositioner
|
||||
WRITE setTransparentForPositioner NOTIFY controlFlagsChanged FINAL )
|
||||
|
||||
#if 0
|
||||
Q_PROPERTY( Qt::FocusPolicy focusPolicy READ focusPolicy
|
||||
WRITE setFocusPolicy NOTIFY focusPolicyChanged FINAL )
|
||||
|
||||
Q_PROPERTY( bool wheelEnabled READ isWheelEnabled
|
||||
WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL )
|
||||
#else
|
||||
Q_PROPERTY( Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy FINAL )
|
||||
Q_PROPERTY( bool wheelEnabled READ isWheelEnabled WRITE setWheelEnabled FINAL )
|
||||
#endif
|
||||
|
||||
Q_PROPERTY( bool tabFence READ isTabFence
|
||||
WRITE setTabFence NOTIFY controlFlagsChanged FINAL )
|
||||
|
||||
@ -56,11 +67,6 @@ class QSK_EXPORT QskControl : public QQuickItem, public QskResizable, public Qsk
|
||||
Q_PROPERTY( QSizeF maximumSize READ maximumSize WRITE setMaximumSize )
|
||||
Q_PROPERTY( QSizeF preferredSize READ preferredSize WRITE setPreferredSize )
|
||||
|
||||
#if 0
|
||||
Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy
|
||||
WRITE setFocusPolicy NOTIFY focusPolicyChanged FINAL)
|
||||
#endif
|
||||
|
||||
using Inherited = QQuickItem;
|
||||
|
||||
public:
|
||||
@ -122,6 +128,12 @@ public:
|
||||
static const QSGNode* itemNode( const QQuickItem* );
|
||||
static const QSGNode* paintNode( const QQuickItem* );
|
||||
|
||||
void setWheelEnabled( bool );
|
||||
bool isWheelEnabled() const;
|
||||
|
||||
void setFocusPolicy( Qt::FocusPolicy );
|
||||
Qt::FocusPolicy focusPolicy() const;
|
||||
|
||||
void setTabFence( bool );
|
||||
bool isTabFence() const;
|
||||
|
||||
@ -203,6 +215,8 @@ private Q_SLOTS:
|
||||
void updateControlFlags();
|
||||
|
||||
private:
|
||||
void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy instead
|
||||
|
||||
virtual QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override final;
|
||||
virtual void updatePolish() override final;
|
||||
|
||||
@ -237,6 +251,9 @@ private:
|
||||
|
||||
bool m_isInitiallyPainted : 1;
|
||||
|
||||
uint m_focusPolicy : 4;
|
||||
bool m_isWheelEnabled;
|
||||
|
||||
Q_DECLARE_PRIVATE( QskControl )
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,6 @@ QskListView::QskListView( QQuickItem* parent ):
|
||||
QskScrollView( parent ),
|
||||
m_data( new PrivateData() )
|
||||
{
|
||||
setAcceptedMouseButtons( Qt::LeftButton );
|
||||
}
|
||||
|
||||
QskListView::~QskListView()
|
||||
@ -248,8 +247,6 @@ void QskListView::keyReleaseEvent( QKeyEvent* event )
|
||||
|
||||
void QskListView::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
forceActiveFocus( Qt::MouseFocusReason );
|
||||
|
||||
if ( m_data->selectionMode != NoSelection )
|
||||
{
|
||||
const QRectF vr = viewContentsRect();
|
||||
@ -258,12 +255,8 @@ void QskListView::mousePressEvent( QMouseEvent* event )
|
||||
const int row = ( event->pos().y() - vr.top() + scrollPos().y() ) / rowHeight();
|
||||
if ( row >= 0 && row < rowCount() )
|
||||
setSelectedRow( row );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Inherited::mousePressEvent( event );
|
||||
}
|
||||
|
||||
void QskListView::mouseReleaseEvent( QMouseEvent* event )
|
||||
|
@ -34,8 +34,8 @@ QskRangeControl::QskRangeControl( QQuickItem* parent ):
|
||||
QskControl( parent ),
|
||||
m_data( new PrivateData() )
|
||||
{
|
||||
setActiveFocusOnTab( !m_data->readOnly );
|
||||
setAcceptedMouseButtons( Qt::LeftButton );
|
||||
setWheelEnabled( true );
|
||||
}
|
||||
|
||||
QskRangeControl::~QskRangeControl()
|
||||
@ -219,7 +219,9 @@ void QskRangeControl::setReadOnly( bool readOnly )
|
||||
if ( m_data->readOnly == readOnly )
|
||||
return;
|
||||
|
||||
setActiveFocusOnTab( !readOnly );
|
||||
// we are killing user settings here !!
|
||||
setFocusPolicy( m_data->readOnly ? Qt::NoFocus : Qt::StrongFocus );
|
||||
setWheelEnabled( m_data->readOnly );
|
||||
|
||||
m_data->readOnly = readOnly;
|
||||
Q_EMIT readOnlyChanged( readOnly );
|
||||
@ -274,18 +276,12 @@ void QskRangeControl::keyPressEvent( QKeyEvent* event )
|
||||
|
||||
void QskRangeControl::wheelEvent( QWheelEvent* event )
|
||||
{
|
||||
if ( isReadOnly() )
|
||||
{
|
||||
return Inherited::wheelEvent( event );
|
||||
}
|
||||
|
||||
const int steps = event->delta() / 120;
|
||||
setValue( m_data->value + steps * m_data->stepSize );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void QskRangeControl::componentComplete()
|
||||
{
|
||||
Inherited::componentComplete();
|
||||
|
@ -85,7 +85,8 @@ QskScrollView::QskScrollView( QQuickItem* parent ):
|
||||
m_data->panRecognizer.setTimeout( 200 );
|
||||
|
||||
setAcceptedMouseButtons( Qt::LeftButton );
|
||||
setActiveFocusOnTab( true );
|
||||
setWheelEnabled( true );
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
}
|
||||
|
||||
QskScrollView::~QskScrollView()
|
||||
@ -256,11 +257,7 @@ void QskScrollView::mousePressEvent( QMouseEvent* event )
|
||||
|
||||
setScrollPos( QPointF( x, m_data->scrollPos.y() ) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Inherited::mousePressEvent( event );
|
||||
}
|
||||
|
||||
void QskScrollView::mouseMoveEvent( QMouseEvent* event )
|
||||
@ -294,7 +291,7 @@ void QskScrollView::mouseMoveEvent( QMouseEvent* event )
|
||||
setScrollPos( pos );
|
||||
}
|
||||
|
||||
void QskScrollView::mouseReleaseEvent( QMouseEvent* event )
|
||||
void QskScrollView::mouseReleaseEvent( QMouseEvent* )
|
||||
{
|
||||
if ( m_data->isScrolling )
|
||||
{
|
||||
@ -303,11 +300,7 @@ void QskScrollView::mouseReleaseEvent( QMouseEvent* event )
|
||||
|
||||
setSkinStateFlag( HorizontalHandlePressed, false );
|
||||
setSkinStateFlag( VerticalHandlePressed, false );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Inherited::mouseReleaseEvent( event );
|
||||
}
|
||||
|
||||
void QskScrollView::gestureEvent( QskGestureEvent* event )
|
||||
@ -347,11 +340,6 @@ void QskScrollView::gestureEvent( QskGestureEvent* event )
|
||||
|
||||
void QskScrollView::wheelEvent( QWheelEvent* event )
|
||||
{
|
||||
if ( !isEnabled() )
|
||||
{
|
||||
return Inherited::wheelEvent( event );
|
||||
}
|
||||
|
||||
const qreal dy = event->delta() / 120 * 20.0;
|
||||
setScrollPos( m_data->scrollPos - QPointF( 0.0, dy ) );
|
||||
}
|
||||
|
@ -12,7 +12,9 @@
|
||||
#include "QskWindow.h"
|
||||
#include "QskObjectTree.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QGuiApplication>
|
||||
#include <QStyleHints>
|
||||
|
||||
#include <QPointer>
|
||||
#include <QDebug>
|
||||
|
||||
@ -66,7 +68,13 @@ static void qskApplicationHook()
|
||||
qAddPostRoutine( QskSetup::cleanup );
|
||||
}
|
||||
|
||||
static void qskApplicationFilter()
|
||||
{
|
||||
QCoreApplication::instance()->installEventFilter( QskSetup::instance() );
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskApplicationHook )
|
||||
Q_COREAPP_STARTUP_FUNCTION( qskApplicationFilter )
|
||||
|
||||
extern bool qskInheritLocale( QskControl*, const QLocale& );
|
||||
extern bool qskInheritLocale( QskWindow*, const QLocale& );
|
||||
@ -260,7 +268,7 @@ QskSkin* QskSetup::skin()
|
||||
void QskSetup::addGraphicProvider( const QString& providerId, QskGraphicProvider* provider )
|
||||
{
|
||||
m_data->graphicProviders.insert( providerId, provider );
|
||||
}
|
||||
}
|
||||
|
||||
QskGraphicProvider* QskSetup::graphicProvider( const QString& providerId ) const
|
||||
{
|
||||
@ -272,7 +280,7 @@ QskGraphicProvider* QskSetup::graphicProvider( const QString& providerId ) const
|
||||
}
|
||||
|
||||
return m_data->graphicProviders.provider( providerId );
|
||||
}
|
||||
}
|
||||
|
||||
void QskSetup::setInputPanel( QskInputPanel* inputPanel )
|
||||
{
|
||||
@ -306,6 +314,75 @@ void QskSetup::inheritLocale( QObject* object, const QLocale& locale )
|
||||
QskObjectTree::traverseDown( object, visitor );
|
||||
}
|
||||
|
||||
bool QskSetup::eventFilter( QObject* object, QEvent* event )
|
||||
{
|
||||
if ( auto control = qobject_cast< QskControl* >( object ) )
|
||||
{
|
||||
/*
|
||||
Qt::FocusPolicy has always been there with widgets, got lost with
|
||||
Qt/Quick and has been reintroduced with Qt/Quick Controls 2 ( QC2 ).
|
||||
Unfortunately this was done once more by adding code on top instead
|
||||
of fixing the foundation.
|
||||
|
||||
But we also don't want to have how it is done in QC2 by adding
|
||||
the focus management in the event handler of the base class.
|
||||
This implementatio reverts the expected default behaviour of when
|
||||
events are accepted/ignored + is an error prone nightmare, when it
|
||||
comes to overloading event handlers missing to call the base class.
|
||||
|
||||
That's why we prefer to do the focus management outside of the
|
||||
event handlers.
|
||||
*/
|
||||
switch( event->type() )
|
||||
{
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
if ( ( control->focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
|
||||
{
|
||||
const bool focusOnRelease =
|
||||
QGuiApplication::styleHints()->setFocusOnTouchRelease();
|
||||
|
||||
if ( focusOnRelease )
|
||||
{
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
control->forceActiveFocus( Qt::MouseFocusReason );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( event->type() == QEvent::MouseButtonPress )
|
||||
control->forceActiveFocus( Qt::MouseFocusReason );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::Wheel:
|
||||
{
|
||||
if ( !control->isWheelEnabled() )
|
||||
{
|
||||
/*
|
||||
We block further processing of the event. This is in line
|
||||
with not receiving any mouse event that have not been
|
||||
explicitly enabled with setAcceptedMouseButtons().
|
||||
|
||||
*/
|
||||
event->ignore();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ( control->focusPolicy() & Qt::WheelFocus ) == Qt::WheelFocus )
|
||||
control->forceActiveFocus( Qt::MouseFocusReason );
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QskSetup* QskSetup::qmlAttachedProperties( QObject* )
|
||||
{
|
||||
return QskSetup::instance();
|
||||
|
@ -84,6 +84,8 @@ private:
|
||||
QskSetup();
|
||||
virtual ~QskSetup();
|
||||
|
||||
virtual bool eventFilter( QObject*, QEvent* ) override final;
|
||||
|
||||
static QskSetup* s_instance;
|
||||
|
||||
class PrivateData;
|
||||
|
@ -45,7 +45,7 @@ QskSlider::QskSlider( Qt::Orientation orientation, QQuickItem* parent ):
|
||||
m_data( new PrivateData( orientation ) )
|
||||
{
|
||||
setAcceptHoverEvents( true );
|
||||
setActiveFocusOnTab( true );
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
if ( orientation == Qt::Horizontal )
|
||||
initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Fixed );
|
||||
@ -130,27 +130,26 @@ QRectF QskSlider::handleRect() const
|
||||
|
||||
void QskSlider::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
// Case 1: press started in the handle, start sliding
|
||||
|
||||
if ( handleRect().contains( event->pos() ) )
|
||||
{
|
||||
// Case 1: press started in the handle, start sliding
|
||||
|
||||
m_data->pressedPos = event->pos();
|
||||
m_data->pressedValue = value();
|
||||
setSkinStateFlag( Pressed );
|
||||
Q_EMIT pressedChanged( true );
|
||||
return;
|
||||
}
|
||||
|
||||
// Case 2: pageSize is not used, we're done here
|
||||
if ( !pageSize() )
|
||||
else if ( !pageSize() )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
// Case 2: pageSize is not used, we're done here
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 3: pressed outside of the handle, page the scroller in
|
||||
// the direction of the press requires an auto-repeat behavior
|
||||
// until the slider reaches the destination, or it simply jumps
|
||||
// there (configurable)
|
||||
}
|
||||
|
||||
// Case 3: pressed outside of the handle, page the scroller in the direction of the press
|
||||
// requires an auto-repeat behavior until the slider reaches the destination, or it simply jumps there (configurable)
|
||||
|
||||
}
|
||||
|
||||
void QskSlider::mouseMoveEvent( QMouseEvent* event )
|
||||
|
Loading…
x
Reference in New Issue
Block a user