| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 |
- import QtQuick 2.12
- import QtQuick.Controls 2.12
- import QtQuick.Layouts 1.12
- import QtQuick.Particles 2.0
- import Qt.labs.settings 1.0
- import org.qfield 1.0
- import Theme 1.0
- Page {
- id: welcomeScreen
- property bool firstShown: false
- property alias model: table.model
- signal showOpenProjectDialog
- signal showQFieldCloudScreen
- Settings {
- id: registry
- category: 'QField'
- property string baseMapProject: ''
- }
- Rectangle {
- id: welcomeBackground
- anchors.fill: parent
- gradient: Gradient {
- GradientStop {
- position: 0.0
- color: "#ffdedede"
- }
- GradientStop {
- position: 0.33
- color: "#00dedede"
- }
- }
- }
- ScrollView {
- padding: 0
- ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
- ScrollBar.vertical.policy: ScrollBar.AsNeeded
- contentItem: welcomeGrid
- contentWidth: welcomeGrid.width
- contentHeight: welcomeGrid.height
- anchors.fill: parent
- clip: true
- GridLayout {
- id: welcomeGrid
- columns: 1
- rowSpacing: 4
- width: mainWindow.width
- ImageDial{
- id: imageDialLogo
- value: 1
- Layout.margins: 6
- Layout.topMargin: 14
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- Layout.preferredWidth: Math.min( 138, mainWindow.height / 4 )
- Layout.preferredHeight: Math.min( 138, mainWindow.height / 4 )
- source: "qrc:/images/qfield_logo.svg"
- rotationOffset: 220
- }
- SwipeView {
- id: feedbackView
- visible: false
- Layout.margins: 6
- Layout.topMargin: 10
- Layout.bottomMargin: 10
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- Layout.preferredWidth: Math.min( 410, mainWindow.width - 30 )
- Layout.preferredHeight: Math.max(ohno.childrenRect.height, intro.childrenRect.height, ohyeah.childrenRect.height)
- clip: true
- Behavior on Layout.preferredHeight {
- NumberAnimation { duration: 100; easing.type: Easing.InQuad; }
- }
- interactive: false
- currentIndex: 1
- Item {
- id: ohno
- Rectangle {
- anchors.fill: parent
- gradient: Gradient {
- GradientStop {
- position: 0.0
- color: "#4480cc28"
- }
- GradientStop {
- position: 0.88
- color: "#0580cc28"
- }
- }
- radius: 6
- }
- ColumnLayout {
- spacing: 0
- anchors.centerIn: parent
- Text {
- Layout.margins: 6
- Layout.maximumWidth: feedbackView.width - 12
- text: qsTr("We're sorry to hear that. Click on the button below to comment or seek support.")
- font: Theme.defaultFont
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- }
- RowLayout {
- spacing: 6
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- Layout.bottomMargin: 10
- QfButton {
- leftPadding: 20
- rightPadding: 20
- text: qsTr("Reach out")
- icon.source: Theme.getThemeIcon( 'ic_create_white_24dp' )
- onClicked: {
- Qt.openUrlExternally("https://www.qfield.org/")
- feedbackView.Layout.preferredHeight = 0
- }
- }
- }
- }
- }
- Item {
- id: intro
- Rectangle {
- anchors.fill: parent
- gradient: Gradient {
- GradientStop {
- position: 0.0
- color: "#4480cc28"
- }
- GradientStop {
- position: 0.88
- color: "#0580cc28"
- }
- }
- radius: 6
- }
- ColumnLayout {
- spacing: 0
- anchors.centerIn: parent
- Text {
- Layout.margins: 6
- Layout.maximumWidth: feedbackView.width - 12
- text: qsTr("Hey there, how do you like your experience with QField so far?")
- font: Theme.defaultFont
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- }
- RowLayout {
- spacing: 6
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- Layout.bottomMargin: 10
- QfToolButton {
- iconSource: Theme.getThemeVectorIcon('ic_dissatisfied_white_24dp')
- bgcolor: Theme.mainColor
- round: true
- onClicked: {
- feedbackView.currentIndex = 0
- }
- }
- QfToolButton {
- iconSource: Theme.getThemeVectorIcon('ic_satisfied_white_24dp')
- bgcolor: Theme.mainColor
- round: true
- onClicked: {
- feedbackView.currentIndex = 2
- }
- }
- }
- }
- }
- Item {
- id: ohyeah
- Rectangle {
- anchors.fill: parent
- gradient: Gradient {
- GradientStop {
- position: 0.0
- color: "#4480cc28"
- }
- GradientStop {
- position: 0.88
- color: "#0580cc28"
- }
- }
- radius: 6
- }
- ColumnLayout {
- spacing: 0
- anchors.centerIn: parent
- Text {
- Layout.margins: 6
- Layout.maximumWidth: feedbackView.width - 12
- text: qsTr("That's great! We'd love for you to click on the button below and leave a comment on the store.")
- font: Theme.defaultFont
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- }
- RowLayout {
- spacing: 6
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- Layout.margins: 6
- Layout.bottomMargin: 10
- QfButton {
- leftPadding: 20
- rightPadding: 20
- text: qsTr("Rate us")
- icon.source: Theme.getThemeVectorIcon( 'ic_star_white_24dp' )
- onClicked: {
- Qt.openUrlExternally("market://details?id=ch.opengis.qfield")
- feedbackView.Layout.preferredHeight = 0
- }
- }
- }
- }
- }
- }
- Text {
- id: welcomeText
- visible: !feedbackView.visible
- Layout.leftMargin: 6
- Layout.rightMargin: 6
- Layout.topMargin: 2
- Layout.bottomMargin: 2
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- text: ""
- font: Theme.defaultFont
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- }
- Rectangle {
- Layout.leftMargin: 6
- Layout.rightMargin: 6
- Layout.topMargin: 2
- Layout.bottomMargin: 2
- Layout.fillWidth: true
- Layout.maximumWidth: 410
- Layout.minimumHeight: welcomeActions.height
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- color: "transparent"
- ColumnLayout {
- id: welcomeActions
- width: parent.width
- spacing: 12
- QfButton {
- id: localProjectButton
- Layout.fillWidth: true
- text: qsTr( "Open local file" )
- onClicked: {
- showOpenProjectDialog()
- }
- }
- QfButton {
- id: cloudProjectButton
- Layout.fillWidth: true
- text: qsTr( "QField Cloud projects" )
- onClicked: {
- showQFieldCloudScreen()
- }
- }
- Text {
- id: recentText
- text: qsTr( "Recent Projects" )
- font.pointSize: Theme.tipFont.pointSize
- font.bold: true
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- Layout.fillWidth: true
- }
- Rectangle {
- Layout.fillWidth: true
- height: table.height
- color: "transparent"
- border.color: "transparent"
- border.width: 1
- ListView {
- id: table
- ScrollBar.vertical: ScrollBar {}
- flickableDirection: Flickable.VerticalFlick
- boundsBehavior: Flickable.StopAtBounds
- clip: true
- width: parent.width
- height: childrenRect.height
- delegate: Rectangle {
- id: rectangle
- objectName: "loadProjectItem_1" // todo, suffix with e.g. ProjectTitle
- property string path: ProjectPath
- property string title: ProjectTitle
- property var type: ProjectType
- width: parent ? parent.width : undefined
- height: line.height
- color: "transparent"
- Row {
- id: line
- Layout.fillWidth: true
- leftPadding: 6
- rightPadding: 10
- topPadding: 9
- bottomPadding: 3
- spacing: 0
- Image {
- id: type
- anchors.verticalCenter: inner.verticalCenter
- source: switch(ProjectType) {
- case 0: return Theme.getThemeIcon('ic_map_green_48dp'); // local project
- case 1: return Theme.getThemeIcon('ic_cloud_project_48dp'); // cloud project
- case 2: return Theme.getThemeIcon('ic_file_green_48dp'); // local dataset
- default: return '';
- }
- sourceSize.width: 80
- sourceSize.height: 80
- width: 40
- height: 40
- }
- ColumnLayout {
- id: inner
- width: rectangle.width - type.width - 10
- Text {
- id: projectTitle
- topPadding: 5
- leftPadding: 3
- text: ProjectTitle
- font.pointSize: Theme.tipFont.pointSize
- font.underline: true
- color: Theme.mainColor
- wrapMode: Text.WordWrap
- Layout.fillWidth: true
- }
- Text {
- id: projectNote
- leftPadding: 3
- text: {
- var notes = [];
- if ( index == 0 ) {
- var firstRun = settings && !settings.value( "/QField/FirstRunFlag", false )
- if (!firstRun && firstShown === false) notes.push( qsTr( "Last session" ) );
- }
- if ( ProjectPath === registry.baseMapProject ) {
- notes.push( qsTr( "Base map project" ) );
- }
- if ( notes.length > 0 ) {
- return notes.join( '; ' );
- } else {
- return "";
- }
- }
- visible: text != ""
- font.pointSize: Theme.tipFont.pointSize - 2
- font.italic: true
- wrapMode: Text.WordWrap
- Layout.fillWidth: true
- }
- }
- }
- }
- MouseArea {
- property Item pressedItem
- anchors.fill: parent
- onClicked: {
- var item = table.itemAt(mouse.x, mouse.y)
- if (item) {
- if ( item.type == 1 && cloudConnection.hasToken && cloudConnection.status !== QFieldCloudConnection.LoggedIn ) {
- cloudConnection.login()
- }
- iface.loadFile(item.path,item.title)
- }
- }
- onPressed: {
- var item = table.itemAt(mouse.x, mouse.y)
- if (item) {
- pressedItem = item.children[0].children[1].children[0];
- pressedItem.color = "#5a8725"
- }
- }
- onCanceled: {
- if (pressedItem) {
- pressedItem.color = Theme.mainColor
- pressedItem = null
- }
- }
- onReleased: {
- if (pressedItem) {
- pressedItem.color = Theme.mainColor
- pressedItem = null
- }
- }
- onPressAndHold: {
- var item = table.itemAt(mouse.x, mouse.y)
- if (item) {
- recentProjectActions.recentProjectPath = item.path;
- recentProjectActions.recentProjectType = item.type;
- recentProjectActions.popup(mouse.x, mouse.y)
- }
- }
- }
- Menu {
- id: recentProjectActions
- property string recentProjectPath: ''
- property int recentProjectType: 0
- title: 'Recent Project Actions'
- width: {
- var result = 0;
- var padding = 0;
- for (var i = 0; i < count; ++i) {
- var item = itemAt(i);
- result = Math.max(item.contentItem.implicitWidth, result);
- padding = Math.max(item.padding, padding);
- }
- return Math.min( result + padding * 2,mainWindow.width - 20);
- }
- MenuItem {
- id: baseMapProject
- visible: recentProjectActions.recentProjectType != 2;
- font: Theme.defaultFont
- width: parent.width
- height: visible ? 48: 0
- checkable: true
- checked: recentProjectActions.recentProjectPath === registry.baseMapProject
- text: qsTr( "Base Map Project" )
- onTriggered: {
- registry.baseMapProject = recentProjectActions.recentProjectPath === registry.baseMapProject ? '' : recentProjectActions.recentProjectPath;
- }
- }
- MenuSeparator {
- visible: baseMapProject.visible
- width: parent.width
- height: visible ? undefined : 0
- }
- MenuItem {
- id: removeProject
- font: Theme.defaultFont
- width: parent.width
- height: visible ? 48: 0
- leftPadding: 10
- text: qsTr( "Remove from Recent Projects" )
- onTriggered: {
- iface.removeRecentProject( recentProjectActions.recentProjectPath );
- model.reloadModel();
- }
- }
- }
- }
- }
- }
- }
- }
- }
- QfToolButton {
- id: currentProjectButton
- visible: false
- anchors {
- top: parent.top
- left: parent.left
- }
- iconSource: Theme.getThemeIcon( 'ic_chevron_left_black_24dp' )
- bgcolor: "transparent"
- onClicked: {
- welcomeScreen.visible = false;
- welcomeScreen.focus = false;
- }
- }
- // Sparkles & unicorns
- Rectangle {
- anchors.fill: parent
- color: "#00000000"
- visible: imageDialLogo.value < 0.1
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- acceptedButtons: Qt.LeftButton | Qt.RightButton
- hoverEnabled: true
- propagateComposedEvents: true
- onReleased: mouse.accepted = false
- onDoubleClicked: mouse.accepted = false
- onPressAndHold: mouse.accepted = false
- onClicked: {
- burstSomeSparkles(mouse.x, mouse.y)
- mouse.accepted = false
- }
- onPressed: {
- burstSomeSparkles(mouse.x, mouse.y)
- mouse.accepted = false
- }
- onPositionChanged: {
- burstSomeSparkles(mouse.x, mouse.y)
- mouse.accepted = false
- }
- }
- ParticleSystem {
- id: particles
- running: imageDialLogo.value < 0.1
- }
- ParticleSystem {
- id: unicorns
- running: imageDialLogo.value < 0.1
- }
- ImageParticle {
- anchors.fill: parent
- system: particles
- source: "qrc:///particleresources/star.png"
- sizeTable: "qrc:///images/sparkleSize.png"
- alpha: 1
- colorVariation: 0.3
- }
- ImageParticle {
- anchors.fill: parent
- system: unicorns
- source: "qrc:///images/icons/unicorn.png"
- alpha: 1
- redVariation: 0
- blueVariation: 0
- greenVariation: 0
- rotation: 0
- rotationVariation: 360
- }
- Emitter {
- id: emitterParticles
- x: -100
- y: -100
- system: particles
- emitRate: 60
- lifeSpan: 700
- size: 50
- sizeVariation: 10
- maximumEmitted: 100
- velocity: AngleDirection {
- angle: 0
- angleVariation: 360
- magnitude: 100
- magnitudeVariation: 50
- }
- }
- Emitter {
- id: emitterUnicorns
- x: -100
- y: -100
- system: unicorns
- emitRate: 20
- lifeSpan: 900
- size: 70
- sizeVariation: 10
- maximumEmitted: 100
- velocity: AngleDirection {
- angle: 90
- angleVariation: 20
- magnitude: 200
- magnitudeVariation: 50
- }
- }
- }
- function burstSomeSparkles(x, y) {
- emitterParticles.burst(50, x, y)
- emitterUnicorns.burst(1, x, y)
- }
- function adjustWelcomeScreen() {
- if (visible) {
- if (firstShown) {
- welcomeText.text = " ";
- currentProjectButton.visible = true
- } else {
- var firstRun = !settings.value( "/QField/FirstRunFlag", false )
- if ( firstRun ) {
- welcomeText.text = qsTr( "Welcome to QField. First time using this application? Try out a few demos listed in the recent projects below." )
- } else {
- welcomeText.text = qsTr( "Welcome back to QField." )
- }
- currentProjectButton.visible = false
- }
- }
- }
- Component.onCompleted: {
- adjustWelcomeScreen()
- var runCount = settings.value("/QField/RunCount",0) * 1
- var feedbackFormShown = settings.value("/QField/FeedbackFormShown",false)
- if (!feedbackFormShown) {
- var now = new Date()
- var dt = settings.value("/QField/FirstRunDate", "")
- if (dt != "") {
- dt = new Date(dt)
- var daysToPrompt = 30;
- var runsToPrompt = 5;
- if (runCount >= runsToPrompt && (now - dt) >= (daysToPrompt * 24 * 60 * 60 * 1000)) {
- feedbackView.visible = true
- settings.setValue("/QField/FeedbackFormShown",true)
- }
- } else {
- settings.setValue("/QField/FirstRunDate", now.toISOString())
- }
- }
- settings.setValue("/QField/RunCount",runCount + 1)
- }
- onVisibleChanged: {
- adjustWelcomeScreen()
- if (!visible) {
- feedbackView.visible = false
- firstShown = true
- }
- }
- }
|