a very raw activity manager

it's just a port of the old qml code, will need more rework
This commit is contained in:
Marco Martin 2013-10-29 18:09:05 +01:00
parent 8507084d62
commit 3b6c2c82e3
2 changed files with 572 additions and 7 deletions

View File

@ -0,0 +1,293 @@
/*
* Copyright 2011 Marco Martin <mart@kde.org>
*
* This program 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 or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 2.1
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.qtextracomponents 2.0
PlasmaCore.FrameSvgItem {
id: background
width: Math.max((delegateStack.currentPage ? delegateStack.currentPage.implicitWidth : 0) + margins.left + margins.right, list.delegateWidth)
height: Math.max((delegateStack.currentPage ? delegateStack.currentPage.implicitHeight : 0) + margins.top + margins.bottom, list.delegateHeight)
imagePath: "widgets/viewitem"
prefix: Current ? (mainMouseArea.containsMouse ? "selected+hover" : "selected") : (mainMouseArea.containsMouse ? "hover" : "normal")
Behavior on width {
NumberAnimation { duration: 250 }
}
Behavior on height {
NumberAnimation { duration: 250 }
}
PlasmaComponents.PageStack {
id: delegateStack
anchors {
fill: parent
leftMargin: background.margins.left
topMargin: background.margins.top
rightMargin: background.margins.right
bottomMargin: background.margins.bottom
}
clip: true
initialPage: iconComponent
}
property Item mainMouseArea
Component {
id: iconComponent
Item {
anchors.fill: parent
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
var activityId = model["DataEngineSource"]
var service = activitySource.serviceForSource(activityId)
var operation = service.operationDescription("setCurrent")
service.startOperationCall(operation)
}
Component.onCompleted: mainMouseArea = mouseArea
QIconItem {
id: iconWidget
anchors.verticalCenter: parent.verticalCenter
x: y
width: theme.hugeIconSize
height: width
icon: QIcon(Icon)
}
QPixmapItem {
anchors.fill: iconWidget
pixmap: Icon ? undefined : activityManager.pixmapForActivity(model["DataEngineSource"])
visible: Icon == ""
}
QIconItem {
width: theme.mediumIconSize
height: width
anchors.centerIn: iconWidget
icon: QIcon("media-playback-start")
visible: model["State"] != "Running"
}
Column {
anchors {
left: iconWidget.right
right: parent.right
verticalCenter: parent.verticalCenter
leftMargin: background.margins.left
}
PlasmaComponents.Label {
id: titleText
text: Name
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
height: paintedHeight
wrapMode: Text.WordWrap
//go with nowrap only if there is a single word too long
onPaintedWidthChanged: {
wrapTimer.restart()
}
Timer {
id: wrapTimer
interval: 200
onTriggered: {
//give it some pixels of tolerance
if (titleText.paintedWidth > titleText.width + 3) {
titleText.wrapMode = Text.NoWrap
titleText.elide = Text.ElideRight
} else {
titleText.wrapMode = Text.WordWrap
titleText.elide = Text.ElideNone
}
}
}
}
Row {
id: buttonsRow
visible: model["State"] == "Running"
anchors.horizontalCenter: parent.horizontalCenter
PlasmaComponents.ToolButton {
id: configureButton
flat: false
iconSource: "configure"
onClicked: delegateStack.push(configurationComponent)
}
PlasmaComponents.ToolButton {
visible: !model["Current"]
iconSource: "media-playback-stop"
flat: false
onClicked: {
var activityId = model["DataEngineSource"]
var service = activitySource.serviceForSource(activityId)
var operation = service.operationDescription("stop")
service.startOperationCall(operation)
}
}
}
PlasmaComponents.ToolButton {
visible: model["State"] != "Running"
iconSource: "edit-delete"
text: i18n("Delete")
width: Math.min(implicitWidth, parent.width)
anchors.horizontalCenter: parent.horizontalCenter
onClicked: delegateStack.push(confirmationComponent)
}
}
}
}
}
Component {
id: confirmationComponent
MouseArea {
anchors.fill: parent
//20 is just a number arbitrarly low, won't be followed
implicitWidth: (activityManager.orientation == Qt.Horizontal) ? confirmationLabel.paintedWidth : 20
implicitHeight: (activityManager.orientation == Qt.Horizontal) ? 20 : confirmationColumn.childrenRect.height
onClicked: delegateStack.pop()
Column {
id: confirmationColumn
anchors.fill: parent
spacing: 4
PlasmaComponents.Label {
id: confirmationLabel
anchors {
left: parent.left
right: parent.right
}
horizontalAlignment: Text.AlignHCenter
text: i18n("Remove activity %1?", Name)
wrapMode: (activityManager.orientation == Qt.Horizontal) ? Text.NoWrap : Text.Wrap
}
PlasmaComponents.Button {
anchors.horizontalCenter: parent.horizontalCenter
text: i18n("Remove")
onClicked: {
var activityId = model["DataEngineSource"]
var service = activitySource.serviceForSource(activityId)
var operation = service.operationDescription("remove")
operation["Id"] = activityId
service.startOperationCall(operation)
}
}
PlasmaComponents.Button {
anchors.horizontalCenter: parent.horizontalCenter
text: i18n("Cancel")
onClicked: delegateStack.pop()
}
}
}
}
Component {
id: configurationComponent
MouseArea {
anchors.fill: parent
//20 is just a number arbitrarly low, won't be followed
implicitWidth: (activityManager.orientation == Qt.Horizontal) ? (iconButton.x*3 + iconButton.width + theme.mSize(theme.defaultFont).width * 12) : 20
// set the implicit height to a meaningful value, otherwise the layouting goes a little crazy :)
implicitHeight: iconButton.y*3
onClicked: delegateStack.pop()
PlasmaComponents.Button {
id: iconButton
iconSource: Icon
anchors {
top: configurationLayout.top
bottom: configurationLayout.bottom
}
x: y
width: height
QPixmapItem {
anchors.centerIn: parent
width: theme.largeIconSize
height: width
smooth: true
visible: iconButton.iconSource == ""
pixmap: visible ? undefined : activityManager.pixmapForActivity(model["DataEngineSource"])
}
onClicked: iconSource = activityManager.chooseIcon()
}
Column {
id: configurationLayout
anchors {
left: iconButton.right
verticalCenter: parent.verticalCenter
right: parent.right
leftMargin: iconButton.x
rightMargin: iconButton.x
}
spacing: 4
PlasmaComponents.TextField {
id: activityNameField
text: Name
anchors {
left: parent.left
right: parent.right
}
}
PlasmaComponents.Button {
anchors.horizontalCenter: parent.horizontalCenter
text: i18n("Apply")
onClicked: {
var activityId = model["DataEngineSource"]
var service = activitySource.serviceForSource(activityId)
var operation = service.operationDescription("setName")
operation["Name"] = activityNameField.text
service.startOperationCall(operation)
var operation = service.operationDescription("setIcon")
operation["Icon"] = iconButton.iconSource
service.startOperationCall(operation)
delegateStack.pop()
}
anchors {
left: parent.left
right: parent.right
}
}
PlasmaComponents.Button {
anchors.horizontalCenter: parent.horizontalCenter
text: i18n("Cancel")
onClicked: delegateStack.pop()
anchors {
left: parent.left
right: parent.right
}
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2011 Marco Martin <mart@kde.org>
* Copyright 2013 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
@ -18,19 +18,291 @@
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.qtextracomponents 2.0
Rectangle {
id: root
color: "red"
Item {
id: main
signal closed()
PlasmaComponents.ToolButton {
//this is used to perfectly align the filter field and delegates
property int cellWidth: theme.mSize(theme.defaultFont).width * 20
QtObject {
id: activityManager
property int orientation: Qt.Vertical
}
property int minimumWidth: cellWidth + (
activityManager.orientation == Qt.Horizontal
? 0
: (scrollBar.width + 4 * 2) // 4 * 2 == left and right margins
)
property int minimumHeight: topBar.height + list.delegateHeight + (activityManager.orientation == Qt.Horizontal ? scrollBar.height : 0) + 4
PlasmaCore.DataSource {
id: activitySource
engine: "org.kde.activities"
onSourceAdded: {
if (source != "Status") {
connectSource(source)
}
}
Component.onCompleted: {
connectedSources = sources.filter(function(val) {
return val != "Status";
})
}
}
PlasmaComponents.ContextMenu {
id: newActivityMenu
visualParent: topBar.newActivityButton
PlasmaComponents.MenuItem {
id: templatesItem
text: i18n("Templates")
onClicked: activityTemplatesMenu.open()
}
PlasmaComponents.MenuItem {
icon: QIcon("user-desktop")
text: i18n("Empty Desktop")
onClicked: activityManager.createActivity("desktop")
}
PlasmaComponents.MenuItem {
icon: QIcon("edit-copy")
text: i18n("Clone current activity")
onClicked: activityManager.cloneCurrentActivity()
}
}
PlasmaComponents.ContextMenu {
id: activityTemplatesMenu
visualParent: templatesItem
}
Repeater {
parent: activityTemplatesMenu
model: activityManager.activityTypeActions
delegate: PlasmaComponents.MenuItem {
icon: QIcon(modelData.icon)
text: modelData.text
separator: modelData.separator
onClicked: {
//is a plugin?
if (modelData.pluginName) {
activityManager.createActivity(modelData.pluginName)
//is a script?
} else if (modelData.scriptFile) {
activityManager.createActivityFromScript(modelData.scriptFile, modelData.text, modelData.icon, modelData.startupApps)
//invoke ghns
} else {
activityManager.downloadActivityScripts()
}
}
Component.onCompleted: {
parent = activityTemplatesMenu
}
}
}
Loader {
id: topBar
property string query
property Item newActivityButton
sourceComponent: (activityManager.orientation == Qt.Horizontal) ? horizontalTopBarComponent : verticalTopBarComponent
height: item.height + 2
anchors {
top: parent.top
left: parent.left
right: parent.right
topMargin: activityManager.orientation == Qt.Horizontal ? 4 : 0
leftMargin: 4
}
}
Component {
id: horizontalTopBarComponent
Item {
anchors {
top: parent.top
left:parent.left
right: parent.right
}
height: filterField.height
PlasmaComponents.TextField {
id: filterField
anchors {
left: parent.left
leftMargin: 2
}
width: list.width / Math.floor(list.width / cellWidth) - 4
clearButtonShown: true
onTextChanged: topBar.query = text
placeholderText: i18n("Enter search term...")
Component.onCompleted: forceActiveFocus()
}
Row {
anchors.right: parent.right
spacing: 4
PlasmaComponents.Button {
id: newActivityButton
iconSource: "list-add"
text: i18n("Create activity...")
onClicked: newActivityMenu.open()
}
PlasmaComponents.Button {
iconSource: "plasma"
text: i18n("Add widgets")
onClicked: activityManager.addWidgetsRequested()
}
PlasmaComponents.ToolButton {
iconSource: "window-close"
onClicked: root.closed()
}
}
Component.onCompleted: {
topBar.newActivityButton = newActivityButton
}
}
}
Component {
id: verticalTopBarComponent
Column {
spacing: 4
anchors {
top: parent.top
left:parent.left
right: parent.right
}
PlasmaComponents.ToolButton {
anchors.right: parent.right
iconSource: "window-close"
onClicked: root.closed()
}
PlasmaComponents.TextField {
id: filterField
anchors {
left: parent.left
right: parent.right
}
clearButtonShown: true
onTextChanged: topBar.query = text
placeholderText: i18n("Enter search term...")
Component.onCompleted: forceActiveFocus()
}
PlasmaComponents.Button {
id: newActivityButton
anchors {
left: parent.left
right: parent.right
}
iconSource: "list-add"
text: i18n("Create activity...")
onClicked: newActivityMenu.open()
}
Component.onCompleted: {
topBar.newActivityButton = newActivityButton
}
}
}
MouseEventListener {
id: listParent
anchors {
top: topBar.bottom
left: parent.left
right: activityManager.orientation == Qt.Horizontal
? parent.right
: (scrollBar.visible ? scrollBar.left : parent.right)
bottom: activityManager.orientation == Qt.Horizontal ? scrollBar.top : bottomBar.top
leftMargin: 4
bottomMargin: 4
}
onWheelMoved: {
//use this only if the wheel orientation is vertical and the list orientation is horizontal, otherwise will be the list itself managing the wheel
if (wheel.orientation == Qt.Vertical && list.orientation == ListView.Horizontal) {
var delta = wheel.delta > 0 ? 20 : -20
list.contentX = Math.min(Math.max(0, list.contentWidth - list.width),
Math.max(0, list.contentX - delta))
}
}
ListView {
id: list
property int delegateWidth: (activityManager.orientation == Qt.Horizontal) ? (list.width / Math.floor(list.width / cellWidth)) : list.width
property int delegateHeight: theme.mSize(theme.defaultFont).height * 7 - 4
anchors.fill: parent
orientation: activityManager.orientation == Qt.Horizontal ? ListView.Horizontal : ListView.vertical
snapMode: ListView.SnapToItem
model: PlasmaCore.SortFilterModel {
sourceModel: PlasmaCore.DataModel {
dataSource: activitySource
}
filterRole: "Name"
filterRegExp: ".*"+topBar.query+".*"
}
clip: activityManager.orientation == Qt.Vertical
delegate: ActivityDelegate {}
}
}
PlasmaComponents.ScrollBar {
id: scrollBar
orientation: activityManager.orientation == Qt.Horizontal ? ListView.Horizontal : ListView.Vertical
anchors {
top: activityManager.orientation == Qt.Horizontal ? undefined : listParent.top
bottom: activityManager.orientation == Qt.Horizontal ? parent.bottom : bottomBar.top
left: activityManager.orientation == Qt.Horizontal ? parent.left : undefined
right: parent.right
}
iconSource: "window-close"
onClicked: root.closed()
flickableItem: list
}
Loader {
id: bottomBar
sourceComponent: (activityManager.orientation == Qt.Horizontal) ? undefined : verticalBottomBarComponent
height: item.height
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
leftMargin: 4
}
}
Component {
id: verticalBottomBarComponent
Column {
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
spacing: 4
PlasmaComponents.Button {
anchors {
left: parent.left
right: parent.right
}
iconSource: "plasma"
text: i18n("Add widgets")
onClicked: activityManager.addWidgetsRequested()
}
}
}
}