diff options
author | Balazs Egedi <egedib@inf.u-szeged.hu> | 2021-08-17 12:59:28 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-09-13 12:05:52 +0000 |
commit | 1eb92daca5b3dbbcdd54a561f5f32c435a4f551f (patch) | |
tree | d7f697a4330a60b965f1f7f43aa5e0d7d07fc353 /examples/webenginequick/lifecycle | |
parent | edd6de237f2f66dc04eebb10782928f9a5b6fb40 (diff) |
Rename Quick examples' folder from webengine to webenginequick
Fix webengine directory path in project files and comments
Change-Id: I06ed9ee41111e7135fa9feb152ad2a5eb2262b76
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit a32ef7057c01fbcadcf451e7f2b785f7b3dd3942)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'examples/webenginequick/lifecycle')
15 files changed, 1055 insertions, 0 deletions
diff --git a/examples/webenginequick/lifecycle/CMakeLists.txt b/examples/webenginequick/lifecycle/CMakeLists.txt new file mode 100644 index 000000000..2d7b3e26b --- /dev/null +++ b/examples/webenginequick/lifecycle/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.16) +project(lifecycle LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/lifecycle") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS QuickControls2) +find_package(Qt6 COMPONENTS WebEngineQuick) + +qt_add_executable(lifecycle + main.cpp +) +set_target_properties(lifecycle PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(lifecycle PUBLIC + Qt::Core + Qt::Gui + Qt::WebEngineQuick +) + + +# Resources: +set(resources_resource_files + "WebBrowser.qml" + "WebTab.qml" + "WebTabBar.qml" + "WebTabButton.qml" + "WebTabStack.qml" + "WebToolButton.qml" + "qtquickcontrols2.conf" +) + +qt6_add_resources(lifecycle "resources" + PREFIX + "/" + FILES + ${resources_resource_files} +) + +install(TARGETS lifecycle + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/webenginequick/lifecycle/WebBrowser.qml b/examples/webenginequick/lifecycle/WebBrowser.qml new file mode 100644 index 000000000..e29ac4f90 --- /dev/null +++ b/examples/webenginequick/lifecycle/WebBrowser.qml @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtQuick.Window + +ApplicationWindow { + id: root + + readonly property Action newTabAction: Action { + text: qsTr("New tab") + shortcut: StandardKey.AddTab + onTriggered: root.createNewTab({url: "about:blank"}) + } + + visible: true + width: Screen.width * 0.5 + height: Screen.height * 0.5 + title: tabStack.currentTab ? tabStack.currentTab.title : "" + + header: WebTabBar { + id: tabBar + + z: 1 + + newTabAction: root.newTabAction + } + + WebTabStack { + id: tabStack + + z: 0 + anchors.fill: parent + + currentIndex: tabBar.currentIndex + freezeDelay: freezeSpin.enabled && freezeSpin.value + discardDelay: discardSpin.enabled && discardSpin.value + + onCloseRequested: function(index) { + root.closeTab(index) + } + + onDrawerRequested: drawer.toggle() + } + + Drawer { + id: drawer + + edge: Qt.RightEdge + height: root.height + + Control { + padding: 16 + contentItem: ColumnLayout { + Label { + Layout.alignment: Qt.AlignHCenter + text: qsTr("Settings") + font.capitalization: Font.AllUppercase + } + MenuSeparator {} + CheckBox { + id: lifecycleCheck + text: qsTr("Automatic lifecycle control") + checked: true + } + CheckBox { + id: freezeCheck + text: qsTr("Freeze after delay (seconds)") + enabled: lifecycleCheck.checked + checked: true + } + SpinBox { + id: freezeSpin + editable: true + enabled: freezeCheck.checked + value: 60 + from: 1 + to: 60*60 + } + CheckBox { + id: discardCheck + text: qsTr("Discard after delay (seconds)") + enabled: lifecycleCheck.checked + checked: true + } + SpinBox { + id: discardSpin + editable: true + enabled: discardCheck.checked + value: 60*60 + from: 1 + to: 60*60 + } + } + } + + function toggle() { + if (drawer.visible) + drawer.close() + else + drawer.open() + } + } + + Component.onCompleted: { + createNewTab({url: "https://www.qt.io"}) + } + + function createNewTab(properties) { + const tab = tabStack.createNewTab(properties) + tabBar.createNewTab({tab: tab}) + tabBar.currentIndex = tab.index + return tab + } + + function closeTab(index) { + if (tabStack.count == 1) + Qt.quit() + tabBar.closeTab(index) + tabStack.closeTab(index) + } +} diff --git a/examples/webenginequick/lifecycle/WebTab.qml b/examples/webenginequick/lifecycle/WebTab.qml new file mode 100644 index 000000000..f83ce9404 --- /dev/null +++ b/examples/webenginequick/lifecycle/WebTab.qml @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtWebEngine + +ColumnLayout { + id: root + + signal closeRequested + signal drawerRequested + + property int freezeDelay + property int discardDelay + + property alias icon : view.icon + property alias loading : view.loading + property alias url : view.url + property alias lifecycleState : view.lifecycleState + property alias recommendedState : view.recommendedState + + readonly property string title : { + if (view.url == "about:blank") + return qsTr("New tab") + if (view.title) + return view.title + return view.url + } + + readonly property Action backAction: Action { + property WebEngineAction webAction: view.action(WebEngineView.Back) + enabled: webAction.enabled + text: qsTr("Back") + shortcut: root.visible && StandardKey.Back + onTriggered: webAction.trigger() + } + + readonly property Action forwardAction: Action { + property WebEngineAction webAction: view.action(WebEngineView.Forward) + enabled: webAction.enabled + text: qsTr("Forward") + shortcut: root.visible && StandardKey.Forward + onTriggered: webAction.trigger() + } + + readonly property Action reloadAction: Action { + property WebEngineAction webAction: view.action(WebEngineView.Reload) + enabled: webAction.enabled + text: qsTr("Reload") + shortcut: root.visible && StandardKey.Refresh + onTriggered: webAction.trigger() + } + + readonly property Action stopAction: Action { + property WebEngineAction webAction: view.action(WebEngineView.Stop) + enabled: webAction.enabled + text: qsTr("Stop") + shortcut: root.visible && StandardKey.Cancel + onTriggered: webAction.trigger() + } + + readonly property Action closeAction: Action { + text: qsTr("Close") + shortcut: root.visible && StandardKey.Close + onTriggered: root.closeRequested() + } + + readonly property Action activateAction: Action { + text: qsTr("Active") + checkable: true + checked: view.lifecycleState == WebEngineView.LifecycleState.Active + enabled: checked || (view.lifecycleState != WebEngineView.LifecycleState.Active) + onTriggered: view.lifecycleState = WebEngineView.LifecycleState.Active + } + + readonly property Action freezeAction: Action { + text: qsTr("Frozen") + checkable: true + checked: view.lifecycleState == WebEngineView.LifecycleState.Frozen + enabled: checked || (!view.visible && view.lifecycleState == WebEngineView.LifecycleState.Active) + onTriggered: view.lifecycleState = WebEngineView.LifecycleState.Frozen + } + + readonly property Action discardAction: Action { + text: qsTr("Discarded") + checkable: true + checked: view.lifecycleState == WebEngineView.LifecycleState.Discarded + enabled: checked || (!view.visible && view.lifecycleState == WebEngineView.LifecycleState.Frozen) + onTriggered: view.lifecycleState = WebEngineView.LifecycleState.Discarded + } + + spacing: 0 + + ToolBar { + Layout.fillWidth: true + Material.elevation: 0 + Material.background: Material.color(Material.Grey, Material.Shade800) + + RowLayout { + anchors.fill: parent + WebToolButton { + action: root.backAction + text: "←" + ToolTip.text: root.backAction.text + } + WebToolButton { + action: root.forwardAction + text: "→" + ToolTip.text: root.forwardAction.text + } + WebToolButton { + action: root.reloadAction + visible: root.reloadAction.enabled + text: "↻" + ToolTip.text: root.reloadAction.text + } + WebToolButton { + action: root.stopAction + visible: root.stopAction.enabled + text: "✕" + ToolTip.text: root.stopAction.text + } + TextField { + Layout.fillWidth: true + Layout.topMargin: 6 + + placeholderText: qsTr("Type a URL") + text: view.url == "about:blank" ? "" : view.url + selectByMouse: true + + onAccepted: { view.url = text } + } + WebToolButton { + text: "⋮" + ToolTip.text: qsTr("Settings") + onClicked: root.drawerRequested() + } + } + } + + WebEngineView { + id: view + Layout.fillHeight: true + Layout.fillWidth: true + } + + Timer { + interval: { + switch (view.recommendedState) { + case WebEngineView.LifecycleState.Active: + return 1 + case WebEngineView.LifecycleState.Frozen: + return root.freezeDelay * 1000 + case WebEngineView.LifecycleState.Discarded: + return root.discardDelay * 1000 + } + } + running: interval && view.lifecycleState != view.recommendedState + onTriggered: view.lifecycleState = view.recommendedState + } +} diff --git a/examples/webenginequick/lifecycle/WebTabBar.qml b/examples/webenginequick/lifecycle/WebTabBar.qml new file mode 100644 index 000000000..b883cfc36 --- /dev/null +++ b/examples/webenginequick/lifecycle/WebTabBar.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts + +Pane { + id: root + + property Action newTabAction + + property alias currentIndex: tabBar.currentIndex + + signal closeRequested(int index) + + Material.background: Material.color(Material.Grey, Material.Shade900) + Material.elevation: 4 + padding: 0 + + RowLayout { + spacing: 0 + anchors.fill: parent + + TabBar { + id: tabBar + Layout.fillWidth: true + Layout.fillHeight: true + } + + WebToolButton { + Layout.bottomMargin: 2 + + action: root.newTabAction + text: "+" + ToolTip.text: root.newTabAction.text + } + } + + Component { + id: factory + WebTabButton {} + } + + function createNewTab(properties) { + return factory.createObject(tabBar, properties) + } + + function closeTab(index) { + tabBar.takeItem(index).destroy() + } +} diff --git a/examples/webenginequick/lifecycle/WebTabButton.qml b/examples/webenginequick/lifecycle/WebTabButton.qml new file mode 100644 index 000000000..50bc463da --- /dev/null +++ b/examples/webenginequick/lifecycle/WebTabButton.qml @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts +import QtWebEngine + +TabButton { + id: root + + property WebTab tab + + text: root.tab.title + + ToolTip.delay: 1000 + ToolTip.visible: root.hovered + ToolTip.text: root.text + + padding: 6 + + contentItem: RowLayout { + Item { + implicitWidth: 16 + implicitHeight: 16 + BusyIndicator { + visible: root.tab.loading + anchors.fill: parent + leftInset: 0 + topInset: 0 + rightInset: 0 + bottomInset: 0 + padding: 0 + } + Image { + visible: !root.tab.loading + source: root.tab.icon + anchors.fill: parent + } + } + Label { + Layout.fillWidth: true + Layout.leftMargin: 4 + Layout.rightMargin: 4 + text: root.text + elide: Text.ElideRight + color: { + switch (root.tab.lifecycleState) { + case WebEngineView.LifecycleState.Active: + return Material.color(Material.Grey, Material.Shade100) + case WebEngineView.LifecycleState.Frozen: + return Material.color(Material.Blue, Material.Shade400) + case WebEngineView.LifecycleState.Discarded: + return Material.color(Material.Red, Material.Shade400) + } + } + + } + WebToolButton { + action: root.tab.closeAction + text: "✕" + ToolTip.text: action.text + } + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton + propagateComposedEvents: true + onClicked: contextMenu.popup() + } + + Menu { + id: contextMenu + Control { + contentItem: Label { + text: qsTr("Manual lifecycle control") + } + verticalPadding: 9 + horizontalPadding: 14 + } + Repeater { + model: [root.tab.activateAction, root.tab.freezeAction, root.tab.discardAction] + RadioButton { + action: modelData + verticalPadding: 9 + horizontalPadding: 14 + } + } + Control { + contentItem: Label { + text: qsTr("Recommended: %1").arg(recommendedStateText) + property string recommendedStateText: { + switch (root.tab.recommendedState) { + case WebEngineView.LifecycleState.Active: + return root.tab.activateAction.text + case WebEngineView.LifecycleState.Frozen: + return root.tab.freezeAction.text + case WebEngineView.LifecycleState.Discarded: + return root.tab.discardAction.text + } + } + color: Material.hintTextColor + } + font.pointSize: 8 + verticalPadding: 9 + horizontalPadding: 14 + } + } +} diff --git a/examples/webenginequick/lifecycle/WebTabStack.qml b/examples/webenginequick/lifecycle/WebTabStack.qml new file mode 100644 index 000000000..6ceedb8a5 --- /dev/null +++ b/examples/webenginequick/lifecycle/WebTabStack.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml.Models +import QtQuick +import QtQuick.Controls + +Rectangle { + id: root + + signal closeRequested(int index) + signal drawerRequested + + property int freezeDelay + property int discardDelay + + property int currentIndex + property var currentTab: model.children[currentIndex] + property alias count: model.count + + color: "white" + + ObjectModel { + id: model + } + + Component { + id: factory + WebTab { + readonly property int index : ObjectModel.index + anchors.fill: parent + visible: index == root.currentIndex + freezeDelay: root.freezeDelay + discardDelay: root.discardDelay + onCloseRequested: root.closeRequested(index) + onDrawerRequested: root.drawerRequested() + } + } + + function createNewTab(properties) { + const tab = factory.createObject(root, properties) + model.append(tab) + return tab + } + + function closeTab(index) { + const tab = model.get(index) + model.remove(index) + tab.destroy() + } +} diff --git a/examples/webenginequick/lifecycle/WebToolButton.qml b/examples/webenginequick/lifecycle/WebToolButton.qml new file mode 100644 index 000000000..9565dfb1d --- /dev/null +++ b/examples/webenginequick/lifecycle/WebToolButton.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +ToolButton { + id: root + font.bold: true + font.pointSize: 12 + ToolTip.delay: 1000 + ToolTip.visible: hovered + implicitWidth: 32 + implicitHeight: 32 +} diff --git a/examples/webenginequick/lifecycle/doc/images/lifecycle-automatic.png b/examples/webenginequick/lifecycle/doc/images/lifecycle-automatic.png Binary files differnew file mode 100644 index 000000000..2c62967af --- /dev/null +++ b/examples/webenginequick/lifecycle/doc/images/lifecycle-automatic.png diff --git a/examples/webenginequick/lifecycle/doc/images/lifecycle-manual.png b/examples/webenginequick/lifecycle/doc/images/lifecycle-manual.png Binary files differnew file mode 100644 index 000000000..7fb5c5a80 --- /dev/null +++ b/examples/webenginequick/lifecycle/doc/images/lifecycle-manual.png diff --git a/examples/webenginequick/lifecycle/doc/images/lifecycle.png b/examples/webenginequick/lifecycle/doc/images/lifecycle.png Binary files differnew file mode 100644 index 000000000..87b719022 --- /dev/null +++ b/examples/webenginequick/lifecycle/doc/images/lifecycle.png diff --git a/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc new file mode 100644 index 000000000..80faf8b1e --- /dev/null +++ b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example webenginequick/lifecycle + \title WebEngine Lifecycle Example + \ingroup webengine-examples + \brief Freezes and discards background tabs to reduce CPU and memory usage. + + \image lifecycle.png + + \e {WebEngine Lifecycle Example} demonstrates how the \l + {WebEngineView::}{lifecycleState} and \l {WebEngineView::}{recommendedState} + properties of the \l {WebEngineView} can be used to reduce the CPU and + memory usage of background tabs in a tabbed browser. + + For an overview of the lifecycle feature, see \l {Page Lifecycle API}. + + \include examples-run.qdocinc + + \section1 UI Elements of the Example + + The example uses \l {Qt Quick Controls 2} to implement a traditional tabbed + browser in the \l {Material Style} (dark variant). The main application + window (\c {WebBrowser.qml}) is divided into a header bar at the top and a + main viewing area filling the rest of the window. The header contains the + tab bar (\c {WebTabBar.qml}) with one button per tab (\c + {WebTabButton.qml}). The main area consists of a stack of tabs (\c + {WebTabStack.qml} and \c {WebTab.qml}). Each tab in turn has a tool bar at + the top and a \l {WebEngineView} for displaying web pages. Finally, the main + window also has a \l {Drawer} for changing settings. The drawer can be + opened by clicking the "⋮" button on the tool bar. + + \section1 Lifecycle States in the Example + + The example implements two ways of changing the lifecycle state: manual and + automatic. The manual way uses the \l {WebEngineView::}{lifecycleState} + property directly to change the web view lifecycle state, while the + automatic way is timer-based and also takes into account the \l + {WebEngineView::}{recommendedState}. + + The tab titles in the tab bar are color coded with frozen tabs shown in blue + and discarded in red. + + \section2 Manual Lifecycle Control + + \image lifecycle-manual.png + + Manual control is provided by context menus on the tab bar buttons (\c + {WebTabButton.qml}). The menu has three radio buttons, one for each + lifecycle state, with the current state checked. Some buttons may be + disabled, either because they represent illegal state transitions (for + example, a \c {Discarded} view cannot directly transition to the \c {Frozen} + state), or because other preconditions are not fulfilled (for example, a + visible view can only be in the \c {Active} state). + + \section2 Automatic Lifecycle Control + + \image lifecycle-automatic.png + + Automatic control is implemented with a \l {Timer} in the \c {WebTab} + component (\c {WebTab.qml}). The timer is started whenever the \l + {WebEngineView::}{lifecycleState} of the web view does not match it's \l + {WebEngineView::}{recommendedState}. Once the timer fires, the view's + lifecycle state is set to the recommended state. + + The time delay is used to avoid changing the lifecycle state too quickly + when the user is switching between tabs. The freezing and discarding delays + can be changed in the settings drawer accessed through the "⋮" button on the + tool bar. + + This is a rather simple algorithm for automatic lifecycle control, however + more sophisticated algorithms could also be conceived and implemented on the + basis of the \l {WebEngineView::}{lifecycleState} property. For example, the + Chromium browser experimentally uses a pretrained deep neural network to + predict the next tab activation time by the user, essentially ranking tabs + based on how interesting they are to the user. Implementing such an + algorithm is left as an exercise to the reader for now. + +*/ diff --git a/examples/webenginequick/lifecycle/lifecycle.pro b/examples/webenginequick/lifecycle/lifecycle.pro new file mode 100644 index 000000000..ccbe801f3 --- /dev/null +++ b/examples/webenginequick/lifecycle/lifecycle.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +QT += quickcontrols2 webenginequick + +SOURCES += main.cpp + +RESOURCES += resources.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/webenginequick/lifecycle +INSTALLS += target diff --git a/examples/webenginequick/lifecycle/main.cpp b/examples/webenginequick/lifecycle/main.cpp new file mode 100644 index 000000000..1e2a48679 --- /dev/null +++ b/examples/webenginequick/lifecycle/main.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QtWebEngineQuick/qtwebenginequickglobal.h> + +int main(int argc, char *argv[]) +{ + QCoreApplication::setOrganizationName("QtExamples"); + QtWebEngineQuick::initialize(); + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/WebBrowser.qml"))); + return app.exec(); +} diff --git a/examples/webenginequick/lifecycle/qtquickcontrols2.conf b/examples/webenginequick/lifecycle/qtquickcontrols2.conf new file mode 100644 index 000000000..68c77cec5 --- /dev/null +++ b/examples/webenginequick/lifecycle/qtquickcontrols2.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Material + +[Material] +Theme=Dark +Variant=Dense diff --git a/examples/webenginequick/lifecycle/resources.qrc b/examples/webenginequick/lifecycle/resources.qrc new file mode 100644 index 000000000..41e5092ce --- /dev/null +++ b/examples/webenginequick/lifecycle/resources.qrc @@ -0,0 +1,11 @@ +<RCC> + <qresource prefix="/"> + <file>WebBrowser.qml</file> + <file>WebTab.qml</file> + <file>WebTabBar.qml</file> + <file>WebTabButton.qml</file> + <file>WebTabStack.qml</file> + <file>WebToolButton.qml</file> + <file>qtquickcontrols2.conf</file> + </qresource> +</RCC> |