diff --git a/applets/systemtray/package/contents/ui/ExpandedRepresentation.qml b/applets/systemtray/package/contents/ui/ExpandedRepresentation.qml index b835f8a81..94ad3488c 100644 --- a/applets/systemtray/package/contents/ui/ExpandedRepresentation.qml +++ b/applets/systemtray/package/contents/ui/ExpandedRepresentation.qml @@ -1,122 +1,124 @@ /* * Copyright 2016 Marco Martin * * 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 Library 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 QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras Item { id: expandedRepresentation Layout.minimumWidth: units.gridUnit * 24 Layout.minimumHeight: units.gridUnit * 21 Layout.preferredWidth: Layout.minimumWidth Layout.preferredHeight: Layout.minimumHeight * 1.5 property bool hideOnWindowDeactivate: !pinButton.checked property alias activeApplet: container.activeApplet property alias hiddenLayout: hiddenItemsView.layout PlasmaComponents.ToolButton { id: pinButton anchors.right: parent.right width: Math.round(units.gridUnit * 1.25) height: width checkable: true iconSource: "window-pin" z: 2 } PlasmaExtras.Heading { id: heading level: 1 anchors { left: parent.left top: parent.top right: parent.right topMargin: hiddenItemsView.visible ? units.smallSpacing : 0 leftMargin: { //Menu mode if (!activeApplet && hiddenItemsView.visible) { return units.smallSpacing; //applet open, sidebar } else if (activeApplet && hiddenItemsView.visible) { return hiddenItemsView.iconColumnWidth + units.largeSpacing; //applet open, no sidebar } else { return 0; } } } text: activeApplet ? activeApplet.title : i18n("Status & Notifications") MouseArea { anchors.fill: parent onClicked: { if (activeApplet) { activeApplet.expanded = false; dialog.visible = true; } } } } PlasmaCore.SvgItem { - visible: hiddenItemsView.visible && activeApplet - width: lineSvg.elementSize("vertical-line").width - x: hiddenLayout.width anchors { + left: parent.left + leftMargin: hiddenLayout.width top: parent.top bottom: parent.bottom margins: -units.gridUnit } + visible: hiddenItemsView.visible && activeApplet + width: lineSvg.elementSize("vertical-line").width + elementId: "vertical-line" svg: PlasmaCore.Svg { id: lineSvg; imagePath: "widgets/line" } } HiddenItemsView { id: hiddenItemsView anchors { left: parent.left top: heading.bottom bottom: parent.bottom } } PlasmoidPopupsContainer { id: container anchors { left: parent.left right: parent.right top: heading.bottom bottom: parent.bottom leftMargin: hiddenItemsView.visible ? hiddenItemsView.iconColumnWidth + units.largeSpacing : 0 } } } diff --git a/applets/systemtray/package/contents/ui/items/AbstractItem.qml b/applets/systemtray/package/contents/ui/items/AbstractItem.qml index 2f1a17650..f2a0df3fd 100644 --- a/applets/systemtray/package/contents/ui/items/AbstractItem.qml +++ b/applets/systemtray/package/contents/ui/items/AbstractItem.qml @@ -1,118 +1,119 @@ /* * Copyright 2016 Marco Martin * * 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 Library 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 PlasmaCore.ToolTipArea { id: abstractItem height: effectiveItemSize + marginHints.top + marginHints.bottom width: labelVisible ? parent.width : effectiveItemSize + marginHints.left + marginHints.right property real effectiveItemSize: hidden ? root.hiddenItemSize : root.itemSize property string itemId property string category property alias text: label.text property bool hidden: parent.objectName == "hiddenTasksColumn" property QtObject marginHints: parent.marginHints property bool labelVisible: abstractItem.hidden && !root.activeApplet property Item iconItem //PlasmaCore.Types.ItemStatus property int status property QtObject model signal clicked(var mouse) signal wheel(var wheel) property bool forcedHidden: plasmoid.configuration.hiddenItems.indexOf(itemId) !== -1 property bool forcedShown: plasmoid.configuration.showAllItems || plasmoid.configuration.shownItems.indexOf(itemId) !== -1 property bool categoryShown: shownCategories.indexOf(category) != -1; /* subclasses need to assign to this tiiltip properties mainText: subText: icon: */ location: if (abstractItem.parent && abstractItem.parent.objectName == "hiddenTasksColumn" && plasmoid.location != PlasmaCore.Types.LeftEdge) { return PlasmaCore.Types.RightEdge; } else { return plasmoid.location; } //BEGIN CONNECTIONS onStatusChanged: updateItemVisibility(abstractItem); onContainsMouseChanged: { if (hidden && containsMouse) { root.hiddenLayout.hoveredItem = abstractItem } } Component.onCompleted: updateItemVisibility(abstractItem); onForcedHiddenChanged: updateItemVisibility(abstractItem); onForcedShownChanged: updateItemVisibility(abstractItem); onCategoryShownChanged: updateItemVisibility(abstractItem); //dangerous but needed due how repeater reparents onParentChanged: updateItemVisibility(abstractItem); //END CONNECTIONS PulseAnimation { targetItem: abstractItem running: (abstractItem.status === PlasmaCore.Types.NeedsAttentionStatus || abstractItem.status === PlasmaCore.Types.RequiresAttentionStatus ) && units.longDuration > 0 } MouseArea { id: mouseArea anchors.fill: abstractItem hoverEnabled: true drag.filterChildren: true acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton onClicked: { abstractItem.hideToolTip() abstractItem.clicked(mouse) } onWheel: abstractItem.wheel(wheel) } PlasmaComponents.Label { id: label + anchors { + left: parent.left + leftMargin: iconItem ? iconItem.width + units.smallSpacing : 0 + verticalCenter: parent.verticalCenter + } opacity: labelVisible ? 1 : 0 - x: iconItem ? iconItem.width + units.smallSpacing : 0 visible: abstractItem.hidden Behavior on opacity { NumberAnimation { duration: units.longDuration easing.type: Easing.InOutQuad } } - anchors { - verticalCenter: parent.verticalCenter - } } } diff --git a/applets/systemtray/package/contents/ui/main.qml b/applets/systemtray/package/contents/ui/main.qml index 20fd211da..beade6391 100644 --- a/applets/systemtray/package/contents/ui/main.qml +++ b/applets/systemtray/package/contents/ui/main.qml @@ -1,295 +1,298 @@ /* * Copyright 2011 Marco Martin * * 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 Library 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.5 import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.plasmoid 2.0 import "items" MouseArea { id: root Layout.minimumWidth: vertical ? units.iconSizes.small : tasksRow.implicitWidth + expander.implicitWidth + units.smallSpacing Layout.minimumHeight: vertical ? tasksRow.implicitHeight+ expander.implicitHeight + units.smallSpacing : units.smallSpacing property bool vertical: plasmoid.formFactor == PlasmaCore.Types.Vertical property int itemSize: Math.min(Math.min(width, height), units.iconSizes.smallMedium) property int hiddenItemSize: units.iconSizes.smallMedium property alias expanded: dialog.visible property Item activeApplet property alias visibleLayout: tasksRow property alias hiddenLayout: expandedRepresentation.hiddenLayout property alias statusNotifierModel: statusNotifierModel function updateItemVisibility(item) { //Invisible if (!item.categoryShown) { if (item.parent == invisibleEntriesContainer) { return; } item.parent = invisibleEntriesContainer; //visible } else if (item.forcedShown || !(item.forcedHidden || item.status == PlasmaCore.Types.PassiveStatus)) { if (visibleLayout.children.length == 0) { item.parent = visibleLayout; //notifications is always the first } else if (visibleLayout.children[0].itemId == "org.kde.plasma.notifications" && item.itemId != "org.kde.plasma.notifications") { plasmoid.nativeInterface.reorderItemAfter(item, visibleLayout.children[0]); } else if (visibleLayout.children[0] != item) { plasmoid.nativeInterface.reorderItemBefore(item, visibleLayout.children[0]); } //hidden } else { if (hiddenLayout.children.length == 0) { item.parent = hiddenLayout; //notifications is always the first } else if (hiddenLayout.children[0].itemId == "org.kde.plasma.notifications" && item.itemId != "org.kde.plasma.notifications") { plasmoid.nativeInterface.reorderItemAfter(item, hiddenLayout.children[0]); } else if (hiddenLayout.children[0] != item) { plasmoid.nativeInterface.reorderItemBefore(item, hiddenLayout.children[0]); } item.x = 0; } } Containment.onAppletAdded: { var component = Qt.createComponent("items/PlasmoidItem.qml") var plasmoidContainer = component.createObject(invisibleEntriesContainer, {"x": x, "y": y, "applet": applet}); applet.parent = plasmoidContainer applet.anchors.left = plasmoidContainer.left applet.anchors.top = plasmoidContainer.top applet.anchors.bottom = plasmoidContainer.bottom applet.width = plasmoidContainer.height applet.visible = true plasmoidContainer.visible = true } Containment.onAppletRemoved: { } Connections { target: plasmoid onUserConfiguringChanged: { if (plasmoid.userConfiguring) { dialog.visible = false } } } Connections { target: plasmoid.configuration onExtraItemsChanged: plasmoid.nativeInterface.allowedPlasmoids = plasmoid.configuration.extraItems } Component.onCompleted: { //script, don't bind plasmoid.nativeInterface.allowedPlasmoids = initializePlasmoidList(); } function initializePlasmoidList() { var newKnownItems = []; var newExtraItems = []; //NOTE:why this? otherwise the interpreter will execute plasmoid.nativeInterface.defaultPlasmoids() on //every access of defaults[], resulting in a very slow iteration var defaults = []; //defaults = defaults.concat(plasmoid.nativeInterface.defaultPlasmoids); defaults = plasmoid.nativeInterface.defaultPlasmoids.slice() var candidate; //Add every plasmoid that is both not enabled explicitly and not already known for (var i = 0; i < defaults.length; ++i) { candidate = defaults[i]; if (plasmoid.configuration.knownItems.indexOf(candidate) === -1) { newKnownItems.push(candidate); if (plasmoid.configuration.extraItems.indexOf(candidate) === -1) { newExtraItems.push(candidate); } } } if (newExtraItems.length > 0) { plasmoid.configuration.extraItems = plasmoid.configuration.extraItems.slice().concat(newExtraItems); } if (newKnownItems.length > 0) { plasmoid.configuration.knownItems = plasmoid.configuration.knownItems.slice().concat(newKnownItems); } return plasmoid.configuration.extraItems; } PlasmaCore.DataSource { id: statusNotifierSource engine: "statusnotifieritem" interval: 0 onSourceAdded: { connectSource(source) } Component.onCompleted: { connectedSources = sources } } //due to the magic of property bindings this function will be //re-executed all the times a setting changes property var shownCategories: { var array = []; if (plasmoid.configuration.applicationStatusShown) { array.push("ApplicationStatus"); } if (plasmoid.configuration.communicationsShown) { array.push("Communications"); } if (plasmoid.configuration.systemServicesShown) { array.push("SystemServices"); } if (plasmoid.configuration.hardwareControlShown) { array.push("Hardware"); } if (plasmoid.configuration.miscellaneousShown) { array.push("UnknownCategory"); } //nothing? make a regexp that matches nothing if (array.length == 0) { array.push("$^") } return array; } PlasmaCore.SortFilterModel { id: statusNotifierModel sourceModel: PlasmaCore.DataModel { dataSource: statusNotifierSource } } //This is a dump for items we don't want to be seen or as an incubation, when they are //created as a nursery before going in their final place Item { id: invisibleEntriesContainer visible: false Repeater { id: tasksRepeater model: statusNotifierModel delegate: StatusNotifierItem {} } //NOTE: this exists mostly for not causing reference errors property QtObject marginHints: QtObject { property int left: 0 property int top: 0 property int right: 0 property int bottom: 0 } } CurrentItemHighLight { visualParent: tasksRow target: root.activeApplet && root.activeApplet.parent.parent == tasksRow ? root.activeApplet.parent : root location: plasmoid.location } //Main Layout Flow { id: tasksRow spacing: 0 height: parent.height - (vertical ? expander.height : 0) width: parent.width - (vertical ? 0 : expander.width) property string skipItems flow: vertical ? Flow.LeftToRight : Flow.TopToBottom //To make it look centered y: Math.round(height/2 - childrenRect.height/2) x: Math.round(width/2 - childrenRect.width/2) //Do spacing with margins, to correctly compute the number of lines property QtObject marginHints: QtObject { property int left: Math.round(units.smallSpacing / 2) property int top: Math.round(units.smallSpacing / 2) property int right: Math.round(units.smallSpacing / 2) property int bottom: Math.round(units.smallSpacing / 2) } //add doesn't seem to work used in conjunction with stackBefore/stackAfter /*add: Transition { NumberAnimation { property: "scale" from: 0 to: 1 easing.type: Easing.InQuad duration: units.longDuration } } move: Transition { NumberAnimation { properties: "x,y" easing.type: Easing.InQuad duration: units.longDuration } }*/ } ExpanderArrow { id: expander anchors { fill: parent leftMargin: vertical ? 0 : parent.width - implicitWidth topMargin: vertical ? parent.height - implicitHeight : 0 } } //Main popup PlasmaCore.Dialog { id: dialog visualParent: root flags: Qt.WindowStaysOnTopHint location: plasmoid.location hideOnWindowDeactivate: expandedRepresentation.hideOnWindowDeactivate onVisibleChanged: { if (!visible) { plasmoid.status = PlasmaCore.Types.PassiveStatus; if (root.activeApplet) { root.activeApplet.expanded = false; } } else { plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus; } } mainItem: ExpandedRepresentation { id: expandedRepresentation activeApplet: root.activeApplet + + LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft + LayoutMirroring.childrenInherit: true } } }