/* * Copyright 2016 Smith AR * Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * Latte-Dock is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtQuick.Layouts 1.1 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.plasmoid 2.0 import org.kde.taskmanager 0.1 as TaskManager import org.kde.plasma.private.taskmanager 0.1 as TaskManagerApplet import org.kde.activities 0.1 as Activities import org.kde.latte 0.1 as Latte import "../code/tools.js" as TaskTools import "../code/activitiesTools.js" as ActivitiesTools Item { id:root Layout.fillHeight: userPanelPosition === 0 ? true : false Layout.fillWidth: userPanelPosition === 0 ? true : false ///IMPORTANT: These values must be tested when the Now Dock Panel support ///also the four new anchors. A small issue is shown between the animation /// of the now dock plasmoid and the neighbour widgets... Layout.minimumWidth: (userPanelPosition !== 0)&&(!latteDock) ? clearWidth : -1 Layout.minimumHeight: (userPanelPosition !== 0)&&(!latteDock) ? clearHeight : -1 Layout.preferredWidth: (userPanelPosition !== 0)&&(!latteDock) ? tasksWidth : -1 Layout.preferredHeight: (userPanelPosition !== 0)&&(!latteDock) ? tasksHeight : -1 property bool debugLocation: false property bool editMode: plasmoid.userConfiguring property bool disableRestoreZoom: false //blocks restore animation in rightClick property bool dropNewLauncher: false property bool initializationStep: true property bool initializatedBuffers: noInitCreatedBuffers >= tasksStarting ? true : false property bool isHovered: false property bool showBarLine: plasmoid.configuration.showBarLine property bool useThemePanel: plasmoid.configuration.useThemePanel property bool taskInAnimation: noTasksInAnimation > 0 ? true : false property bool transparentPanel: plasmoid.configuration.transparentPanel property bool vertical: ((root.position === PlasmaCore.Types.LeftPositioned) || (root.position === PlasmaCore.Types.RightPositioned)) ? true : false property int clearWidth property int clearHeight property int newLocationDebugUse: PlasmaCore.Types.BottomPositioned property int newDroppedPosition: -1 property int noInitCreatedBuffers: 0 property int noTasksInAnimation: 0 property int themePanelSize: plasmoid.configuration.panelSize property int position : PlasmaCore.Types.BottomPositioned property int tasksStarting: 0 property int realSize: iconSize + iconMargin property real textColorLuma: 0.2126*theme.textColor.r + 0.7152*theme.textColor.g + 0.0722*theme.textColor.b property variant launchersOnActivities: [] property QtObject contextMenuComponent: Qt.createComponent("ContextMenu.qml"); property Item dragSource: null property color minimizedDotColor: textColorLuma > 0.5 ? Qt.darker(theme.textColor, 1+ (1-textColorLuma)) : Qt.lighter(theme.textColor, 1+(1-textColorLuma)) //BEGIN Now Dock Panel properties property bool enableShadows: latteDock ? latteDock.enableShadows > 0 : plasmoid.configuration.showShadows property bool forceHidePanel: false property bool disableLeftSpacer: false property bool disableRightSpacer: false property bool dockIsHidden: latteDock ? latteDock.dockIsHidden : false property bool highlightWindows: latteDock ? latteDock.highlightWindows: plasmoid.configuration.highlightWindows property bool reverseLinesPosition: latteDock ? latteDock.reverseLinesPosition : plasmoid.configuration.reverseLinesPosition property bool dotsOnActive: latteDock ? latteDock.dotsOnActive : plasmoid.configuration.dotsOnActive property bool showGlow: latteDock ? latteDock.showGlow : plasmoid.configuration.showGlow property bool showOnlyCurrentScreen: latteDock ? latteDock.showOnlyCurrentScreen : plasmoid.configuration.showOnlyCurrentScreen property bool showOnlyCurrentDesktop: latteDock ? latteDock.showOnlyCurrentDesktop : plasmoid.configuration.showOnlyCurrentDesktop property bool showOnlyCurrentActivity: latteDock ? latteDock.showOnlyCurrentActivity : plasmoid.configuration.showOnlyCurrentActivity property bool showPreviews: latteDock ? latteDock.showToolTips : plasmoid.configuration.showToolTips property bool showWindowActions: latteDock ? latteDock.showWindowActions : plasmoid.configuration.showWindowActions property bool smartLaunchersEnabled: latteDock ? latteDock.smartLaunchersEnabled : plasmoid.configuration.smartLaunchersEnabled property bool threeColorsWindows: latteDock ? latteDock.threeColorsWindows : plasmoid.configuration.threeColorsWindows property int durationTime: latteDock ? latteDock.durationTime : plasmoid.configuration.durationTime property int iconMargin: latteDock ? latteDock.iconMargin : 0.12*iconSize property int iconSize: latteDock ? latteDock.iconSize : Math.max(plasmoid.configuration.iconSize, 16) property int statesLineSize: latteDock ? latteDock.statesLineSize : Math.ceil( root.iconSize/13 ) property int tasksHeight: mouseHandler.height property int tasksWidth: mouseHandler.width property int userPanelPosition: latteDock ? latteDock.panelAlignment : plasmoid.configuration.plasmoidPosition property real zoomFactor: latteDock ? latteDock.zoomFactor : ( 1 + (plasmoid.configuration.zoomLevel / 20) ) property alias tasksCount: tasksModel.count property alias hoveredIndex: icList.hoveredIndex property Item latteDock: null //END Now Dock Panel properties Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground signal clearZoomSignal(); signal draggingFinished(); signal mouseWasEntered(int delegateIndex, bool value); signal presentWindows(variant winIds); signal requestLayout; signal signalAnimationsNeedBothAxis(int value); signal signalAnimationsNeedLength(int value); signal signalAnimationsNeedThickness(int value); signal signalDraggingState(bool value); signal showPreviewForTasks(QtObject group); //trigger updating scaling of neighbour delegates of zoomed delegate signal updateScale(int delegateIndex, real newScale, real step) signal publishTasksGeometries(); signal windowsHovered(variant winIds, bool hovered) //onAnimationsChanged: console.log(animations); /* Rectangle{ anchors.fill: parent border.width: 1 border.color: "red" color: "white" } */ onLatteDockChanged: { if (latteDock) plasmoid.configuration.isInLatteDock = true; else plasmoid.configuration.isInLatteDock = false; } Connections { target: plasmoid onLocationChanged: { root.updatePosition(); iconGeometryTimer.start(); } } Connections { target: plasmoid.configuration // onLaunchersChanged: tasksModel.launcherList = plasmoid.configuration.launchers onGroupingAppIdBlacklistChanged: tasksModel.groupingAppIdBlacklist = plasmoid.configuration.groupingAppIdBlacklist; onGroupingLauncherUrlBlacklistChanged: tasksModel.groupingLauncherUrlBlacklist = plasmoid.configuration.groupingLauncherUrlBlacklist; } ///// PlasmaCore.ColorScope{ id: colorScopePalette } ///// onDragSourceChanged: { if (dragSource == null) { root.draggingFinished(); root.signalDraggingState(false); tasksModel.syncLaunchers(); } else { root.signalDraggingState(true); } } /////Winwow previews/////////// ToolTipDelegate2 { id: toolTipDelegate visible: false property int currentItem: -1 } ////BEGIN interfaces Latte.WindowSystem{ id:windowSystem } PlasmaCore.Dialog{ id: windowsPreviewDlg // hideOnWindowDeactivate: false type: PlasmaCore.Dialog.Tooltip flags: Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.ToolTip location: plasmoid.location mainItem: toolTipDelegate visible: false property Item activeItem: null function hide(){ if (latteDock) { //it is used to unblock dock hiding root.signalDraggingState(false); } visible = false; //activeItem = null; initializePreviewComponent.createObject(windowsPreviewDlg); } function show(){ //used to initialize windows previews buffers visible = false; var tasks = icList.contentItem.children; for(var i=0; i 0) && root.initializatedBuffers ? 1 : 0 /* anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? parent.bottom : undefined anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? parent.top : undefined anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? parent.left : undefined anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? parent.right : undefined anchors.horizontalCenter: !parent.vertical ? parent.horizontalCenter : undefined anchors.verticalCenter: parent.vertical ? parent.verticalCenter : undefined */ width: ( icList.orientation === Qt.Horizontal ) ? icList.width + spacing : smallSize height: ( icList.orientation === Qt.Vertical ) ? icList.height + spacing : smallSize property int spacing: root.iconSize / 2 property int smallSize: Math.max(3.7*root.statesLineSize, 16) Behavior on opacity{ NumberAnimation { duration: root.durationTime*units.longDuration } } /// plasmoid's default panel BorderImage{ anchors.fill:parent source: "../images/panel-west.png" border { left:8; right:8; top:8; bottom:8 } opacity: (plasmoid.configuration.showBarLine && !plasmoid.configuration.useThemePanel && !root.forceHidePanel) ? 1 : 0 visible: (opacity == 0) ? false : true horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch Behavior on opacity{ NumberAnimation { duration: root.durationTime*units.longDuration } } } /// item which is used as anchors for the plasma's theme Item{ id:belower width: (root.position === PlasmaCore.Types.LeftPositioned) ? shadowsSvgItem.margins.left : shadowsSvgItem.margins.right height: (root.position === PlasmaCore.Types.BottomPositioned)? shadowsSvgItem.margins.bottom : shadowsSvgItem.margins.top anchors.top: (root.position === PlasmaCore.Types.BottomPositioned) ? parent.bottom : undefined anchors.bottom: (root.position === PlasmaCore.Types.TopPositioned) ? parent.top : undefined anchors.right: (root.position === PlasmaCore.Types.LeftPositioned) ? parent.left : undefined anchors.left: (root.position === PlasmaCore.Types.RightPositioned) ? parent.right : undefined } /// the current theme's panel PlasmaCore.FrameSvgItem{ id: shadowsSvgItem anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? belower.bottom : undefined anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? belower.top : undefined anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? belower.left : undefined anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? belower.right : undefined anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined width: root.vertical ? panelSize + margins.left + margins.right: parent.width height: root.vertical ? parent.height : panelSize + margins.top + margins.bottom imagePath: "translucent/widgets/panel-background" prefix:"shadow" opacity: (plasmoid.configuration.showBarLine && plasmoid.configuration.useThemePanel && !root.forceHidePanel) ? 1 : 0 visible: (opacity == 0) ? false : true property int panelSize: ((root.position === PlasmaCore.Types.BottomPositioned) || (root.position === PlasmaCore.Types.TopPositioned)) ? plasmoid.configuration.panelSize + belower.height: plasmoid.configuration.panelSize + belower.width Behavior on opacity{ NumberAnimation { duration: root.durationTime*units.longDuration } } PlasmaCore.FrameSvgItem{ anchors.margins: belower.width-1 anchors.fill:parent imagePath: plasmoid.configuration.transparentPanel ? "translucent/widgets/panel-background" : "widgets/panel-background" } } MouseHandler { id: mouseHandler anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? icList.bottom : undefined anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? icList.top : undefined anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? icList.left : undefined anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? icList.right : undefined anchors.horizontalCenter: !root.vertical ? icList.horizontalCenter : undefined anchors.verticalCenter: root.vertical ? icList.verticalCenter : undefined width: root.vertical ? maxSize : icList.width height: root.vertical ? icList.height : maxSize target: icList property int maxSize: (root.hoveredIndex>=0 && !root.dragSource) ? root.statesLineSize + root.zoomFactor * (root.iconSize + root.iconMargin) - 1 : root.statesLineSize + root.iconSize + root.iconMargin - 1 onUrlsDropped: { // If all dropped URLs point to application desktop files, we'll add a launcher for each of them. var createLaunchers = urls.every(function (item) { return backend.isApplication(item) }); if (createLaunchers) { urls.forEach(function (item) { addLauncher(item); }); return; } if (!hoveredItem) { return; } // DeclarativeMimeData urls is a QJsonArray but requestOpenUrls expects a proper QList. var urlsList = backend.jsonArrayToUrlList(urls); // Otherwise we'll just start a new instance of the application with the URLs as argument, // as you probably don't expect some of your files to open in the app and others to spawn launchers. tasksModel.requestOpenUrls(hoveredItem.modelIndex(), urlsList); } } ListView { id:icList property int currentSpot : -1000 property int hoveredIndex : -1 property int previousCount : 0 property int tasksCount: contentItem.children.length property bool delayingRemoval: false onTasksCountChanged: updateImplicits(); // property int count: children ? children.length : 0 /* anchors.bottom: (root.position === PlasmaCore.Types.BottomPositioned) ? parent.bottom : undefined anchors.top: (root.position === PlasmaCore.Types.TopPositioned) ? parent.top : undefined anchors.left: (root.position === PlasmaCore.Types.LeftPositioned) ? parent.left : undefined anchors.right: (root.position === PlasmaCore.Types.RightPositioned) ? parent.right : undefined anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined */ width: contentWidth height: contentHeight orientation: Qt.Horizontal delegate: TaskDelegate{} /*Rectangle{ anchors.fill: parent border.width: 1 border.color: "red" color: "transparent" }*/ //the duration of this animation should be as small as possible //it fixes a small issue with the dragging an item to change it's //position, if the duration is too big there is a point in the //list that an item is going back and forth too fast //more of a trouble moveDisplaced: Transition { NumberAnimation { properties: "x,y"; duration: root.durationTime*units.shortDuration; easing.type: Easing.Linear } } ///this transition can not be used with dragging !!!! I breaks ///the lists indexes !!!!! /* move: Transition { NumberAnimation { properties: "x,y"; duration: units.longDuration; easing.type: Easing.Linear } } */ function childAtPos(x, y){ var tasks = icList.contentItem.children; for(var i=0; i=choords.x) && (x<=choords.x+task.width) && (y>=choords.y) && (y<=choords.y+task.height)){ return task } } return null; } } VisualAddItem{ id: newDroppedLauncherVisual anchors.fill: mouseHandler visible: opacity == 0 ? false : true opacity: root.dropNewLauncher && mouseHandler.onlyLaunchers && (root.dragSource == null)? 1 : 0 } } //// helpers Timer { id: iconGeometryTimer // INVESTIGATE: such big interval but unfortunately it doesnot work otherwise interval: 500 repeat: false onTriggered: { // console.debug("Found children: "+icList.contentItem.children.length); TaskTools.publishIconGeometries(icList.contentItem.children); } } ////Activities List ////it can be used to cleanup the launchers from garbage-deleted activities.... Item{ id: activityModelInstance property int count: activityModelRepeater.count Repeater { id:activityModelRepeater model: Activities.ActivityModel { id: activityModel // shownStates: "Running" } delegate: Item { visible: false property string activityId: model.id property string activityName: model.name } } function activities(){ var activitiesResult = []; for(var i=0; i0) { url = url.substring( 0, url.indexOf("?iconData=" ) ); } tasksModel.requestAddLauncher(url); } function resetDragSource() { dragSource = null; } function createContextMenu(task) { var menu = root.contextMenuComponent.createObject(task); menu.visualParent = task; menu.mpris2Source = mpris2Source; menu.activitiesCount = activityModelInstance.count; return menu; } Component.onCompleted: { updatePosition(); root.presentWindows.connect(backend.presentWindows); root.windowsHovered.connect(backend.windowsHovered); // mouseHandler.urlDropped.connect(backend.urlDropped); dragHelper.dropped.connect(resetDragSource); } //BEGIN states //user set Panel Positions // 0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom states: [ ///Bottom Edge State { name: "bottomCenter" when: (root.position === PlasmaCore.Types.BottomPosition && userPanelPosition===Latte.Dock.Center) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } }, State { name: "bottomLeft" when: (root.position === PlasmaCore.Types.BottomPosition && userPanelPosition===Latte.Dock.Left) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } }, State { name: "bottomRight" when: (root.position === PlasmaCore.Types.BottomPosition && userPanelPosition===Latte.Dock.Right) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } }, ///Top Edge State { name: "topCenter" when: (root.position === PlasmaCore.Types.TopPosition && userPanelPosition===Latte.Dock.Center) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } }, State { name: "topLeft" when: (root.position === PlasmaCore.Types.TopPosition && userPanelPosition===Latte.Dock.Left) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } }, State { name: "topRight" when: (root.position === PlasmaCore.Types.TopPosition && userPanelPosition===Latte.Dock.Right) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } }, ////Left Edge State { name: "leftCenter" when: (root.position === PlasmaCore.Types.LeftPosition && userPanelPosition===Latte.Dock.Center) AnchorChanges { target: barLine anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } AnchorChanges { target: icList anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } }, State { name: "leftTop" when: (root.position === PlasmaCore.Types.LeftPosition && userPanelPosition===Latte.Dock.Top) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } }, State { name: "leftBottom" when: (root.position === PlasmaCore.Types.LeftPosition && userPanelPosition===Latte.Dock.Bottom) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } }, ///Right Edge State { name: "rightCenter" when: (root.position === PlasmaCore.Types.RightPosition && userPanelPosition===Latte.Dock.Center) AnchorChanges { target: barLine anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } AnchorChanges { target: icList anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } }, State { name: "rightTop" when: (root.position === PlasmaCore.Types.RightPosition && userPanelPosition===Latte.Dock.Top) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } }, State { name: "rightBottom" when: (root.position === PlasmaCore.Types.RightPosition && userPanelPosition===Latte.Dock.Bottom) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: icList anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } } ] //END states }