Skip to content

Commit

Permalink
Merge pull request #5930 from opengisch/focusstack_object
Browse files Browse the repository at this point in the history
Generalize the focus stack to also handle popups
  • Loading branch information
nirvn authored Jan 4, 2025
2 parents 4be990c + aacbfe2 commit 4a9ab89
Show file tree
Hide file tree
Showing 22 changed files with 154 additions and 108 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
10 changes: 10 additions & 0 deletions src/qml/About.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import Theme
Item {
id: aboutPanel

visible: false
focus: visible

Rectangle {
color: "black"
opacity: 0.8
Expand Down Expand Up @@ -208,4 +211,11 @@ Item {
}
}
}

Keys.onReleased: event => {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
event.accepted = true;
visible = false;
}
}
}
8 changes: 8 additions & 0 deletions src/qml/BookmarkProperties.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Popup {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
padding: 0
focus: visible

onAboutToShow: {
nameField.text = bookmarkName;
Expand Down Expand Up @@ -193,4 +194,11 @@ Popup {
bookmarkProperties.close();
}
}

Keys.onReleased: event => {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
event.accepted = true;
visible = false;
}
}
}
1 change: 1 addition & 0 deletions src/qml/BrowserPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Popup {
padding: 0
modal: true
closePolicy: Popup.CloseOnEscape
focus: visible

Page {
id: browserContainer
Expand Down
2 changes: 1 addition & 1 deletion src/qml/Changelog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Popup {
height: parent.height - Theme.popupScreenEdgeMargin * 2
padding: 0
modal: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
closePolicy: Popup.CloseOnEscape
focus: visible

Page {
Expand Down
4 changes: 2 additions & 2 deletions 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 Expand Up @@ -374,7 +374,7 @@ Drawer {
id: temporalProperties
mapSettings: dashBoard.mapSettings
modal: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
closePolicy: Popup.CloseOnEscape
parent: mainWindow.contentItem
}
}
5 changes: 2 additions & 3 deletions src/qml/EmbeddedFeatureForm.qml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Popup {
signal featureCancelled

parent: mainWindow.contentItem
closePolicy: Popup.NoAutoClose // prevent accidental feature addition and editing
closePolicy: form.state === "ReadOnly" ? Popup.CloseOnEscape : Popup.NoAutoClose // prevent accidental feature addition and editing

x: Theme.popupScreenEdgeMargin / 2
y: Theme.popupScreenEdgeMargin
Expand All @@ -56,6 +56,7 @@ Popup {
width: parent.width - Theme.popupScreenEdgeMargin
height: parent.height - Theme.popupScreenEdgeMargin * 2
modal: true
focus: visible

FeatureForm {
id: form
Expand All @@ -73,8 +74,6 @@ Popup {
}
}

focus: true

embedded: true
toolbarVisible: true

Expand Down
3 changes: 3 additions & 0 deletions src/qml/LayerTreeItemProperties.qml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Popup {
x: (mainWindow.width - width) / 2
y: (mainWindow.height - height) / 2
padding: 0
modal: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
focus: visible

onClosed: {
index = undefined;
Expand Down
3 changes: 0 additions & 3 deletions src/qml/Legend.qml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ ListView {
function openProperties(index) {
itemProperties.index = legend.model.index(index, 0);
itemProperties.open();
itemProperties.forceActiveFocus();
}

delegate: Rectangle {
Expand Down Expand Up @@ -339,7 +338,5 @@ ListView {
LayerTreeItemProperties {
id: itemProperties
layerTree: legend.model
modal: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
}
}
7 changes: 7 additions & 0 deletions src/qml/LocatorItem.qml
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,11 @@ Item {
}
}
}

Keys.onReleased: event => {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
event.accepted = true;
state = "off";
}
}
}
11 changes: 11 additions & 0 deletions src/qml/LocatorSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Popup {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
padding: 0
modal: true
closePolicy: Popup.CloseOnEscape
parent: Overlay.overlay
focus: visible

Page {
id: page
Expand Down Expand Up @@ -103,4 +107,11 @@ Popup {
}
}
}

Keys.onReleased: event => {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
event.accepted = true;
visible = false;
}
}
}
10 changes: 10 additions & 0 deletions src/qml/MessageLog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Page {

signal finished

visible: false
focus: visible

header: QfPageHeader {
title: qsTr('Message Logs')

Expand Down Expand Up @@ -218,4 +221,11 @@ Page {
if (visible)
unreadMessages = false;
}

Keys.onReleased: event => {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
event.accepted = true;
visible = false;
}
}
}
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
11 changes: 11 additions & 0 deletions src/qml/PluginManagerSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ Popup {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
padding: 0
modal: true
closePolicy: Popup.CloseOnEscape
parent: Overlay.overlay
focus: visible

Page {
id: page
Expand Down Expand Up @@ -399,6 +403,13 @@ Popup {
}
}

Keys.onReleased: event => {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
event.accepted = true;
visible = false;
}
}

Component.onCompleted: {
refreshAppPluginsList();
}
Expand Down
1 change: 1 addition & 0 deletions src/qml/PositioningDeviceSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Popup {
x: Theme.popupScreenEdgeMargin
y: Theme.popupScreenEdgeMargin
padding: 0
focus: visible

property alias name: positioningDeviceName.text
property alias type: positioningDeviceType.currentValue
Expand Down
6 changes: 2 additions & 4 deletions src/qml/QFieldLocalDataPickerScreen.qml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Page {

signal finished(var loading)

focus: visible

header: QfPageHeader {
title: projectFolderView ? qsTr("Project Folder") : qsTr("Local Projects & Datasets")

Expand Down Expand Up @@ -705,8 +707,4 @@ Page {
}
}
}

onVisibleChanged: {
focus = visible;
}
}
Loading

1 comment on commit 4a9ab89

@qfield-fairy
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.