Commit 46805191 authored by eekkelund's avatar eekkelund

[AppLauncher] Change AppLauncher grid delegate to use Loader so in the future...

[AppLauncher] Change AppLauncher grid delegate to use Loader so in the future widgets could be used as delegate also.
Add scaling for not NemoMobile icons.
Code structure changes.
Improve folder support: Code structure changes, folder UI is more polished, add possibility to create folders, add to folder, change position inside of the folder, close the folder with InverseMouseArea/Lipstick.compositor.
parent 938c8cee
*.pro.user
*.pyc
.directory
*.o
*.so
*.qmlc
moc_*
qrc_*
.qmake.stash
*.spec.*
documentation.list
examples/touch/glacier-components
Makefile
installroot/
RPMS/
debug*.list
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
// //
// Copyright (c) 2011, Tom Swindell <t.swindell@rubyx.co.uk> // Copyright (c) 2011, Tom Swindell <t.swindell@rubyx.co.uk>
// Copyright (c) 2012, Timur Kristóf <venemo@fedoraproject.org> // Copyright (c) 2012, Timur Kristóf <venemo@fedoraproject.org>
// Copyright (c) 2017, Eetu Kahelin
import QtQuick 2.0 import QtQuick 2.6
import org.nemomobile.lipstick 0.1 import org.nemomobile.lipstick 0.1
import QtQuick.Controls.Nemo 1.0 import QtQuick.Controls.Nemo 1.0
import QtQuick.Controls.Styles.Nemo 1.0 import QtQuick.Controls.Styles.Nemo 1.0
...@@ -32,14 +33,20 @@ import QtQuick.Controls.Styles.Nemo 1.0 ...@@ -32,14 +33,20 @@ import QtQuick.Controls.Styles.Nemo 1.0
GridView { GridView {
id: gridview id: gridview
cellWidth: Math.min(parent.width,parent.height)/4 cellWidth: cellSize
cellHeight: cellWidth + 30 cellHeight: cellSize
width: parent.width width: parent.width
cacheBuffer: gridview.contentHeight cacheBuffer: gridview.contentHeight
property Item reorderItem property Item reorderItem
property bool onUninstall property bool onUninstall
property alias deleter: deleter property alias deleter: deleter
property var switcher: null property var switcher: null
property int cellSize: Math.min(parent.width,parent.height)/4
property int folderIndex: -1
property bool isRootFolder:true
property bool newFolderActive
property bool newFolder: newFolderActive && isRootFolder && folderIndex >= 0
// just for margin purposes // just for margin purposes
header: Item { header: Item {
...@@ -49,12 +56,12 @@ GridView { ...@@ -49,12 +56,12 @@ GridView {
height: Math.min(parent.width,parent.height)/10 height: Math.min(parent.width,parent.height)/10
} }
Item { Item {//todo
id: deleter id: deleter
anchors.top: parent.top anchors.top: parent.top
property alias remove: remove property alias remove: remove
property alias uninstall: uninstall property alias uninstall: uninstall
Rectangle { Rectangle {//todo
id: remove id: remove
property alias text: removeLabel.text property alias text: removeLabel.text
visible: onUninstall visible: onUninstall
...@@ -68,7 +75,7 @@ GridView { ...@@ -68,7 +75,7 @@ GridView {
font.pointSize: 8 font.pointSize: 8
} }
} }
Rectangle { Rectangle {//todo
id: uninstall id: uninstall
property alias text: uninstallLabel.text property alias text: uninstallLabel.text
anchors.left: remove.right anchors.left: remove.right
...@@ -85,15 +92,50 @@ GridView { ...@@ -85,15 +92,50 @@ GridView {
} }
} }
onFolderIndexChanged: if (folderIndex == -1) newFolderActive = false
model: LauncherFolderModel { id: launcherModel } model: LauncherFolderModel { id: launcherModel }
//Using loader that in the future we can also have widgets as delegate
delegate: Loader {
id:loader
width: cellSize
height: cellSize
onXChanged: item.x = x
onYChanged: item.y = y
property QtObject modelData : model
property int cellSize: gridview.cellHeight //delete
property int cellIndex: index
sourceComponent: object.type == LauncherModel.Folder ? folder : app
}
Component {
id:app
LauncherItemDelegate {
id: launcherItem
parent: gridview
parentItem: gridview
iconCaption.color:Theme.textColor
iconCaption.text: modelData.object.title
isFolder: modelData.object.type == LauncherModel.Folder
folderAppsCount: isFolder && modelData.object ? modelData.object.itemCount : 0
source: modelData.object.iconId == "" || isFolder ? "/usr/share/lipstick-glacier-home-qt5/qml/theme/default-icon.png" : (modelData.object.iconId.indexOf("/") == 0 ? "file://" : "image://theme/") + modelData.object.iconId
notNemoIcon: isFolder || modelData.object.iconId == "" ? false : modelData.object.iconId.indexOf("harbour") > -1 || modelData.object.iconId.indexOf("apkd_launcher") > -1 ? true : false
folderModel:launcherModel
delegate: LauncherItemDelegate { }
id: launcherItem }
width: gridview.cellWidth Component {
height: gridview.cellHeight id:folder
iconCaption: model.object.title LauncherItemFolder {
isFolder: model.object.type == LauncherModel.Folder id: launcherfolder
folderAppsCount: isFolder && model.object ? model.object.itemCount : 0 parent: gridview
source: model.object.iconId == "" || isFolder ? "/usr/share/lipstick-glacier-home-qt5/qml/theme/default-icon.png" : (model.object.iconId.indexOf("/") == 0 ? "file://" : "image://theme/") + model.object.iconId iconCaption.color:Theme.textColor
iconCaption.text: modelData.object.title
isFolder: modelData.object.type == LauncherModel.Folder
folderAppsCount: isFolder && modelData.object ? modelData.object.itemCount : 0
source: modelData.object.iconId == "" || isFolder ? "/usr/share/lipstick-glacier-home-qt5/qml/theme/default-icon.png" : (modelData.object.iconId.indexOf("/") == 0 ? "file://" : "image://theme/") + modelData.object.iconId
notNemoIcon: isFolder || modelData.object.iconId == "" ? false : modelData.object.iconId.indexOf("harbour") > -1 || modelData.object.iconId.indexOf("apkd_launcher") > -1 ? true : false
folderModel:launcherModel
}
} }
} }
...@@ -19,27 +19,31 @@ ...@@ -19,27 +19,31 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
// //
// Copyright (c) 2017, Eetu Kahelin
// Copyright (c) 2013, Jolla Ltd <robin.burchell@jollamobile.com> // Copyright (c) 2013, Jolla Ltd <robin.burchell@jollamobile.com>
// Copyright (c) 2012, Timur Kristóf <venemo@fedoraproject.org> // Copyright (c) 2012, Timur Kristóf <venemo@fedoraproject.org>
// Copyright (c) 2011, Tom Swindell <t.swindell@rubyx.co.uk> // Copyright (c) 2011, Tom Swindell <t.swindell@rubyx.co.uk>
import QtQuick 2.0 import QtQuick 2.6
import QtQuick.Controls.Nemo 1.0 import QtQuick.Controls.Nemo 1.0
import QtQuick.Controls.Styles.Nemo 1.0 import QtQuick.Controls.Styles.Nemo 1.0
import org.nemomobile.lipstick 0.1 import org.nemomobile.lipstick 0.1
Item { Item {
id: wrapper id: wrapper
property alias source: iconImage.source property string source
property alias iconCaption: iconText.text property alias iconCaption: launcherItem.iconCaption
property bool reordering property bool reordering: launcherItem.reordering
property int newIndex: -1
property real oldY
property bool isFolder property bool isFolder
property int folderAppsCount: 0 property int folderAppsCount
//Sailfish and other app icons are larger than nemo icons. Thats why this property could be used to scale them
property bool notNemoIcon
property alias parentItem: launcherItem.parentItem
property alias folderModel:launcherItem.folderModel
onXChanged: moveTimer.start() onXChanged: moveTimer.start()
onYChanged: moveTimer.start() onYChanged: moveTimer.start()
clip: true
Timer { Timer {
id: moveTimer id: moveTimer
...@@ -49,230 +53,21 @@ Item { ...@@ -49,230 +53,21 @@ Item {
function moveIcon() { function moveIcon() {
if (!reordering) { if (!reordering) {
if (!slideMoveAnim.running) { if (!launcherItem.slideMoveAnim.running) {
slideMoveAnim.start() launcherItem.slideMoveAnim.start()
} }
} }
} }
GridView {
id: folderLoader
parent: gridview.contentItem
y: wrapper.y + wrapper.height
x: 0
z: wrapper.z + 100
width: gridview.width
height: childrenRect.height
cellWidth: gridview.cellWidth
cellHeight: cellWidth + 30
visible: false
Rectangle {
anchors.fill: parent
opacity: 0.75
color: "white"
z: -1
}
delegate: MouseArea {
width: gridview.cellWidth
height: gridview.cellHeight
Image {
id: iconimage
source: model.object.iconId
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 8
}
width: gridview.cellWidth - gridview.cellWidth/10
height: width
asynchronous: true
Spinner {
id: spinner
anchors.centerIn: parent
enabled: (model.object.type === LauncherModel.Application) ? model.object.isLaunching : false
}
}
Text {
id: icontext
// elide only works if an explicit width is set
width: parent.width
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
font.pixelSize: gridview.cellWidth/10
color: 'black'
anchors {
left: parent.left
right: parent.right
top: iconimage.bottom
topMargin: 5
}
text: model.object.title
}
onClicked: {
model.object.launchApplication()
}
}
}
// Application icon for the launcher // Application icon for the launcher
MouseArea { LauncherItemWrapper {
id: launcherItem id: launcherItem
width: wrapper.width width: wrapper.width
height: wrapper.height height: wrapper.height
parent: gridview.contentItem folderAppsCount: wrapper.folderAppsCount
scale: reordering ? 1.3 : 1 isFolder: wrapper.isFolder
transformOrigin: Item.Center notNemoIcon: wrapper.notNemoIcon
onXChanged: moved() source: wrapper.source
onYChanged: moved() }
onClicked: {
// TODO: disallow if close mode enabled
if (model.object.type !== LauncherModel.Folder) {
var winId = switcher.switchModel.getWindowIdForTitle(model.object.title)
console.log("Window id found: " + winId)
if (winId == 0)
model.object.launchApplication()
else
Lipstick.compositor.windowToFront(winId)
} else {
if (!folderLoader.visible) {
folderLoader.visible = true
folderLoader.model = model.object
} else {
folderLoader.visible = false
}
}
}
onPressAndHold: {
reparent(gridview)
reorderItem = launcherItem
drag.target = launcherItem
z = 1000
reordering = true
gridview.onUninstall = true
// don't allow dragging an icon out of pages with a horizontal flick
pager.interactive = false
}
onReleased: {
if (reordering) {
reordering = false
reorderTimer.stop()
drag.target = null
reorderItem = null
pager.interactive = true
gridview.onUninstall = false
deleter.remove.text = qsTr("Remove")
deleter.uninstall.text = qsTr("Uninstall")
reparent(gridview.contentItem)
slideMoveAnim.start()
}
}
function reparent(newParent) {
var newPos = mapToItem(newParent, 0, 0)
parent = newParent
x = newPos.x - width/2 * (1-scale)
y = newPos.y - height/2 * (1-scale)
}
function moved() {
if (reordering) {
var gridViewPos = gridview.contentItem.mapFromItem(launcherItem, width/2, height/2)
var idx = gridview.indexAt(gridViewPos.x, gridViewPos.y)
var delPos = deleter.remove.mapFromItem(launcherItem, width/2, height/2)
var isdel = deleter.childAt(delPos.x, delPos.y)
if (isdel === deleter.remove) {
deleter.remove.text = qsTr("Removing") + " " + iconCaption
} else if (isdel === deleter.uninstall) {
deleter.uninstall.text = qsTr("Uninstalling") + " " + iconCaption
}
if (newIndex !== idx) {
reorderTimer.restart()
newIndex = idx
}
}
}
Timer {
id: reorderTimer
interval: 100
onTriggered: {
if (newIndex != -1 && newIndex !== index) {
launcherModel.move(index, newIndex)
}
newIndex = -1
}
}
Behavior on scale {
NumberAnimation { easing.type: Easing.InOutQuad; duration: 150 }
}
ParallelAnimation {
id: slideMoveAnim
NumberAnimation { target: launcherItem; property: "x"; to: wrapper.x; duration: 130; easing.type: Easing.OutQuint }
NumberAnimation { target: launcherItem; property: "y"; to: wrapper.y; duration: 130; easing.type: Easing.OutQuint }
}
Image {
id: iconImage
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 8
}
width: gridview.cellWidth - gridview.cellWidth/10
height: width
asynchronous: true
Spinner {
id: spinner
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 8
}
width: gridview.cellWidth - gridview.cellWidth/10
height: width
enabled: (model.object.type === LauncherModel.Application) ? model.object.isLaunching : false
}
}
Text{
id: itemsCount
visible: isFolder
text: folderAppsCount
anchors.centerIn: iconImage
horizontalAlignment: Text.AlignHCenter
font.pixelSize: gridview.cellWidth/4
color: "white"
}
// Caption for the icon
Text {
id: iconText
// elide only works if an explicit width is set
width: parent.width
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
font.pixelSize: gridview.cellWidth/8
color: 'white'
anchors {
left: parent.left
right: parent.right
top: iconImage.bottom
topMargin: 5
}
}
}
} }
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Copyright (c) 2017, Eetu Kahelin
// Copyright (c) 2013, Jolla Ltd <robin.burchell@jollamobile.com>
// Copyright (c) 2012, Timur Kristóf <venemo@fedoraproject.org>
// Copyright (c) 2011, Tom Swindell <t.swindell@rubyx.co.uk>
import QtQuick 2.6
import QtQuick.Controls.Nemo 1.0
import QtQuick.Controls.Styles.Nemo 1.0
import org.nemomobile.lipstick 0.1
Item {
id: wrapper
property string source
property alias iconCaption: launcherItem.iconCaption
property bool reordering: launcherItem.reordering
property bool isFolder
property int folderAppsCount
property bool notNemoIcon
property alias folderLoader: folderLoader
property alias folderModel:launcherItem.folderModel
onXChanged: moveTimer.start()
onYChanged: moveTimer.start()
Timer {
id: moveTimer
interval: 1
onTriggered: moveIcon()
}
function moveIcon() {
if (!reordering) {
if (!launcherItem.slideMoveAnim.running) {
launcherItem.slideMoveAnim.start()
}
}
}
// Application icon for the launcher
LauncherItemWrapper {
id: launcherItem
width: wrapper.width
height: wrapper.height
folderAppsCount:wrapper.folderAppsCount
isFolder: wrapper.isFolder
notNemoIcon:wrapper.notNemoIcon
parentItem: wrapper.parent
source: wrapper.source
clip: true
onClicked: {
// TODO: disallow if close mode enabled
if (modelData.object.type !== LauncherModel.Folder) {
var winId = switcher.switchModel.getWindowIdForTitle(modelData.object.title)
if (winId == 0 || !modelData.object.isLaunching)
modelData.object.launchApplication()
else
Lipstick.compositor.windowToFront(winId)
} else {
folderLoader.model = modelData.object
folderLoader.visible = true
}
}
Rectangle {
id:triangle
width: wrapper.height/4
height: width
rotation: 45
color: "white"
opacity: 0.85
visible: folderLoader.visible && folderLoader.count > 0
anchors.top:launcherItem.bottom
anchors.horizontalCenter: launcherItem.horizontalCenter
}
}
GridView {
id: folderLoader
property Item reorderItem
property bool isRootFolder:false
cacheBuffer: gridview.contentHeight
parent: gridview.contentItem
y: wrapper.y + wrapper.width
x: 0
z: wrapper.z + 100
width: gridview.width
height: count==0 ? 0 : (Math.floor((count*wrapper.height-1)/width) + 1) * wrapper.height
cellWidth: wrapper.width
cellHeight: wrapper.width
visible:false
Rectangle {
width: parent.width
height: parent.height
opacity: 0.85
color: "white"
radius: Theme.itemSpacingMedium
z: -1
}
delegate: LauncherItemDelegate {
id:folderLauncherItem
property QtObject modelData : model
property int cellIndex: index
parent: folderLoader
parentItem: folderLoader
width: wrapper.width
height: wrapper.height
notNemoIcon: isFolder || model.object.iconId == "" ? false : model.object.iconId.indexOf("harbour") > -1 || model.object.iconId.indexOf("apkd_launcher") > -1 ? true : false //Dirty but works most of the times
isFolder: model.object.type == LauncherModel.Folder
folderAppsCount: isFolder && model.object ? model.object.itemCount : 0
source: model.object.iconId == "" || isFolder ? "/usr/share/lipstick-glacier-home-qt5/qml/theme/default-icon.png" : (model.object.iconId.indexOf("/") == 0 ? "file://" : "image://theme/") + model.object.iconId
iconCaption.text: model.object.title
iconCaption.color: Theme.backgroundColor
folderModel:folderLoader.model
}
}
//When display goes off, close the folderloader
Connections {
target: Lipstick.compositor
onDisplayOff: {
folderLoader.visible=false
folderLoader.model = 0
}
}
Connections {
target: Lipstick.compositor
onWindowAdded: {
if(window.category=="" && window.title !== "Home"){
folderLoader.visible=false
folderLoader.model = 0
}
}
}
InverseMouseArea {
anchors.fill: folderLoader
enabled: folderLoader.visible && folderLoader.count > 0
parent:folderLoader.contentItem
onPressed: {
folderLoader.visible=false
folderLoader.model = 0
}
}
}
// This file is part of colorful-home, a nice user experience for touchscreens.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Copyright (c) 2017, Eetu Kahelin
// Copyright (c) 2013, Jolla Ltd <robin.burchell@jollamobile.com>
// Copyright (c) 2012, Timur Kristóf <venemo@fedoraproject.org>
// Copyright (c) 2011, Tom Swindell <t.swindell@rubyx.co.uk>
import QtQuick 2.6
import QtQuick.Controls.Nemo 1.0
import QtQuick.Controls.Styles.Nemo 1.0
import org.nemomobile.lipstick 0.1
MouseArea {
property alias source: iconImage.source
property alias iconCaption: iconText
property bool reordering
property int newIndex: -1
property int newFolderIndex: -1
property real oldY
property bool isFolder
property int folderAppsCount
property bool notNemoIcon
property Item parentItem
property alias slideMoveAnim: slideMoveAnim
property QtObject folderModel
property Item folderItem
id: launcherItem
parent: parentItem.contentItem
scale: newFolder && folderIndex == cellIndex && !isFolder ? 0.5 : (reordering || folderIndex == cellIndex ? 1.3 : 1)
transformOrigin: Item.Center
onXChanged: moved()
onYChanged: moved()
onClicked: {
// TODO: disallow if close mode enabled
if (modelData.object.type !== LauncherModel.Folder) {
var winId = switcher.switchModel.getWindowIdForTitle(modelData.object.title)
if (winId == 0 || !modelData.object.isLaunching)
modelData.object.launchApplication()
else
Lipstick.compositor.windowToFront(winId)
}
}
onPressed: {
newIndex = -1
newFolderIndex = -1
}
onPressAndHold: {
reparent(parentItem)
reorderItem = launcherItem
drag.target = launcherItem
z = 1000
reordering = true
parentItem.onUninstall = true
// don't allow dragging an icon out of pages with a horizontal flick
pager.interactive = false
}
onReleased: {
if (reordering) {
reorderEnded()
reordering = false
reorderTimer.stop()
drag.target = null
reorderItem = null
pager.interactive = true
parentItem.onUninstall = false
deleter.remove.text = qsTr("Remove")
deleter.uninstall.text = qsTr("Uninstall")
folderIndex = -1
reparent(parentItem.contentItem)
z = parent.z
slideMoveAnim.start()
}
}
function reparent(newParent) {
var newPos = mapToItem(newParent, 0, 0)
parent = newParent
x = newPos.x - width/2 * (1-scale)
y = newPos.y - height/2 * (1-scale)
}
function moved() {
if (reordering) {
var gridViewPos = parentItem.contentItem.mapFromItem(launcherItem, width/2, height/2)
var item = parentItem.itemAt(gridViewPos.x, gridViewPos.y)
var idx = -1
var folderIdx = -1
var delPos = deleter.remove.mapFromItem(launcherItem, width/2, height/2)
var isdel = deleter.childAt(delPos.x, delPos.y)
if (isdel === deleter.remove) {
deleter.remove.text = qsTr("Removing") + " " + iconCaption
} else if (isdel === deleter.uninstall) {
deleter.uninstall.text = qsTr("Uninstalling") + " " + iconCaption
}
//When adding new icon to folder or creating new folder
var offset = gridViewPos.x - item.x
var folderThreshold = !isFolder ? item.width / 4 : item.width / 2
if (offset < folderThreshold) {
if (Math.abs(cellIndex - item.cellIndex) > 1 || cellIndex > item.cellIndex || item.y !== wrapper.offsetY) {
idx = cellIndex < item.cellIndex ? item.cellIndex - 1 : item.cellIndex
folderItem = null
}
} else if (offset >= item.width - folderThreshold) {
if (Math.abs(cellIndex - item.cellIndex) > 1 || cellIndex < item.cellIndex || item.y !== wrapper.offsetY) {
idx = cellIndex > item.cellIndex ? item.cellIndex + 1 : item.cellIndex
folderItem = null
}
} else if (item.cellIndex !== cellIndex && parent.isRootFolder && !isFolder) {
folderItem = item
folderIdx = item.cellIndex
}
if (newIndex !== idx) {
newIndex = idx
reorderTimer.restart()
}
if (newFolderIndex != folderIdx) {
newFolderIndex = folderIdx
reorderTimer.restart()
}
if (newFolderIndex != folderIndex) {
folderIndex = -1
}
}
}
function reorderEnded() {
//called when icon is released and reordering is true
if (folderIndex >= 0) {
if (folderModel.get(folderIndex).type == LauncherModel.Application) {
var folder = folderModel.createFolder(folderIndex, "folder")
if (folder) {
folderModel.moveToFolder(modelData.object, folder)
}
} else {
folderModel.moveToFolder(modelData.object, folderModel.get(folderIndex))
}
folderIndex = -1
newFolderActive = false
}
}
Timer {
id: reorderTimer
interval: folderItem && folderItem.isFolder ? 10 : 100
onTriggered: {
if (newFolderIndex >= 0 && newFolderIndex !== cellIndex) {
if (!folderItem.isFolder) {
newFolderActive = true
} else {
newFolderActive = false
}
folderIndex = newFolderIndex
} else if (newIndex != -1 && newIndex !== cellIndex) {
folderModel.move(cellIndex, newIndex)
}
newIndex = -1
}
}
Behavior on scale {
NumberAnimation { easing.type: Easing.InOutQuad; duration: 150 }
}
ParallelAnimation {
id: slideMoveAnim
NumberAnimation { target: launcherItem; property: "x"; to: wrapper.x; duration: 130; easing.type: Easing.OutQuint }
NumberAnimation { target: launcherItem; property: "y"; to: wrapper.y; duration: 130; easing.type: Easing.OutQuint }
}
Item {
id: iconWrapper
width: parent.width -parent.width/10
height: width - iconText.height
anchors.centerIn: parent
Image {
id: iconImage
anchors {
// centerIn: notNemoIcon ? parent : undefined
horizontalCenter: /* notNemoIcon ? undefined : */parent.horizontalCenter
top: parent.top
//topMargin: Theme.itemSpacingExtraSmall
}
width:/* notNemoIcon ? parent.width-parent.width/3 : */parent.width - parent.width/4
height: width
asynchronous: true
Spinner {
id: spinnerr
anchors {
centerIn: parent
top: parent.top
topMargin: Theme.itemSpacingExtraSmall
}
width: parent.cellWidth - parent.cellWidth/10
height: width
enabled: (modelData.object.type === LauncherModel.Application) ? modelData.object.isLaunching ? switcher.switchModel.getWindowIdForTitle(modelData.object.title) == 0 : false : false
Connections {
target: Lipstick.compositor
onWindowAdded: {
if(window.category=="" && window.title !== "Home"){
spinnerr.stop()
}
}
}
}
Text{
id: itemsCount
visible: isFolder
text: folderAppsCount
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
font.pixelSize: iconImage.width/4
color: "white"
}
}
}
// Caption for the icon
Text {
id: iconText
// elide only works if an explicit width is set
width: iconWrapper.width
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Theme.fontSizeSmall
color: Theme.textColor
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
topMargin: Theme.itemSpacingExtraSmall
}
}
}
...@@ -398,6 +398,7 @@ Compositor { ...@@ -398,6 +398,7 @@ Compositor {
var isNotificationWindow = window.category == "notification" var isNotificationWindow = window.category == "notification"
var isOverlayWindow = window.category == "overlay" var isOverlayWindow = window.category == "overlay"
var isAlarmWindow = window.category == "alarm" var isAlarmWindow = window.category == "alarm"
var isApplicationWindow = window.category == ""
var parent = null var parent = null
if (window.category == "cover") { if (window.category == "cover") {
window.visible = false window.visible = false
...@@ -411,10 +412,14 @@ Compositor { ...@@ -411,10 +412,14 @@ Compositor {
parent = overlayLayer parent = overlayLayer
} else if (isAlarmWindow) { } else if (isAlarmWindow) {
parent = alarmsLayer parent = alarmsLayer
} else if (isApplicationWindow) {
parent = appLayer
} else { } else {
parent = appLayer parent = appLayer
} }
window.focusOnTouch = !window.isInProcess && !isOverlayWindow && !isNotificationWindow
var w; var w;
if (isOverlayWindow) w = alphaWrapper.createObject(parent, { window: window }) if (isOverlayWindow) w = alphaWrapper.createObject(parent, { window: window })
else w = windowWrapper.createObject(parent, { window: window }) else w = windowWrapper.createObject(parent, { window: window })
......
...@@ -44,7 +44,9 @@ qml.files = qml/MainScreen.qml \ ...@@ -44,7 +44,9 @@ qml.files = qml/MainScreen.qml \
qml/CommonPanel.qml \ qml/CommonPanel.qml \
qml/ShutdownScreen.qml \ qml/ShutdownScreen.qml \
qml/GlacierRotation.qml \ qml/GlacierRotation.qml \
qml/DeviceLockUI.qml qml/DeviceLockUI.qml \
qml/LauncherItemWrapper.qml \
qml/LauncherItemFolder.qml
qmlcompositor.path = /usr/share/lipstick-glacier-home-qt5/qml/compositor qmlcompositor.path = /usr/share/lipstick-glacier-home-qt5/qml/compositor
qmlcompositor.files = qml/compositor/WindowWrapperMystic.qml \ qmlcompositor.files = qml/compositor/WindowWrapperMystic.qml \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment