a very raw activity manager
it's just a port of the old qml code, will need more rework
This commit is contained in:
parent
8507084d62
commit
3b6c2c82e3
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user