summaryrefslogtreecommitdiffstats
path: root/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml
diff options
context:
space:
mode:
Diffstat (limited to 'basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml')
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml705
1 files changed, 705 insertions, 0 deletions
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml
new file mode 100644
index 0000000..01445c6
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml
@@ -0,0 +1,705 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtWebEngine 1.1
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.2
+import QtGraphicalEffects 1.0
+
+import WebBrowser 1.0
+import "assets"
+
+Rectangle {
+ id: root
+
+ property int itemWidth: browserWindow.width / 2
+ property int itemHeight: browserWindow.height / 2
+
+ property bool interactive: true
+
+ property alias currentIndex: pathView.currentIndex
+ property alias count: pathView.count
+
+ property string viewState: "page"
+
+ onViewStateChanged: {
+ if (viewState == "page" || viewState == "fullscreen")
+ homeScreen.state = "disabled"
+ }
+
+ property QtObject otrProfile: WebEngineProfile {
+ offTheRecord: true
+ }
+
+ property QtObject defaultProfile: WebEngineProfile {
+ storageName: "YABProfile"
+ offTheRecord: false
+ }
+
+ Component {
+ id: tabComponent
+ Rectangle {
+ id: tabItem
+ property alias webView: webEngineView
+ property alias title: webEngineView.title
+
+ property var image: QtObject {
+ property var snapshot: null
+ property string url: "about:blank"
+ }
+
+ visible: opacity != 0.0
+
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ anchors.fill: parent
+
+ Action {
+ shortcut: "Ctrl+F"
+ onTriggered: {
+ findBar.visible = !findBar.visible
+ if (findBar.visible) {
+ findTextField.forceActiveFocus()
+ }
+ }
+ }
+
+ FeaturePermissionBar {
+ id: permBar
+ view: webEngineView
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: parent.top
+ }
+ z: 3
+ }
+
+ WebEngineView {
+ id: webEngineView
+
+ anchors {
+ fill: parent
+ top: permBar.bottom
+ }
+
+ profile: settingsView.privateBrowsingEnabled ? otrProfile : defaultProfile
+ enabled: root.interactive
+
+ function takeSnapshot() {
+ if (webEngineView.url == "" || webEngineView.url == "about:blank") {
+ tabItem.image.url = "about:blank"
+ tabItem.image.snapshot = null
+ return
+ }
+
+ if (tabItem.image.url == webEngineView.url || tabItem.opacity != 1.0)
+ return
+
+ tabItem.image.url = webEngineView.url
+ webEngineView.grabToImage(function(result) {
+ tabItem.image.snapshot = result;
+ console.log("takeSnapshot("+result.url+")")
+ });
+ }
+
+ // Trigger a refresh to check if the new url is bookmarked.
+ onUrlChanged: navigation.refresh()
+
+
+ settings.autoLoadImages: settingsView.autoLoadImages
+ settings.javascriptEnabled: !settingsView.javaScriptDisabled
+
+ // This should be enabled as we can switch to Qt 5.6 (i.e. import QtWebEngine 1.2)
+ // settings.pluginsEnabled: settingsView.pluginsEnabled
+
+ onLoadingChanged: {
+ if (loading)
+ navigation.state = "enabled"
+ }
+
+ onCertificateError: {
+ if (!acceptedCertificates.shouldAutoAccept(error)){
+ error.defer()
+ sslDialog.enqueue(error)
+ } else{
+ error.ignoreCertificateError()
+ }
+ }
+
+ onNewViewRequested: {
+ webEngineView.takeSnapshot()
+ var tab
+ if (!request.userInitiated) {
+ print("Warning: Blocked a popup window.")
+ return
+ }
+
+ tab = tabView.createEmptyTab()
+
+ if (!tab)
+ return
+
+ if (request.destination == WebEngineView.NewViewInTab) {
+ pathView.positionViewAtIndex(tabView.count - 1, PathView.Center)
+ request.openIn(tab.webView)
+ } else if (request.destination == WebEngineView.NewViewInBackgroundTab) {
+ var index = pathView.currentIndex
+ request.openIn(tab.webView)
+ pathView.positionViewAtIndex(index, PathView.Center)
+ } else if (request.destination == WebEngineView.NewViewInDialog) {
+ request.openIn(tab.webView)
+ } else {
+ request.openIn(tab.webView)
+ }
+ }
+
+ onFeaturePermissionRequested: {
+ permBar.securityOrigin = securityOrigin;
+ permBar.requestedFeature = feature;
+ permBar.visible = true;
+ }
+
+ onFullScreenRequested: {
+ if (request.toggleOn)
+ viewState = "fullscreen"
+ else
+ viewState = "page"
+ request.accept()
+ }
+ }
+
+ Desaturate {
+ id: desaturate
+ visible: desaturation != 0.0
+ anchors.fill: webEngineView
+ source: webEngineView
+ desaturation: root.interactive ? 0.0 : 1.0
+
+ Behavior on desaturation {
+ NumberAnimation { duration: animationDuration }
+ }
+ }
+
+ FastBlur {
+ id: blur
+ visible: radius != 0.0
+ anchors.fill: desaturate
+ source: desaturate
+ radius: desaturate.desaturation * 25
+ }
+
+ TouchTracker {
+ id: tracker
+ enabled: root.interactive
+ target: webEngineView
+ anchors.fill: parent
+ onTouchYChanged: browserWindow.touchY = tracker.touchY
+ onYVelocityChanged: browserWindow.velocityY = yVelocity
+ onTouchBegin: {
+ browserWindow.touchY = tracker.touchY
+ browserWindow.velocityY = yVelocity
+ browserWindow.touchReference = tracker.touchY
+ browserWindow.touchGesture = true
+ navigation.state = "tracking"
+ }
+ onTouchEnd: {
+ browserWindow.velocityY = yVelocity
+ browserWindow.touchGesture = false
+ navigation.state = "tracking"
+ }
+ onScrollDirectionChanged: {
+ browserWindow.velocityY = 0
+ browserWindow.touchReference = tracker.touchY
+ }
+ }
+
+ Rectangle {
+ opacity: {
+ if (inputPanel.state === "visible")
+ return 0.0
+ if (webEngineView.url == "" || webEngineView.url == "about:blank")
+ return 1.0
+ return 0.0
+ }
+ anchors.fill: parent
+ visible: opacity != 0.0
+ color: "#09102b"
+ Image {
+ id: placeholder
+ y: placeholder.height - navigation.y
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: "assets/icons/AppLogoColor.png"
+ }
+ Text {
+ id: label
+ anchors {
+ top: placeholder.bottom
+ topMargin: 20
+ horizontalCenter: placeholder.horizontalCenter
+ }
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ color: "white"
+ text: "Qt WebBrowser"
+ }
+
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration }
+ }
+ }
+
+ Rectangle {
+ id: findBar
+ anchors {
+ right: webEngineView.right
+ left: webEngineView.left
+ top: webEngineView.top
+ }
+ height: toolBarSize / 2 + 10
+ visible: false
+ color: uiColor
+
+ RowLayout {
+ spacing: 0
+ anchors.fill: parent
+ Rectangle {
+ width: 5
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiColor
+ }
+ TextField {
+ id: findTextField
+ Layout.fillWidth: true
+ onAccepted: {
+ webEngineView.findText(text)
+ }
+ style: TextFieldStyle {
+ textColor: "black"
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ selectionColor: uiHighlightColor
+ selectedTextColor: "black"
+ placeholderTextColor: placeholderColor
+ background: Rectangle {
+ implicitWidth: 514
+ implicitHeight: toolBarSize / 2
+ border.color: textFieldStrokeColor
+ border.width: 1
+ }
+ }
+ }
+ Rectangle {
+ width: 5
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiColor
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: findBackwardButton
+ iconSource: "assets/icons/Btn_Back.png"
+ implicitHeight: parent.height
+ onClicked: webEngineView.findText(findTextField.text, WebEngineView.FindBackward)
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: findForwardButton
+ iconSource: "assets/icons/Btn_Forward.png"
+ implicitHeight: parent.height
+ onClicked: webEngineView.findText(findTextField.text)
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: findCancelButton
+ iconSource: "assets/icons/Btn_Clear.png"
+ implicitHeight: parent.height
+ onClicked: findBar.visible = false
+ }
+ }
+ }
+ }
+ }
+
+ ListModel {
+ id: listModel
+ }
+
+ function makeCurrent(index) {
+ viewState = "list"
+ pathView.positionViewAtIndex(index, PathView.Center)
+ viewState = "page"
+ }
+
+ function createEmptyTab() {
+ var tab = add(tabComponent)
+ return tab
+ }
+
+ function add(component) {
+ if (listModel.count === tabViewMaxTabs) {
+ homeScreen.messageBox.state = "tabsfull"
+ homeScreen.state = "enabled"
+ homeScreen.forceActiveFocus()
+ return null
+ }
+
+ var element = {"item": null }
+ element.item = component.createObject(root, { "width": root.width, "height": root.height, "opacity": 0.0 })
+
+ if (element.item == null) {
+ console.log("PageView::add(): Error creating object");
+ return
+ }
+
+ listModel.append(element)
+ return element.item
+ }
+
+ function remove(index) {
+ pathView.interactive = false
+ pathView.currentItem.state = ""
+ pathView.currentItem.visible = false
+ listModel.remove(index)
+ pathView.decrementCurrentIndex()
+ pathView.interactive = true
+ }
+
+ function get(index) {
+ return listModel.get(index)
+ }
+
+ Component {
+ id: delegate
+
+ Rectangle {
+ id: wrapper
+
+ parent: item
+
+ property real visibility: 0.0
+ property bool isCurrentItem: PathView.isCurrentItem
+
+ visible: PathView.onPath && visibility != 0.0
+ state: isCurrentItem ? root.viewState : "list"
+
+ Behavior on scale {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ states: [
+ State {
+ name: "page"
+ PropertyChanges { target: wrapper; width: root.width; height: root.height; visibility: 0.0 }
+ PropertyChanges { target: pathView; interactive: false }
+ PropertyChanges { target: item; opacity: 1.0 }
+ PropertyChanges { target: navigation; state: "enabled" }
+ },
+ State {
+ name: "list"
+ PropertyChanges { target: wrapper; width: itemWidth; height: itemHeight; visibility: 1.0 }
+ PropertyChanges { target: pathView; interactive: true }
+ PropertyChanges { target: item; opacity: 0.0 }
+ },
+ State {
+ name: "fullscreen"
+ PropertyChanges { target: wrapper; width: root.width; height: root.height; visibility: 0.0 }
+ PropertyChanges { target: pathView; interactive: false }
+ PropertyChanges { target: item; opacity: 1.0 }
+ PropertyChanges { target: navigation; state: "disabled" }
+ }
+ ]
+
+ transitions: Transition {
+ ParallelAnimation {
+ PropertyAnimation { property: "visibility"; duration: animationDuration; easing.type : Easing.InSine }
+ PropertyAnimation { properties: "x,y"; duration: animationDuration; easing.type: Easing.InSine }
+ PropertyAnimation { properties: "width,height"; duration: animationDuration; easing.type: Easing.InSine }
+ }
+ }
+
+ width: itemWidth; height: itemHeight
+ scale: {
+ if (pathView.count == 1)
+ return 1.0
+ if (pathView.count < 4)
+ return isCurrentItem ? 1.0 : 0.5
+
+ if (isCurrentItem)
+ return 1.0
+
+ var index1 = pathView.currentIndex - 2
+ var index2 = pathView.currentIndex - 1
+ var index4 = (pathView.currentIndex + 1) % pathView.count
+ var index5 = (pathView.currentIndex + 2) % pathView.count
+
+ if (index1 < 0)
+ index1 = pathView.count + index1
+ if (index2 < 0)
+ index2 = pathView.count + index2
+
+ switch (index) {
+ case index1 :
+ return 0.25
+ case index2:
+ return 0.5
+ case index4:
+ return 0.5
+ case index5:
+ return 0.25
+ }
+
+ return 0.25
+ }
+ z: PathView.itemZ
+
+ MouseArea {
+ enabled: pathView.interactive
+ anchors.fill: wrapper
+ onClicked: {
+ mouse.accepted = true
+ if (index < 0)
+ return
+
+ if (index == pathView.currentIndex) {
+ if (root.viewState == "list")
+ root.viewState = "page"
+ return
+ }
+ pathView.currentIndex = index
+ }
+ }
+ Rectangle {
+ id: shadow
+ visible: false
+ property real size: 24
+ anchors {
+ top: parent.top
+ topMargin: 9
+ horizontalCenter: parent.horizontalCenter
+ }
+ color: iconOverlayColor
+ radius: size / 2
+ width: snapshot.width
+ height: snapshot.height
+ }
+ GaussianBlur {
+ anchors.fill: shadow
+ source: shadow
+ radius: shadow.size
+ samples: shadow.size * 2
+ opacity: 0.3
+ transparentBorder: true
+ visible: wrapper.visibility == 1.0
+ }
+
+ Rectangle {
+ id: snapshot
+ color: uiColor
+
+ Image {
+ source: {
+ if (!item.image.snapshot)
+ return "assets/icons/about_blank.png"
+ return item.image.snapshot.url
+ }
+ anchors.fill: parent
+ Rectangle {
+ enabled: index == pathView.currentIndex && !pathView.moving && !pathView.flicking && wrapper.visibility == 1.0
+ opacity: enabled ? 1.0 : 0.0
+ visible: wrapper.visibility == 1.0 && listModel.count > 1
+ width: image.sourceSize.width
+ height: image.sourceSize.height - 2
+ radius: width / 2
+ color: iconOverlayColor
+ anchors {
+ horizontalCenter: parent.right
+ verticalCenter: parent.top
+ }
+ Image {
+ id: image
+ opacity: {
+ if (closeButton.pressed)
+ return 0.70
+ return 1.0
+ }
+ anchors {
+ top: parent.top
+ left: parent.left
+ }
+ source: "assets/icons/Btn_Delete.png"
+ MouseArea {
+ id: closeButton
+ anchors.fill: parent
+ onClicked: {
+ mouse.accepted = true
+ remove(pathView.currentIndex)
+ }
+ }
+ }
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration / 2 }
+ }
+ }
+ }
+ anchors.fill: wrapper
+ }
+
+ Text {
+ anchors {
+ topMargin: -25
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ }
+ horizontalAlignment: Text.AlignHCenter
+ width: parent.width - image.width
+ elide: Text.ElideRight
+ text: item.title
+ font.pixelSize: 16
+ font.family: defaultFontFamily
+ color: "white"
+ visible: wrapper.isCurrentItem && wrapper.visibility == 1.0
+ }
+ }
+ }
+
+ Rectangle {
+ color: "#09102b"
+ anchors.fill: parent
+ }
+
+ PathView {
+ id: pathView
+ pathItemCount: 5
+ anchors.fill: parent
+ model: listModel
+ delegate: delegate
+ highlightMoveDuration: animationDuration
+ highlightRangeMode: PathView.StrictlyEnforceRange
+ snapMode: PathView.SnapToItem
+ preferredHighlightBegin: 0.5
+ preferredHighlightEnd: 0.5
+
+ dragMargin: itemHeight
+
+ focus: pathView.interactive
+
+ property real offset: 30
+
+ property real margin: {
+ if (count == 2)
+ return root.width / 4 - offset
+ if (count == 3)
+ return root.width / 8 + offset
+ if (count == 4)
+ return root.width / 8 - offset
+
+ return offset
+ }
+
+ property real middle: {
+ if (currentItem)
+ return (pathView.height / 2) - (currentItem.visibility * 50)
+ return (pathView.height / 2 - 50)
+ }
+
+ path: Path {
+ startX: pathView.margin
+ startY: pathView.middle
+
+ PathPercent { value: 0.0 }
+ PathAttribute { name: "itemZ"; value: 0 }
+ PathLine {
+ x: (pathView.width - itemWidth) / 2 + 106
+ y: pathView.middle
+ }
+ PathPercent { value: 0.49 }
+ PathAttribute { name: "itemZ"; value: 6 }
+
+ PathLine { relativeX: 0; relativeY: 0 }
+
+ PathLine {
+ x: (pathView.width - itemWidth) / 2 + itemWidth - 106
+ y: pathView.middle
+ }
+ PathPercent { value: 0.51 }
+
+ PathLine { relativeX: 0; relativeY: 0 }
+
+ PathAttribute { name: "itemZ"; value: 4 }
+ PathLine {
+ x: pathView.width - pathView.margin
+ y: pathView.middle
+ }
+ PathPercent { value: 1 }
+ PathAttribute { name: "itemZ"; value: 2 }
+ }
+
+ Keys.onLeftPressed: decrementCurrentIndex()
+ Keys.onRightPressed: incrementCurrentIndex()
+ }
+}