summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@theqtcompany.com>2015-07-27 18:25:58 +0200
committerAndras Becsi <andras.becsi@theqtcompany.com>2015-08-12 17:22:03 +0200
commit0544031867f31e191f8a1d855dbf33dc81161198 (patch)
treed509b9ae3e657e9f354a67532db411f201910f90 /src
parenta8061cb3910caca4ca48f0dd7f7883ccca9920d5 (diff)
Add GridView for HomeScreen
This patch also adds hooks for apple-touch-icon handling
Diffstat (limited to 'src')
-rw-r--r--src/qml/BrowserDialog.qml56
-rw-r--r--src/qml/BrowserWindow.qml53
-rw-r--r--src/qml/HomeScreen.qml416
-rw-r--r--src/qml/NavigationBar.qml46
-rw-r--r--src/qml/PageView.qml29
-rw-r--r--src/qml/assets/UIButton.qml4
-rw-r--r--src/resources.qrc2
-rw-r--r--src/src.pro2
-rw-r--r--src/utils.h54
9 files changed, 553 insertions, 109 deletions
diff --git a/src/qml/BrowserDialog.qml b/src/qml/BrowserDialog.qml
deleted file mode 100644
index d463be6..0000000
--- a/src/qml/BrowserDialog.qml
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 2.1
-import QtQuick.Window 2.2
-import QtWebEngine 1.1
-
-Window {
- property alias defaultProfile: webView.profile
- property alias currentWebView: webView
- flags: Qt.Dialog
- width: 800
- height: 600
- visible: true
- onClosing: destroy()
- WebEngineView {
- id: webView
- anchors.fill: parent
- }
-}
diff --git a/src/qml/BrowserWindow.qml b/src/qml/BrowserWindow.qml
index bedf57a..7e6a5e4 100644
--- a/src/qml/BrowserWindow.qml
+++ b/src/qml/BrowserWindow.qml
@@ -35,7 +35,7 @@
**
****************************************************************************/
-import QtQuick 2.1
+import QtQuick 2.5
import QtWebEngine 1.1
import QtWebEngine.experimental 1.0
@@ -53,15 +53,19 @@ Item {
id: browserWindow
property Item currentWebView: {
- return tabs.get(tabs.currentIndex) ? tabs.get(tabs.currentIndex).item.webView : null
+ return tabView.get(tabView.currentIndex) ? tabView.get(tabView.currentIndex).item.webView : null
}
property int toolBarSize: 80
property string uiColor: "#46a2da"
property string uiSeparatorColor: "#7ebee5"
- property string uiSeparatorColor2: "#a3d1ed"
- property string buttonHighlightColor: "#3f91c4"
- property string uiSelectionColor: "#fddd5c"
+ property string tabEditSeparatorColor: "#a3d1ed"
+ property string buttonPressedColor: "#3f91c4"
+ property string uiHighlightColor: "#fddd5c"
+ property string inactivePagerColor: "#bcbdbe"
+ property string textFieldStrokeColor: "#3882ae"
+ property string placeholderColor: "#a0a1a2"
+ property string iconStrokeColor: "#0e202c"
property string defaultFontFamily: "Open Sans"
property int animationDuration: 200
@@ -109,15 +113,15 @@ Item {
id: newTabAction
shortcut: "Ctrl+T"
onTriggered: {
- tabs.createEmptyTab()
+ tabView.createEmptyTab()
navigation.addressBar.forceActiveFocus();
navigation.addressBar.selectAll();
- tabs.currentIndex = tabs.count - 1
+ tabView.currentIndex = tabView.count - 1
}
}
Action {
shortcut: "Ctrl+W"
- onTriggered: tabs.remove(tabs.currentIndex)
+ onTriggered: tabView.remove(tabView.currentIndex)
}
@@ -145,7 +149,7 @@ Item {
}
visible: opacity != 0.0
- opacity: tabs.viewState == "list" ? 1.0 : 0.0
+ opacity: tabView.viewState == "list" ? 1.0 : 0.0
RowLayout {
spacing: 0
@@ -163,7 +167,7 @@ Item {
top: parent.top
bottom: parent.bottom
}
- color: uiSeparatorColor2
+ color: tabEditSeparatorColor
}
Rectangle {
width: 40
@@ -189,10 +193,10 @@ Item {
anchors.centerIn: parent
Text {
anchors.centerIn: parent
- text: tabs.count
+ text: tabView.count
color: "white"
font.family: defaultFontFamily
- font.pointSize: 20
+ font.pixelSize: 20
}
}
}
@@ -202,7 +206,7 @@ Item {
top: parent.top
bottom: parent.bottom
}
- color: uiSeparatorColor2
+ color: tabEditSeparatorColor
}
UIButton {
id:doneButton
@@ -212,11 +216,11 @@ Item {
anchors.centerIn: parent
text: "Done"
font.family: defaultFontFamily
- font.pointSize: 28
+ font.pixelSize: 28
}
implicitWidth: 120
onClicked: {
- tabs.viewState = "page"
+ tabView.viewState = "page"
}
}
}
@@ -272,8 +276,8 @@ Item {
}
}
PageView {
- id: tabs
- interactive: !sslDialog.visible
+ id: tabView
+ interactive: !sslDialog.visible && homeScreen.state == "disabled"
height: parent.height
@@ -289,9 +293,9 @@ Item {
tab.webView.url = engine.fromUserInput("qt.io")
}
onCurrentIndexChanged: {
- if (!tabs.get(tabs.currentIndex))
+ if (!tabView.get(tabView.currentIndex))
return
- navigation.webView = tabs.get(tabs.currentIndex).item.webView
+ navigation.webView = tabView.get(tabView.currentIndex).item.webView
}
}
@@ -343,4 +347,15 @@ Item {
informativeText = "SSL error from URL\n\n" + currentError.url + "\n\n" + currentError.description + "\n"
}
}
+
+ HomeScreen {
+ id: homeScreen
+ z: 5
+ height: parent.height - toolBarSize
+ anchors {
+ top: navigation.bottom
+ left: parent.left
+ right: parent.right
+ }
+ }
}
diff --git a/src/qml/HomeScreen.qml b/src/qml/HomeScreen.qml
new file mode 100644
index 0000000..881fcb4
--- /dev/null
+++ b/src/qml/HomeScreen.qml
@@ -0,0 +1,416 @@
+/****************************************************************************
+**
+** 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 "assets"
+
+Rectangle {
+ id: homeScreen
+
+ property int padding: 60
+ property int cellSize: width / 5 - padding
+
+ state: "disabled"
+
+ signal add(string title, string url, string iconUrl, string fallbackColor)
+ onAdd: {
+ var element = { "title": title, "url": url, "iconUrl": iconUrl, "fallbackColor": fallbackColor }
+ listModel.append(element)
+ }
+
+ function contains(url) {
+ for (var idx = 0; idx < listModel.count; ++idx) {
+ if (listModel.get(idx).url === url)
+ return idx;
+ }
+ return -1;
+ }
+
+ function select(index) {
+ gridView.positionViewAtIndex(index, GridView.Contain)
+ gridView.draggingChanged()
+ }
+
+ states: [
+ State {
+ name: "enabled"
+ AnchorChanges {
+ target: homeScreen
+ anchors.top: navigation.bottom
+ }
+ },
+ State {
+ name: "disabled"
+ AnchorChanges {
+ target: homeScreen
+ anchors.top: homeScreen.parent.bottom
+ }
+ },
+ State {
+ name: "edit"
+ }
+ ]
+
+ transitions: Transition {
+ AnchorAnimation { duration: animationDuration; easing.type : Easing.InSine }
+ }
+
+ ListModel {
+ id: listModel
+ }
+
+ GridView {
+ id: gridView
+
+ property real dragStart: 0
+ property real page: 4 * cellWidth
+
+ anchors.fill: parent
+ model: listModel
+ cellWidth: homeScreen.cellSize + homeScreen.padding
+ cellHeight: cellWidth
+ flow: GridView.FlowTopToBottom
+ boundsBehavior: Flickable.StopAtBounds
+ maximumFlickVelocity: 0
+ contentHeight: parent.height
+ displayMarginEnd: 3 * page
+ rightMargin: (parent.width - 4 * gridView.cellWidth - homeScreen.padding) / 2
+
+ Behavior on contentX {
+ NumberAnimation { duration: 1.5 * animationDuration; easing.type : Easing.InSine}
+ }
+
+ anchors {
+ topMargin: toolBarSize
+ leftMargin: (parent.width - 4 * gridView.cellWidth + homeScreen.padding) / 2
+ }
+ onDraggingChanged: {
+ if (dragging) {
+ dragStart = contentX
+ return
+ }
+ if (dragStart == 2 * page && contentX < 2 * page) {
+ contentX = page
+ return
+ }
+ if (dragStart == page) {
+ if (contentX < page) {
+ contentX = 0
+ return
+ }
+ if (page < contentX) {
+ contentX = 2 * page
+ return
+ }
+ }
+ if (dragStart == 0 && 0 < contentX) {
+ contentX = page
+ return
+ }
+ contentX = 0
+ }
+
+ delegate: Rectangle {
+ id: square
+ property string iconColor: "white"
+ width: homeScreen.cellSize
+ height: width
+ border.color: iconStrokeColor
+ border.width: 1
+
+ Text {
+ function cleanup(string) {
+ var t = string.replace("-", " ")
+ .replace("|", " ").replace(",", " ")
+ return t
+ }
+
+ visible: bg.color != "white"
+ text: cleanup(title)
+ font.family: defaultFontFamily
+ font.pixelSize: 18
+ color: engine.oppositeColor(square.color)
+ anchors.centerIn: parent
+ width: parent.width - 10
+ height: parent.height
+ maximumLineCount: 3
+ elide: Text.ElideRight
+ wrapMode: Text.Wrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Rectangle {
+ id: bg
+ anchors {
+ left: parent.left
+ top: parent.top
+ margins: 1
+ }
+ state: "fallback"
+ width: {
+ if (icon.sourceSize.width < 100)
+ return 32
+ return square.width - 2
+ }
+ height: width
+ states: [
+ State {
+ name: "fallback"
+ PropertyChanges {
+ target: square
+ color: fallbackColor
+ }
+ PropertyChanges {
+ target: bg
+ color: square.color
+ }
+ },
+ State {
+ name: "snapshot"
+ PropertyChanges {
+ target: bg
+ color: "white"
+ }
+ },
+ State {
+ name: "normal"
+ PropertyChanges {
+ target: square
+ color: iconColor
+ }
+ PropertyChanges {
+ target: bg
+ color: square.color
+ }
+ }
+ ]
+ Timer {
+ id: timer
+ onTriggered: {
+ if (!bg.width || !bg.height)
+ return
+
+ bg.state = "snapshot"
+ bg.grabToImage(function(result) {
+ square.iconColor = engine.colorForIcon(result)
+ bg.state = "normal"
+ });
+ }
+ }
+
+ Image {
+ id: icon
+ anchors.centerIn: parent
+ width: bg.width
+ height: bg.height
+ source: iconUrl
+ onSourceChanged: bg.state = "snapshot"
+ onStatusChanged: {
+ switch (status) {
+ case Image.Null:
+ case Image.Loading:
+ case Image.Error:
+ square.iconColor = "white"
+ bg.state = "fallback"
+ break
+ case Image.Ready:
+ bg.state = "normal"
+ timer.restart()
+ break
+ }
+ }
+ }
+ }
+ Rectangle {
+ id: overlay
+ visible: opacity != 0.0
+ anchors.fill: parent
+ color: iconStrokeColor
+ opacity: {
+ if (iconMouse.pressed) {
+ if (homeScreen.state != "edit")
+ return 0.1
+ return 0.4
+ }
+ if (homeScreen.state == "edit")
+ return 0.3
+ return 0.0
+ }
+ }
+ MouseArea {
+ id: iconMouse
+ anchors.fill: parent
+ onPressAndHold: {
+ if (homeScreen.state == "edit") {
+ homeScreen.state = "visible"
+ return
+ }
+ homeScreen.state = "edit"
+ }
+ onPressed: {
+ console.log("index="+ index +" | title=" + title + " | url=" + url + " | iconUrl=" + iconUrl + " | fallbackColor=" + fallbackColor)
+ // TODO: open bookmark
+ }
+ }
+ Rectangle {
+ enabled: homeScreen.state == "edit"
+ opacity: enabled ? 1.0 : 0.0
+ width: image.sourceSize.width
+ height: image.sourceSize.height - 2
+ radius: width / 2
+ color: iconStrokeColor
+ anchors {
+ horizontalCenter: parent.right
+ verticalCenter: parent.top
+ }
+ Image {
+ id: image
+ opacity: {
+ if (deleteButton.pressed)
+ return 0.70
+ return 1.0
+ }
+ anchors {
+ top: parent.top
+ left: parent.left
+ }
+ source: "qrc:///delete"
+ MouseArea {
+ id: deleteButton
+ anchors.fill: parent
+ onClicked: {
+ mouse.accepted = true
+ listModel.remove(index)
+ gridView.forceLayout()
+ }
+ }
+ }
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration }
+ }
+ }
+ }
+ }
+ Rectangle {
+ width: homeScreen.cellSize - homeScreen.padding / 2 - 10
+ anchors {
+ left: parent.left
+ top: parent.top
+ bottom: parent.bottom
+ }
+ MouseArea {
+ enabled: homeScreen.state == "edit"
+ anchors.fill: parent
+ onPressed: homeScreen.state = "visible"
+ }
+ }
+ Rectangle {
+ width: homeScreen.cellSize - homeScreen.padding / 2 - 10
+ anchors {
+ right: parent.right
+ top: parent.top
+ bottom: parent.bottom
+ }
+ MouseArea {
+ enabled: homeScreen.state == "edit"
+ anchors.fill: parent
+ onPressed: homeScreen.state = "visible"
+ }
+ }
+ Rectangle {
+ id: pageIndicator
+ color: "transparent"
+ anchors {
+ bottom: parent.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ height: 80
+ width: 150
+ Rectangle {
+ property bool active: gridView.contentX < gridView.page
+ width: enabled && active ? 10 : 8
+ height: width
+ radius: width / 2
+ color: active ? iconStrokeColor : uiColor
+ anchors.verticalCenter: parent.verticalCenter
+ x: parent.width / 4 - width / 2
+ MouseArea {
+ anchors.fill: parent
+ onClicked: gridView.contentX = 0
+ }
+ }
+ Rectangle {
+ property bool active: gridView.page <= gridView.contentX && gridView.contentX < 2 * gridView.page
+ width: enabled && active ? 10 : 8
+ enabled: gridView.count > 8
+ height: width
+ radius: width / 2
+ color: {
+ if (!enabled)
+ return inactivePagerColor
+
+ return active ? iconStrokeColor : uiColor
+ }
+ anchors.verticalCenter: parent.verticalCenter
+ x: parent.width / 2 - width / 2
+ MouseArea {
+ anchors.fill: parent
+ onClicked: gridView.contentX = gridView.page
+ }
+ }
+ Rectangle {
+ property bool active: 2 * gridView.page <= gridView.contentX
+ width: enabled && active ? 10 : 8
+ enabled: gridView.count > 16
+ height: width
+ radius: width / 2
+ color: {
+ if (!enabled)
+ return inactivePagerColor
+
+ return active ? iconStrokeColor : uiColor
+ }
+ anchors.verticalCenter: parent.verticalCenter
+ x: 3 * parent.width / 4 - width / 2
+ MouseArea {
+ anchors.fill: parent
+ onClicked: gridView.contentX = 2 * gridView.page
+ }
+ }
+ }
+}
diff --git a/src/qml/NavigationBar.qml b/src/qml/NavigationBar.qml
index 23cca7e..ce0b80b 100644
--- a/src/qml/NavigationBar.qml
+++ b/src/qml/NavigationBar.qml
@@ -13,7 +13,7 @@ ToolBar {
property Item webView: null
visible: opacity != 0.0
- opacity: tabs.viewState == "page" ? 1.0 : 0.0
+ opacity: tabView.viewState == "page" ? 1.0 : 0.0
style: ToolBarStyle {
background: Rectangle {
@@ -100,14 +100,14 @@ ToolBar {
style: TextFieldStyle {
textColor: "black"
font.family: defaultFontFamily
- font.pointSize: 28
- selectionColor: uiSelectionColor
+ font.pixelSize: 28
+ selectionColor: uiHighlightColor
selectedTextColor: "black"
- placeholderTextColor: "#a0a1a2"
+ placeholderTextColor: placeholderColor
background: Rectangle {
implicitWidth: 514
implicitHeight: 56
- border.color: "#3881ae"
+ border.color: textFieldStrokeColor
border.width: 1
}
padding {
@@ -117,7 +117,8 @@ ToolBar {
}
onAccepted: {
webView.url = engine.fromUserInput(text)
- tabs.viewState = "page"
+ homeScreen.state = "disabled"
+ tabView.viewState = "page"
}
onEditingFinished: selectAll()
onFocusChanged: {
@@ -151,7 +152,10 @@ ToolBar {
id: homeButton
source: "qrc:///home"
onClicked: {
- console.log("Home clicked")
+ if (homeScreen.state == "disabled" || homeScreen.state == "edit")
+ homeScreen.state = "enabled"
+ else if (homeScreen.state != "disabled")
+ homeScreen.state = "disabled"
}
}
Rectangle {
@@ -166,11 +170,12 @@ ToolBar {
id: pageViewButton
source: "qrc:///tabs"
onClicked: {
- if (tabs.viewState == "list") {
- tabs.viewState = "page"
+ if (tabView.viewState == "list") {
+ tabView.viewState = "page"
} else {
- tabs.get(tabs.currentIndex).item.webView.takeSnapshot()
- tabs.viewState = "list"
+ tabView.get(tabView.currentIndex).item.webView.takeSnapshot()
+ homeScreen.state = "disabled"
+ tabView.viewState = "list"
}
}
Text {
@@ -179,9 +184,9 @@ ToolBar {
verticalCenterOffset: 4
}
- text: tabs.count
+ text: tabView.count
font.family: defaultFontFamily
- font.pointSize: 16
+ font.pixelSize: 16
font.weight: Font.DemiBold
color: "white"
}
@@ -198,7 +203,16 @@ ToolBar {
id: bookmarksButton
source: "qrc:///star"
onClicked: {
- console.log("Bookmarks clicked")
+ if (!webView)
+ return
+
+ var idx = homeScreen.contains(webView.url.toString())
+ if (idx != -1) {
+ homeScreen.state = "enabled"
+ homeScreen.select(idx)
+ return
+ }
+ homeScreen.add(webView.title, webView.url, webView.icon, engine.randomColor())
}
}
Rectangle {
@@ -214,7 +228,7 @@ ToolBar {
source: "qrc:///settings"
checkable: true
checked: false
- onClicked: tabs.interactive = !checked
+ onClicked: tabView.interactive = !checked
}
}
ProgressBar {
@@ -233,7 +247,7 @@ ToolBar {
color: uiSeparatorColor
}
progress: Rectangle {
- color: uiSelectionColor
+ color: uiHighlightColor
}
}
minimumValue: 0
diff --git a/src/qml/PageView.qml b/src/qml/PageView.qml
index bbe687f..3552a0b 100644
--- a/src/qml/PageView.qml
+++ b/src/qml/PageView.qml
@@ -58,6 +58,11 @@ Rectangle {
property string viewState: "page"
+ onViewStateChanged: {
+ if (viewState == "page")
+ homeScreen.state = "disabled"
+ }
+
property QtObject otrProfile: WebEngineProfile {
offTheRecord: true
}
@@ -116,6 +121,7 @@ Rectangle {
}
profile: defaultProfile
+ enabled: root.interactive
function takeSnapshot() {
if (tabItem.image.url == webEngineView.url || tabItem.opacity != 1.0)
@@ -148,19 +154,19 @@ Rectangle {
if (!request.userInitiated)
print("Warning: Blocked a popup window.")
else if (request.destination == WebEngineView.NewViewInTab) {
- tab = tabs.createEmptyTab()
- pathView.positionViewAtIndex(tabs.count - 1, PathView.Center)
+ tab = tabView.createEmptyTab()
+ pathView.positionViewAtIndex(tabView.count - 1, PathView.Center)
request.openIn(tab.webView)
} else if (request.destination == WebEngineView.NewViewInBackgroundTab) {
var index = pathView.currentIndex
- tab = tabs.createEmptyTab()
+ tab = tabView.createEmptyTab()
request.openIn(tab.webView)
pathView.positionViewAtIndex(index, PathView.Center)
} else if (request.destination == WebEngineView.NewViewInDialog) {
- var dialog = tabs.createEmptyTab()
+ var dialog = tabView.createEmptyTab()
request.openIn(dialog.webView)
} else {
- var window = tabs.createEmptyTab()
+ var window = tabView.createEmptyTab()
request.openIn(window.webView)
}
}
@@ -194,7 +200,7 @@ Rectangle {
TouchTracker {
id: tracker
-
+ enabled: root.interactive
target: webEngineView
anchors.fill: parent
onTouchYChanged: browserWindow.touchY = tracker.touchY
@@ -282,7 +288,6 @@ Rectangle {
}
element.item.webView.url = "about:blank"
- element.index = listModel.count
listModel.append(element)
return element.item
}
@@ -291,10 +296,6 @@ Rectangle {
pathView.interactive = false
pathView.currentItem.state = ""
pathView.currentItem.visible = false
- // Update indices of remaining items
- for (var idx = index + 1; idx < listModel.count; ++idx)
- listModel.get(idx).index -= 1
-
listModel.remove(index)
pathView.decrementCurrentIndex()
pathView.interactive = true
@@ -407,7 +408,7 @@ Rectangle {
topMargin: 9
horizontalCenter: parent.horizontalCenter
}
- color: "#0e202c"
+ color: iconStrokeColor
radius: size / 2
width: snapshot.width
height: snapshot.height
@@ -440,7 +441,7 @@ Rectangle {
width: image.sourceSize.width
height: image.sourceSize.height - 2
radius: width / 2
- color: "darkgrey"
+ color: iconStrokeColor
anchors {
horizontalCenter: parent.right
verticalCenter: parent.top
@@ -484,7 +485,7 @@ Rectangle {
width: parent.width - image.width
elide: Text.ElideRight
text: item.title
- font.pointSize: 16
+ font.pixelSize: 16
font.family: defaultFontFamily
color: "#0B508C"
visible: wrapper.isCurrentItem && wrapper.visibility == 1.0
diff --git a/src/qml/assets/UIButton.qml b/src/qml/assets/UIButton.qml
index e83c2e4..3a65c12 100644
--- a/src/qml/assets/UIButton.qml
+++ b/src/qml/assets/UIButton.qml
@@ -12,11 +12,11 @@ ToolButton {
property string source: ""
property real radius: 0.0
property string color: uiColor
- property string highlightColor: buttonHighlightColor
+ property string highlightColor: buttonPressedColor
style: ButtonStyle {
background: Rectangle {
opacity: root.enabled ? 1.0 : 0.3
- color: root.pressed ? root.highlightColor : root.color
+ color: root.pressed || root.checked ? root.highlightColor : root.color
radius: root.radius
Image {
source: root.source
diff --git a/src/resources.qrc b/src/resources.qrc
index 5d375e1..17e28c8 100644
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -1,11 +1,11 @@
<RCC>
<qresource prefix="/">
- <file>qml/BrowserDialog.qml</file>
<file>qml/BrowserWindow.qml</file>
<file>qml/FeaturePermissionBar.qml</file>
<file>qml/MockTouchPoint.qml</file>
<file>qml/PageView.qml</file>
<file>qml/NavigationBar.qml</file>
+ <file>qml/HomeScreen.qml</file>
<file>qml/assets/UIButton.qml</file>
<file alias="home">qml/assets/icons/Btn_Home.png</file>
<file alias="tabs">qml/assets/icons/Btn_Tabs.png</file>
diff --git a/src/src.pro b/src/src.pro
index d0088da..f70fb48 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -17,12 +17,12 @@ HEADERS = utils.h \
OTHER_FILES = \
qml/assets/UIButton.qml \
qml/ApplicationRoot.qml \
- qml/BrowserDialog.qml \
qml/BrowserWindow.qml \
qml/FeaturePermissionBar.qml \
qml/MockTouchPoint.qml \
qml/PageView.qml \
qml/NavigationBar.qml \
+ qml/HomeScreen.qml \
QT += qml quick webengine
QT_PRIVATE += quick-private gui-private core-private
diff --git a/src/utils.h b/src/utils.h
index 45ba2ad..04c181e 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -41,6 +41,8 @@
#include <QtCore/QEvent>
#include <QtCore/QFileInfo>
#include <QtCore/QUrl>
+#include <QtGui/QColor>
+#include <QtQuick/QQuickItemGrabResult>
namespace utils {
inline bool isTouchEvent(const QEvent* event)
@@ -68,16 +70,23 @@ inline bool isMouseEvent(const QEvent* event)
}
}
+inline int randomColor()
+{
+ return qrand() % 255;
+}
+
}
class Utils : public QObject {
Q_OBJECT
Q_PROPERTY(QObject * rootWindow READ rootWindow FINAL CONSTANT)
+
public:
Utils(QObject *parent)
: QObject(parent)
{
+ qsrand(255);
}
QObject *rootWindow()
{
@@ -86,6 +95,9 @@ public:
Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
Q_INVOKABLE static QString domainFromString(const QString& urlString);
+ Q_INVOKABLE static QString randomColor();
+ Q_INVOKABLE static QString colorForIcon(QQuickItemGrabResult *result);
+ Q_INVOKABLE static QString oppositeColor(const QString & color);
};
inline QUrl Utils::fromUserInput(const QString& userInput)
@@ -101,4 +113,46 @@ inline QString Utils::domainFromString(const QString& urlString)
return QUrl::fromUserInput(urlString).host();
}
+inline QString Utils::randomColor()
+{
+ QColor color(utils::randomColor(), utils::randomColor(), utils::randomColor());
+ return color.name();
+}
+
+inline QString Utils::colorForIcon(QQuickItemGrabResult *result)
+{
+ QImage image = result->image();
+ int hue = 0;
+ int saturation = 0;
+ int value = 0;
+ for (int i = 0, width = image.width(); i < width; ++i) {
+ int skip = 0;
+ int h = 0;
+ int s = 0;
+ int v = 0;
+ for (int j = 0, height = image.height(); j < height; ++j) {
+ const QColor color(QColor(image.pixel(i, j)).toHsv());
+ if (color.alpha() < 127) {
+ ++skip;
+ continue;
+ }
+
+ h += color.hsvHue();
+ s += color.hsvSaturation();
+ v += color.value();
+ }
+ int count = image.height() - skip + 1;
+ hue = h / count;
+ saturation = s / count;
+ value = v / count;
+ }
+ return QColor::fromHsv(hue, saturation, value).name();
+}
+
+inline QString Utils::oppositeColor(const QString &color)
+{
+ const QColor c(QColor(color).toHsv());
+ return QColor::fromHsv(c.hue(), c.saturation(), c.value() < 127 ? 255 : c.value() - 100).name();
+}
+
#endif // UTILS_H