diff --git a/src/qml/homescreen/CourseSelector.qml b/src/qml/homescreen/CourseSelector.qml index 018d078..c69aa33 100644 --- a/src/qml/homescreen/CourseSelector.qml +++ b/src/qml/homescreen/CourseSelector.qml @@ -1,180 +1,192 @@ /* * Copyright 2012 Sebastian Gottfried * Copyright 2015 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.4 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 import ktouch 1.0 import "../common" FocusScope { id: root property Profile profile - property KeyboardLayout keyboardLayout property string currentKeyboardLayoutName property string selectedKeyboardLayoutName + property DataIndexKeyboardLayout selectedKeyboardLayout property DataIndexCourse selectedCourse signal lessonSelected(variant course, variant lesson) signal courseSelectec(Course course) function selectLastUsedCourse() { if (!profile) { return } var courseId = profile.lastUsedCourseId; // fist try to to select the course the user has used last for (var i = 0; i < allCoursesModel.rowCount(); i++) { var dataIndexCourse = allCoursesModel.data(allCoursesModel.index(i, 0), ResourceModel.DataRole); if (dataIndexCourse.id === courseId) { root.selectedCourse = dataIndexCourse return } } // if this fails try to select course matching the current keyboard layout if (coursesForCurrentKeyboardLayoutModel.rowCount() > 0) { var blub = coursesForCurrentKeyboardLayoutModel.data(coursesForCurrentKeyboardLayoutModel.index(0, 0), ResourceModel.DataRole); console.log(blub) root.selectedCourse = blub return; } // finally just select the first course if (allCoursesModel.rowCount() > 0) { root.selectedCourse = allCoursesModel.data(allCoursesModel.index(0, 0), ResourceModel.DataRole); } } onSelectedCourseChanged: { root.selectedKeyboardLayoutName = root.selectedCourse.keyboardLayoutName; + + for (var i = 0; i < ktouch.globalDataIndex.keyboardLayoutCount; i++) + { + var dataIndexLayout = ktouch.globalDataIndex.keyboardLayout(i) + + if (dataIndexLayout.name === root.selectedKeyboardLayoutName) { + root.selectedKeyboardLayout = dataIndexLayout; + return + } + } + + root.selectedKeyboardLayout = null; } function saveLastUsedCourse(course) { if (profile.lastUsedCourseId != course.id) { profile.lastUsedCourseId = course.id; profileDataAccess.updateProfile(profileDataAccess.indexOfProfile(profile)); } } onProfileChanged: selectLastUsedCourse() ResourceModel { id: resourceModel dataIndex: ktouch.globalDataIndex onRowsRemoved: { selectLastUsedCourse() } onRowsInserted: { selectLastUsedCourse() } } CategorizedResourceSortFilterProxyModel { id: allCoursesModel resourceModel: resourceModel resourceTypeFilter: ResourceModel.CourseItem } CategorizedResourceSortFilterProxyModel { id: coursesForCurrentKeyboardLayoutModel resourceModel: resourceModel resourceTypeFilter: ResourceModel.CourseItem keyboardLayoutNameFilter: root.currentKeyboardLayoutName } CategorizedResourceSortFilterProxyModel { id: currentKeyboardLayoutsModel resourceModel: resourceModel resourceTypeFilter: ResourceModel.KeyboardLayoutItem keyboardLayoutNameFilter: root.currentKeyboardLayoutName } CategorizedResourceSortFilterProxyModel { id: otherKeyboardLayoutsModel resourceModel: resourceModel resourceTypeFilter: ResourceModel.KeyboardLayoutItem keyboardLayoutNameFilter: root.currentKeyboardLayoutName invertedKeyboardLayoutNameFilter: true } KColorScheme { id: courseSelectorColorScheme colorGroup: KColorScheme.Active colorSet: KColorScheme.View } Rectangle { id: bg anchors.fill: parent color: courseSelectorColorScheme.normalBackground } Flickable { clip: true anchors.fill: parent contentWidth: width contentHeight: content.height Column { id: content width: parent.width CourseSelectorKeyboardLayoutList { width: parent.width title: i18n('Courses For Your Keyboard Layout') model: currentKeyboardLayoutsModel resourceModel: resourceModel colorScheme: courseSelectorColorScheme selectedKeyboardLayoutName: root.selectedKeyboardLayoutName selectedCourse: root.selectedCourse onCourseSelected: { root.selectedCourse = course root.saveLastUsedCourse(course) } } CourseSelectorKeyboardLayoutList { width: parent.width title: i18n('Other courses') model: otherKeyboardLayoutsModel resourceModel: resourceModel colorScheme: courseSelectorColorScheme selectedKeyboardLayoutName: root.selectedKeyboardLayoutName selectedCourse: root.selectedCourse onCourseSelected: { root.selectedCourse = course root.saveLastUsedCourse(course) } } } ScrollBar.vertical: ScrollBar { } } } diff --git a/src/qml/homescreen/HomeScreen.qml b/src/qml/homescreen/HomeScreen.qml index d5e2cd3..efa9dfa 100644 --- a/src/qml/homescreen/HomeScreen.qml +++ b/src/qml/homescreen/HomeScreen.qml @@ -1,155 +1,157 @@ /* * Copyright 2012 Sebastian Gottfried * Copyright 2015 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.6 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import ktouch 1.0 import "../common" FocusScope { id: screen - property KeyboardLayout keyboardLayout - property string keyboardLayoutName + property KeyboardLayout selectedKeyboardLayout: KeyboardLayout {} + property string activeKeyboardLayoutName signal lessonSelected(variant course, variant lesson, variant profile) Connections { target: profileDataAccess onProfileCountChanged: findCurrentProfile() } function start() {} function reset() { profileDataAccess.loadProfiles(); } function findCurrentProfile() { profileComboBox.profile = null var lastProfileId = preferences.lastUsedProfileId for (var i = 0; i < profileDataAccess.profileCount; i++) { var profile = profileDataAccess.profile(i) if (profile.id === lastProfileId) { profileComboBox.profile = profile return; } } if (profileDataAccess.profileCount > 0) { profileComboBox.profile = profileDataAccess.profile(0) preferences.lastUsedProfileId = profileComboBox.profile.id preferences.writeConfig() } } function safeLastUsedProfile(profile) { preferences.lastUsedProfileId = profile.id preferences.writeConfig() } RowLayout { anchors.fill: parent spacing: 0 Item { id: navigationArea z: 2 Layout.preferredWidth: 300 Layout.fillHeight: true DropShadow { anchors.fill: navigationAreaLayout source: navigationAreaLayout samples: 16 horizontalOffset: 0 verticalOffset: 0 } ColumnLayout { id: navigationAreaLayout anchors.fill: parent spacing: 0 ToolBar { id: header Layout.fillWidth: true background: Rectangle { color: toolbarColorScheme.toolbarBackground } KColorScheme { id: toolbarColorScheme colorGroup: KColorScheme.Active colorSet: KColorScheme.Complementary property color toolbarBackground: Qt.darker(toolbarColorScheme.shade(toolbarColorScheme.hoverDecoration, KColorScheme.MidShade, toolbarColorScheme.contrast, -0.2), 1.3) } RowLayout { anchors.fill: parent spacing: 5 ProfileComboBox { id: profileComboBox colorScheme: toolbarColorScheme manageProfileButtonBgColor: toolbarColorScheme.toolbarBackground Layout.fillHeight: true Layout.preferredWidth: 300 Layout.fillWidth: true onActivated: { safeLastUsedProfile(profile) } } } } CourseSelector { id: courseSelector Layout.fillHeight: true Layout.fillWidth: true profile: profileComboBox.profile - keyboardLayout: screen.keyboardLayout - currentKeyboardLayoutName: screen.keyboardLayoutName + currentKeyboardLayoutName: screen.activeKeyboardLayoutName + onSelectedKeyboardLayoutChanged: { + dataAccess.loadKeyboardLayout(courseSelector.selectedKeyboardLayout, screen.selectedKeyboardLayout) + } } } } LessonSelector { Layout.fillHeight: true Layout.fillWidth: true profile: profileComboBox.profile - keyboardLayout: screen.keyboardLayout - currentKeyboardLayoutName: screen.keyboardLayoutName + selectedKeyboardLayout: screen.selectedKeyboardLayout + activeKeyboardLayoutName: screen.activeKeyboardLayoutName dataIndexCourse: courseSelector.selectedCourse onLessonSelected: screen.lessonSelected(course, lesson, profileComboBox.profile) z: 1 } } InitialProfileDialog { id: initialProfileForm visible: profileDataAccess.profileCount == 0 } } diff --git a/src/qml/homescreen/LessonSelector.qml b/src/qml/homescreen/LessonSelector.qml index 797b666..a25a6c3 100644 --- a/src/qml/homescreen/LessonSelector.qml +++ b/src/qml/homescreen/LessonSelector.qml @@ -1,408 +1,408 @@ /* * Copyright 2012 Sebastian Gottfried * Copyright 2015 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.4 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.1 import ktouch 1.0 import QtGraphicalEffects 1.0 import "../common" ColumnLayout { id: root property Profile profile property DataIndexCourse dataIndexCourse - property KeyboardLayout keyboardLayout - property string currentKeyboardLayoutName + property KeyboardLayout selectedKeyboardLayout + property string activeKeyboardLayoutName property alias course: courseItem property Lesson selectedLesson: null signal lessonSelected(Course course, Lesson lesson) function update() { if (!course.isValid) return; if (!profile) return; course.updateLastUnlockedLessonIndex(); selectLastLesson() } spacing: 0 function selectLastLesson() { var lessonId = profileDataAccess.courseProgress(profile, course.id, ProfileDataAccess.LastSelectedLesson); if (lessonId !== "") { for (var index = 0; index < course.lessonCount; index++) { if (course.lesson(index).id === lessonId) { root.selectedLesson = course.lesson(index) content.currentIndex = index break } } } } onProfileChanged: update() onDataIndexCourseChanged: { root.selectedLesson = null; course.update(); root.update(); } Course { id: courseItem property int lastUnlockedLessonIndex: -1 property bool editable: courseItem.isValid && courseItem.id === "custom_lessons" function update() { if (root.dataIndexCourse === null) { return } if (dataIndexCourse.id == "custom_lessons") { profileDataAccess.loadCustomLessons(root.profile, dataIndexCourse.keyboardLayoutName, courseItem) } else { if (isValid && courseItem.id === dataIndexCourse.id) { return } dataAccess.loadCourse(dataIndexCourse, courseItem) } } function updateLastUnlockedLessonIndex() { lastUnlockedLessonIndex = 0; if (course.kind == Course.LessonCollection || profile.skillLevel === Profile.Advanced) { lastUnlockedLessonIndex = course.lessonCount - 1; return } var lastUnlockedLessonId = profileDataAccess.courseProgress(profile, course.id, ProfileDataAccess.LastUnlockedLesson); if (lastUnlockedLessonId !== "") { for (var index = 0; index < course.lessonCount; index++) { lastUnlockedLessonIndex = index if (course.lesson(index).id === lastUnlockedLessonId) { return } } } } function createNewCustomLesson() { var lesson = ktouch.createLesson(); lesson.id = utils.uuid() - profileDataAccess.storeCustomLesson(lesson, root.profile, root.keyboardLayout.name) + profileDataAccess.storeCustomLesson(lesson, root.profile, root.selectedKeyboardLayout.name) course.addLesson(lesson) updateLastUnlockedLessonIndex() content.currentIndex = course.indexOfLesson(lesson) root.selectedLesson = lesson lessonEditorDialog.open() } function deleteCustomLesson() { var msgItem = lessonDeletedMessageComponent.createObject(header); msgItem.deletedLesson.copyFrom(selectedLesson); profileDataAccess.deleteCustomLesson(selectedLesson.id); course.removeLesson(course.indexOfLesson(selectedLesson)); root.selectedLesson = null; content.currentIndex = -1; } function restoreCustomLesson(lesson) { course.addLesson(lesson); - profileDataAccess.storeCustomLesson(lesson, root.profile, root.keyboardLayout.name) + profileDataAccess.storeCustomLesson(lesson, root.profile, root.selectedKeyboardLayout.name) content.currentIndex = course.indexOfLesson(lesson); updateLastUnlockedLessonIndex(); } Component.onCompleted: update() } StatPopupDialog { id: statPopupDialog profile: root.profile course: course lesson: root.selectedLesson } LessonEditorDialog { id: lessonEditorDialog profile: root.profile - keyboardLayout: root.keyboardLayout + keyboardLayout: root.selectedKeyboardLayout lesson: root.selectedLesson } Item { Layout.fillWidth: true Layout.preferredHeight: header.height z: 2 Column { id: header width: parent.width ToolBar { id: toolbar width: parent.width background: Rectangle { color: toolbarColorScheme.toolbarBackground } KColorScheme { id: toolbarColorScheme colorGroup: KColorScheme.Active colorSet: KColorScheme.Complementary property color toolbarBackground: Qt.darker(toolbarColorScheme.shade(toolbarColorScheme.hoverDecoration, KColorScheme.MidShade, toolbarColorScheme.contrast, -0.2), 1.5) } RowLayout { anchors.fill: parent anchors.leftMargin: 20 spacing: 5 Label { text: root.course? root.course.title: "" font.bold: true color: toolbarColorScheme.normalText } IconToolButton { id: toggleCourseDesciptionButton icon: "help-about" checkable: true color: toolbarColorScheme.normalText backgroundColor: toolbarColorScheme.normalBackground Layout.fillHeight: true Layout.preferredWidth: toolbar.height } ToolSeparator { visible: courseItem.editable } IconToolButton { id: newLessonButton icon: "document-new" text: "Add New Lesson" color: toolbarColorScheme.normalText visible: courseItem.editable backgroundColor: toolbarColorScheme.normalBackground Layout.fillHeight: true onClicked: { course.createNewCustomLesson() } } Item { Layout.fillWidth: true } IconToolButton { id: configureButton icon: "application-menu" color: toolbarColorScheme.normalText backgroundColor: toolbarColorScheme.normalBackground Layout.fillHeight: true Layout.preferredWidth: toolbar.height onClicked: { var position = mapToItem(null, 0, height) ktouch.showMenu(position.x, position.y) } } } } CourseDescriptionItem { id: courseDescriptionItem width: parent.width collapsed: !toggleCourseDesciptionButton.checked description: courseItem.description } KeyboardLayoutMismatchMessage { width: parent.width - collapsed: !root.course || !root.course.isValid || root.currentKeyboardLayoutName == root.course.keyboardLayoutName + collapsed: !root.course || !root.course.isValid || root.activeKeyboardLayoutName == root.course.keyboardLayoutName } Component { id: lessonDeletedMessageComponent LessonDeletedMessage { width: parent.width onUndeleteRequested: { course.restoreCustomLesson(deletedLesson) } } } } DropShadow { anchors.fill: header source: header samples: 16 horizontalOffset: 0 verticalOffset: 0 } } Item { Layout.fillHeight: true Layout.fillWidth: true z: 1 KColorScheme { id: gridColorScheme colorGroup: KColorScheme.Active colorSet: KColorScheme.View } Rectangle { anchors.fill: parent color: gridColorScheme.shade(gridColorScheme.normalBackground, KColorScheme.DarkShade, 1, 0.0) } GridView { id: content anchors.fill: parent anchors.leftMargin: 20 clip: true focus: true property int columns: Math.floor(width / (300 + 20)) cellWidth: Math.floor(content.width / content.columns) cellHeight: Math.round(cellWidth * 2 / 3) Keys.onPressed: { if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { event.accepted = true; if (root.selectedLesson && content.currentIndex <= course.lastUnlockedLessonIndex) { lessonSelected(course, root.selectedLesson) } } } model: LessonModel { id: lessonModel course: courseItem } onCurrentIndexChanged: { if (lessonModel.rowCount() > 0 && currentIndex != -1) { root.selectedLesson = lessonModel.data(lessonModel.index(currentIndex, 0), LessonModel.DataRole) } else { root.selectedLesson = null } } delegate: Item { id: item width: content.cellWidth height: content.cellHeight LessonSelectorItem { id: lessonItem anchors.fill: parent anchors.topMargin: 10 anchors.leftMargin: 0 anchors.rightMargin: 20 anchors.bottomMargin: 10 anchors.centerIn: parent lesson: dataRole selected: content.currentIndex == index editable: courseItem.editable onClicked: { item.forceActiveFocus() content.currentIndex = index } onDoubleClicked: { if (index <= course.lastUnlockedLessonIndex) { lessonSelected(course, dataRole) } } onStatButtonClicked: { statPopupDialog.open() } onEditButtonClicked: { lessonEditorDialog.open() } onDeleteButtonClicked: { course.deleteCustomLesson(); } } LessonLockedNotice { anchors.centerIn: parent visible: index > course.lastUnlockedLessonIndex glowColor: lessonItem.background.color } } ScrollBar.vertical: ScrollBar { } } } Item { Layout.fillWidth: true height: footer.height z: 2 ToolBar { id: footer width: parent.width KColorScheme { id: footerColorScheme colorGroup: KColorScheme.Active colorSet: KColorScheme.Window } background: Rectangle { color: footerColorScheme.normalBackground } RowLayout { anchors.fill: parent spacing: 0 Item { Layout.fillWidth: true height: startButton.implicitHeight IconButton { id: startButton icon: "go-next-view" bgColor: colorScheme.positiveBackground anchors.centerIn: parent text: i18n("Start Training") enabled: root.selectedLesson && content.currentIndex <= course.lastUnlockedLessonIndex onClicked: lessonSelected(course, root.selectedLesson) } } } } DropShadow { anchors.fill: footer source: footer samples: 16 horizontalOffset: 0 verticalOffset: 0 } } } diff --git a/src/qml/main.qml b/src/qml/main.qml index d63e7cf..3c8b59f 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -1,240 +1,239 @@ /* * Copyright 2012 Sebastian Gottfried * Copyright 2015 Sebastian Gottfried * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.4 import ktouch 1.0 import "./common" import "./meters" import "./homescreen" import "./trainingscreen" import "./scorescreen" Rectangle { id: main color: activePallete.normalBackground property Item appContent: appContentItem function switchScreen(from, to) { switchScreenAnimation.from = from switchScreenAnimation.to = to switchScreenAnimation.start() } KColorScheme { id: activePallete colorGroup: KColorScheme.Active colorSet: KColorScheme.Window } DataAccess { id: dataAccess } QtObject { id: helper property string name: ktouch.keyboardLayoutName property int keyboardLayoutCount: ktouch.globalDataIndex.keyboardLayoutCount property int courseCount: ktouch.globalDataIndex.courseCount onNameChanged: { - keyboardLayout.update() + activeKeyboardLayout.update() } onKeyboardLayoutCountChanged: { if (ktouch.globalDataIndex.isValid) - keyboardLayout.update() + activeKeyboardLayout.update() } } ResourceModel { id: resourceModel dataIndex: ktouch.globalDataIndex } ProfileDataAccess { id: profileDataAccess } Preferences { id: preferences } KeyboardLayout { - id: keyboardLayout + id: activeKeyboardLayout Component.onCompleted: { if (ktouch.globalDataIndex.isValid) { - keyboardLayout.update() + activeKeyboardLayout.update() } } function update() { isValid = false var name = ktouch.keyboardLayoutName; // first pass - exact match for (var i = 0; i < ktouch.globalDataIndex.keyboardLayoutCount; i++) { var dataIndexLayout = ktouch.globalDataIndex.keyboardLayout(i) if (dataIndexLayout.name === name) { - dataAccess.loadKeyboardLayout(dataIndexLayout, keyboardLayout) + dataAccess.loadKeyboardLayout(dataIndexLayout, activeKeyboardLayout) return } } // second pass - substring match for (var i = 0; i < ktouch.globalDataIndex.keyboardLayoutCount; i++) { var dataIndexLayout = ktouch.globalDataIndex.keyboardLayout(i) if (name.search(dataIndexLayout.name) === 0) { - dataAccess.loadKeyboardLayout(dataIndexLayout, keyboardLayout) + dataAccess.loadKeyboardLayout(dataIndexLayout, activeKeyboardLayout) return } } } } Course { id: selectedCourse property Lesson selectedLesson } Lesson { id: customLessonCopy } Item { anchors.fill: parent id: appContentItem layer.enabled: true HomeScreen { id: homeScreen anchors.fill: parent - keyboardLayout: keyboardLayout - keyboardLayoutName: keyboardLayout.isValid? keyboardLayout.name: helper.name + activeKeyboardLayoutName: activeKeyboardLayout.isValid? activeKeyboardLayout.name: helper.name visible: false focus: true onLessonSelected: { trainingScreen.profile = profile var lessonIndex = -1; for (var i = 0; i < course.lessonCount; i++) { if (lesson === course.lesson(i)) { lessonIndex = i break } } selectedCourse.copyFrom(course) if (lessonIndex !== -1) { selectedCourse.selectedLesson = selectedCourse.lesson(lessonIndex) } else { customLessonCopy.copyFrom(lesson) selectedCourse.selectedLesson = customLessonCopy } main.switchScreen(homeScreen, trainingScreen) } Component.onCompleted: { homeScreen.reset() homeScreen.visible = true homeScreen.start() } } TrainingScreen { id: trainingScreen anchors.fill: parent visible: false - keyboardLayout: keyboardLayout + keyboardLayout: homeScreen.selectedKeyboardLayout course: selectedCourse lesson: selectedCourse.selectedLesson onRestartRequested: main.switchScreen(trainingScreen, trainingScreen) onAbortRequested: main.switchScreen(trainingScreen, homeScreen) onFinished: main.switchScreen(trainingScreen, scoreScreen) } ScoreScreen { id: scoreScreen anchors.fill: parent visible: false course: trainingScreen.course lesson: trainingScreen.lesson stats: trainingScreen.stats profile: trainingScreen.profile referenceStats: trainingScreen.referenceStats onHomeScreenRequested: main.switchScreen(scoreScreen, homeScreen) onLessonRepetionRequested: main.switchScreen(scoreScreen, trainingScreen) onNextLessonRequested: { selectedCourse.selectedLesson = lesson main.switchScreen(scoreScreen, trainingScreen) } } } Rectangle { id: curtain anchors.fill: parent color: "#000" opacity: 0 } SequentialAnimation { id: switchScreenAnimation property Item from property Item to NumberAnimation { target: curtain property: "opacity" to: 1 duration: switchScreenAnimation.to == homeScreen? 250: 750 easing.type: Easing.OutQuad } PropertyAction { target: switchScreenAnimation.from property: "visible" value: false } ScriptAction { script: switchScreenAnimation.to.reset() } PropertyAction { target: switchScreenAnimation.to property: "visible" value: true } ScriptAction { script: { switchScreenAnimation.to.start() switchScreenAnimation.to.forceActiveFocus() } } NumberAnimation { target: curtain property: "opacity" to: 0 duration: switchScreenAnimation.to == homeScreen? 250: 750 easing.type: Easing.InQuad } } }