Commit 8c51695a authored by Andreas Cord-Landwehr's avatar Andreas Cord-Landwehr
Browse files

Initial UI port of trainer to Kirigami2

Rebuild the main UI logic based on the Kirigami 2 framework to provide
a common look and feel with other KDE applications and remove code
duplication.
parent a307f6e5
### ###
# Copyright 2013-2015 Andreas Cord-Landwehr <cordlandwehr@kde.org> # Copyright 2013-2016 Andreas Cord-Landwehr <cordlandwehr@kde.org>
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions # modification, are permitted provided that the following conditions
...@@ -50,13 +50,14 @@ find_package(Qt5 5.5 REQUIRED COMPONENTS ...@@ -50,13 +50,14 @@ find_package(Qt5 5.5 REQUIRED COMPONENTS
QuickWidgets QuickWidgets
Test Test
) )
find_package(KF5 REQUIRED COMPONENTS find_package(KF5 5.36 REQUIRED COMPONENTS
Archive Archive
Config Config
Crash Crash
I18n I18n
NewStuff NewStuff
XmlGui XmlGui
Kirigami2
) )
# options # options
......
/* /*
* Copyright 2013-2016 Andreas Cord-Landwehr <cordlandwehr@kde.org> * Copyright 2013-2017 Andreas Cord-Landwehr <cordlandwehr@kde.org>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -19,37 +19,94 @@ ...@@ -19,37 +19,94 @@
*/ */
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.4 import QtQuick.Controls 2.0 as QQC2
import QtQuick.Layouts 1.2 import org.kde.kirigami 2.0 as Kirigami2
import QtQml.Models 2.2
import artikulate 1.0 import artikulate 1.0
ApplicationWindow { Kirigami2.ApplicationWindow {
id: root id: root
visible: true
minimumWidth: 800
minimumHeight: 600
signal triggerDownloadCourses(); function changePage(pageItem) {
signal triggerEditProfile(); root.pageStack.clear();
signal triggerSettingsDialog(); root.pageStack.push(pageItem);
signal triggerAction(string actionName); root.pageStack.push(pageItem);
signal switchMenuBarVisibility(); }
onTriggerEditProfile: { header: Kirigami2.ApplicationHeader {
editProfileDialog.open()
} }
Item { globalDrawer: Kirigami2.GlobalDrawer {
id: theme title: "Artikulate"
property string backgroundColor: "#ffffff" titleIcon: "artikulate"
property int smallIconSize: 18 actions: [
property int smallMediumIconSize: 22 Kirigami2.Action {
property int mediumIconSize: 32 text: i18n("Welcome")
property int fontPointSize: 11 iconName: "artikulate"
property int spacing: 15 onTriggered: {
root.pageStack.clear();
root.pageStack.push(welcomePageComponent);
}
},
Kirigami2.Action {
text: i18n("Training")
iconName: "document-open"
onTriggered: {
root.pageStack.clear();
root.pageStack.push(trainingItemsPageComponent);
root.pageStack.push(trainingPageComponent);
}
},
Kirigami2.Action {
text: i18n("Download Training")
iconName: "get-hot-new-stuff"
onTriggered: triggerDownloadCourses()
},
Kirigami2.Action {
text: i18n("User Profile")
iconName: "user-properties"
onTriggered: {
root.pageStack.clear();
root.pageStack.push(profileSettingsPageComponent);
}
},
Kirigami2.Action {
text: i18n("Configure Artikulate...")
iconName: "settings-configure"
onTriggered: triggerSettingsDialog()
},
Kirigami2.Action {
text: i18n("Help")
iconName: "help-about"
Kirigami2.Action {
text: i18n("Artikulate Handbook")
iconName: "help-contents"
onTriggered: triggerAction("help_contents")
}
Kirigami2.Action {
text: i18n("Report Bug")
iconName: "tools-report-bug"
onTriggered: triggerAction("help_report_bug")
}
Kirigami2.Action {
text: i18n("About Artikulate")
iconName: "artikulate"
onTriggered: triggerAction("help_about_app")
}
Kirigami2.Action {
text: i18n("About KDE")
iconName: "help-about"
onTriggered: triggerAction("help_about_kde")
}
}
]
} }
signal triggerDownloadCourses();
signal triggerSettingsDialog();
signal triggerAction(string actionName);
signal switchMenuBarVisibility();
property Learner learner: g_profileManager.activeProfile property Learner learner: g_profileManager.activeProfile
property ResourceManager resourceManager: g_resourceManager property ResourceManager resourceManager: g_resourceManager
...@@ -58,145 +115,23 @@ ApplicationWindow { ...@@ -58,145 +115,23 @@ ApplicationWindow {
resourceManager: g_resourceManager resourceManager: g_resourceManager
} }
// main menu bar pageStack.initialPage: welcomePageComponent
menuBar: MainMenuBar {
id: topMenu
// note: this is access to internal API, but the only way to unset/hide the menu bar
__contentItem.visible: kcfg_ShowMenuBar
}
// pages
Component { Component {
id: welcomeScreen id: welcomePageComponent
NewUserWelcome { } WelcomePage { }
} }
Component { Component {
id: trainingScreen id: trainingPageComponent
RowLayout { TrainingPage { }
id: mainRow
Layout.fillHeight: true
spacing: theme.spacing
TreeView {
id: phraseTree
implicitWidth: Math.floor(root.width * 0.3)
Layout.fillHeight: true
TableViewColumn {
title: i18n("Categories")
role: "text"
}
model: PhraseModel {
id: phraseModel
course: g_trainingSession.course
}
selection: ItemSelectionModel {
model: phraseTree.model
}
itemDelegate: Item {
property bool isUnit: phraseModel.isUnit(styleData.index)
Component {
id: unitRowBackground
Rectangle {anchors.fill: parent; color: "steelblue"}
}
Component {
id: phraseProgress
Row {
property int progress: isUnit ? 0 : phraseModel.phrase(styleData.index).progress
Repeater {
model: 3
Icon {
width: 16
height: width
icon: progress > index ? "rating" : "rating-unrated"
}
}
}
}
Loader {
anchors.fill: parent
sourceComponent: isUnit ? unitRowBackground : null
}
Row {
Text {
width: phraseTree.width - 130 //TODO check if this is really a reasonable value
anchors {
verticalCenter: parent.verticalCenter
topMargin: 5
bottomMargin: 5
}
color: {
if (isUnit) {
return "white";
}
return styleData.textColor
}
elide: Text.ElideRight
text: " " + styleData.value
font.bold: isUnit
}
Loader {
sourceComponent: isUnit ? null : phraseProgress
}
}
}
onClicked: {
g_trainingSession.phrase = phraseModel.phrase(index)
}
Connections {
target: g_trainingSession
onPhraseChanged: {
phraseTree.expand(phraseModel.indexUnit(g_trainingSession.phrase.unit))
phraseTree.selection.setCurrentIndex(
phraseModel.indexPhrase(g_trainingSession.phrase),
ItemSelectionModel.ClearAndSelect)
}
}
}
TrainerSessionScreen {
id: trainerMain
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: Math.floor(main.width * 0.7) - 30
Layout.fillHeight: true
}
}
}
MainToolBar {
id: mainToolBar
} }
Component {
ColumnLayout { id: trainingItemsPageComponent
id: main TrainingItemsPage { }
spacing: theme.spacing
anchors {
fill: parent
topMargin: mainToolBar.height + theme.spacing
leftMargin: theme.spacing
rightMargin: theme.spacing
bottomMargin: theme.spacing
}
Loader {
Layout.fillHeight: true
sourceComponent: {
g_trainingSession.language == null
? welcomeScreen
: trainingScreen
}
}
} }
Component {
//TODO change to loader for arbitrary dialogs id: profileSettingsPageComponent
//TODO add margin for main menu ProfileSettingsPage { }
SheetDialog {
id: editProfileDialog
anchors {
fill: main
}
content: ProfileSettingsItem {
anchors.fill: parent
}
} }
} }
/*
* Copyright 2015-2016 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.5
import QtQuick.Controls 1.2
MenuBar {
id: root
Menu {
title: i18n("File")
MenuItem {
text: i18n("Edit User")
iconName: "user-properties"
onTriggered: triggerEditProfile()
}
MenuSeparator { }
MenuItem {
text: i18n("Quit")
iconName: "application-exit"
shortcut: StandardKey.Quit
onTriggered: triggerAction("file_quit")
}
}
Menu {
title: i18n("Settings")
MenuItem {
text: i18n("Download Courses")
iconName: "get-hot-new-stuff"
onTriggered: triggerDownloadCourses()
}
MenuSeparator { }
// TODO requires proper support of KKeySequenceWidget's settings
// MenuItem {
// text: i18n("Configure Shortcuts...")
// iconName: "configure-shortcuts"
// onTriggered: triggerAction("options_configure_keybinding")
// }
MenuItem {
text: i18n("Configure Artikulate...")
iconName: "settings-configure"
onTriggered: triggerSettingsDialog()
}
MenuSeparator { }
MenuItem {
text: i18n("Show Menubar")
iconName: "show-menu"
checkable: true
checked: kcfg_ShowMenuBar
onTriggered: {
switchMenuBarVisibility()
}
}
}
Menu {
title: i18n("Help")
MenuItem {
text: i18n("Artikulate Handbook")
iconName: "help-contents"
shortcut: StandardKey.HelpContents
onTriggered: triggerAction("help_contents")
}
MenuSeparator { }
MenuItem {
text: i18n("Report Bug")
iconName: "tools-report-bug"
onTriggered: triggerAction("help_report_bug")
}
MenuSeparator { }
MenuItem {
text: i18n("About Artikulate")
iconName: "artikulate"
onTriggered: triggerAction("help_about_app")
}
MenuItem {
text: i18n("About KDE")
iconName: "help-about"
onTriggered: triggerAction("help_about_kde")
}
}
}
/*
* Copyright 2013-2015 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
import artikulate 1.0
ToolBar{
RowLayout {
anchors.fill: parent
Layout.fillWidth: true
Layout.preferredHeight: langIcon.height
spacing: 20
Icon {
id: langIcon
icon: "language-artikulate"
width: 48
height: 48
}
ComboBox {
id: comboLanguage
Layout.minimumWidth: 200
model: LanguageModel {
id: languageModel
resourceModel: LanguageResourceModel {
resourceManager: g_resourceManager
}
}
textRole: "title"
onCurrentIndexChanged: {
if (languageModel.language(currentIndex)) {
g_trainingSession.language = languageModel.language(currentIndex)
}
}
}
ComboBox {
id: comboCourse
enabled: {
courseFilterModel.filteredCount == 0 ? false : true
}
Layout.minimumWidth: 200
model: CourseFilterModel {
id: courseFilterModel
view: {
kcfg_UseContributorResources
? CourseFilterModel.AllResources
: CourseFilterModel.OnlyGetHotNewStuffResources
}
courseModel: CourseModel {
id: courseModel
resourceManager: g_resourceManager
language: g_trainingSession.language
onLanguageChanged: {
if (courseFilterModel.course(0)) {
g_trainingSession.course = courseFilterModel.course(0)
}
}
}
}
textRole: "title"
onCurrentIndexChanged: {
if (courseFilterModel.course(currentIndex)) {
g_trainingSession.course = courseFilterModel.course(currentIndex)
}
}
}
// horizontal fill
Item { Layout.fillWidth: true }
ToolButton {
Layout.alignment: Qt.AlignRight
iconName: "application-menu"
menu: Menu {
id: recentFilesMenu
MenuItem {
text: i18n("Download Courses")
iconName: "get-hot-new-stuff"
onTriggered: triggerDownloadCourses()
}
MenuSeparator { }
MenuItem {
text: i18n("Edit User")
iconName: "user-properties"
onTriggered: triggerEditProfile()
}
MenuSeparator { }
// TODO requires proper support of KKeySequenceWidget's settings
// MenuItem {
// text: i18n("Configure Shortcuts...")
// iconName: "configure-shortcuts"
// onTriggered: triggerAction("options_configure_keybinding")
// }
MenuItem {
text: i18n("Configure Artikulate...")
iconName: "settings-configure"
onTriggered: triggerSettingsDialog()
}
MenuSeparator { }
Menu {
title: i18n("Help")
MenuItem {
text: i18n("Artikulate Handbook")
iconName: "help-contents"
shortcut: StandardKey.HelpContents
onTriggered: triggerAction("help_contents")
}
MenuSeparator { }
MenuItem {
text: i18n("Report Bug")
iconName: "tools-report-bug"
onTriggered: triggerAction("help_report_bug")
}
MenuSeparator { }
MenuItem {
text: i18n("About Artikulate")
iconName: "artikulate"
onTriggered: triggerAction("help_about_app")
}
MenuItem {
text: i18n("About KDE")
iconName: "help-about"
onTriggered: triggerAction("help_about_kde")
}
}
MenuSeparator { }
MenuItem {
text: i18n("Show Menubar")
iconName: "show-menu"
checkable: true
checked: kcfg_ShowMenuBar
onTriggered: {
switchMenuBarVisibility()
}
}
MenuSeparator { }
MenuItem {
text: i18n("Quit")
iconName: "application-exit"
shortcut: StandardKey.Quit
onTriggered: triggerAction("file_quit")
}
}
}
}
}
/*
* Copyright 2015 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.1
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.2
import artikulate 1.0
Item {
id: root
Layout.fillWidth: true
Layout.fillHeight: true
height: 50
ColumnLayout {