Warning, /plasma/kdeplasma-addons/applets/colorpicker/package/contents/ui/main.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 0008 import QtQuick.Controls as QQC2 0009 import QtQuick.Layouts 0010 import QtQuick.Dialogs as QtDialogs 0011 0012 import org.kde.plasma.plasmoid 2.0 0013 import org.kde.plasma.core as PlasmaCore 0014 import org.kde.plasma.components 3.0 as PlasmaComponents3 0015 import org.kde.plasma.extras 2.0 as PlasmaExtras 0016 import org.kde.kirigami 2.20 as Kirigami 0017 import org.kde.kcmutils as KCMUtils 0018 import org.kde.config as KConfig 0019 import org.kde.kwindowsystem 1.0 0020 0021 import org.kde.plasma.private.colorpicker 2.0 as ColorPicker 0022 import "logic.js" as Logic 0023 0024 PlasmoidItem { 0025 id: root 0026 0027 readonly property bool isVertical: Plasmoid.formFactor === PlasmaCore.Types.Vertical 0028 0029 readonly property color recentColor: historyModel.count > 0 ? historyModel.get(0).color : "#00000000" // transparent as fallback 0030 readonly property string defaultFormat: Plasmoid.configuration.defaultFormat 0031 readonly property int maxColorCount: 9 0032 0033 preferredRepresentation: compactRepresentation 0034 0035 function addColorToHistory(color) { 0036 // this .toString() is needed otherwise Qt completely screws it up 0037 // replacing *all* items in the list by the new items and other nonsense 0038 historyModel.insert(0, { color: color.toString() }); 0039 // limit to 9 entries 0040 if (historyModel.count > maxColorCount) { 0041 historyModel.remove(maxColorCount); 0042 } 0043 historyModel.save(); 0044 } 0045 0046 function colorPicked(color) { 0047 if (color != recentColor) { 0048 addColorToHistory(color) 0049 } 0050 0051 if (Plasmoid.configuration.autoClipboard) { 0052 picker.copyToClipboard(Logic.formatColor(color, root.defaultFormat)) 0053 } 0054 } 0055 0056 function pickColor() { 0057 root.expanded = false 0058 picker.pick() 0059 } 0060 0061 ColorPicker.GrabWidget { 0062 id: picker 0063 onCurrentColorChanged: colorPicked(currentColor) 0064 } 0065 0066 Component { 0067 id: colorWindowComponent 0068 0069 Window { // QTBUG-119055 0070 id: window 0071 width: Kirigami.Units.gridUnit * 19 0072 height: Kirigami.Units.gridUnit * 23 0073 visible: true 0074 title: Plasmoid.title 0075 QtDialogs.ColorDialog { 0076 id: colorDialog 0077 title: Plasmoid.title 0078 selectedColor: historyModel.count > 0 ? root.recentColor : undefined /* Prevent transparent colors */ 0079 onAccepted: { 0080 root.colorPicked(selectedColor); 0081 window.destroy(); 0082 } 0083 onRejected: window.destroy() 0084 } 0085 onClosing: destroy() 0086 Component.onCompleted: colorDialog.open() 0087 } 0088 } 0089 0090 // prevents the popup from actually opening, needs to be queued 0091 Timer { 0092 id: delayedPickTimer 0093 interval: 0 0094 onTriggered: root.pickColor() 0095 } 0096 0097 ListModel { 0098 id: historyModel 0099 0100 function save() { 0101 let history = []; 0102 for (let i = 0; i < count; i++) { 0103 history.push(get(i).color); 0104 } 0105 Plasmoid.configuration.history = history; 0106 } 0107 } 0108 0109 Plasmoid.onActivated: { 0110 if (Plasmoid.configuration.pickOnActivate) { 0111 delayedPickTimer.start(); 0112 } 0113 } 0114 0115 Plasmoid.contextualActions: [ 0116 PlasmaCore.Action { 0117 text: i18nc("@action", "Open Color Dialog") 0118 icon.name: "color-management" 0119 onTriggered: colorWindowComponent.createObject(root) 0120 }, 0121 PlasmaCore.Action { 0122 text: i18nc("@action", "Clear History") 0123 icon.name: "edit-clear-history" 0124 onTriggered: { 0125 historyModel.clear(); 0126 historyModel.save(); 0127 } 0128 }, 0129 PlasmaCore.Action { 0130 text: i18nc("@action", "View History") 0131 icon.name: "view-history" 0132 onTriggered: root.expanded = true 0133 } 0134 ] 0135 0136 Component.onCompleted: { 0137 Plasmoid.configuration.history.forEach(item => historyModel.append({ color: item })); 0138 Logic.copyToClipboardText = i18ndc("plasma_applet_org.kde.plasma.colorpicker", "@title:menu", "Copy to Clipboard"); // i18n is not supported in js library 0139 } 0140 0141 compactRepresentation: CompactRepresentation { } 0142 0143 fullRepresentation: GridView { 0144 id: fullRoot 0145 0146 readonly property int columns: 3 0147 0148 Layout.minimumWidth: columns * Kirigami.Units.gridUnit * 6 0149 Layout.minimumHeight: Layout.minimumWidth 0150 Layout.maximumWidth: Layout.minimumWidth 0151 Layout.maximumHeight: Layout.minimumHeight 0152 0153 cellWidth: Math.floor(fullRoot.width / fullRoot.columns) 0154 cellHeight: cellWidth 0155 boundsBehavior: Flickable.StopAtBounds 0156 0157 model: historyModel 0158 0159 highlight: PlasmaExtras.Highlight {} 0160 highlightMoveDuration: 0 0161 0162 Loader { 0163 width: parent.width - Kirigami.Units.gridUnit * 2 0164 anchors.centerIn: parent 0165 visible: active 0166 0167 active: fullRoot.count === 0 && root.expanded 0168 asynchronous: true 0169 0170 sourceComponent: PlasmaExtras.PlaceholderMessage { 0171 id: emptyHint 0172 0173 opacity: 0 0174 iconName: "edit-none" 0175 0176 readonly property bool compositingActive: KWindowSystem.isPlatformWayland || KX11Extras.compositingActive 0177 0178 text: compositingActive ? i18nc("@info:usagetip", "No colors") : i18nc("@info:status when color picking is unavailable", "Color picking unavailable when compositing is disabled") 0179 explanation: compositingActive ? "" : i18nc("@info:status when color pick is unavailable", "Compositing has been manually disabled or blocked by a running application") 0180 0181 helpfulAction: compositingActive ? pickColorAction : enableCompositingAction 0182 0183 QQC2.Action { 0184 id: pickColorAction 0185 icon.name: "color-picker" 0186 text: i18nc("@action:button", "Pick Color") 0187 onTriggered: root.pickColor() 0188 } 0189 0190 QQC2.Action { 0191 id: enableCompositingAction 0192 enabled: KConfig.KAuthorized.authorizeControlModule("kwincompositing") 0193 icon.name: "settings-configure" 0194 text: i18nc("@action:button open kwincompositing KCM", "Configure Compositing") 0195 onTriggered: KCMUtils.KCMLauncher.openSystemSettings("kwincompositing") 0196 } 0197 0198 NumberAnimation { 0199 duration: Kirigami.Units.longDuration 0200 easing.type: Easing.OutCubic 0201 property: "opacity" 0202 running: true 0203 target: emptyHint 0204 to: 1 0205 } 0206 } 0207 } 0208 0209 Connections { 0210 target: root 0211 function onExpandedChanged() { 0212 if (root.expanded) { 0213 fullRoot.forceActiveFocus() 0214 } 0215 } 0216 } 0217 0218 Keys.onPressed: event => { 0219 if (event.key === Qt.Key_Escape) { 0220 root.expanded = false; 0221 event.accepted = true; 0222 } 0223 } 0224 0225 // This item serves as a drag pixmap and is captured when a drag starts 0226 Rectangle { 0227 id: dragImageDummy 0228 border { 0229 color: Kirigami.Theme.textColor 0230 width: 1 0231 } 0232 radius: width 0233 width: Kirigami.Units.iconSizes.large 0234 height: Kirigami.Units.iconSizes.large 0235 visible: false 0236 } 0237 0238 delegate: MouseArea { 0239 id: delegateMouse 0240 0241 readonly property color currentColor: model.color 0242 0243 width: fullRoot.cellWidth 0244 height: fullRoot.cellHeight 0245 0246 drag.target: rect 0247 Drag.dragType: Drag.Automatic 0248 Drag.active: delegateMouse.drag.active 0249 Drag.mimeData: { 0250 "application/x-color": rect.color, 0251 "text/plain": colorLabel.text 0252 } 0253 0254 acceptedButtons: Qt.LeftButton | Qt.RightButton 0255 hoverEnabled: true 0256 0257 Keys.onDeletePressed: event => remove() 0258 Keys.onPressed: event => { 0259 switch (event.key) { 0260 case Qt.Key_Space: 0261 case Qt.Key_Enter: 0262 case Qt.Key_Return: 0263 case Qt.Key_Select: 0264 copy(); 0265 break; 0266 case Qt.Key_Menu: 0267 openMenu(); 0268 break; 0269 } 0270 } 0271 0272 Accessible.name: colorLabel.text 0273 Accessible.role: Accessible.ButtonMenu 0274 0275 onContainsMouseChanged: { 0276 if (containsMouse) { 0277 fullRoot.currentIndex = index; 0278 } else if (fullRoot.currentIndex === index) { 0279 fullRoot.currentIndex = -1; 0280 } 0281 } 0282 0283 onPressed: mouse => { 0284 // grab pixmap only once 0285 if (Drag.imageSource.toString() === "") { // cannot just do !Drag.imageSource on QUrl 0286 dragImageDummy.color = currentColor; 0287 dragImageDummy.grabToImage(result => { 0288 Drag.imageSource = result.url; 0289 }); 0290 } 0291 } 0292 0293 onClicked: mouse => { 0294 if (mouse.button === Qt.LeftButton) { 0295 copy(); 0296 } else if (mouse.button === Qt.RightButton) { 0297 openMenu(); 0298 } 0299 } 0300 0301 function copy() { 0302 picker.copyToClipboard(Logic.formatColor(currentColor, root.defaultFormat)) 0303 colorLabel.visible = false; 0304 copyIndicatorLabel.visible = true; 0305 colorLabelRestoreTimer.start() 0306 } 0307 0308 function openMenu() { 0309 const menu = Logic.createContextMenu(this, currentColor, picker, colorLabel, copyIndicatorLabel, colorLabelRestoreTimer); 0310 menu.openRelative(); 0311 } 0312 0313 function remove() { 0314 historyModel.remove(index); 0315 historyModel.save(); 0316 } 0317 0318 PlasmaCore.ToolTipArea { 0319 anchors.fill: parent 0320 active: colorLabel.truncated 0321 mainText: colorLabel.text 0322 } 0323 0324 Timer { 0325 id: colorLabelRestoreTimer 0326 interval: Kirigami.Units.humanMoment 0327 onTriggered: { 0328 colorLabel.visible = true; 0329 copyIndicatorLabel.visible = false; 0330 } 0331 } 0332 0333 Rectangle { 0334 id: rect 0335 0336 anchors { 0337 fill: parent 0338 margins: Kirigami.Units.smallSpacing 0339 } 0340 0341 color: delegateMouse.currentColor 0342 0343 border { 0344 color: Kirigami.Theme.textColor 0345 width: 1 0346 } 0347 0348 Rectangle { 0349 anchors { 0350 bottom: parent.bottom 0351 left: parent.left 0352 right: parent.right 0353 margins: rect.border.width 0354 } 0355 height: colorLabel.contentHeight + 2 * Kirigami.Units.smallSpacing 0356 color: Kirigami.Theme.backgroundColor 0357 opacity: 0.8 0358 0359 PlasmaComponents3.Label { 0360 id: colorLabel 0361 anchors.fill: parent 0362 horizontalAlignment: Text.AlignHCenter 0363 verticalAlignment: Text.AlignVCenter 0364 elide: Text.ElideLeft 0365 fontSizeMode: Text.HorizontalFit 0366 minimumPointSize: Kirigami.Theme.smallFont.pointSize 0367 text: Logic.formatColor(delegateMouse.currentColor, root.defaultFormat) 0368 textFormat: Text.PlainText 0369 } 0370 0371 PlasmaComponents3.Label { 0372 id: copyIndicatorLabel 0373 visible: false 0374 anchors.fill: parent 0375 horizontalAlignment: Text.AlignHCenter 0376 verticalAlignment: Text.AlignVCenter 0377 elide: Text.ElideLeft 0378 fontSizeMode: Text.HorizontalFit 0379 minimumPointSize: Kirigami.Theme.smallFont.pointSize 0380 text: i18nc("@info:progress just copied a color to clipboard", "Copied!") 0381 textFormat: Text.PlainText 0382 } 0383 } 0384 } 0385 0386 Loader { 0387 active: parent.containsMouse || Kirigami.Settings.tabletMode || Kirigami.Settings.hasTransientTouchInput 0388 anchors.right: parent.right 0389 anchors.top: parent.top 0390 sourceComponent: PlasmaComponents3.Button { 0391 text: i18nc("@action:button", "Delete") 0392 icon.name: "delete" 0393 display: PlasmaComponents3.AbstractButton.IconOnly 0394 0395 onClicked: delegateMouse.remove() 0396 0397 PlasmaComponents3.ToolTip { 0398 text: parent.text 0399 } 0400 } 0401 } 0402 } 0403 } 0404 }