summaryrefslogtreecommitdiffstats
path: root/demos/declarative/webbrowser/content/FlickableWebView.qml
blob: 7c46d4c8d49898641ae59d4dcaad638759fb19a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import Qt 4.6

Flickable {
    property alias title: webView.title
    property alias progress: webView.progress
    property alias url: webView.url
    property alias back: webView.back
    property alias reload: webView.reload
    property alias forward: webView.forward

    id: flickable
    width: parent.width
    viewportWidth: Math.max(parent.width,webView.width*webView.scale)
    viewportHeight: Math.max(parent.height,webView.height*webView.scale)
    anchors.top: headerSpace.bottom
    anchors.bottom: footer.top
    anchors.left: parent.left
    anchors.right: parent.right
    pressDelay: 200

    WebView {
        id: webView
        pixelCacheSize: 4000000

        Script {
            function fixUrl(url)
            {
                if (url == "") return url
                if (url[0] == "/") return "file://"+url
                if (url.indexOf(":")<0) {
                    if (url.indexOf(".")<0 || url.indexOf(" ")>=0) {
                        // Fall back to a search engine; hard-code Wikipedia
                        return "http://en.wikipedia.org/w/index.php?search="+url
                    } else {
                        return "http://"+url
                    }
                }
                return url
            }
        }

        url: fixUrl(webBrowser.urlString)
        smooth: false // We don't want smooth scaling, since we only scale during (fast) transitions
        smoothCache: true // We do want smooth rendering
        fillColor: "white"
        focus: true
        zoomFactor: 4

        onAlert: console.log(message)

        function doZoom(zoom,centerX,centerY)
        {
            if (centerX) {
                var sc = zoom/contentsScale;
                scaleAnim.to = sc;
                flickVX.from = flickable.viewportX
                flickVX.to = Math.max(0,Math.min(centerX-flickable.width/2,webView.width*sc-flickable.width))
                finalX.value = flickVX.to
                flickVY.from = flickable.viewportY
                flickVY.to = Math.max(0,Math.min(centerY-flickable.height/2,webView.height*sc-flickable.height))
                finalY.value = flickVY.to
                finalZoom.value = zoom
                quickZoom.start()
            }
        }

        Keys.onLeftPressed: webView.contentsScale -= 0.1
        Keys.onRightPressed: webView.contentsScale += 0.1

        preferredWidth: flickable.width*zoomFactor
        preferredHeight: flickable.height*zoomFactor
        contentsScale: 1/zoomFactor
        onContentsSizeChanged: {
            // zoom out
            contentsScale = Math.min(0.25,flickable.width / contentsSize.width)
        }
        onUrlChanged: {
            // got to topleft
            flickable.viewportX = 0
            flickable.viewportY = 0
            if (url != null) { header.editUrl = url.toString(); }
        }
        onDoubleClick: {
                        if (!heuristicZoom(clickX,clickY,2.5)) {
                            var zf = flickable.width / contentsSize.width
                            if (zf >= contentsScale)
                                zf = 2.0/zoomFactor // zoom in (else zooming out)
                            doZoom(zf,clickX*zf,clickY*zf)
                         }
                       }

        SequentialAnimation {
            id: quickZoom

            PropertyAction {
                target: webView
                property: "renderingEnabled"
                value: false
            }
            ParallelAnimation {
                NumberAnimation {
                    id: scaleAnim
                    target: webView
                    property: "scale"
                    from: 1
                    to: 0 // set before calling
                    easing: "easeLinear"
                    duration: 200
                }
                NumberAnimation {
                    id: flickVX
                    target: flickable
                    property: "viewportX"
                    easing: "easeLinear"
                    duration: 200
                    from: 0 // set before calling
                    to: 0 // set before calling
                }
                NumberAnimation {
                    id: flickVY
                    target: flickable
                    property: "viewportY"
                    easing: "easeLinear"
                    duration: 200
                    from: 0 // set before calling
                    to: 0 // set before calling
                }
            }
            PropertyAction {
                id: finalZoom
                target: webView
                property: "contentsScale"
            }
            PropertyAction {
                target: webView
                property: "scale"
                value: 1.0
            }
            // Have to set the viewportXY, since the above 2
            // size changes may have started a correction if
            // contentsScale < 1.0.
            PropertyAction {
                id: finalX
                target: flickable
                property: "viewportX"
                value: 0 // set before calling
            }
            PropertyAction {
                id: finalY
                target: flickable
                property: "viewportY"
                value: 0 // set before calling
            }
            PropertyAction {
                target: webView
                property: "renderingEnabled"
                value: true
            }
        }
        onZoomTo: doZoom(zoom,centerX,centerY)
    }
}