diff --git a/examples/touch/content/BlurredImagePage.qml b/examples/touch/content/BlurredImagePage.qml new file mode 100644 index 0000000..e83ca89 --- /dev/null +++ b/examples/touch/content/BlurredImagePage.qml @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2021 Chupligin Sergey (NeoChapay) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.6 +import QtQuick.Controls 1.0 //needed for the Stack attached property +import QtQuick.Controls.Nemo 1.0 +import QtQuick.Controls.Styles.Nemo 1.0 + +Page { + id: root + + headerTools: HeaderToolsLayout { + showBackButton: false; + title: qsTr("Blurred page") + } + + + + ScrollDecorator{ + flickable: mainContent + } + + + Flickable{ + id: mainContent + width: parent.width + height: parent.height + + contentHeight: contentColumn.height+Theme.itemHeightExtraLarge + + Column { + id: contentColumn + spacing: Theme.itemSpacingLarge*2 + width: parent.width + + anchors{ + top: parent.top + topMargin: Theme.itemSpacingLarge + left: parent.left + leftMargin: Theme.itemSpacingLarge + } + + NemoBlurredImage{ + id: blurred + width: parent.width - Theme.itemSpacingLarge*2 + height: root.height/3 + + source: "/usr/share/glacier-components/images/example.jpg" + } + + Label { + text: qsTr("Select dim color") + } + + Row{ + width: parent.width - Theme.itemSpacingLarge*2 + height: Theme.itemHeightExtraLarge + + Rectangle{ + width: parent.width/3 + height: parent.height + color: "red" + Label{ + anchors.fill: parent + text: "Red" + } + + MouseArea{ + anchors.fill: parent + onClicked: blurred.dimColor = "red" + } + } + + + Rectangle{ + width: parent.width/3 + height: parent.height + color: "black" + Label{ + anchors.fill: parent + text: "Black" + } + + MouseArea{ + anchors.fill: parent + onClicked: blurred.dimColor = "black" + } + } + + Rectangle{ + width: parent.width/3 + height: parent.height + color: "white" + Label{ + anchors.fill: parent + text: "White" + color: "black" + } + + MouseArea{ + anchors.fill: parent + onClicked: blurred.dimColor = "white" + } + } + } + + Label { + text: qsTr("Blur radius") + } + + Slider { + id: radiusSlider + anchors.margins: 20 + minimumValue: 0 + maximumValue: 100 + value: blurred.radius + width: parent.width - Theme.itemSpacingLarge*2 + onValueChanged: { + blurred.radius = radiusSlider.value + } + } + + + Label { + text: qsTr("Opacity") + } + + Slider { + id: opacitySlider + anchors.margins: 20 + value: blurred.opacity + minimumValue: 0 + maximumValue: 1 + width: parent.width - Theme.itemSpacingLarge*2 + onValueChanged: { + blurred.opacity = opacitySlider.value + } + } + } + } +} + diff --git a/examples/touch/content/ButtonPage.qml b/examples/touch/content/ButtonPage.qml index 940dffc..a925733 100644 --- a/examples/touch/content/ButtonPage.qml +++ b/examples/touch/content/ButtonPage.qml @@ -2,6 +2,7 @@ ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal +** Copyright (C) 2021 Chupligin Sergey ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. ** @@ -46,7 +47,10 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: false; title: "Buttons (portrait only, no back arrow)" } + headerTools: HeaderToolsLayout { + showBackButton: false; + title: qsTr("Buttons (portrait only, no back arrow)") + } allowedOrientations: Qt.PortraitOrientation Column { @@ -57,8 +61,15 @@ Page { property bool isGlacier: true anchors.margins: 20 text: isGlacier ? "Set Ugly Theme" : "Set Nice Theme" - onClicked: isGlacier ? Theme.loadTheme("ugly") - : Theme.loadTheme("glacier") + onClicked: { + if (isGlacier ) { + Theme.loadTheme("/usr/lib/qt/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_orange.json") + } else { + Theme.loadTheme("/usr/lib/qt/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_black.json") + } + isGlacier = !isGlacier; + } + } Button { diff --git a/examples/touch/content/ButtonRowPage.qml b/examples/touch/content/ButtonRowPage.qml index 93a5538..13c11e2 100644 --- a/examples/touch/content/ButtonRowPage.qml +++ b/examples/touch/content/ButtonRowPage.qml @@ -1,6 +1,7 @@ /**************************************************************************************** ** ** Copyright (C) 2014 Aleksi Suomalainen +** Copyright (C) 2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -37,7 +38,10 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Button row (Landscape only)" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Button row (Landscape only)") + } allowedOrientations: Qt.LandscapeOrientation Column { @@ -69,14 +73,14 @@ Page { Connections { target: row onCurrentIndexChanged: { - selector.text = "Selected " + buttonModel.get(row.currentIndex).name + selector.text = qsTr("Selected") + " " + buttonModel.get(row.currentIndex).name } } Label { id: selector anchors.horizontalCenter: parent.horizontalCenter - text: "Nothing selected" + text: qsTr("Nothing selected") } ButtonRow { id: row2 diff --git a/examples/touch/content/CheckboxPage.qml b/examples/touch/content/CheckboxPage.qml index 60791e6..961091a 100644 --- a/examples/touch/content/CheckboxPage.qml +++ b/examples/touch/content/CheckboxPage.qml @@ -1,6 +1,7 @@ /**************************************************************************************** ** ** Copyright (C) 2013 Aleksi Suomalainen +** Copyright (C) 2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -37,7 +38,10 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: qsTr("Switch") } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Switch") + } Column { spacing: 40 diff --git a/examples/touch/content/DatePickerPage.qml b/examples/touch/content/DatePickerPage.qml index d7f8e07..2418cc5 100644 --- a/examples/touch/content/DatePickerPage.qml +++ b/examples/touch/content/DatePickerPage.qml @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2017 Chupligin Sergey +** Copyright (C) 2017-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -37,12 +37,20 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Date Picker" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Date Picker") + } Column { - spacing: 40 + spacing: Theme.itemSpacingSmall + width: parent.width DatePicker{ + id: datePicker + onDateSelect: { + currentDate = date + } } } } diff --git a/examples/touch/content/DialogsPage.qml b/examples/touch/content/DialogsPage.qml index 0fd9168..e123c2e 100644 --- a/examples/touch/content/DialogsPage.qml +++ b/examples/touch/content/DialogsPage.qml @@ -1,7 +1,7 @@ /**************************************************************************************** ** ** Copyright (C) 2014 Aleksi Suomalainen -** Copyright (C) 2017 Chupligin Sergey +** Copyright (C) 2017-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -40,7 +40,10 @@ import Nemo.Dialogs 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: qsTr("Query dialog example") } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Query dialog example") + } Image { id: bgImage diff --git a/examples/touch/content/IconPage.qml b/examples/touch/content/IconPage.qml index 0edbbe0..046c628 100644 --- a/examples/touch/content/IconPage.qml +++ b/examples/touch/content/IconPage.qml @@ -1,6 +1,7 @@ /**************************************************************************************** ** ** Copyright (C) 2017 Eetu Kahelin +** Copyright (C) 2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -37,7 +38,10 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Icon example" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Icons") + } allowedOrientations: Qt.PortraitOrientation | Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation | Qt.InvertedPortraitOrientation Column { diff --git a/examples/touch/content/LabelPage.qml b/examples/touch/content/LabelPage.qml index a1f7b23..8120f17 100644 --- a/examples/touch/content/LabelPage.qml +++ b/examples/touch/content/LabelPage.qml @@ -1,6 +1,7 @@ /**************************************************************************************** ** ** Copyright (C) 2013 Aleksi Suomalainen +** Copyright (C) 2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -37,14 +38,18 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Label" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Label") + } + allowedOrientations: Qt.PortraitOrientation | Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation | Qt.InvertedPortraitOrientation Column { spacing: 40 anchors.centerIn: parent Label { - text: "Test label" + text: qsTr("Test label") } } } diff --git a/examples/touch/content/ListViewPage.qml b/examples/touch/content/ListViewPage.qml index aa4a848..a5f1eb0 100644 --- a/examples/touch/content/ListViewPage.qml +++ b/examples/touch/content/ListViewPage.qml @@ -1,3 +1,34 @@ +/**************************************************************************************** +** +** Copyright (C) 2017-2021 Chupligin Sergey +** All rights reserved. +** +** You may use this file under the terms of 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 author 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 HOLDERS 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. +** +****************************************************************************************/ + import QtQuick 2.6 import QtQuick.Controls 1.0 import QtQuick.Controls.Nemo 1.0 @@ -6,26 +37,29 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: listViewPage - headerTools: HeaderToolsLayout { showBackButton: true; title: "ListView" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("ListView") + } ListModel { id: animalsModel - ListElement { name: "Ant"; desc: "Small description"; size: "Tiny"; canRemove: true} - ListElement { name: "Flea"; desc: ""; size: "Tiny"; canRemove: false } - ListElement { name: "Parrot"; desc: ""; size: "Small"; canRemove: true } - ListElement { name: "Guinea pig"; desc: "The guinea pig, cavy or domestic guinea pig, or cuy for livestock breeds, is a species of rodent belonging to the family Caviidae and the genus Cavia"; size: "Small"; canRemove: false } - ListElement { name: "Rat"; desc: ""; size: "Small"; canRemove: true } - ListElement { name: "Butterfly"; desc: ""; size: "Small"; canRemove: false } - ListElement { name: "Dog"; desc: ""; size: "Medium"; canRemove: true } - ListElement { name: "Cat"; desc: ""; size: "Medium"; canRemove: false } - ListElement { name: "Pony"; desc: ""; size: "Medium"; canRemove: true } - ListElement { name: "Koala"; desc: ""; size: "Medium"; canRemove: false } - ListElement { name: "Horse"; desc: ""; size: "Large"; canRemove: true } - ListElement { name: "Tiger"; desc: ""; size: "Large"; canRemove: false } - ListElement { name: "Giraffe"; desc: ""; size: "Large"; canRemove: true } - ListElement { name: "Elephant"; desc: ""; size: "Huge"; canRemove: false } - ListElement { name: "Whale"; desc: ""; size: "Huge"; canRemove: true } + ListElement { name: "Ant"; desc: "Small description"; size: "Tiny"; canRemove: true; canLove: true; } + ListElement { name: "Flea"; desc: ""; size: "Tiny"; canRemove: false; canLove: false; } + ListElement { name: "Parrot"; desc: ""; size: "Small"; canRemove: false; canLove: false; image: "image://theme/twitter"; } + ListElement { name: "Guinea pig"; desc: "The guinea pig, cavy or domestic guinea pig, or cuy for livestock breeds, is a species of rodent belonging to the family Caviidae and the genus Cavia"; size: "Small"; canRemove: false; canLove: true; image:"image://theme/piggy-bank"} + ListElement { name: "Rat"; desc: ""; size: "Small"; canRemove: true; canLove: false; } + ListElement { name: "Butterfly"; desc: ""; size: "Small"; canRemove: false; canLove: true; } + ListElement { name: "Dog"; desc: ""; size: "Medium"; canRemove: true; canLove: true; image: "image://theme/dog"; } + ListElement { name: "Cat"; desc: ""; size: "Medium"; canRemove: false; canLove: false; image: "image://theme/cat"; } + ListElement { name: "Pony"; desc: ""; size: "Medium"; canRemove: true; canLove: true; } + ListElement { name: "Koala"; desc: ""; size: "Medium"; canRemove: false; canLove: true; } + ListElement { name: "Horse"; desc: ""; size: "Large"; canRemove: true; canLove: false; image: "image://theme/horse"; } + ListElement { name: "Tiger"; desc: ""; size: "Large"; canRemove: false; canLove: true; } + ListElement { name: "Giraffe"; desc: ""; size: "Large"; canRemove: true; canLove: true; } + ListElement { name: "Elephant"; desc: ""; size: "Huge"; canRemove: false; canLove: true; image: "image://theme/evernote" } + ListElement { name: "Whale"; desc: ""; size: "Huge"; canRemove: true; canLove: true; image: "image://theme/docker" } } ListView { @@ -38,14 +72,24 @@ Page { label: name description: desc showNext: false - showActions: canRemove + showActions: canRemove || canLove + icon: (image !== undefined) ? image : "" + iconVisible: (image !== undefined) && (image !== "") - width: parent.width + width: parent.width !== null ? parent.width : 200 height: Theme.itemHeightLarge actions:[ ActionButton { iconSource: "image://theme/times" + visible: canRemove + }, + ActionButton { + iconSource: "image://theme/heart" + visible: canLove + onClicked: { + console.log("I love "+ name) + } } ] diff --git a/examples/touch/content/LiveCoding.qml b/examples/touch/content/LiveCoding.qml index 628354c..75e4f5a 100644 --- a/examples/touch/content/LiveCoding.qml +++ b/examples/touch/content/LiveCoding.qml @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Andrea Bernabei + * Copyright (C) 2021 Chupligin Sergey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,7 +22,6 @@ import QtQuick 2.6 import QtQuick.Controls 1.0 //needed for the Stack attached property import QtQuick.Controls.Nemo 1.0 import QtQuick.Controls.Styles.Nemo 1.0 -import QtQuick.Layouts 1.0 Page { id: root @@ -29,7 +29,10 @@ Page { property var oldItem property var newItem - headerTools: HeaderToolsLayout { showBackButton: true; title: "Live Coding Arena" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Live Coding Arena") + } SplitView { anchors.fill: parent @@ -45,7 +48,7 @@ Page { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - text: "Update LiveItem" + text: qsTr("Update LiveItem") onClicked: { txt.qmlError = false try { diff --git a/examples/touch/content/NotificationsPage.qml b/examples/touch/content/NotificationsPage.qml index 841bc89..b8b391c 100644 --- a/examples/touch/content/NotificationsPage.qml +++ b/examples/touch/content/NotificationsPage.qml @@ -41,7 +41,7 @@ Page { headerTools: HeaderToolsLayout { showBackButton: true; - title: "Notifications" + title: qsTr("Notifications") } allowedOrientations: Qt.PortraitOrientation | Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation | Qt.InvertedPortraitOrientation diff --git a/examples/touch/content/ProgressBarPage.qml b/examples/touch/content/ProgressBarPage.qml index 7be92d2..617b490 100644 --- a/examples/touch/content/ProgressBarPage.qml +++ b/examples/touch/content/ProgressBarPage.qml @@ -2,6 +2,7 @@ ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal +** Copyright (C) 2021 Chupligin Sergey ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. ** @@ -62,7 +63,10 @@ Page { } } - headerTools: HeaderToolsLayout { showBackButton: true; title: "Progress Bars" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Progress Bars") + } Column { spacing: 40 diff --git a/examples/touch/content/RingIndicatorPage.qml b/examples/touch/content/RingIndicatorPage.qml new file mode 100644 index 0000000..e7635cb --- /dev/null +++ b/examples/touch/content/RingIndicatorPage.qml @@ -0,0 +1,135 @@ +/**************************************************************************************** +** +** Copyright (C) 2021 Chupligin Sergey +** All rights reserved. +** +** You may use this file under the terms of 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 author 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 HOLDERS 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. +** +****************************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.0 //needed for the Stack attached property +import QtQuick.Controls.Nemo 1.0 + +Page { + id: root + + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Ring Indicator") + } + + ScrollDecorator{ + flickable: content + } + + Flickable{ + id: content + width: parent.width + height: parent.height + + contentHeight: mainColumn.height + + Column { + id: mainColumn + spacing: 40 + width: content.width-Theme.itemSpacingMedium*2 + + anchors{ + left: parent.left + leftMargin: Theme.itemSpacingMedium + right: parent.right + rightMargin: Theme.itemSpacingMedium + } + + RingIndicator{ + id: ring + width: 200 + height: 200 + startAngle: startAngleSlider.value + stopAngle: stopAngleSlider.value + rounded: roundCheckbox.checked + lineWidth: lineWidthSlider.value + color: Theme.accentColor + } + + Label{ + text: qsTr("Start angle") + width: mainColumn.width + } + + Slider { + width: 250 + id: startAngleSlider + anchors.margins: 20 + value: 0 + showValue: true + minimumValue: 0 + maximumValue: 360 + stepSize: 1 + alwaysUp: true + } + + Label{ + text: qsTr("Stop angle") + width: mainColumn.width + } + + Slider { + width: 250 + id: stopAngleSlider + anchors.margins: 20 + value: 90 + showValue: true + minimumValue: 0 + maximumValue: 360 + stepSize: 1 + alwaysUp: true + } + + Label{ + text: qsTr("Line width") + width: mainColumn.width + } + + Slider { + width: 250 + id: lineWidthSlider + anchors.margins: 20 + value: 10 + showValue: true + minimumValue: 0 + maximumValue: 100 + stepSize: 1 + alwaysUp: true + } + + CheckBox { + id: roundCheckbox + text: qsTr("Rounding") + } + } + } +} diff --git a/examples/touch/content/SelectRollerPage.qml b/examples/touch/content/SelectRollerPage.qml index 682a1cd..1f45249 100644 --- a/examples/touch/content/SelectRollerPage.qml +++ b/examples/touch/content/SelectRollerPage.qml @@ -1,3 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2021 Chupligin Sergey +** +** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** +** $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 Digia Plc and its Subsidiary(-ies) 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.6 import QtQuick.Controls 1.0 //needed for the Stack attached property import QtQuick.Controls.Nemo 1.0 @@ -6,7 +45,10 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Label" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Select roller") + } allowedOrientations: Qt.PortraitOrientation | Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation | Qt.InvertedPortraitOrientation Column { diff --git a/examples/touch/content/SliderPage.qml b/examples/touch/content/SliderPage.qml index 220bcbf..5800aa9 100644 --- a/examples/touch/content/SliderPage.qml +++ b/examples/touch/content/SliderPage.qml @@ -2,6 +2,7 @@ ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal +** Copyright (C) 2021 Chupligin Sergey ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. ** @@ -46,7 +47,10 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Sliders" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Sliders") + } Column { spacing: 12 diff --git a/examples/touch/content/SpinnerPage.qml b/examples/touch/content/SpinnerPage.qml index afb32d6..3ec4f97 100644 --- a/examples/touch/content/SpinnerPage.qml +++ b/examples/touch/content/SpinnerPage.qml @@ -1,6 +1,7 @@ /**************************************************************************************** ** ** Copyright (C) 2013 Lucien Xu +** Copyright (C) 2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -37,14 +38,17 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Spinner" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Spinner") + } Column { spacing: 40 anchors.centerIn: parent Button { - text: "Toggle spinner" + text: qsTr("Toggle spinner") onClicked: spinner.enabled = !spinner.enabled } diff --git a/examples/touch/content/StatusNotifyPage.qml b/examples/touch/content/StatusNotifyPage.qml new file mode 100644 index 0000000..247c270 --- /dev/null +++ b/examples/touch/content/StatusNotifyPage.qml @@ -0,0 +1,83 @@ +/**************************************************************************************** +** +** Copyright (C) 2021 Chupligin Sergey +** All rights reserved. +** +** You may use this file under the terms of 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 author 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 HOLDERS 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. +** +****************************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Controls 1.0 //needed for the Stack attached property +import QtQuick.Controls.Nemo 1.0 +import QtQuick.Controls.Styles.Nemo 1.0 + +import org.nemomobile.statusnotifier 1.0 + + +Page { + id: root + + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Status icon") + } + + StatusNotifierItem { + id: snItem + status: StatusNotifierItem.PassiveStatus + title: qsTr("Glacier UX") + icon: "image://theme/terminal" + overlayIcon: "image://theme/code" + attentionIcon: "image://theme/window-close" + + + onActivateRequested: { + pageStack.pop(); + } + + onScrollRequested: { + snItem.status = StatusNotifierItem.NeedsAttentionStatus + } + } + + Column { + spacing: 40 + anchors.centerIn: parent + Button { + text: qsTr("Make icon active") + onClicked:{ + snItem.status = StatusNotifierItem.ActiveStatus + } + } + + Button { + text: qsTr("Make icon attention") + onClicked:{ + snItem.status = StatusNotifierItem.NeedsAttentionStatus + } + } + } +} diff --git a/examples/touch/content/TabBarPage.qml b/examples/touch/content/TabBarPage.qml index a200802..03eb9e3 100644 --- a/examples/touch/content/TabBarPage.qml +++ b/examples/touch/content/TabBarPage.qml @@ -2,6 +2,7 @@ ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal +** Copyright (C) 2021 Chupligin Sergey ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. ** @@ -46,22 +47,25 @@ import QtQuick.Controls.Styles.Nemo 1.0 Page { id: root - headerTools: HeaderToolsLayout { showBackButton: true; title: "Tab bars" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Tab bars") + } TabView { anchors.fill: parent style: TabViewStyle { } Tab { - title: "Buttons" + title: qsTr("Buttons") ButtonPage{ visible: true } } Tab { - title: "Sliders" + title: qsTr("Sliders") SliderPage{ visible: true } } Tab { - title: "Progress" + title: qsTr("Progress") ProgressBarPage{ visible: true } } } diff --git a/examples/touch/content/TextInputPage.qml b/examples/touch/content/TextInputPage.qml index 824315a..893d431 100644 --- a/examples/touch/content/TextInputPage.qml +++ b/examples/touch/content/TextInputPage.qml @@ -2,6 +2,7 @@ ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal +** Copyright (C) 2021 Chupligin Sergey ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. ** @@ -63,7 +64,10 @@ Page { } } - headerTools: HeaderToolsLayout { showBackButton: true; title: "Text input" } + headerTools: HeaderToolsLayout { + showBackButton: true; + title: qsTr("Text input") + } Column { spacing:Theme.itemSpacingHuge @@ -71,24 +75,24 @@ Page { TextField { anchors.margins: Theme.itemSpacingLarge - text: "Text input" + text: qsTr("Text input") } TextField { anchors.margins: Theme.itemSpacingLarge - text: "Readonly Text input" + text: qsTr("Readonly Text input") readOnly: true } TextField { anchors.margins: Theme.itemSpacingLarge - text: "Disabled textfield" + text: qsTr("Disabled textfield") enabled: false } TextField { anchors.margins: Theme.itemSpacingLarge - text: "Text input" + text: qsTr("Text input") style: touchStyle } diff --git a/examples/touch/content/TimePickerPage.qml b/examples/touch/content/TimePickerPage.qml index eafe0be..0fbe606 100644 --- a/examples/touch/content/TimePickerPage.qml +++ b/examples/touch/content/TimePickerPage.qml @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2018 Chupligin Sergey +** Copyright (C) 2018-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -46,6 +46,14 @@ Page { Column { spacing: Theme.itemSpacingLarge*2 width: parent.width + + anchors{ + top: parent.top + topMargin: Theme.itemSpacingLarge + left: parent.left + leftMargin: Theme.itemSpacingLarge + } + TimePicker{ width: parent.width-Theme.itemSpacingLarge*2 readOnly: false diff --git a/examples/touch/glacier-components.qml b/examples/touch/glacier-components.qml index 0351530..9a528f8 100644 --- a/examples/touch/glacier-components.qml +++ b/examples/touch/glacier-components.qml @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2017-2021 Chupligin Sergey ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. @@ -43,7 +44,7 @@ import QtQuick.Controls 1.0 import QtQuick.Controls.Nemo 1.0 import QtQuick.Controls.Styles.Nemo 1.0 import QtQuick.Window 2.1 -import QtQuick.Layouts 1.0 + import "content" ApplicationWindow { @@ -66,75 +67,87 @@ ApplicationWindow { ListModel { id: pageModel ListElement { - title: "Live-Coding Arena" + title: qsTr("Live-Coding Arena") page: "content/LiveCoding.qml" } ListElement { - title: "Buttons (locked to portrait)" + title: qsTr("Buttons (locked to portrait)") page: "content/ButtonPage.qml" } ListElement { - title: "Sliders" + title: qsTr("Sliders") page: "content/SliderPage.qml" } ListElement { - title: "ProgressBar" + title: qsTr("ProgressBar") page: "content/ProgressBarPage.qml" } ListElement { - title: "DatePicker" + title: qsTr("DatePicker") page: "content/DatePickerPage.qml" } ListElement { - title: "TimePicker" + title: qsTr("TimePicker") page: "content/TimePickerPage.qml" } ListElement { - title: "Tabs" + title: qsTr("Tabs") page: "content/TabBarPage.qml" } ListElement { - title: "TextInput" + title: qsTr("TextInput") page: "content/TextInputPage.qml" } ListElement { - title: "Spinner" + title: qsTr("Spinner") page: "content/SpinnerPage.qml" } ListElement { - title: "SelectRoller" + title: qsTr("Ring indicator") + page: "content/RingIndicatorPage.qml" + } + ListElement { + title: qsTr("SelectRoller") page: "content/SelectRollerPage.qml" } ListElement { - title: "ListView" + title: qsTr("ListView") page: "content/ListViewPage.qml" } ListElement { - title: "Labels (no orientation locks)" + title: qsTr("Labels (no orientation locks)") page: "content/LabelPage.qml" } ListElement { - title: "Switches" + title: qsTr("Switches") page: "content/CheckboxPage.qml" } ListElement { - title: "ButtonRow (locked to landscape)" + title: qsTr("ButtonRow (locked to landscape)") page: "content/ButtonRowPage.qml" } ListElement { - title: "Dialogs" + title: qsTr("Dialogs") page: "content/DialogsPage.qml" } ListElement { - title: "Icons" + title: qsTr("Icons") page: "content/IconPage.qml" } ListElement { - title: "Notifications" + title: qsTr("Blurred images") + page: "content/BlurredImagePage.qml" + } + ListElement { + title: qsTr("Notifications") page: "content/NotificationsPage.qml" } ListElement { - title: "Broken page" + title: qsTr("Status icon") + page: "content/StatusNotifyPage.qml" + } + ListElement { + title: qsTr("Broken page") page: "content/BrokenPage.qml" } } @@ -145,8 +158,9 @@ ApplicationWindow { headerTools: HeaderToolsLayout { id: tools - title: "Nemo Touch Gallery" - tools: [ ToolButton { + title: qsTr("Nemo components gallery") + tools: [ + ToolButton { iconSource: "image://theme/cog" showCounter: false }, @@ -157,8 +171,10 @@ ApplicationWindow { counterValue: 0 onClicked: { - editIcon.counterValue++ + editIcon.counterValue++ } + + active: true }, ToolButton { iconSource: "image://theme/refresh" @@ -176,58 +192,86 @@ ApplicationWindow { Button { anchors.horizontalCenter: (parent==undefined) ? undefined : parent.horizontalCenter; text: qsTr("Black theme") + primary: Theme.themePath == "/usr/lib/qt/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_black.json" onClicked: { - Theme.loadTheme("/usr/lib/qt5/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_black.json") + Theme.loadTheme("/usr/lib/qt/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_black.json") } }, Button { anchors.horizontalCenter: (parent==undefined) ? undefined : parent.horizontalCenter; text: qsTr("White theme") + primary: Theme.themePath == "/usr/lib/qt/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_white.json" onClicked: { - Theme.loadTheme("/usr/lib/qt5/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_white.json") + Theme.loadTheme("/usr/lib/qt/qml/QtQuick/Controls/Styles/Nemo/themes/glacier_white.json") } }, - RowLayout { - anchors.left: (parent==undefined) ? undefined : parent.left - anchors.right: (parent==undefined) ? undefined : parent.right - anchors.margins: 20 - Layout.preferredHeight: 100 + Row { + id: drawerTestRow + width: appWindow.width + height: Theme.itemHeightMedium + + anchors{ + left: (parent==undefined) ? undefined : parent.left + right: (parent==undefined) ? undefined : parent.right + margins: Theme.itemSpacingLarge + } + Label { - anchors.left: parent.left; + id: drawerTestLabel + text: qsTr("Drawer Test") anchors.verticalCenter: parent.verticalCenter - text: "Drawer Test"} + } + + Rectangle{ + id: spacer1 + width: parent.width-drawerTestLabel.width-drawerTestCheckBox.width + color: "transparent" + height: 1 + } + CheckBox { - anchors.right: parent.right + id: drawerTestCheckBox anchors.verticalCenter: parent.verticalCenter - width : 20 } }, - RowLayout { - anchors.left: (parent==undefined) ? undefined : parent.left - anchors.right: (parent==undefined) ? undefined : parent.right - anchors.margins: 20 - Layout.preferredHeight: 100 + Row{ + id: drawerTest2Row + width: appWindow.width + height: Theme.itemHeightMedium + + anchors{ + left: (parent==undefined) ? undefined : parent.left + right: (parent==undefined) ? undefined : parent.right + margins: Theme.itemSpacingLarge + } + Label { - anchors.left: parent.left; + id: drawerTest2Label + text: qsTr("Drawer Test 2") anchors.verticalCenter: parent.verticalCenter - text: "Drawer Test 2"} + } + + Rectangle{ + id: spacer2 + width: parent.width-drawerTest2Label.width-tool1.width-tool2.width-tool3.width + color: "transparent" + height: 1 + } + ToolButton { id: tool1 - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter iconSource: "image://theme/cog" + anchors.verticalCenter: parent.verticalCenter } ToolButton { id: tool2 - anchors.right: tool1.left - anchors.verticalCenter: parent.verticalCenter iconSource: "image://theme/edit" + anchors.verticalCenter: parent.verticalCenter } ToolButton { id: tool3 - anchors.right: tool2.left - anchors.verticalCenter: parent.verticalCenter iconSource: "image://theme/refresh" + anchors.verticalCenter: parent.verticalCenter } }, ButtonRow { diff --git a/examples/touch/touch.pro b/examples/touch/touch.pro index 121eae0..e4498b5 100644 --- a/examples/touch/touch.pro +++ b/examples/touch/touch.pro @@ -28,12 +28,15 @@ qml.files += \ content/IconPage.qml \ content/DatePickerPage.qml \ content/TimePickerPage.qml \ - content/NotificationsPage.qml + content/NotificationsPage.qml \ + content/StatusNotifyPage.qml \ + content/RingIndicatorPage.qml \ + content/BlurredImagePage.qml qml.path = /usr/share/glacier-components/qml/content -images.files = images/*.png -images.files += images/*.jpg +images.files = $$files(images/*.png,false) +images.files += $$files(images/*.jpg,false) images.path = /usr/share/glacier-components/images OTHER_FILES += $$qml.files @@ -50,4 +53,5 @@ SOURCES += \ src/main.cpp DISTFILES += \ + content/StatusNotifyPage.qml \ content/TimePickerPage.qml diff --git a/rpm/qtquickcontrols-nemo.spec b/rpm/qtquickcontrols-nemo.spec index be8b142..4c339b9 100644 --- a/rpm/qtquickcontrols-nemo.spec +++ b/rpm/qtquickcontrols-nemo.spec @@ -13,8 +13,7 @@ BuildRequires: fdupes Requires: qt5-qtquickcontrols Requires: qt5-qtgraphicaleffects -Requires: qt5-plugin-imageformat-jpeg -Requires: qt5-qtsvg-plugin-imageformat-svg +Requires: qt5-qtvirtualkeyboard Requires: nemo-theme-glacier %description @@ -68,6 +67,8 @@ desktop-file-install --delete-original \ %defattr(-,root,root,-) %{_libdir}/qt5/qml/Nemo/Dialogs %{_libdir}/qt5/qml/Nemo/UX/Models +%{_libdir}/qt5/qml/Nemo/Dialogs +%{_libdir}/qt5/qml/QtQuick/VirtualKeyboard/Styles/Nemo %{_libdir}/qt5/qml/QtQuick/Controls/Nemo %{_libdir}/qt5/qml/QtQuick/Controls/Styles/Nemo diff --git a/src/controls/controls.pro b/src/controls/controls.pro index 105a8f4..dee6447 100644 --- a/src/controls/controls.pro +++ b/src/controls/controls.pro @@ -5,6 +5,9 @@ TARGET=nemocontrolsplugin PLUGIN_IMPORT_PATH = QtQuick/Controls/Nemo THEME_IMPORT_PATH = QtQuick/Controls/Styles/Nemo/themes +CONFIG += link_pkgconfig +PKGCONFIG += mlite5 + # Added/Reimplemented Controls QML_FILES += \ qml/Button.qml \ @@ -40,12 +43,14 @@ OTHER_FILES += qmldir \ $$QML_FILES HEADERS += \ + nemoblurredimage.h \ qquicknemocontrolsextensionplugin.h \ hacks.h \ nemowindow.h \ nemopage.h \ qquickfilteringmousearea.h \ nemoimageprovider.h \ + ringindicator.h \ themedaemon/mlocalthemedaemonclient.h \ themedaemon/mabstractthemedaemonclient.h \ sizing.h \ @@ -54,12 +59,14 @@ HEADERS += \ nemofocussingleton.h SOURCES += \ + nemoblurredimage.cpp \ qquicknemocontrolsextensionplugin.cpp \ hacks.cpp \ nemowindow.cpp \ nemopage.cpp \ qquickfilteringmousearea.cpp \ nemoimageprovider.cpp \ + ringindicator.cpp \ themedaemon/mlocalthemedaemonclient.cpp \ themedaemon/mabstractthemedaemonclient.cpp \ sizing.cpp \ @@ -69,11 +76,11 @@ SOURCES += \ target.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH -qmlfiles.files = $$_PRO_FILE_PWD_/qml/*.qml +qmlfiles.files = $$files($$_PRO_FILE_PWD_/qml/*.qml,false) qmlfiles.files += $$_PRO_FILE_PWD_/qml/qmldir qmlfiles.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH -dialogs.files = $$_PRO_FILE_PWD_/qml/dialogs/*.qml +dialogs.files = $$files($$_PRO_FILE_PWD_/qml/dialogs/*.qml,false) dialogs.files += $$_PRO_FILE_PWD_/qml/dialogs/qmldir dialogs.path = $$[QT_INSTALL_QML]/Nemo/Dialogs diff --git a/src/controls/editfilter.cpp b/src/controls/editfilter.cpp index e2ca661..c94463a 100644 --- a/src/controls/editfilter.cpp +++ b/src/controls/editfilter.cpp @@ -18,7 +18,7 @@ */ #include "editfilter.h" - +class QVariant; EditFilter::EditFilter(QObject *parent) : QObject(parent) { diff --git a/src/controls/editfilter.h b/src/controls/editfilter.h index f2a1475..8e39077 100644 --- a/src/controls/editfilter.h +++ b/src/controls/editfilter.h @@ -25,6 +25,8 @@ #include #include "nemofocussingleton.h" +#include + class EditFilter : public QObject { Q_OBJECT diff --git a/src/controls/nemoblurredimage.cpp b/src/controls/nemoblurredimage.cpp new file mode 100644 index 0000000..d15cb53 --- /dev/null +++ b/src/controls/nemoblurredimage.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2021 Chupligin Sergey (NeoChapay) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "nemoblurredimage.h" +#include "theme.h" + +NemoBlurredImage::NemoBlurredImage(QQuickItem *parent) + :QQuickPaintedItem(parent) + , m_source("") + , m_fillMode(FillMode::Stretch) + , m_radius(50) + , m_opacity(0.5) + , m_dimColor(Qt::black) +{ + +} + +void NemoBlurredImage::paint(QPainter *painter) +{ + QSizeF itemSize = size(); + QRectF target(0, 0, itemSize.width(), itemSize.height()); + QImage source(m_source); + + QImage blurr = makeBlurred(source, source.rect(), m_radius); + Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio; + + if(m_fillMode == FillMode::PreserveAspectFit) { + aspectMode = Qt::KeepAspectRatio; + } + + if(m_fillMode == FillMode::PreserveAspectCrop) { + aspectMode = Qt::KeepAspectRatioByExpanding; + } + + + blurr = blurr.scaled(QSize(itemSize.width(), itemSize.height()), aspectMode); + + painter->drawImage(blurr.rect(), blurr); + + painter->setBrush(QBrush(m_dimColor)); + painter->setOpacity(m_opacity); + painter->drawRect(blurr.rect()); +} + +void NemoBlurredImage::setSource(QString path) +{ + if(path == m_source) { + return; + } + + QFile imgFile(path); + if(!imgFile.exists()) { + qWarning() << "Not exists!!!" << path; + return; + } + + m_source = path; + emit sourceChanged(); + update(); +} + +void NemoBlurredImage::setRadius(int radius) +{ + if(radius != m_radius) { + m_radius = radius; + emit radiusChanged(); + update(); + } +} + +void NemoBlurredImage::setOpacity(qreal opacity) +{ + if(opacity != m_opacity) { + m_opacity = opacity; + emit opacityChanged(); + update(); + } +} + +void NemoBlurredImage::setDimColor(QColor dimColor) +{ + if(dimColor != m_dimColor) { + m_dimColor = dimColor; + emit dimColorChanged(); + update(); + } +} + +void NemoBlurredImage::setFillMode(FillMode mode) +{ + if(mode != m_fillMode) { + m_fillMode = mode; + emit fillModeChanged(); + update(); + } +} + +QImage NemoBlurredImage::makeBlurred(QImage& image, const QRect& rect, int radius, bool alphaOnly) +{ + int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }; + int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1]; + + QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + int r1 = rect.top(); + int r2 = rect.bottom(); + int c1 = rect.left(); + int c2 = rect.right(); + + int bpl = result.bytesPerLine(); + int rgba[4]; + unsigned char* p; + + int i1 = 0; + int i2 = 3; + + if (alphaOnly) { + i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); + } + + for (int col = c1; col <= c2; col++) { + p = result.scanLine(r1) + col * 4; + for (int i = i1; i <= i2; i++) + rgba[i] = p[i] << 4; + + p += bpl; + for (int j = r1; j < r2; j++, p += bpl) + for (int i = i1; i <= i2; i++) + p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + } + + for (int row = r1; row <= r2; row++) { + p = result.scanLine(row) + c1 * 4; + for (int i = i1; i <= i2; i++) + rgba[i] = p[i] << 4; + + p += 4; + for (int j = c1; j < c2; j++, p += 4) + for (int i = i1; i <= i2; i++) + p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + } + + for (int col = c1; col <= c2; col++) { + p = result.scanLine(r2) + col * 4; + for (int i = i1; i <= i2; i++) + rgba[i] = p[i] << 4; + + p -= bpl; + for (int j = r1; j < r2; j++, p -= bpl) + for (int i = i1; i <= i2; i++) + p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + } + + for (int row = r1; row <= r2; row++) { + p = result.scanLine(row) + c2 * 4; + for (int i = i1; i <= i2; i++) + rgba[i] = p[i] << 4; + + p -= 4; + for (int j = c1; j < c2; j++, p -= 4) + for (int i = i1; i <= i2; i++) + p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; + } + + return result; +} diff --git a/src/controls/nemoblurredimage.h b/src/controls/nemoblurredimage.h new file mode 100644 index 0000000..81b6ab7 --- /dev/null +++ b/src/controls/nemoblurredimage.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2021 Chupligin Sergey (NeoChapay) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef NEMOBLURREDIMAGE_H +#define NEMOBLURREDIMAGE_H + +#include +#include + +class NemoBlurredImage: public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged) + Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged) + Q_PROPERTY(QColor dimColor READ dimColor WRITE setDimColor NOTIFY dimColorChanged) + Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged) + +public: + enum class FillMode{ + Stretch, + PreserveAspectFit, + PreserveAspectCrop + }; + + Q_ENUMS(FillMode); + + explicit NemoBlurredImage(QQuickItem *parent = 0); + void paint(QPainter *painter); + QString source() {return m_source;} + void setSource(QString path); + + int radius() {return m_radius;} + void setRadius(int radius); + + qreal opacity() {return m_opacity;} + void setOpacity(qreal opacity); + + QColor dimColor() {return m_dimColor;} + void setDimColor(QColor dimColor); + + FillMode fillMode() {return m_fillMode;} + void setFillMode(FillMode mode); + +signals: + void sourceChanged(); + void radiusChanged(); + void opacityChanged(); + void dimColorChanged(); + void fillModeChanged(); + +private: + QImage makeBlurred(QImage &image, const QRect& rect, int radius, bool alphaOnly = false); + QString m_source; + FillMode m_fillMode; + int m_radius; + qreal m_opacity; + QColor m_dimColor; +}; + +#endif // NEMOBLURREDIMAGE_H diff --git a/src/controls/nemopage.cpp b/src/controls/nemopage.cpp index 5b6d2e7..a522df5 100644 --- a/src/controls/nemopage.cpp +++ b/src/controls/nemopage.cpp @@ -3,7 +3,7 @@ #include NemoPage::NemoPage(QQuickItem *parent) : QQuickItem(parent), - m_allowedOrientations(0) //- The value 0 means Page's allowedOrientations will be ignored + m_allowedOrientations(Qt::PrimaryOrientation) //- The value 0 means Page's allowedOrientations will be ignored //- The value 0 can't be set from QML on purpose (see Hacks::isOrientationMaskValid impl.), // so that we can use the value 0 to know that the app developer has not touched this value // (in fact, as just said, once it's changed from QML, the app dev can't set it back to 0 from QML) diff --git a/src/controls/nemowindow.cpp b/src/controls/nemowindow.cpp index e61f060..f32ce61 100644 --- a/src/controls/nemowindow.cpp +++ b/src/controls/nemowindow.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Andrea Bernabei + * Copyright (C) 2021 Chupligin Sergey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,6 +20,7 @@ #include "nemowindow.h" #include +#include #include "hacks.h" NemoWindow::NemoWindow(QWindow *parent) : @@ -28,6 +30,14 @@ NemoWindow::NemoWindow(QWindow *parent) : m_allowedOrientations = m_defaultAllowedOrientations; m_filter = new EditFilter(); this->installEventFilter(m_filter); + + calculateOrientation(this->screen()->orientation()); + + QScreen *screen = this->screen(); + + connect(screen, &QScreen::orientationChanged, + this, &NemoWindow::calculateOrientation); + } Qt::ScreenOrientations NemoWindow::allowedOrientations() const @@ -40,6 +50,11 @@ const Qt::ScreenOrientations NemoWindow::defaultAllowedOrientations() const return m_defaultAllowedOrientations; } +Qt::ScreenOrientations NemoWindow::orientation() const +{ + return m_orientation; +} + void NemoWindow::setAllowedOrientations(Qt::ScreenOrientations allowed) { //This way no invalid values can get assigned to allowedOrientations @@ -52,3 +67,28 @@ void NemoWindow::setAllowedOrientations(Qt::ScreenOrientations allowed) } } } + +void NemoWindow::calculateOrientation(Qt::ScreenOrientation orientation) +{ + Qt::ScreenOrientation orient; + + if(orientation == Qt::InvertedLandscapeOrientation || orientation == Qt::InvertedPortraitOrientation) { + if(width() < height()) { + orient = Qt::InvertedLandscapeOrientation; + } else { + orient = Qt::InvertedPortraitOrientation; + } + } else { + if(width() < height()) { + orient = Qt::LandscapeOrientation; + } else { + orient = Qt::PortraitOrientation; + } + } + + if(orient != m_orientation) { + m_orientation = orient; + emit orientationChanged(); + } + +} diff --git a/src/controls/nemowindow.h b/src/controls/nemowindow.h index 005a29f..5615ab0 100644 --- a/src/controls/nemowindow.h +++ b/src/controls/nemowindow.h @@ -1,8 +1,6 @@ -#ifndef NEMOWINDOW_H -#define NEMOWINDOW_H - /* * Copyright (C) 2013 Andrea Bernabei + * Copyright (C) 2021 Chupligin Sergey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,6 +18,9 @@ * Boston, MA 02110-1301, USA. */ +#ifndef NEMOWINDOW_H +#define NEMOWINDOW_H + #include #include #include "editfilter.h" @@ -29,19 +30,24 @@ class NemoWindow : public QQuickWindow Q_OBJECT Q_PROPERTY(Qt::ScreenOrientations allowedOrientations READ allowedOrientations WRITE setAllowedOrientations NOTIFY allowedOrientationsChanged) Q_PROPERTY(Qt::ScreenOrientations defaultAllowedOrientations READ allowedOrientations) + Q_PROPERTY(Qt::ScreenOrientations orientation READ orientation NOTIFY orientationChanged) public: explicit NemoWindow(QWindow *parent = 0); Qt::ScreenOrientations allowedOrientations() const; const Qt::ScreenOrientations defaultAllowedOrientations() const; + Qt::ScreenOrientations orientation() const; void setAllowedOrientations(Qt::ScreenOrientations allowed); signals: void allowedOrientationsChanged(); + void orientationChanged(); + void desktopModeChanged(); -public slots: +private slots: + void calculateOrientation(Qt::ScreenOrientation orientation); private: //This is the global allowed orientations settings: @@ -51,8 +57,9 @@ public slots: Qt::ScreenOrientations m_defaultAllowedOrientations; - EditFilter *m_filter; + Qt::ScreenOrientations m_orientation; + EditFilter *m_filter; }; #endif // NEMOWINDOW_H diff --git a/src/controls/qml/ActionButton.qml b/src/controls/qml/ActionButton.qml index 28e418c..df97d24 100644 --- a/src/controls/qml/ActionButton.qml +++ b/src/controls/qml/ActionButton.qml @@ -37,7 +37,7 @@ Item { signal clicked(); - height: parent.height + height: visible ? parent.height : 0; width: height Image{ diff --git a/src/controls/qml/ApplicationWindow.qml b/src/controls/qml/ApplicationWindow.qml index 6873fa2..f8f3878 100644 --- a/src/controls/qml/ApplicationWindow.qml +++ b/src/controls/qml/ApplicationWindow.qml @@ -2,6 +2,7 @@ * Copyright (C) 2013 Andrea Bernabei * Copyright (C) 2013 Jolla Ltd. * Copyright (C) 2017 Eetu Kahelin + * Copyright (C) 2021 Chupligin Sergey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,7 +23,7 @@ import QtQuick.Window 2.2 import QtQuick 2.6 import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 + import QtQuick.Controls.Private 1.0 import QtQuick.Controls.Nemo 1.0 import QtQuick.Controls.Styles.Nemo 1.0 @@ -38,9 +39,8 @@ NemoWindow { property alias initialPage: stackView.initialItem property bool applicationActive: Qt.application.active - - property alias orientation: contentArea.uiOrientation - readonly property int isUiPortrait: orientation == Qt.PortraitOrientation || orientation == Qt.InvertedPortraitOrientation + //property alias orientation: contentArea.uiOrientation + readonly property int isUiPortrait: root.width < root.height //is this safe? can there be some situation in which it's neither portrait nor landscape? readonly property int isUiLandscape: !isUiPortrait @@ -48,10 +48,10 @@ NemoWindow { color: _bgColor //Handles orientation of keyboard, MInputMethodQuick.appOrientation. - contentOrientation: orientation - onOrientationChanged: { + //contentOrientation: orientation + /*onOrientationChanged: { contentOrientation=orientation - } + }*/ //README: allowedOrientations' default value is set in NemoWindow's c++ implementation //The app developer can overwrite it from QML @@ -60,12 +60,6 @@ NemoWindow { orientationConstraintsChanged() } - Screen.onOrientationChanged: { - if (root.isOrientationAllowed(Screen.orientation)) { - contentArea.filteredOrientation = Screen.orientation - } - } - //Safety version of pageStack.push - if we can't load component - show error page page with //error message and back button @@ -96,13 +90,13 @@ NemoWindow { Connections { target: pageStack - onBusyChanged: { + function onBusyChanged(busy) { if (_errorTimer.errorString && !pageStack.busy) { _errorTimer.start() } } - onCurrentItemChanged: { + function onCurrentItemChanged(currentItem) { var qmltype = pageStack.currentItem.toString() if (qmltype.slice(0, 10) === "QQuickText") { _errorTimer.errorString = pageStack.currentItem.text @@ -112,6 +106,7 @@ NemoWindow { function orientationConstraintsChanged() { + return; ///FIX IT! //if the current orientation is not allowed anymore, fallback to an allowed one //stackInitialized check prevents setting an orientation before the stackview //(but more importantly the initialItem of the stack) has been created @@ -121,8 +116,8 @@ NemoWindow { // the phone is in portrait, and a page allowing portrait mode is pushed on the stack. // When the page is pushed, we don't get any orientationChanged signal from the Screen element // because the phone was already held in portrait mode, se we have to enforce it here. - if (isOrientationAllowed(Screen.orientation)) { - contentArea.filteredOrientation = Screen.orientation + if (isOrientationAllowed(root.orientation)) { + contentArea.filteredOrientation = root.orientation } //- If neither the current screen orientation nor the one which the UI is already presented in (filteredOrientation) // are allowed, then fallback to an allowed orientation. @@ -134,6 +129,7 @@ NemoWindow { function fallbackToAnAllowedOrientation() { + return; //FIX IT var orientations = [Qt.PortraitOrientation, Qt.LandscapeOrientation, Qt.InvertedPortraitOrientation, Qt.InvertedLandscapeOrientation] @@ -152,7 +148,7 @@ NemoWindow { // i.e. Screen.width will be width of portrait orientation on all hardware! // (at the moment, Screen.width is the width of the screen in landscape mode in N9/N950, while on // other hardware it could be width of the screen in portrait mode) - property bool __transpose: (rotationToTransposeToPortrait() % 180) != 0 + //property bool __transpose: (rotationToTransposeToPortrait() % 180) != 0 // XXX: This is to account for HW screen rotation // Sooner or later we will get rid of this as the compositor will @@ -191,17 +187,17 @@ NemoWindow { Item { id: backgroundItem - anchors.fill: parent - rotation: rotationToTransposeToPortrait() + anchors.fill: parent Item { id: clipping z: 1 - width: parent.width - (isUiLandscape ? stackView.panelSize : 0) - height: parent.height - (isUiPortrait ? stackView.panelSize : 0) + width: parent.width - (isUiLandscape ? stackView.panelSize : 0) + height: parent.height - (isUiPortrait ? stackView.panelSize : 0) clip: stackView.panelSize > 0 + //This is the rotating item Item { id: contentArea @@ -240,6 +236,7 @@ NemoWindow { : Qt.inputMethod.keyboardRectangle.height) : (root._transpose ? Qt.inputMethod.keyboardRectangle.height : Qt.inputMethod.keyboardRectangle.width)) + onImSizeChanged: { if (imSize <= 0 && previousImSize > 0) { imShowAnimation.stop() @@ -254,7 +251,6 @@ NemoWindow { previousImSize = imSize } - clip: true Component.onCompleted: { stackInitialized = true @@ -297,12 +293,18 @@ NemoWindow { Connections { id: pageConn target: stackView._isCurrentItemNemoPage() ? stackView.currentItem : null - onAllowedOrientationsChanged: root.orientationConstraintsChanged() + function onAllowedOrientationsChanged() { root.orientationConstraintsChanged() } } delegate: StackViewDelegate { pushTransition: Component { StackViewTransition { + ScriptAction { + script: { + imShowAnimation.stop() + imHideAnimation.start() + } + } PropertyAnimation { target: enterItem property: "x" @@ -323,6 +325,12 @@ NemoWindow { } popTransition: Component { StackViewTransition { + ScriptAction { + script: { + imShowAnimation.stop() + imHideAnimation.start() + } + } PropertyAnimation { target: enterItem property: "x" @@ -371,38 +379,6 @@ NemoWindow { id: toolBar stackView: root.pageStack appWindow: root - - //used to animate the dimmer when pages are pushed/popped (see Header's QML code) - property alias __dimmer: headerDimmerContainer - } - - Item { - //This item handles the rotation of the dimmer. - //All this because QML doesn't have a horizontal gradient (unless you import GraphicalEffects) - //and having a container which doesn't rotate but just resizes makes it easier to rotate its inner - //child - id: headerDimmerContainer - - //README: Don't use AnchorChanges for this item! - //Reason: state changes disable bindings while the transition from one state to another is running. - //This causes the dimmer not to follow the drawer when the drawer is closed right before the orientation change - anchors.top: isUiPortrait ? toolBar.bottom : parent.top - anchors.left: isUiPortrait ? parent.left : toolBar.right - anchors.right: isUiPortrait ? parent.right : undefined - anchors.bottom: isUiPortrait ? undefined : parent.bottom - //we only set the size in one orientation, the anchors will take care of the other - width: if (!isUiPortrait) Theme.itemHeightExtraSmall/2 - height: if (isUiPortrait) Theme.itemHeightExtraSmall/2 - //MAKE SURE THAT THE HEIGHT SPECIFIED BY THE THEME IS AN EVEN NUMBER, TO AVOID ROUNDING ERRORS IN THE LAYOUT - - Rectangle { - id: headerDimmer - anchors.centerIn: parent - gradient: Gradient { - GradientStop { position: 0; color: Theme.backgroundColor } - GradientStop { position: 1; color: "transparent" } - } - } } Item { @@ -413,25 +389,19 @@ NemoWindow { states: [ State { name: 'Unanimated' - when: !stackView || !stackInitialized + when: !stackView || !stackView.stackInitialized }, State { name: 'Portrait' - when: contentArea.filteredOrientation === Qt.PortraitOrientation// && stackInitialized + when: root.orientation === Qt.PortraitOrientation// && stackInitialized PropertyChanges { target: contentArea restoreEntryValues: false width: _horizontalDimension height: _verticalDimension - rotation: 0 + //rotation: 0 uiOrientation: Qt.PortraitOrientation } - PropertyChanges { - target: headerDimmer - height: Theme.itemHeightExtraSmall/2 - width: parent.width - rotation: 0 - } AnchorChanges { target: clipping anchors.top: parent.top @@ -442,7 +412,7 @@ NemoWindow { }, State { name: 'Landscape' - when: contentArea.filteredOrientation === Qt.LandscapeOrientation //&& stackInitialized + when: root.width < root.height //root.orientation === Qt.LandscapeOrientation //&& stackInitialized PropertyChanges { target: contentArea restoreEntryValues: false @@ -451,12 +421,6 @@ NemoWindow { rotation: 90 uiOrientation: Qt.LandscapeOrientation } - PropertyChanges { - target: headerDimmer - height: Theme.itemHeightExtraSmall/2 - width: parent.height - rotation: -90 - } AnchorChanges { target: clipping anchors.top: undefined @@ -464,10 +428,17 @@ NemoWindow { anchors.right: parent.right anchors.bottom: parent.bottom } + AnchorChanges { + target: inputClipping + anchors.top: undefined + anchors.left: parent.left + anchors.right: undefined//clipping.left + anchors.bottom: parent.bottom + } }, State { name: 'PortraitInverted' - when: contentArea.filteredOrientation === Qt.InvertedPortraitOrientation //&& stackInitialized + when: root.orientation === Qt.InvertedPortraitOrientation //&& stackInitialized PropertyChanges { target: contentArea restoreEntryValues: false @@ -476,12 +447,6 @@ NemoWindow { rotation: 180 uiOrientation: Qt.InvertedPortraitOrientation } - PropertyChanges { - target: headerDimmer - height: Theme.itemHeightExtraSmall/2 - width: parent.width - rotation: 0 - } AnchorChanges { target: clipping anchors.top: undefined @@ -489,10 +454,17 @@ NemoWindow { anchors.right: parent.right anchors.bottom: parent.bottom } + AnchorChanges { + target: inputClipping + anchors.top: undefined + anchors.left: undefined + anchors.right: clipping.right + anchors.bottom: clipping.top + } }, State { name: 'LandscapeInverted' - when: contentArea.filteredOrientation === Qt.InvertedLandscapeOrientation //&& stackInitialized + when: root.orientation === Qt.InvertedLandscapeOrientation //&& stackInitialized PropertyChanges { target: contentArea restoreEntryValues: false @@ -501,12 +473,6 @@ NemoWindow { rotation: 270 uiOrientation: Qt.InvertedLandscapeOrientation } - PropertyChanges { - target: headerDimmer - height: Theme.itemHeightExtraSmall/2 - width: parent.height - rotation: -90 - } AnchorChanges { target: clipping anchors.top: undefined @@ -514,6 +480,13 @@ NemoWindow { anchors.right: undefined anchors.bottom: parent.bottom } + AnchorChanges { + target: inputClipping + anchors.top: undefined + anchors.left: undefined//clipping.right + anchors.right: parent.right + anchors.bottom: parent.bottom + } } ] @@ -526,11 +499,19 @@ NemoWindow { property: 'orientationTransitionRunning' value: true } - NumberAnimation { - target: contentArea - property: 'opacity' - to: 0 - duration: 150 + ParallelAnimation { + NumberAnimation { + target: contentArea + property: 'opacity' + to: 0 + duration: 150 + } + NumberAnimation { + target: inputPanel + property: 'opacity' + to: 0 + duration: 150 + } } PropertyAction { target: contentArea @@ -539,15 +520,19 @@ NemoWindow { AnchorAnimation { duration: 0 } - PropertyAction { - target: headerDimmer - properties: 'width,height,rotation' - } - NumberAnimation { - target: contentArea - property: 'opacity' - to: 1 - duration: 150 + ParallelAnimation { + NumberAnimation { + target: contentArea + property: 'opacity' + to: 1 + duration: 150 + } + NumberAnimation { + target: inputPanel + property: 'opacity' + to: 1 + duration: 150 + } } PropertyAction { target: contentArea diff --git a/src/controls/qml/Button.qml b/src/controls/qml/Button.qml index bb65c6b..4b58693 100644 --- a/src/controls/qml/Button.qml +++ b/src/controls/qml/Button.qml @@ -35,11 +35,11 @@ Button { // We need those for Glacier's Button pressed effect Connections { target: butt.__behavior - onPressed: { + function onPressed(mouse) { pressX = mouse.x pressY = mouse.y } - onPositionChanged: { + function onPositionChanged(mouse) { pressX = mouse.x pressY = mouse.y } diff --git a/src/controls/qml/ButtonRow.qml b/src/controls/qml/ButtonRow.qml index fbba17a..67a551e 100644 --- a/src/controls/qml/ButtonRow.qml +++ b/src/controls/qml/ButtonRow.qml @@ -2,6 +2,7 @@ ** ** Copyright (C) 2014 Aleksi Suomalainen ** Copyright (C) 2017 Sergey Chupligin +** Copyright (C) 2017 Eetu Kahelin ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: diff --git a/src/controls/qml/DatePicker.qml b/src/controls/qml/DatePicker.qml index a556b88..9e54b8f 100644 --- a/src/controls/qml/DatePicker.qml +++ b/src/controls/qml/DatePicker.qml @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2017 Chupligin Sergey +** Copyright (C) 2017-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -41,6 +41,10 @@ Item { height: childrenRect.height property date currentDate: new Date() + property bool showForwardButton: true + property bool showBackButton: true + property alias dayDelegate: daysGrid.delegate + property alias weekDaysDelegate: weekendListView.delegate property var monthNames: [qsTr("January"), qsTr("February"), qsTr("March"), qsTr("April"), qsTr("May"), qsTr("June"),qsTr("July"), qsTr("August"), qsTr("September"), qsTr("October"), qsTr("November"), qsTr("December")]; @@ -61,6 +65,7 @@ Item { id: leftArrow width: Theme.itemHeightMedium height: width + visible: showBackButton anchors{ left: parent.left @@ -73,18 +78,8 @@ Item { MouseArea{ anchors.fill: parent onClicked: { - var newDate = currentDate; - if(newDate.getMonth() == 1) - { - newDate.setFullYear(currentDate.getFullYear()-1) - newDate.setMonth(12) - } - else - { - newDate.setMonth(currentDate.getMonth()-1) - } - datePicker.currentDate = newDate - monthChanged() + var d = new Date(calendarModel.selectedDate); + calendarModel.selectedDate = new Date(d.setMonth(d.getMonth()-1)) } } } @@ -94,13 +89,14 @@ Item { anchors.centerIn: parent font.pixelSize: Theme.fontSizeLarge color: Theme.textColor - text: monthNames[currentDate.getMonth()] + text: monthNames[calendarModel.selectedDate.getMonth()] } Image{ id: rightArrow width: Theme.itemHeightMedium height: width + visible: showForwardButton anchors{ right: parent.right @@ -113,18 +109,8 @@ Item { MouseArea{ anchors.fill: parent onClicked: { - var newDate = currentDate; - if(newDate.getMonth() == 12) - { - newDate.setFullYear(currentDate.getFullYear()+1) - newDate.setMonth(1) - } - else - { - newDate.setMonth(currentDate.getMonth()+1) - } - datePicker.currentDate = newDate - monthChanged() + var d = new Date(calendarModel.selectedDate); + calendarModel.selectedDate = new Date(d.setMonth(d.getMonth()+1)) } } } @@ -178,9 +164,11 @@ Item { height: parent.height model: weekendModel orientation: ListView.Horizontal + clip: true delegate: Item{ height: parent.height width: height + clip: true Label{ text: label @@ -196,6 +184,7 @@ Item { id: daysGrid width: parent.width height: width + clip: true anchors { top: weekDays.bottom @@ -226,7 +215,7 @@ Item { /*If weekend*/ if(model.dateOfDay.getDay() === 0 || model.dateOfDay.getDay() === 6) { - if(model.isCurrentDay) + if(model.isCurrentDay || Qt.formatDate(model.dateOfDay, "yyMMdd") == Qt.formatDate(currentDate, "yyMMdd")) { color = Theme.textColor } @@ -247,7 +236,7 @@ Item { width: parent.width height: parent.height color: Theme.accentColor - visible: model.isCurrentDay + visible: Qt.formatDate(model.dateOfDay, "yyMMdd") == Qt.formatDate(currentDate, "yyMMdd") } Label{ @@ -267,12 +256,6 @@ Item { } } - onMonthChanged: { - calendarModel.selectedDate = datePicker.currentDate - calendarModel.month = currentDate.getMonth()+1; - calendarModel.year = currentDate.getFullYear(); - } - CalendarModel{ id: calendarModel } diff --git a/src/controls/qml/Header.qml b/src/controls/qml/Header.qml index 8aed14e..ab622e2 100644 --- a/src/controls/qml/Header.qml +++ b/src/controls/qml/Header.qml @@ -1,10 +1,30 @@ +/* + * Copyright (C) 2018-2021 Chupligin Sergey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + import QtQuick 2.6 import QtQuick.Window 2.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Nemo 1.0 import QtQuick.Controls.Styles.Nemo 1.0 -import QtQuick.Layouts 1.0 + import QtGraphicalEffects 1.0 +import QtQml 2.14 Item { id: root @@ -12,20 +32,22 @@ Item { //TODO: Add logic/animations to handle dynamic change of tools and drawer levels in the same page //make sure the header is aligned properly - Binding on y { + /*Binding on y { when: !appWindow.isUiPortrait value: 0 } Binding on x { when: appWindow.isUiPortrait value: 0 - } + }*/ //Since the header drawer behaves differently in portrait/landscape modes //we close the drawer when the UI rotates Connections { target: appWindow - onIsUiPortraitChanged: closeDrawer() + function onIsUiPortraitChanged() { + closeDrawer() + } } //Handle portrait/landscape orientation layout changes @@ -126,14 +148,16 @@ Item { //(i.e. to get header.stackView.depth value) Connections { target: stackView - onCurrentItemChanged: { + function onCurrentItemChanged() { if (changeToolsLayoutAnim.running) { changeToolsLayoutAnim.complete() } changeToolsLayoutAnim.start() } //Close drawer if a page transition is starting - onBusyChanged: if (stackView.busy) closeDrawer() + function onBusyChanged() { + if (stackView.busy) closeDrawer() + } } function propagateHeaderReference() { @@ -183,7 +207,8 @@ Item { color: Theme.backgroundColor - FilteringMouseArea { + //TODO: Check if changing this FilteringMouseArea->MouseArea has any side effects + MouseArea { id: mouseArea anchors.fill: parent property bool swiping: false @@ -215,18 +240,18 @@ Item { } if (appWindow.isUiPortrait) { - startMouseCoord = (pos.y + root.y) + startMouseCoord = (mouse.y + root.y) startCoord = root.y } else { //assuming that otherwise we're in landscape...is this safe? - startMouseCoord = (pos.x + root.x) + startMouseCoord = (mouse.x + root.x) startCoord = root.x } } onPositionChanged: { if (appWindow.isUiPortrait) { - deltaCoord = (pos.y + root.y) - startMouseCoord - if (Math.abs(deltaCoord) > swipeThreshold && !swiping) { grabMouseEvents(); swiping = true; } + deltaCoord = (mouse.y + root.y) - startMouseCoord + if (Math.abs(deltaCoord) > swipeThreshold && !swiping) { swiping = true; } if (swiping) { var swipingY = startCoord + deltaCoord @@ -238,8 +263,8 @@ Item { } } } else { - deltaCoord = (pos.x + root.x) - startMouseCoord - if (Math.abs(deltaCoord) > swipeThreshold && !swiping) { grabMouseEvents(); swiping = true; } + deltaCoord = (mouse.x + root.x) - startMouseCoord + if (Math.abs(deltaCoord) > swipeThreshold && !swiping) { swiping = true; } if (swiping) { //this is the coord that the drawer would be at if it were following our finger var swipingX = startCoord + deltaCoord @@ -285,7 +310,7 @@ Item { //Fully Close/Open the drawer root.slideDrawerTo((root.x == root.closedX) ? 0 : root.closedX) } else { - deltaCoord = (pos.x + root.x) - startMouseCoord + deltaCoord = (mouse.x + root.x) - startMouseCoord if (deltaCoord > gestureThreshold) { root.slideDrawerTo(startCoord < 0 ? 0 : closedX) } else if (deltaCoord < -gestureThreshold){ @@ -308,15 +333,17 @@ Item { color: Theme.backgroundColor Binding on width { + restoreMode: Binding.RestoreBinding value: drawer.width when: !appWindow.isUiPortrait } Binding on height { + restoreMode: Binding.RestoreBinding value: drawer.height when: appWindow.isUiPortrait } - ColumnLayout { + Column { id: drawer //NOTE: if you set the spacing to something != 0 then you have to rewrite the logic which handles drawer speedbumps, diff --git a/src/controls/qml/HeaderToolsLayout.qml b/src/controls/qml/HeaderToolsLayout.qml index 62c0806..cf6906c 100644 --- a/src/controls/qml/HeaderToolsLayout.qml +++ b/src/controls/qml/HeaderToolsLayout.qml @@ -1,7 +1,26 @@ +/* + * Copyright (C) 2018-2021 Chupligin Sergey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + import QtQuick 2.6 import QtQuick.Controls.Nemo 1.0 import QtQuick.Controls.Styles.Nemo 1.0 -import QtQuick.Layouts 1.0 + import QtGraphicalEffects 1.0 //This item handles the UI representation for the toolbar @@ -92,7 +111,7 @@ Item { width: tools ? (Theme.itemHeightMedium * Math.min(maxNumberOfToolButtons, tools.length)) : 0 property int maxNumberOfToolButtons: 3 - RowLayout { + Row { id: toolsRow anchors.centerIn: parent height: toolMeasure diff --git a/src/controls/qml/ListViewItemWithActions.qml b/src/controls/qml/ListViewItemWithActions.qml index d8361a2..24ff1e2 100644 --- a/src/controls/qml/ListViewItemWithActions.qml +++ b/src/controls/qml/ListViewItemWithActions.qml @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2017-2018 Chupligin Sergey +** Copyright (C) 2017-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -36,7 +36,7 @@ import QtGraphicalEffects 1.0 Item { id: root - width: parent.width + width: parent ? parent.width : 0 height: Theme.itemHeightLarge property string label: "" @@ -47,6 +47,7 @@ Item { property bool showNext: true property bool iconVisible: true + property bool iconColorized: true property bool showActions: true @@ -55,12 +56,14 @@ Item { signal clicked function hideAllActions() { - root.ListView.view.hideAllActions(index) + if(actions && root.ListView.view) { + root.ListView.view.hideAllActions(index) + } } Connections { target: root.ListView.view - onHideAllActions: { + function onHideAllActions(hideIndex) { if (hideIndex != index) { listArea.x = 0 } @@ -74,7 +77,7 @@ Item { anchors.right: listArea.left height: listArea.height - width: height*actions.length + width: actionsRow.childrenRect.width Row { id: actionsRow @@ -124,7 +127,7 @@ Item { leftMargin: Theme.itemSpacingLarge verticalCenter:parent.verticalCenter } - + colorized: iconColorized sourceSize.width: width sourceSize.height: height visible: iconVisible diff --git a/src/controls/qml/NemoIcon.qml b/src/controls/qml/NemoIcon.qml index 9b81258..69e7f63 100644 --- a/src/controls/qml/NemoIcon.qml +++ b/src/controls/qml/NemoIcon.qml @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2019 Chupligin Sergey +** Copyright (C) 2019-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -34,10 +34,12 @@ import QtQuick 2.6 Image { id: nemoIcon + property bool colorized: true + property color color: Theme.textColor layer.effect: ShaderEffect { id: shaderItem - property color color: Theme.textColor + property color color: nemoIcon.color fragmentShader: " varying mediump vec2 qt_TexCoord0; @@ -50,6 +52,6 @@ Image { } " } - layer.enabled: true + layer.enabled: colorized layer.samplerName: "source" } diff --git a/src/controls/qml/Slider.qml b/src/controls/qml/Slider.qml index 265b52e..09c0773 100644 --- a/src/controls/qml/Slider.qml +++ b/src/controls/qml/Slider.qml @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2021 Chupligin Sergey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + import QtQuick 2.6 import QtQuick.Controls 1.0 @@ -8,7 +27,7 @@ Slider { id: slider property bool showValue: false property int valueFontSize: Theme.fontSizeTiny - property bool useSpecSlider: true + property bool useSpecSlider: Theme.desktopMode ? false : true property bool alwaysUp: false style: SliderStyle{} diff --git a/src/controls/qml/TextField.qml b/src/controls/qml/TextField.qml index 89dc188..a8af58f 100644 --- a/src/controls/qml/TextField.qml +++ b/src/controls/qml/TextField.qml @@ -1,6 +1,7 @@ /**************************************************************************************** ** ** Copyright (c) 2017, Eetu Kahelin +** Copyright (C) 2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -39,5 +40,6 @@ TextField { if(activeFocus) NemoFocus.nemoregister(this) else NemoFocus.nemoregister(null) } + style: TextFieldStyle { } } diff --git a/src/controls/qml/TimePicker.qml b/src/controls/qml/TimePicker.qml index 76b6051..5a249fc 100644 --- a/src/controls/qml/TimePicker.qml +++ b/src/controls/qml/TimePicker.qml @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2018 Chupligin Sergey +** Copyright (C) 2018-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -39,74 +39,84 @@ Item{ property date currentTime: new Date() - property int hours: currentTime.getHours() - property int minutes: currentTime.getHours() - property bool readOnly: true - Rectangle{ - anchors.fill: parent - color: Theme.backgroundColor - } + Item{ + id: clockWidget + width: parent.width + height: parent.width - Canvas { - id: canvas - anchors.fill: parent - onPaint: { - var context = getContext("2d"); - - var centerX = canvas.width / 2 - var centerY = canvas.height / 2 - - var hour_radius = canvas.width/2*0.8 - 1.5*Theme.itemHeightExtraSmall/4 - Theme.itemHeightExtraSmall/5/2 - var hour_end_angle = getHourAngle() - - var minute_radius = canvas.width/2*0.8 - var minute_end_angle = getMinuteAngle() - - context.clearRect(0, 0, canvas.width, canvas.height) -/*Draw hours */ - context.beginPath() - context.arc(centerX, centerY, hour_radius, -0.5*Math.PI, hour_end_angle, false) - context.lineWidth = Theme.itemHeightExtraSmall/2 - context.strokeStyle = Theme.accentColor - context.globalAlpha = 1 - context.stroke(); -/*Draw subhours if time AM*/ - if(timePicker.hours > 12) - { - context.beginPath() - context.arc(centerX, centerY, hour_radius, 0, 2 * Math.PI, false) - context.lineWidth = Theme.itemHeightExtraSmall/2 - context.strokeStyle = Theme.accentColor - context.globalAlpha = 0.5 - context.stroke() + RingIndicator{ + id: hours12 + anchors.centerIn: parent + + width: parent.width - Theme.itemHeightExtraSmall + height: parent.height - Theme.itemHeightExtraSmall + + startAngle: 0 + stopAngle: 360 + + lineWidth: Theme.itemHeightExtraSmall/2 + color: Theme.accentColor + opacity: 0.5 + visible: currentTime.getHours() >= 12 + } + + RingIndicator{ + id: hours + anchors.centerIn: parent + + width: parent.width - Theme.itemHeightExtraSmall + height: parent.height - Theme.itemHeightExtraSmall + + startAngle: 0 + stopAngle: 360/12*currentTime.getHours() + + lineWidth: Theme.itemHeightExtraSmall/2 + color: Theme.accentColor + + Label{ + id: hourLabel + text: currentTime.getHours() + font.pixelSize: hours.lineWidth + font.bold: true + + anchors{ + top: hours.top + topMargin: -hours.lineWidth/4 + right: hours.horizontalCenter + rightMargin: hours.lineWidth/4 + } } -/*Draw minute*/ - context.beginPath(); - context.arc(centerX, centerY, minute_radius, -0.5*Math.PI, minute_end_angle, false) - context.lineWidth = Theme.itemHeightExtraSmall/5 - context.strokeStyle = Theme.accentColor - context.globalAlpha = 0.5 - context.stroke() } - } - Label{ - id: hourLabel - text: timePicker.hours - font.pixelSize: Theme.itemHeightExtraSmall/2 - font.bold: true - x: canvas.width/2-hourLabel.contentWidth-Theme.itemHeightExtraSmall/10 - y: canvas.height/2-(canvas.width/2*0.8 - 1.5*Theme.itemHeightExtraSmall/4 - Theme.itemHeightExtraSmall/5/2) - Theme.itemHeightExtraSmall/4 - } + RingIndicator{ + id: minutes + anchors.centerIn: parent + + width: parent.width + height: parent.height + + startAngle: 0 + stopAngle: 360/60*currentTime.getMinutes() + + lineWidth: Theme.itemHeightExtraSmall/5 + color: Theme.accentColor + + Label{ + id: minuteLabel + text: currentTime.getMinutes() + font.pixelSize: minutes.lineWidth + font.bold: true - Label{ - id: minuteLabel - text: timePicker.minutes - font.pixelSize: Theme.itemHeightExtraSmall/5 - x: canvas.width/2-minuteLabel.contentWidth-Theme.itemHeightExtraSmall/10 - y: canvas.width/2-canvas.width/2*0.8-Theme.itemHeightExtraSmall/5/2 + anchors{ + top: minutes.top + topMargin: -minutes.lineWidth/4 + right: minutes.horizontalCenter + rightMargin: minutes.lineWidth/4 + } + } + } } MouseArea{ @@ -116,74 +126,38 @@ Item{ { return; } - var minute_rad_max = canvas.width/2*0.8+Theme.itemHeightExtraSmall/10; - var minute_rad_min = canvas.width/2*0.8-Theme.itemHeightExtraSmall/10; - var hour_rad_max = canvas.width/2*0.8 - 1.5*Theme.itemHeightExtraSmall/4 - Theme.itemHeightExtraSmall/5/2 + Theme.itemHeightExtraSmall/2 - var hour_rad_min = canvas.width/2*0.8 - 1.5*Theme.itemHeightExtraSmall/4 - Theme.itemHeightExtraSmall/5/2 - Theme.itemHeightExtraSmall/2 + var minute_rad_max = clockWidget.width/2 + var minute_rad_min = clockWidget.width/2-Theme.itemHeightExtraSmall/5; + var hour_rad_max = (clockWidget.width-Theme.itemHeightExtraSmall)/2 + var hour_rad_min = (clockWidget.width-Theme.itemHeightExtraSmall)/2-Theme.itemHeightExtraSmall/2 + + var clickRad = Math.sqrt(Math.pow((mouseX-clockWidget.width/2),2)+Math.pow((mouseY-clockWidget.width/2),2)) - var clickRad = Math.sqrt(Math.pow((mouseX-canvas.width/2),2)+Math.pow((mouseY-canvas.width/2),2)) - /*If inside min circle*/ if(clickRad <= minute_rad_max && clickRad >= hour_rad_min) { var ang = getAngle(mouseX,mouseY) + var d = new Date(currentTime); if(clickRad>=minute_rad_min) { - var cur_min = Math.round(60*ang/360) - timePicker.minutes = Math.round(60*ang/360) + currentTime = new Date(d.setMinutes(Math.round(60*ang/360))) } else if(clickRad <= hour_rad_max && clickRad >= hour_rad_min) { - if(timePicker.hours >= 12) + if(currentTime.getHours() >= 12) { - timePicker.hours = Math.round(12*ang/360)+12 + currentTime = new Date(d.setHours(Math.round(12*ang/360)+12)) } else { - timePicker.hours = Math.round(12*ang/360) + currentTime = new Date(d.setHours(Math.round(12*ang/360))) } } } } } - Component.onCompleted: { - if(hours > 23 || hours < 0) - { - console.warn("[TimePicker] Uncorrect hours value") - hours = 0 - } - - if(minutes > 59 || minutes < 0) - { - console.warn("[TimePicker] Uncorrect minutes value") - minutes = 0 - } - } - - onMinutesChanged: { - canvas.requestPaint() - } - - onHoursChanged: { - if(timePicker.hours == 24) - { - timePicker.hours = 0 - } - canvas.requestPaint() - } - - function getHourAngle() - { - var hour = timePicker.hours - if(hour > 12) - { - hour = hour-12 - } - return 2*Math.PI/12*hour-0.5*Math.PI - } - function getMinuteAngle() { var minute = timePicker.minutes @@ -192,8 +166,8 @@ Item{ function getAngle(x,y) { - var a = (Math.atan((y - canvas.width/2)/(x - canvas.width/2)) * 180) / Math.PI + 90 - if (x < canvas.width/2) + var a = (Math.atan((y - clockWidget.width/2)/(x - clockWidget.width/2)) * 180) / Math.PI + 90 + if (x < clockWidget.width/2) { a += 180 } diff --git a/src/controls/qml/ToolButton.qml b/src/controls/qml/ToolButton.qml index 56da7bd..b36155e 100644 --- a/src/controls/qml/ToolButton.qml +++ b/src/controls/qml/ToolButton.qml @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2019 Chupligin Sergey +** Copyright (C) 2019-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -39,6 +39,7 @@ Button { property alias iconSource: iconImage.source property bool showCounter: false property bool showZeroCounter: false + property bool active: false property int counterValue: 0 NemoIcon { @@ -46,6 +47,7 @@ Button { anchors.fill: parent fillMode: Image.PreserveAspectFit anchors.margins: Theme.itemSpacingExtraSmall + color: active ? Theme.accentColor : Theme.textColor } Rectangle{ diff --git a/src/controls/qquicknemocontrolsextensionplugin.cpp b/src/controls/qquicknemocontrolsextensionplugin.cpp index 3344430..12e6041 100644 --- a/src/controls/qquicknemocontrolsextensionplugin.cpp +++ b/src/controls/qquicknemocontrolsextensionplugin.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2013 Tomasz Olszak * Copyright (C) 2013 Andrea Bernabei * Copyright (C) 2017 Eetu Kahelin + * Copyright (C) 2021 Chupligin Sergey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -26,9 +27,11 @@ #include "nemopage.h" #include "qquickfilteringmousearea.h" #include "nemoimageprovider.h" +#include "ringindicator.h" #include "sizing.h" #include "theme.h" #include "nemofocussingleton.h" +#include "nemoblurredimage.h" QQuickNemoControlsExtensionPlugin::QQuickNemoControlsExtensionPlugin(QObject *parent) : QQmlExtensionPlugin(parent) @@ -51,10 +54,13 @@ QObject *getNemoFocus(QQmlEngine *engine, QJSEngine *scriptEngine) void QQuickNemoControlsExtensionPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("QtQuick.Controls.Nemo")); + qmlRegisterModule(uri, 1, 0); qmlRegisterSingletonType(uri, 1, 0, "NemoFocus", getNemoFocus); qmlRegisterSingletonType(uri, 1, 0, "NemoHacks", nemo_hacks_singletontype_provider); qmlRegisterType(uri, 1, 0, "NemoWindow"); qmlRegisterType(uri, 1, 0, "NemoPage"); + qmlRegisterType(uri, 1, 0, "NemoBlurredImage"); + qmlRegisterType(uri, 1, 0, "RingIndicator"); qmlRegisterType(uri, 1, 0, "FilteringMouseArea"); } diff --git a/src/controls/ringindicator.cpp b/src/controls/ringindicator.cpp new file mode 100644 index 0000000..77f0a4c --- /dev/null +++ b/src/controls/ringindicator.cpp @@ -0,0 +1,130 @@ +/**************************************************************************************** +** +** Copyright (C) 2021 Chupligin Sergey +** All rights reserved. +** +** You may use this file under the terms of 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 author 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 HOLDERS 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. +** +****************************************************************************************/ + +#include "ringindicator.h" + +RingIndicator::RingIndicator(QQuickItem *parent) + : QQuickPaintedItem(parent) + , m_startAngle(0) + , m_stopAngle(90) + , m_lineWidth(1) + , m_rounded(false) + , m_color(Qt::white) +{ +} + +void RingIndicator::paint(QPainter *painter) +{ + QSizeF itemSize = size(); + Qt::PenCapStyle startStyle = Qt::FlatCap; + if(m_rounded) { + startStyle = Qt::RoundCap; + } + + + QPen pen(m_color, m_lineWidth, Qt::SolidLine, startStyle , Qt::BevelJoin); + QRect painedRect(0+m_lineWidth/2, + 0+m_lineWidth/2, + itemSize.width()-m_lineWidth, + itemSize.height()-m_lineWidth); + + painter->setPen(pen); + painter->setRenderHint(QPainter::Antialiasing); + + painter->drawArc(painedRect,(90-m_startAngle)*16,(m_startAngle-m_stopAngle)*16); +} + + +void RingIndicator::setStartAngle(float startAngle) +{ + startAngle = normalizeAngile(startAngle); + + if(startAngle != m_startAngle) { + m_startAngle = startAngle; + emit startAngleChanged(); + update(); + } +} + +void RingIndicator::setStopAngle(float stopAngle) +{ + stopAngle = normalizeAngile(stopAngle); + + if(stopAngle != m_stopAngle) { + m_stopAngle = stopAngle; + emit stopAngleChanged(); + update(); + } +} + +void RingIndicator::setLineWidth(float lineHeight) +{ + if(lineHeight >= 0 && lineHeight != m_lineWidth) { + m_lineWidth = lineHeight; + emit lineWidthChanged(); + update(); + } +} + +void RingIndicator::setRounded(bool round) +{ + if(round != m_rounded) { + m_rounded = round; + emit roundedChanged(); + update(); + } +} + + +void RingIndicator::setColor(QString color) +{ + QColor newColor(color); + if(newColor != m_color) { + m_color = newColor; + emit colorChanged(); + update(); + } +} + +float RingIndicator::normalizeAngile(float ang) +{ + if(ang > 360) { + int circles = (int)(ang/360); + ang = ang-360*circles; + } + + if(ang < 0) { + int circles = (int)(ang/360); + ang = ang+360*circles; + } + + return abs(ang); +} diff --git a/src/controls/ringindicator.h b/src/controls/ringindicator.h new file mode 100644 index 0000000..9921521 --- /dev/null +++ b/src/controls/ringindicator.h @@ -0,0 +1,81 @@ +/**************************************************************************************** +** +** Copyright (C) 2021 Chupligin Sergey +** All rights reserved. +** +** You may use this file under the terms of 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 author 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 HOLDERS 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. +** +****************************************************************************************/ + +#ifndef RINGINDICATOR_H +#define RINGINDICATOR_H + +#include +#include +#include + +class RingIndicator : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(float startAngle READ startAngle WRITE setStartAngle NOTIFY startAngleChanged) + Q_PROPERTY(float stopAngle READ stopAngle WRITE setStopAngle NOTIFY stopAngleChanged) + Q_PROPERTY(float lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged) + Q_PROPERTY(bool rounded READ rounded WRITE setRounded NOTIFY roundedChanged) + Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) + +public: + RingIndicator(QQuickItem *parent = nullptr); + void paint(QPainter *painter) override; + + float startAngle() {return m_startAngle;} + float stopAngle() {return m_stopAngle;} + float lineWidth() {return m_lineWidth;} + bool rounded() {return m_rounded;} + QString color() {return m_color.name();} + + void setStartAngle(float startAngle); + void setStopAngle(float stopAngle); + void setLineWidth(float height); + void setRounded(bool round); + void setColor(QString color); + +signals: + void startAngleChanged(); + void stopAngleChanged(); + void lineWidthChanged(); + void roundedChanged(); + void colorChanged(); + +private: + float m_startAngle; + float m_stopAngle; + float m_lineWidth; + bool m_rounded; + QColor m_color; + + float normalizeAngile(float ang); +}; + +#endif // RINGINDICATOR_H diff --git a/src/controls/sizing.cpp b/src/controls/sizing.cpp index 7e48ee9..12ce6c9 100644 --- a/src/controls/sizing.cpp +++ b/src/controls/sizing.cpp @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2018-2021 Chupligin Sergey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + #include "sizing.h" #include @@ -19,6 +38,7 @@ Sizing::Sizing(QObject *parent) : QObject(parent) m_p_height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt(); m_p_width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt(); + m_dpi = qgetenv("QT_WAYLAND_FORCE_DPI").toInt(); QScreen *screen = QGuiApplication::primaryScreen(); @@ -35,7 +55,11 @@ Sizing::Sizing(QObject *parent) : QObject(parent) m_height = qMax(screen->size().width(), screen->size().height()); m_width = qMin(screen->size().width(), screen->size().height()); - m_dpi = screen->physicalDotsPerInch(); + if(m_dpi == 0) { + m_dpi = screen->physicalDotsPerInch(); + } else { + qInfo() << "Use QPI from QT_WAYLAND_FORCE_DPI enveroment = " << m_dpi; + } m_scaleRatio = qMin(m_height/refHeight, m_width/refWidth); m_fontRatio = floor(m_scaleRatio*10) /10; //qMin(m_height*refDpi/(m_dpi*refHeight), m_width*refDpi/(m_dpi*refWidth))*10)/10; diff --git a/src/controls/sizing.h b/src/controls/sizing.h index 7bbdfaa..1ee8566 100644 --- a/src/controls/sizing.h +++ b/src/controls/sizing.h @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2018-2021 Chupligin Sergey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + #ifndef SIZING_H #define SIZING_H diff --git a/src/controls/theme.cpp b/src/controls/theme.cpp index ee3b2dc..b23201d 100644 --- a/src/controls/theme.cpp +++ b/src/controls/theme.cpp @@ -1,3 +1,23 @@ +/* + * Copyright (C) 2018-2021 Chupligin Sergey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + #include "theme.h" #include #include @@ -12,57 +32,46 @@ Theme::Theme(QObject *parent) : QObject(parent) m_iconSizeLauncher = size->getLauncherIconSize(); m_scaleRatio = size->getScaleRatio(); m_fontRatio = size->getFontRatio(); - //Load defaults - m_itemWidthLarge = floor(320*m_scaleRatio); - m_itemWidthMedium = floor(240*m_scaleRatio); - m_itemWidthSmall = floor(120*m_scaleRatio); - m_itemWidthExtraSmall = floor(72*m_scaleRatio); - m_itemHeightHuge = floor(80*m_scaleRatio); - m_itemHeightExtraLarge = floor(75*m_scaleRatio); - m_itemHeightLarge = floor(63*m_scaleRatio); - m_itemHeightMedium = floor(50*m_scaleRatio); - m_itemHeightSmall = floor(40*m_scaleRatio); - m_itemHeightExtraSmall = floor(32*m_scaleRatio); + loadDefaultValue(); - m_itemSpacingHuge = floor(40*m_scaleRatio); - m_itemSpacingLarge = floor(20*m_scaleRatio); - m_itemSpacingMedium = floor(15*m_scaleRatio); - m_itemSpacingSmall = floor(10*m_scaleRatio); - m_itemSpacingExtraSmall = floor(8*m_scaleRatio); + MGConfItem *desktopModeValue = new MGConfItem(QStringLiteral("/nemo/apps/libglacier/desktopmode")); + m_themeValue = new MGConfItem(QStringLiteral("/nemo/apps/libglacier/themePath")); + m_desktopMode = desktopModeValue->value().toBool(); + m_theme = m_themeValue->value().toString(); - m_fontSizeExtraLarge = floor(44*m_fontRatio); - m_fontSizeLarge = floor(35*m_fontRatio); - m_fontSizeMedium = floor(28*m_fontRatio); - m_fontSizeSmall = floor(24*m_fontRatio); - m_fontSizeTiny = floor(16*m_fontRatio); - m_fontWeightLarge = 63*m_dp; - m_fontWeightMedium = 25*m_dp; - m_fontFamily = "/usr/share/fonts/google-opensans/OpenSans-Regular.ttf"; + connect(desktopModeValue, &MGConfItem::valueChanged, this, &Theme::desktopModeValueChanged); + connect(m_themeValue, &MGConfItem::valueChanged, this, &Theme::themeValueChanged); - m_accentColor = "#0091e5"; - m_fillColor = "#474747"; - m_fillDarkColor = "#313131"; - m_textColor = "#ffffff"; - m_backgroundColor = "#000000"; - m_backgroundAccentColor = "#ffffff"; + loadTheme(m_theme); } bool Theme::loadTheme(QString fileName) { - QString themeJsonString; - - bool updated = false; + QFile themeFile(fileName); - QFile themeFile; - themeFile.setFileName(fileName); - if(!themeFile.exists()) - { + if(!themeFile.exists()) { qDebug() << "Theme file " << fileName << " not found"; return false; } + if(fileName != m_theme) { + m_themeValue->set(fileName); + } else { + setThemeValues(); + } + return true; +} + +void Theme::setThemeValues() +{ + QString themeJsonString; + + bool updated = false; + + QFile themeFile(m_theme); + themeFile.open(QIODevice::ReadOnly | QIODevice::Text); themeJsonString = themeFile.readAll(); themeFile.close(); @@ -244,7 +253,7 @@ bool Theme::loadTheme(QString fileName) fontFile.setFileName(theme.value("fontFamily").toString()); if(!themeFile.exists()) { - qDebug() << "Font file " << fileName << " not found"; + qDebug() << "Font file " << fontFile.fileName() << " not found"; } else { @@ -300,7 +309,57 @@ bool Theme::loadTheme(QString fileName) if(updated) { emit themeUpdate(); - return true; } - return false; +} + +void Theme::desktopModeValueChanged() +{ + m_desktopMode = MGConfItem(QStringLiteral("/nemo/apps/libglacier/desktopmode")).value().toBool(); + emit desktopModeChanged(); + +} + +void Theme::themeValueChanged() +{ + m_theme = m_themeValue->value().toString(); + setThemeValues(); +} + +void Theme::loadDefaultValue() +{ + //Load defaults + m_itemWidthLarge = floor(320*m_scaleRatio); + m_itemWidthMedium = floor(240*m_scaleRatio); + m_itemWidthSmall = floor(120*m_scaleRatio); + m_itemWidthExtraSmall = floor(72*m_scaleRatio); + + m_itemHeightHuge = floor(80*m_scaleRatio); + m_itemHeightExtraLarge = floor(75*m_scaleRatio); + m_itemHeightLarge = floor(63*m_scaleRatio); + m_itemHeightMedium = floor(50*m_scaleRatio); + m_itemHeightSmall = floor(40*m_scaleRatio); + m_itemHeightExtraSmall = floor(32*m_scaleRatio); + + m_itemSpacingHuge = floor(40*m_scaleRatio); + m_itemSpacingLarge = floor(20*m_scaleRatio); + m_itemSpacingMedium = floor(15*m_scaleRatio); + m_itemSpacingSmall = floor(10*m_scaleRatio); + m_itemSpacingExtraSmall = floor(8*m_scaleRatio); + + + m_fontSizeExtraLarge = floor(44*m_fontRatio); + m_fontSizeLarge = floor(35*m_fontRatio); + m_fontSizeMedium = floor(28*m_fontRatio); + m_fontSizeSmall = floor(24*m_fontRatio); + m_fontSizeTiny = floor(16*m_fontRatio); + m_fontWeightLarge = 63*m_dp; + m_fontWeightMedium = 25*m_dp; + m_fontFamily = "/usr/share/fonts/google-opensans/OpenSans-Regular.ttf"; + + m_accentColor = "#0091e5"; + m_fillColor = "#474747"; + m_fillDarkColor = "#313131"; + m_textColor = "#ffffff"; + m_backgroundColor = "#000000"; + m_backgroundAccentColor = "#ffffff"; } diff --git a/src/controls/theme.h b/src/controls/theme.h index dc37820..5585327 100644 --- a/src/controls/theme.h +++ b/src/controls/theme.h @@ -1,7 +1,8 @@ -#ifndef THEME_He5 +#ifndef THEME_H #define THEME_H #include +#include #include "sizing.h" class Theme : public QObject @@ -45,6 +46,9 @@ class Theme : public QObject Q_PROPERTY(QString backgroundColor READ backgroundColor NOTIFY backgroundColorChanged) Q_PROPERTY(QString backgroundAccentColor READ backgroundAccentColor NOTIFY backgroundAccentColorChanged) + Q_PROPERTY(bool desktopMode READ desktopMode NOTIFY desktopModeChanged) + Q_PROPERTY(QString themePath READ themePath NOTIFY themeUpdate) + public: explicit Theme(QObject *parent = 0); @@ -86,6 +90,9 @@ class Theme : public QObject qreal iconSizeLauncher() {return m_iconSizeLauncher;} + bool desktopMode() {return m_desktopMode;} + QString themePath() {return m_theme;} + Sizing *size; signals: @@ -127,7 +134,11 @@ class Theme : public QObject void iconSizeLauncherChanged(); -public slots: + void desktopModeChanged(); + +private slots: + void desktopModeValueChanged(); + void themeValueChanged(); private: qreal m_iconSizeLauncher; //86 or 108 or 128 or 256 @@ -169,6 +180,14 @@ public slots: qreal m_dp; qreal m_scaleRatio; qreal m_fontRatio; + + bool m_desktopMode; + QString m_theme; + + void loadDefaultValue(); + void setThemeValues(); + + MGConfItem *m_themeValue; }; #endif // THEME_H diff --git a/src/controls/themedaemon/mlocalthemedaemonclient.cpp b/src/controls/themedaemon/mlocalthemedaemonclient.cpp index 3684bc5..89eaf1d 100644 --- a/src/controls/themedaemon/mlocalthemedaemonclient.cpp +++ b/src/controls/themedaemon/mlocalthemedaemonclient.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include MLocalThemeDaemonClient::MLocalThemeDaemonClient(const QString &testPath, QObject *parent) : @@ -56,24 +57,21 @@ MLocalThemeDaemonClient::MLocalThemeDaemonClient(const QString &testPath, QObjec QString themeRoot = testPath; bool testMode = false; - if (themeRoot.isEmpty()) + if (themeRoot.isEmpty()) { themeRoot = qgetenv("M_THEME_DIR"); - else + } else { testMode = true; + } if (themeRoot.isEmpty()) { #if defined(THEME_DIR) - themeRoot = THEME_DIR; + themeRoot = THEME_DIR; #else -# ifdef Q_OS_WIN - themeRoot = "c:\\"; -# else - themeRoot = "/usr/share/themes"; -# endif + themeRoot = "/usr/share/themes"; #endif } - if (testMode == false) { + if (!testMode) { QString themeName; # if !defined(THEME_NAME) # define THEME_NAME "glacier" @@ -148,6 +146,7 @@ MLocalThemeDaemonClient::~MLocalThemeDaemonClient() QPixmap MLocalThemeDaemonClient::requestPixmap(const QString &id, const QSize &requestedSize) { + qDebug() << Q_FUNC_INFO; QPixmap pixmap; QStringList parts = id.split('?'); @@ -205,10 +204,21 @@ QImage MLocalThemeDaemonClient::readImage(const QString &id) const } } } - qDebug() << "Unknown theme image:" << id; - } - + QDir hicolorIconsDir("/usr/share/icons/hicolor/scalable/"); + if(hicolorIconsDir.exists()) { + qDebug() << "trying load into hicolor scalable dir"; + QDirIterator it("/usr/share/icons/hicolor/scalable/", QStringList() << "*.svg", QDir::Files, QDirIterator::Subdirectories); + + while (it.hasNext()) { + QString file = it.next(); + if(file.contains(id+".svg")) { + QImage image(file); + return image; + } + } + } + } return QImage(); } diff --git a/src/models/calendarmodel.cpp b/src/models/calendarmodel.cpp index 7a97174..4ef14e1 100644 --- a/src/models/calendarmodel.cpp +++ b/src/models/calendarmodel.cpp @@ -42,9 +42,7 @@ CalendarModel::CalendarModel(QObject *parent) : m_hash.insert(Qt::UserRole+4 ,QByteArray("dateOfDay")); m_currentDate = QDate::currentDate(); - - m_year = m_currentDate.year(); - m_month = m_currentDate.month(); + m_selectedDate = m_currentDate; fill(); } @@ -111,26 +109,8 @@ void CalendarModel::setSelectedDate(QDate date) { m_selectedDate = date; emit selectedDateChanged(); - } -} -void CalendarModel::setMonth(int month) -{ - if(m_month != month && month > 0 && month < 13) - { - m_month = month; - fill(); - emit monthChanged(); - } -} - -void CalendarModel::setYear(int year) -{ - if(m_year != year) - { - m_year = year; fill(); - emit yearChanged(); } } @@ -138,7 +118,7 @@ void CalendarModel::fill() { m_dateList.clear(); - QDate firstDayOfSelectedMonth = QDate(m_year,m_month,1); + QDate firstDayOfSelectedMonth = QDate(m_selectedDate.year(),m_selectedDate.month(),1); int startWeekDay = firstDayOfSelectedMonth.dayOfWeek(); /*If first dayof moth not Monday add form preview month*/ @@ -157,7 +137,7 @@ void CalendarModel::fill() m_dateList.append(createDateItem(date,false,date == m_currentDate)); } /*if last day of moth not Sunday add from next mont*/ - QDate lastDayOfSelectedMonth = QDate(m_year,m_month,firstDayOfSelectedMonth.daysInMonth()); + QDate lastDayOfSelectedMonth = QDate(m_selectedDate.year(),m_selectedDate.month(),firstDayOfSelectedMonth.daysInMonth()); int endWeekDay = lastDayOfSelectedMonth.dayOfWeek(); if(endWeekDay != 7) { diff --git a/src/models/calendarmodel.h b/src/models/calendarmodel.h index dacaf6d..0e50bfb 100644 --- a/src/models/calendarmodel.h +++ b/src/models/calendarmodel.h @@ -1,6 +1,6 @@ /**************************************************************************************** ** -** Copyright (C) 2017 Chupligin Sergey +** Copyright (C) 2017-2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -47,8 +47,6 @@ class CalendarModel : public QAbstractListModel }; Q_PROPERTY(QDate currentDate READ currentDate) - Q_PROPERTY(int month READ month WRITE setMonth NOTIFY monthChanged) - Q_PROPERTY(int year READ year WRITE setYear NOTIFY yearChanged) Q_PROPERTY(QDate selectedDate READ selectedDate WRITE setSelectedDate NOTIFY selectedDateChanged) public: @@ -58,21 +56,15 @@ class CalendarModel : public QAbstractListModel QHash roleNames() const {return m_hash;} void setSelectedDate(QDate date); - void setMonth(int month); - void setYear(int year); const QDate currentDate(){return m_currentDate;} QDate selectedDate(){return m_selectedDate;} - int month(){return m_month;} - int year(){return m_year;} public slots: QVariant get(const int idx) const; signals: void selectedDateChanged(); - void monthChanged(); - void yearChanged(); private: QHash m_hash; @@ -87,9 +79,6 @@ public slots: QDate m_currentDate; QDate m_selectedDate; - - int m_month; - int m_year; }; #endif // DATELISTMODEL_H diff --git a/src/styles/SliderStyle.qml b/src/styles/SliderStyle.qml new file mode 100644 index 0000000..aad37ab --- /dev/null +++ b/src/styles/SliderStyle.qml @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2013 Andrea Bernabei + * Copyright (C) 2017 Chupligin Sergey + * Copyright (C) 2017 Eetu Kahelin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.6 +import QtQuick.Controls.Styles 1.0 +import QtQuick.Controls.Nemo 1.0 + +SliderStyle{ + handle: Rectangle { + id: handle + anchors.centerIn: parent + color: Theme.backgroundColor + border.color: Theme.accentColor + border.width: 2 + implicitWidth: Theme.itemHeightExtraSmall + implicitHeight: Theme.itemHeightExtraSmall + radius: implicitHeight / 2 + visible: control.enabled + + Text{ + id: valueLabel + anchors.centerIn: parent + text: parseInt(control.value) + visible: control.showValue + color: Theme.textColor + font.pixelSize: control.valueFontSize + } + } + + groove: Rectangle{ + id: grove + + implicitHeight: Theme.itemHeightExtraSmall / 2 + implicitWidth: Theme.itemWidthLarge + Theme.itemWidthSmall + color: Theme.fillDarkColor + z: 1 + Rectangle{ + id: dataLine + height: parent.height + width: styleData.handlePosition + color: Theme.accentColor + } + + Image { + id: disabledImg + anchors.fill: parent + visible: !control.enabled + source: "images/disabled-overlay.png" + fillMode: Image.Tile + } + + Image{ + id: left + anchors{ + right: dataLine.right + verticalCenter: dataLine.verticalCenter + } + source: "images/slider-handle-left.svg" + height:Theme.itemHeightExtraSmall + visible: control.enabled + width: (styleData.handlePosition > Theme.itemHeightHuge) ? Theme.itemHeightHuge : styleData.handlePosition + sourceSize.width: width + sourceSize.height: height + } + } +} diff --git a/src/styles/images/virtualkeyboard/backspace-868482.svg b/src/styles/images/virtualkeyboard/backspace-868482.svg new file mode 100644 index 0000000..fb607be --- /dev/null +++ b/src/styles/images/virtualkeyboard/backspace-868482.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/check-868482.svg b/src/styles/images/virtualkeyboard/check-868482.svg new file mode 100644 index 0000000..c8af5f3 --- /dev/null +++ b/src/styles/images/virtualkeyboard/check-868482.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/src/styles/images/virtualkeyboard/enter-868482.svg b/src/styles/images/virtualkeyboard/enter-868482.svg new file mode 100644 index 0000000..75080f6 --- /dev/null +++ b/src/styles/images/virtualkeyboard/enter-868482.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/globe-868482.svg b/src/styles/images/virtualkeyboard/globe-868482.svg new file mode 100644 index 0000000..2d26586 --- /dev/null +++ b/src/styles/images/virtualkeyboard/globe-868482.svg @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/handwriting-868482.svg b/src/styles/images/virtualkeyboard/handwriting-868482.svg new file mode 100644 index 0000000..d7af73c --- /dev/null +++ b/src/styles/images/virtualkeyboard/handwriting-868482.svg @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/hidekeyboard-868482.svg b/src/styles/images/virtualkeyboard/hidekeyboard-868482.svg new file mode 100644 index 0000000..d6996b1 --- /dev/null +++ b/src/styles/images/virtualkeyboard/hidekeyboard-868482.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/icon-backspace.svg b/src/styles/images/virtualkeyboard/icon-backspace.svg new file mode 100644 index 0000000..fa395f8 --- /dev/null +++ b/src/styles/images/virtualkeyboard/icon-backspace.svg @@ -0,0 +1,65 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/src/styles/images/virtualkeyboard/icon-enter.svg b/src/styles/images/virtualkeyboard/icon-enter.svg new file mode 100644 index 0000000..b0c25d3 --- /dev/null +++ b/src/styles/images/virtualkeyboard/icon-enter.svg @@ -0,0 +1,63 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/src/styles/images/virtualkeyboard/icon-m-input-methods-backspace.png b/src/styles/images/virtualkeyboard/icon-m-input-methods-backspace.png new file mode 100644 index 0000000..7a6c4f3 Binary files /dev/null and b/src/styles/images/virtualkeyboard/icon-m-input-methods-backspace.png differ diff --git a/src/styles/images/virtualkeyboard/icon-m-input-methods-capslock.png b/src/styles/images/virtualkeyboard/icon-m-input-methods-capslock.png new file mode 100644 index 0000000..e67d3f4 Binary files /dev/null and b/src/styles/images/virtualkeyboard/icon-m-input-methods-capslock.png differ diff --git a/src/styles/images/virtualkeyboard/icon-m-input-methods-enter.png b/src/styles/images/virtualkeyboard/icon-m-input-methods-enter.png new file mode 100644 index 0000000..828a881 Binary files /dev/null and b/src/styles/images/virtualkeyboard/icon-m-input-methods-enter.png differ diff --git a/src/styles/images/virtualkeyboard/icon-m-input-methods-enter.svg b/src/styles/images/virtualkeyboard/icon-m-input-methods-enter.svg new file mode 100644 index 0000000..b0c25d3 --- /dev/null +++ b/src/styles/images/virtualkeyboard/icon-m-input-methods-enter.svg @@ -0,0 +1,63 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-lowercase.png b/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-lowercase.png new file mode 100644 index 0000000..a44dc4e Binary files /dev/null and b/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-lowercase.png differ diff --git a/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-uppercase.png b/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-uppercase.png new file mode 100644 index 0000000..71675e1 Binary files /dev/null and b/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-uppercase.png differ diff --git a/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-uppercase.svg b/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-uppercase.svg new file mode 100644 index 0000000..218f146 --- /dev/null +++ b/src/styles/images/virtualkeyboard/icon-m-input-methods-shift-uppercase.svg @@ -0,0 +1,62 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/src/styles/images/virtualkeyboard/icon-shift-locked.svg b/src/styles/images/virtualkeyboard/icon-shift-locked.svg new file mode 100644 index 0000000..af7c2e7 --- /dev/null +++ b/src/styles/images/virtualkeyboard/icon-shift-locked.svg @@ -0,0 +1,66 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/src/styles/images/virtualkeyboard/icon-shift-pressed.svg b/src/styles/images/virtualkeyboard/icon-shift-pressed.svg new file mode 100644 index 0000000..218f146 --- /dev/null +++ b/src/styles/images/virtualkeyboard/icon-shift-pressed.svg @@ -0,0 +1,62 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/src/styles/images/virtualkeyboard/icon-shift.svg b/src/styles/images/virtualkeyboard/icon-shift.svg new file mode 100644 index 0000000..86b1385 --- /dev/null +++ b/src/styles/images/virtualkeyboard/icon-shift.svg @@ -0,0 +1,60 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/src/styles/images/virtualkeyboard/key.svg b/src/styles/images/virtualkeyboard/key.svg new file mode 100755 index 0000000..bdc0ff5 --- /dev/null +++ b/src/styles/images/virtualkeyboard/key.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-104x60.png b/src/styles/images/virtualkeyboard/keyboard-key-104x60.png new file mode 100755 index 0000000..2873be4 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-104x60.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-104x60.svg b/src/styles/images/virtualkeyboard/keyboard-key-104x60.svg new file mode 100755 index 0000000..c73a869 --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-104x60.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-120x46.png b/src/styles/images/virtualkeyboard/keyboard-key-120x46.png new file mode 100755 index 0000000..c03e8bb Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-120x46.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-120x46.svg b/src/styles/images/virtualkeyboard/keyboard-key-120x46.svg new file mode 100755 index 0000000..6d3a16b --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-120x46.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-136x60.png b/src/styles/images/virtualkeyboard/keyboard-key-136x60.png new file mode 100755 index 0000000..e6b4233 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-136x60.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-136x60.svg b/src/styles/images/virtualkeyboard/keyboard-key-136x60.svg new file mode 100755 index 0000000..98614b1 --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-136x60.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-228x46.png b/src/styles/images/virtualkeyboard/keyboard-key-228x46.png new file mode 100755 index 0000000..a34325d Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-228x46.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-228x46.svg b/src/styles/images/virtualkeyboard/keyboard-key-228x46.svg new file mode 100755 index 0000000..8efb339 --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-228x46.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-38x60.png b/src/styles/images/virtualkeyboard/keyboard-key-38x60.png new file mode 100755 index 0000000..b99123d Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-38x60.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-38x60.svg b/src/styles/images/virtualkeyboard/keyboard-key-38x60.svg new file mode 100755 index 0000000..2bb495c --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-38x60.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-40x60.png b/src/styles/images/virtualkeyboard/keyboard-key-40x60.png new file mode 100755 index 0000000..31d71c8 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-40x60.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-40x60.svg b/src/styles/images/virtualkeyboard/keyboard-key-40x60.svg new file mode 100755 index 0000000..f49482d --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-40x60.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-43x60.png b/src/styles/images/virtualkeyboard/keyboard-key-43x60.png new file mode 100755 index 0000000..a8a25b7 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-43x60.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-43x60.svg b/src/styles/images/virtualkeyboard/keyboard-key-43x60.svg new file mode 100755 index 0000000..091b05e --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-43x60.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-56x60.png b/src/styles/images/virtualkeyboard/keyboard-key-56x60.png new file mode 100755 index 0000000..b082d5c Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-56x60.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-56x60.svg b/src/styles/images/virtualkeyboard/keyboard-key-56x60.svg new file mode 100755 index 0000000..9cc2063 --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-56x60.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-72x46.png b/src/styles/images/virtualkeyboard/keyboard-key-72x46.png new file mode 100755 index 0000000..2c9346b Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-72x46.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-72x46.svg b/src/styles/images/virtualkeyboard/keyboard-key-72x46.svg new file mode 100755 index 0000000..5d4b5ca --- /dev/null +++ b/src/styles/images/virtualkeyboard/keyboard-key-72x46.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/keyboard-key-portrait-function-pressed.png b/src/styles/images/virtualkeyboard/keyboard-key-portrait-function-pressed.png new file mode 100644 index 0000000..943eca1 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-portrait-function-pressed.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-portrait-function.png b/src/styles/images/virtualkeyboard/keyboard-key-portrait-function.png new file mode 100644 index 0000000..c7b8081 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-portrait-function.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-portrait-pressed.png b/src/styles/images/virtualkeyboard/keyboard-key-portrait-pressed.png new file mode 100644 index 0000000..4f6ead8 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-portrait-pressed.png differ diff --git a/src/styles/images/virtualkeyboard/keyboard-key-portrait.png b/src/styles/images/virtualkeyboard/keyboard-key-portrait.png new file mode 100644 index 0000000..dca0a77 Binary files /dev/null and b/src/styles/images/virtualkeyboard/keyboard-key-portrait.png differ diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left-landscape.png b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left-landscape.png new file mode 100755 index 0000000..9a35b8f Binary files /dev/null and b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left-landscape.png differ diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left-landscape.svg b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left-landscape.svg new file mode 100755 index 0000000..b75e2ec --- /dev/null +++ b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left-landscape.svg @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left.png b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left.png new file mode 100755 index 0000000..a35c386 Binary files /dev/null and b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left.png differ diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left.svg b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left.svg new file mode 100755 index 0000000..18b9fa6 --- /dev/null +++ b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-left.svg @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid-landscape.png b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid-landscape.png new file mode 100755 index 0000000..b497ced Binary files /dev/null and b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid-landscape.png differ diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid-landscape.svg b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid-landscape.svg new file mode 100755 index 0000000..fda3654 --- /dev/null +++ b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid-landscape.svg @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid.png b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid.png new file mode 100755 index 0000000..a35c386 Binary files /dev/null and b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid.png differ diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid.svg b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid.svg new file mode 100755 index 0000000..7562e02 --- /dev/null +++ b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-mid.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right-landscape.png b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right-landscape.png new file mode 100755 index 0000000..a3b1027 Binary files /dev/null and b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right-landscape.png differ diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right-landscape.svg b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right-landscape.svg new file mode 100755 index 0000000..8c69931 --- /dev/null +++ b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right-landscape.svg @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right.png b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right.png new file mode 100755 index 0000000..a35c386 Binary files /dev/null and b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right.png differ diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right.svg b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right.svg new file mode 100755 index 0000000..62cd1cc --- /dev/null +++ b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key-right.svg @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key.png b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key.png new file mode 100755 index 0000000..a35c386 Binary files /dev/null and b/src/styles/images/virtualkeyboard/meegotouch-keyboard-function-key.png differ diff --git a/src/styles/images/virtualkeyboard/popper.png b/src/styles/images/virtualkeyboard/popper.png new file mode 100755 index 0000000..05adeff Binary files /dev/null and b/src/styles/images/virtualkeyboard/popper.png differ diff --git a/src/styles/images/virtualkeyboard/search-868482.svg b/src/styles/images/virtualkeyboard/search-868482.svg new file mode 100644 index 0000000..6ee0ba9 --- /dev/null +++ b/src/styles/images/virtualkeyboard/search-868482.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/selectionhandle-bottom.svg b/src/styles/images/virtualkeyboard/selectionhandle-bottom.svg new file mode 100644 index 0000000..312e3ab --- /dev/null +++ b/src/styles/images/virtualkeyboard/selectionhandle-bottom.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/shift-80c342.svg b/src/styles/images/virtualkeyboard/shift-80c342.svg new file mode 100644 index 0000000..07eb508 --- /dev/null +++ b/src/styles/images/virtualkeyboard/shift-80c342.svg @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/shift-868482.svg b/src/styles/images/virtualkeyboard/shift-868482.svg new file mode 100644 index 0000000..f0ce693 --- /dev/null +++ b/src/styles/images/virtualkeyboard/shift-868482.svg @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/shift-c5d6b6.svg b/src/styles/images/virtualkeyboard/shift-c5d6b6.svg new file mode 100644 index 0000000..6cfc345 --- /dev/null +++ b/src/styles/images/virtualkeyboard/shift-c5d6b6.svg @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/textmode-868482.svg b/src/styles/images/virtualkeyboard/textmode-868482.svg new file mode 100644 index 0000000..2f9428c --- /dev/null +++ b/src/styles/images/virtualkeyboard/textmode-868482.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + diff --git a/src/styles/images/virtualkeyboard/vkb-body.png b/src/styles/images/virtualkeyboard/vkb-body.png new file mode 100644 index 0000000..59c0828 Binary files /dev/null and b/src/styles/images/virtualkeyboard/vkb-body.png differ diff --git a/src/styles/qml/CheckBoxStyle.qml b/src/styles/qml/CheckBoxStyle.qml index a2389d7..d919937 100644 --- a/src/styles/qml/CheckBoxStyle.qml +++ b/src/styles/qml/CheckBoxStyle.qml @@ -1,6 +1,7 @@ /**************************************************************************************** ** ** Copyright (C) 2013 Aleksi Suomalainen +** Copyright (C) 2021 Chupligin Sergey ** All rights reserved. ** ** You may use this file under the terms of BSD license as follows: @@ -75,7 +76,7 @@ CheckBoxStyle { Connections { target: control - onCheckedChanged: { + function onCheckedChanged() { if(!indeterminate) { if (control.checked) { checkAnimation.restart() @@ -85,7 +86,7 @@ CheckBoxStyle { } } - onIndeterminateChanged: { + function onIndeterminateChanged() { indeterminateAnimation.stop() if(indeterminate) { indeterminateAnimation.start() diff --git a/src/styles/qml/SliderStyle.qml b/src/styles/qml/SliderStyle.qml index a12e386..1cd9334 100644 --- a/src/styles/qml/SliderStyle.qml +++ b/src/styles/qml/SliderStyle.qml @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Andrea Bernabei - * Copyright (C) 2017 Chupligin Sergey + * Copyright (C) 2017-2021 Chupligin Sergey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,8 +31,8 @@ SliderStyle{ handle: Rectangle { id: handle anchors.verticalCenter:useSpecSlider ? undefined : parent.verticalCenter - y: useSpecSlider ? (control.pressed ? alwaysUp ? parent.y - Theme.itemHeightLarge : ((handleValue > 0.8) ? parent.y - (Theme.itemHeightLarge*_multiple2) : parent.y ) : parent.y) : undefined - x: useSpecSlider ? (control.pressed ? alwaysUp ? Theme.itemHeightExtraSmall / 2 : (handleValue > 0.8) ? (_multiple*Theme.itemHeightHuge) : Theme.itemHeightHuge : 0) : undefined + y: useSpecSlider ? (control.pressed ? alwaysUp ? parent.y - Theme.itemHeightLarge : ((handleValue > 0.8) ? parent.y - (Theme.itemHeightLarge*_multiple2) : parent.y ) : parent.y) : 0 + x: useSpecSlider ? (control.pressed ? alwaysUp ? Theme.itemHeightExtraSmall / 2 : (handleValue > 0.8) ? (_multiple*Theme.itemHeightHuge) : Theme.itemHeightHuge : 0) : 0 color: Theme.backgroundColor border.color: Theme.textColor border.width: size.ratio(2) diff --git a/src/styles/qml/ToolButtonStyle.qml b/src/styles/qml/ToolButtonStyle.qml index 538d498..631f7d8 100644 --- a/src/styles/qml/ToolButtonStyle.qml +++ b/src/styles/qml/ToolButtonStyle.qml @@ -26,7 +26,7 @@ import QtQuick.Controls.Private 1.0 // ToolButtonStyle is private in QQC 5.1.0 Style { - readonly property ToolButton control: __control + readonly property Button control: __control property Component panel: Item { id: styleitem diff --git a/src/styles/qquicknemostyleextensionplugin.cpp b/src/styles/qquicknemostyleextensionplugin.cpp index 668576b..b79c2f8 100644 --- a/src/styles/qquicknemostyleextensionplugin.cpp +++ b/src/styles/qquicknemostyleextensionplugin.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2013 Tomasz Olszak * Copyright (C) 2013 Andrea Bernabei + * Copyright (C) 2021 Chupligin Sergey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,6 +30,7 @@ QQuickNemoStyleExtensionPlugin::QQuickNemoStyleExtensionPlugin(QObject *parent) void QQuickNemoStyleExtensionPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("QtQuick.Controls.Styles.Nemo")); + qmlRegisterModule(uri, 1, 0); } void QQuickNemoStyleExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri) diff --git a/src/styles/styles.pro b/src/styles/styles.pro index 8c1825e..d3dd365 100644 --- a/src/styles/styles.pro +++ b/src/styles/styles.pro @@ -18,6 +18,9 @@ QML_FILES += \ images/slider-trumpet-up.png \ images/slider-trumpet.png +keyboard.files = virtualkeyboard/style.qml +keyboard.path = $$[QT_INSTALL_QML]/QtQuick/VirtualKeyboard/Styles/Nemo + target.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH qmlfiles.files = qml/ButtonStyle.qml \ @@ -45,15 +48,21 @@ qmlfiles.files = qml/ButtonStyle.qml \ qmlfiles.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH themes.files = $$_PRO_FILE_PWD_/themes/glacier_black.json \ - $$_PRO_FILE_PWD_/themes/glacier_white.json + $$_PRO_FILE_PWD_/themes/glacier_white.json \ + $$_PRO_FILE_PWD_/themes/glacier_orange.json themes.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/themes -images.files = $$_PRO_FILE_PWD_/images/*.svg\ - $$_PRO_FILE_PWD_/images/*.png +images.files = $$files($$_PRO_FILE_PWD_/images/*.svg,false)\ + $$files($$_PRO_FILE_PWD_/images/*.png,false) images.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/images/ +kbdimages.files = $$files($$_PRO_FILE_PWD_/images/virtualkeyboard/*.svg,false)\ + $$files($$_PRO_FILE_PWD_/images/virtualkeyboard/*.png,false) + +kbdimages.path = $$[QT_INSTALL_QML]/QtQuick/VirtualKeyboard/Styles/Nemo/images + HEADERS += \ qquicknemostyleextensionplugin.h @@ -63,6 +72,8 @@ SOURCES += \ INSTALLS += target \ images \ qmlfiles \ - themes + themes \ + keyboard \ + kbdimages DEFINES += 'THEME_DIR=\'\"$$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/themes"\'' diff --git a/src/styles/virtualkeyboard/style.qml b/src/styles/virtualkeyboard/style.qml new file mode 100644 index 0000000..8411ab0 --- /dev/null +++ b/src/styles/virtualkeyboard/style.qml @@ -0,0 +1,975 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls.Nemo 1.0 +import QtQuick.VirtualKeyboard 2.1 +import QtQuick.VirtualKeyboard.Styles 2.1 + +KeyboardStyle { + id: currentStyle + readonly property bool compactSelectionList: [InputEngine.Pinyin, InputEngine.Cangjie, InputEngine.Zhuyin].indexOf(InputContext.inputEngine.inputMode) !== -1 + readonly property string fontFamily: "sans" + readonly property real keyBackgroundMargin: Theme.itemSpacingExtraSmall/2 + readonly property real keyContentMargin: Math.round(45 * scaleHint) + readonly property real keyIconScale: scaleHint * 0.6 + readonly property string resourcePrefix: "" + + readonly property real horizontalBorder: size.ratio(1) + readonly property real topBorder: Theme.itemSpacingExtraSmall/2 + + readonly property string inputLocale: InputContext.locale + property color inputLocaleIndicatorColor: Theme.backgroundColor + property Timer inputLocaleIndicatorHighlightTimer: Timer { + interval: 1000 + onTriggered: inputLocaleIndicatorColor = Theme.fillColor + } + onInputLocaleChanged: { + inputLocaleIndicatorColor = Theme.backgroundAccentColor + inputLocaleIndicatorHighlightTimer.restart() + } + + keyboardDesignWidth: size.ratio(854)//N9 + keyboardDesignHeight: size.ratio(480) + keyboardRelativeLeftMargin: Theme.itemSpacingMedium / keyboardDesignWidth + keyboardRelativeRightMargin: Theme.itemSpacingMedium / keyboardDesignWidth + keyboardRelativeTopMargin: Theme.itemSpacingSmall / keyboardDesignWidth + keyboardRelativeBottomMargin:Theme.itemSpacingExtraSmall/ keyboardDesignWidth + + keyboardBackground: Rectangle { + color: Theme.fillColor + } + + keyPanel: KeyPanel { + BorderImage { + id: bgImage + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + + Text { + id: keySmallText + text: control.smallText + visible: control.smallTextVisible + color: Theme.textColor + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: keyContentMargin / 3 + font { + family: fontFamily + pixelSize: Theme.fontSizeTiny + capitalization: control.uppercased ? Font.AllUppercase : Font.MixedCase + } + } + Text { + id: keyText + text: control.displayText + color: Theme.textColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.fill: parent + anchors.leftMargin: keyContentMargin + anchors.topMargin: control.smallTextVisible ? keyContentMargin * 1.2 : keyContentMargin + anchors.rightMargin: keyContentMargin + anchors.bottomMargin: control.smallTextVisible ? keyContentMargin * 0.8 : keyContentMargin + font { + family: fontFamily + pixelSize: Theme.fontSizeMedium + capitalization: control.uppercased ? Font.AllUppercase : Font.MixedCase + } + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: bgImage + source:"images/keyboard-key-portrait-pressed.png" + } + PropertyChanges { + target: keyText + opacity: 0.5 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + target: bgImage + opacity: 0.75 + } + PropertyChanges { + target: keyText + opacity: 0.05 + } + } + ] + } + + backspaceKeyPanel: KeyPanel { + id:panel + BorderImage { + id: backspaceBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Image { + id: backspaceKeyIcon + fillMode: Image.PreserveAspectFit + anchors.centerIn: parent + sourceSize.width: width + sourceSize.height: height + width: Theme.fontSizeMedium //?? + smooth: true + source: "images/icon-backspace.svg" + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: backspaceBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + + } + PropertyChanges { + target: backspaceKeyIcon + opacity: 0.6 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + target: backspaceKeyIcon + opacity: 0.2 + } + } + ] + } + + languageKeyPanel: KeyPanel { + BorderImage { + id: languageBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Image { + id: languageKeyIcon + anchors.centerIn: parent + sourceSize.width: 144 * keyIconScale + sourceSize.height: 144 * keyIconScale + smooth: true + source: resourcePrefix + "images/globe-868482.svg" + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: languageBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + } + PropertyChanges { + target: languageKeyIcon + opacity: 0.75 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + target: languageKeyIcon + opacity: 0.2 + } + } + ] + } + + enterKeyPanel: KeyPanel { + BorderImage { + id: enterBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Image { + id: enterKeyIcon + visible: enterKeyText.text.length === 0 + anchors.centerIn: parent + fillMode: Image.PreserveAspectFit + readonly property size enterKeyIconSize: { + switch (control.actionId) { + case EnterKeyAction.Go: + case EnterKeyAction.Send: + case EnterKeyAction.Next: + case EnterKeyAction.Done: + return Qt.size(170, 119) + case EnterKeyAction.Search: + return Qt.size(148, 148) + default: + return Qt.size(211, 80) + } + } + sourceSize.width: enterKeyIconSize.width * keyIconScale + sourceSize.height: enterKeyIconSize.height * keyIconScale + width: Theme.fontSizeLarge + smooth: true + source: { + switch (control.actionId) { + case EnterKeyAction.Go: + case EnterKeyAction.Send: + case EnterKeyAction.Next: + case EnterKeyAction.Done: + return resourcePrefix + "images/check-868482.svg" + case EnterKeyAction.Search: + return resourcePrefix + "images/search-868482.svg" + default: + return "images/icon-m-input-methods-enter.svg" + } + } + } + Text { + id: enterKeyText + visible: text.length !== 0 + text: control.actionId !== EnterKeyAction.None ? control.displayText : "" + clip: true + fontSizeMode: Text.HorizontalFit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: Theme.textColor + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeMedium + capitalization: Font.AllUppercase + } + anchors.fill: parent + anchors.margins: Math.round(42 * scaleHint) + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: enterBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + } + PropertyChanges { + target: enterKeyIcon + opacity: 0.6 + } + PropertyChanges { + target: enterKeyText + opacity: 0.6 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + target: enterKeyIcon + opacity: 0.2 + } + PropertyChanges { + target: enterKeyText + opacity: 0.2 + } + } + ] + } + + hideKeyPanel: KeyPanel { + BorderImage { + id: hideKbdBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Image { + id: hideKeyIcon + anchors.centerIn: parent + sourceSize.width: 144 * keyIconScale + sourceSize.height: 127 * keyIconScale + smooth: true + source: resourcePrefix + "images/hidekeyboard-868482.svg" + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: hideKbdBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + } + PropertyChanges { + target: hideKeyIcon + opacity: 0.6 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + target: hideKeyIcon + opacity: 0.2 + } + } + ] + } + + shiftKeyPanel: KeyPanel { + BorderImage { + id: shiftBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Image { + id: shiftKeyIcon + anchors.centerIn: parent + sourceSize.width: width + sourceSize.height: height + smooth: true + fillMode: Image.PreserveAspectFit + width: Theme.fontSizeLarge + source: "images/icon-shift.svg" + } + states: [ + State { + name: "capslock" + when: InputContext.capsLock + + PropertyChanges { + target: shiftKeyIcon + source: "images/icon-shift-locked.svg" + } + }, + State { + name: "shift" + when: InputContext.shift + PropertyChanges { + target: shiftKeyIcon + source: "images/icon-shift-pressed.svg" + } + } + ] + } + states: [ + State { + name: "pressed" + when: control.pressed + + PropertyChanges { + target: shiftBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + + } + PropertyChanges { + target: shiftKeyIcon + opacity: 0.6 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + target: shiftKeyIcon + opacity: 0.2 + } + } + ] + } + + spaceKeyPanel: KeyPanel { + BorderImage { + id: spaceBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Text { + id: spaceKeyText + text: Qt.locale(InputContext.locale).nativeLanguageName + color: Theme.textColor + Behavior on color { PropertyAnimation { duration: 250 } } + anchors.centerIn: parent + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeMedium * scaleHint + } + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: spaceBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + + } + }, + State { + name: "disabled" + when: !control.enabled + } + ] + } + + symbolKeyPanel: KeyPanel { + BorderImage { + id: symbolBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Text { + id: symbolKeyText + text: control.displayText + color: Theme.textColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.fill: parent + anchors.margins: keyContentMargin + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeMedium * scaleHint + capitalization: Font.AllUppercase + } + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: symbolBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + } + PropertyChanges { + target: symbolKeyText + opacity: 0.6 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + target: symbolKeyText + opacity: 0.2 + } + } + ] + } + + modeKeyPanel: KeyPanel { + BorderImage { + id: modelBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Text { + id: modeKeyText + text: control.displayText + color: Theme.textColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.fill: parent + anchors.margins: keyContentMargin + font { + family: fontFamily + weight: Font.Normal + pixelSize: 44 * scaleHint + capitalization: Font.AllUppercase + } + } + Rectangle { + id: modeKeyIndicator + implicitHeight: parent.height * 0.1 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.leftMargin: parent.width * 0.4 + anchors.rightMargin: parent.width * 0.4 + anchors.bottomMargin: parent.height * 0.12 + color: Theme.accentColor + visible: control.mode + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: modelBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + } + PropertyChanges { + target: modeKeyText + opacity: 0.6 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + opacity: 0.8 + } + PropertyChanges { + target: modeKeyText + opacity: 0.2 + } + } + ] + } + + handwritingKeyPanel: KeyPanel { + BorderImage { + id: hwrBgimg + border { left: horizontalBorder; top: topBorder; right: horizontalBorder; bottom:0 } + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + source: "images/keyboard-key-portrait-function.png" + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Image { + id: hwrKeyIcon + anchors.centerIn: parent + readonly property size hwrKeyIconSize: keyboard.handwritingMode ? Qt.size(124, 96) : Qt.size(156, 104) + sourceSize.width: hwrKeyIconSize.width * keyIconScale + sourceSize.height: hwrKeyIconSize.height * keyIconScale + smooth: true + source: resourcePrefix + (keyboard.handwritingMode ? "images/textmode-868482.svg" : "images/handwriting-868482.svg") + } + } + states: [ + State { + name: "pressed" + when: control.pressed + PropertyChanges { + target: hwrBgimg + source:"images/keyboard-key-portrait-function-pressed.png" + } + PropertyChanges { + target: hwrKeyIcon + opacity: 0.6 + } + }, + State { + name: "disabled" + when: !control.enabled + PropertyChanges { + opacity: 0.8 + } + PropertyChanges { + target: hwrKeyIcon + opacity: 0.2 + } + } + ] + } + + characterPreviewMargin: 0 + characterPreviewDelegate: Item { + property string text + id: characterPreview + Image { + id: popper + source: "images/popper.png" + anchors.fill: parent + Text { + id: characterPreviewText + color: Theme.textColor + text: characterPreview.text + fontSizeMode: Text.HorizontalFit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.fill: parent + anchors.margins: Math.round(48 * scaleHint) + font { + family: fontFamily + weight: Font.Normal + bold:true + pixelSize: Theme.fontSizeExtraLarge * scaleHint + } + } + } + } + + alternateKeysListItemWidth: characterPreview.width + alternateKeysListItemHeight: characterPreview.height + alternateKeysListDelegate: Item { + id: alternateKeysListItem + width: alternateKeysListItemWidth + height: alternateKeysListItemHeight + Text { + id: listItemText + text: model.text + color: Theme.textColor + opacity: 0.8 + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeExtraLarge * scaleHint + } + anchors.centerIn: parent + } + states: State { + name: "current" + when: alternateKeysListItem.ListView.isCurrentItem + PropertyChanges { + target: listItemText + opacity: 1 + } + } + } + alternateKeysListHighlight: Image { + source: "images/popper.png" + } + alternateKeysListBackground: Rectangle { + color: Theme.backgroundColor + } + + selectionListHeight: 85 * scaleHint + selectionListDelegate: SelectionListItem { + id: selectionListItem + width: Math.round(selectionListLabel.width + selectionListLabel.anchors.leftMargin * 2) + Text { + id: selectionListLabel + anchors.left: parent.left + anchors.leftMargin: Math.round((compactSelectionList ? 50 : 140) * scaleHint) + anchors.verticalCenter: parent.verticalCenter + text: decorateText(display, wordCompletionLength) + color: Theme.accentColor + font { + family: fontFamily + weight: Font.Normal + pixelSize: 44 * scaleHint + } + function decorateText(text, wordCompletionLength) { + if (wordCompletionLength > 0) { + return text.slice(0, -wordCompletionLength) + '' + text.slice(-wordCompletionLength) + '' + } + return text + } + } + Rectangle { + id: selectionListSeparator + width: 4 * scaleHint + height: 36 * scaleHint + radius: 2 + color: "#35322f" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.left + } + states: State { + name: "current" + when: selectionListItem.ListView.isCurrentItem + PropertyChanges { + target: selectionListLabel + color: "white" + } + } + } + selectionListBackground: Rectangle { + color: "#1e1b18" + } + selectionListAdd: Transition { + NumberAnimation { property: "y"; from: wordCandidateView.height; duration: 200 } + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 } + } + selectionListRemove: Transition { + NumberAnimation { property: "y"; to: -wordCandidateView.height; duration: 200 } + NumberAnimation { property: "opacity"; to: 0; duration: 200 } + } + + navigationHighlight: Rectangle { + color: "transparent" + border.color: Theme.accentColor + border.width: Theme.itemSpacingExtraSmall + } + + traceInputKeyPanelDelegate: TraceInputKeyPanel { + traceMargins: keyBackgroundMargin + Rectangle { + id: traceInputKeyPanelBackground + color: Theme.fillDarkColor + anchors.fill: parent + anchors.margins: keyBackgroundMargin + Text { + id: hwrInputModeIndicator + visible: control.patternRecognitionMode === InputEngine.HandwritingRecoginition + text: InputContext.inputEngine.inputMode === InputEngine.Latin ? "Abc" : "123" + color: Theme.textColor + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: keyContentMargin + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeSmall * scaleHint + capitalization: { + if (InputContext.capsLock) + return Font.AllUppercase + if (InputContext.shift) + return Font.MixedCase + return Font.AllLowercase + } + } + } + } + Canvas { + id: traceInputKeyGuideLines + anchors.fill: traceInputKeyPanelBackground + opacity: 0.1 + onPaint: { + var ctx = getContext("2d") + ctx.lineWidth = 1 + ctx.strokeStyle = Qt.rgba(0xFF, 0xFF, 0xFF) + ctx.clearRect(0, 0, width, height) + var i + if (control.horizontalRulers) { + for (i = 0; i < control.horizontalRulers.length; i++) { + ctx.beginPath() + ctx.moveTo(0, control.horizontalRulers[i]) + ctx.lineTo(width, control.horizontalRulers[i]) + ctx.stroke() + } + } + if (control.verticalRulers) { + for (i = 0; i < control.verticalRulers.length; i++) { + ctx.beginPath() + ctx.moveTo(control.verticalRulers[i], 0) + ctx.lineTo(control.verticalRulers[i], height) + ctx.stroke() + } + } + } + } + } + + traceCanvasDelegate: TraceCanvas { + id: traceCanvas + onAvailableChanged: { + if (!available) + return + var ctx = getContext("2d") + if (parent.canvasType === "fullscreen") { + ctx.lineWidth = 10 + ctx.strokeStyle = Qt.rgba(0, 0, 0) + } else { + ctx.lineWidth = 10 * scaleHint + ctx.strokeStyle = Qt.rgba(0xFF, 0xFF, 0xFF) + } + ctx.lineCap = "round" + ctx.fillStyle = ctx.strokeStyle + } + autoDestroyDelay: 800 + onTraceChanged: if (trace === null) opacity = 0 + Behavior on opacity { PropertyAnimation { easing.type: Easing.OutCubic; duration: 150 } } + } + + popupListDelegate: SelectionListItem { + property real cursorAnchor: popupListLabel.x + popupListLabel.width + id: popupListItem + width: popupListLabel.width + popupListLabel.anchors.leftMargin * 2 + height: popupListLabel.height + popupListLabel.anchors.topMargin * 2 + Text { + id: popupListLabel + anchors.left: parent.left + anchors.top: parent.top + anchors.leftMargin: popupListLabel.height / 2 + anchors.topMargin: popupListLabel.height / 3 + text: decorateText(display, wordCompletionLength) + color: Theme.accentColor + font { + family: fontFamily + weight: Font.Normal + pixelSize: Qt.inputMethod.cursorRectangle.height * 0.8 + } + function decorateText(text, wordCompletionLength) { + if (wordCompletionLength > 0) { + return text.slice(0, -wordCompletionLength) + '' + text.slice(-wordCompletionLength) + '' + } + return text + } + } + states: State { + name: "current" + when: popupListItem.ListView.isCurrentItem + PropertyChanges { + target: popupListLabel + color: "black" + } + } + } + + popupListBackground: Item { + Rectangle { + width: parent.width + height: parent.height + color: Theme.textColor + border { + width: 1 + color: "#929495" + } + } + } + + popupListAdd: Transition { + NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 200 } + } + + popupListRemove: Transition { + NumberAnimation { property: "opacity"; to: 0; duration: 200 } + } + + languagePopupListEnabled: true + + languageListDelegate: SelectionListItem { + id: languageListItem + width: languageNameTextMetrics.width * 17 + height: languageNameTextMetrics.height + languageListLabel.anchors.topMargin + languageListLabel.anchors.bottomMargin + Text { + id: languageListLabel + anchors.left: parent.left + anchors.top: parent.top + anchors.leftMargin: languageNameTextMetrics.height / 2 + anchors.rightMargin: anchors.leftMargin + anchors.topMargin: languageNameTextMetrics.height / 3 + anchors.bottomMargin: anchors.topMargin + text: languageNameFormatter.elidedText + color: Theme.textColor + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeSmall * scaleHint + } + } + TextMetrics { + id: languageNameTextMetrics + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeSmall * scaleHint + } + text: "X" + } + TextMetrics { + id: languageNameFormatter + font { + family: fontFamily + weight: Font.Normal + pixelSize: Theme.fontSizeSmall * scaleHint + } + elide: Text.ElideRight + elideWidth: languageListItem.width - languageListLabel.anchors.leftMargin - languageListLabel.anchors.rightMargin + text: displayName + } + states: State { + name: "current" + when: languageListItem.ListView.isCurrentItem + PropertyChanges { + target: languageListLabel + color: Theme.accentColor + } + } + } + + languageListBackground: Rectangle { + color: Theme.fillDarkColor + border { + width: 1 + color: Theme.fillColor + } + } + + languageListAdd: Transition { + NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 200 } + } + + languageListRemove: Transition { + NumberAnimation { property: "opacity"; to: 0; duration: 200 } + } + + selectionHandle: Image { + sourceSize.width: 20 + source: resourcePrefix + "images/selectionhandle-bottom.svg" + } + + fullScreenInputContainerBackground: Rectangle { + color: "#FFF" + } + + fullScreenInputBackground: Rectangle { + color: "#FFF" + } + + fullScreenInputMargins: Math.round(15 * scaleHint) + + fullScreenInputPadding: Math.round(30 * scaleHint) + + fullScreenInputCursor: Rectangle { + width: 1 + color: Theme.accentColor + visible: parent.blinkStatus + } + + fullScreenInputFont.pixelSize: 58 * scaleHint +}