Skip to content

Commit

Permalink
Generalize the focus stack to also handle popups
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed Jan 2, 2025
1 parent 4be990c commit 776f950
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 31 deletions.
62 changes: 49 additions & 13 deletions src/core/focusstack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,73 @@
***************************************************************************/
#include "focusstack.h"

void FocusStack::addFocusTaker( QQuickItem *item )
void FocusStack::addFocusTaker( QObject *object )
{
connect( item, &QQuickItem::activeFocusChanged, this, &FocusStack::itemFocusChanged );
QVariant visible = object->property( "visible" );
QVariant opened = object->property( "opened" );
if ( opened.isValid() )
{
connect( object, SIGNAL( opened() ), this, SLOT( popupOpened() ) );
connect( object, SIGNAL( closed() ), this, SLOT( popupClosed() ) );
}
else if ( visible.isValid() )
{
connect( object, SIGNAL( activeFocusChanged( bool ) ), this, SLOT( itemFocusChanged( bool ) ) );
}
}

void FocusStack::popupOpened()
{
setFocused( sender() );
}

void FocusStack::popupClosed()
{
setUnfocused( sender() );
}

void FocusStack::itemFocusChanged( bool itemActiveFocus )
{
if ( itemActiveFocus )
{
setFocused( qobject_cast<QQuickItem *>( sender() ) );
setFocused( sender() );
}
else
{
setUnfocused( qobject_cast<QQuickItem *>( sender() ) );
setUnfocused( sender() );
}
}

void FocusStack::setFocused( QQuickItem *item )
void FocusStack::setFocused( QObject *object )
{
mStackList.removeAll( item );
mStackList.append( item );
mStackList.removeAll( object );
mStackList.append( object );
}

void FocusStack::setUnfocused( QQuickItem *item )
void FocusStack::setUnfocused( QObject *object )
{
if ( !item->isVisible() )
QVariant visible = object->property( "visible" );
QVariant opened = object->property( "opened" );
if ( opened.isValid() )
{
if ( !opened.toBool() )
{
mStackList.removeAll( object );
if ( !mStackList.isEmpty() )
{
QMetaObject::invokeMethod( mStackList.last(), "forceActiveFocus", Qt::DirectConnection );
}
}
}
else if ( visible.isValid() )
{
mStackList.removeAll( item );
if ( !mStackList.isEmpty() )
if ( !visible.toBool() )
{
mStackList.last()->forceActiveFocus();
mStackList.removeAll( object );
if ( !mStackList.isEmpty() )
{
QMetaObject::invokeMethod( mStackList.last(), "forceActiveFocus", Qt::DirectConnection );
}
}
}
}
Expand All @@ -55,5 +91,5 @@ void FocusStack::forceActiveFocusOnLastTaker() const
if ( mStackList.isEmpty() )
return;

mStackList.last()->forceActiveFocus();
QMetaObject::invokeMethod( mStackList.last(), "forceActiveFocus", Qt::DirectConnection );
}
10 changes: 6 additions & 4 deletions src/core/focusstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,18 @@ class FocusStack : public QObject
Q_OBJECT

public:
Q_INVOKABLE void addFocusTaker( QQuickItem *item );
Q_INVOKABLE void addFocusTaker( QObject *object );
Q_INVOKABLE void forceActiveFocusOnLastTaker() const;

private slots:
void itemFocusChanged( bool itemActiveFocus );
void popupOpened();
void popupClosed();

private:
QList<QQuickItem *> mStackList;
void setFocused( QQuickItem *item );
void setUnfocused( QQuickItem *item );
QList<QObject *> mStackList;
void setFocused( QObject *object );
void setUnfocused( QObject *object );
};

#endif // FOCUSSTACK_H
2 changes: 1 addition & 1 deletion src/qml/DashBoard.qml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Drawer {
property bool preventFromOpening: overlayFeatureFormDrawer.visible

position: 0
focus: opened
focus: visible
clip: true

onShowMenu: mainMenu.popup(settingsButton.x + 2, mainWindow.sceneTopMargin + settingsButton.y + 2)
Expand Down
7 changes: 1 addition & 6 deletions src/qml/OverlayFeatureFormDrawer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Drawer {

edge: parent.width < parent.height ? Qt.BottomEdge : Qt.RightEdge
closePolicy: Popup.NoAutoClose // prevent accidental feature addition when clicking outside of the popup drawer
focus: visible

width: {
if (qfieldSettings.fullScreenIdentifyView || parent.width < parent.height || parent.width < 300) {
Expand Down Expand Up @@ -93,8 +94,6 @@ Drawer {

state: "Add"

focus: overlayFeatureFormDrawer.opened

onConfirmed: {
displayToast(qsTr("Changes saved"));
//close drawer if still open
Expand Down Expand Up @@ -132,10 +131,6 @@ Drawer {
event.accepted = true;
}
}

Component.onCompleted: {
focusstack.addFocusTaker(this);
}
}

Component.onCompleted: {
Expand Down
10 changes: 3 additions & 7 deletions src/qml/qgismobileapp.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2318,13 +2318,7 @@ ApplicationWindow {
mapSettings: mapCanvas.mapSettings
interactive: !welcomeScreen.visible && !qfieldSettings.visible && !qfieldCloudScreen.visible && !qfieldLocalDataPickerScreen.visible && !codeReader.visible && !screenLocker.enabled

onAboutToShow: {
dashBoard.contentItem.forceActiveFocus();
}

onClosed: {
focusstack.forceActiveFocusOnLastTaker();
}
Component.onCompleted: focusstack.addFocusTaker(this)

function ensureEditableLayerSelected() {
var firstEditableLayer = null;
Expand Down Expand Up @@ -3516,6 +3510,8 @@ ApplicationWindow {
digitizingToolbar: digitizingToolbar
codeReader: codeReader
featureModel.currentLayer: dashBoard.activeLayer

Component.onCompleted: focusstack.addFocusTaker(this)
}

function displayToast(message, type, action_text, action_function) {
Expand Down

0 comments on commit 776f950

Please sign in to comment.