color picker: remove recent colors with a hover button, delete or backspace (#3764)

* color picker: remove recent colors with right-click or delete

* color picker: remove recent colors with a hover button, delete or backspace
This commit is contained in:
Mario Mohar
2026-10-13 21:06:02 -04:00
committed by GitHub
parent 57cfb5e493
commit 699eb23775
4 changed files with 96 additions and 5 deletions
+9
View File
@@ -1512,6 +1512,15 @@ Singleton {
saveSettings();
}
function removeRecentColor(color) {
const colorStr = color.toString();
const recent = recentColors.filter(c => c !== colorStr);
if (recent.length === recentColors.length)
return;
recentColors = recent;
saveSettings();
}
function setShowThirdPartyPlugins(enabled) {
showThirdPartyPlugins = enabled;
saveSettings();
+6 -1
View File
@@ -42,7 +42,12 @@ DModal {
shouldBeVisible ? hideInstant() : show();
}
onSelectedColorChanged: contentLoader?.item?.setColor(selectedColor)
// show() applies selectedColor on open. While the picker is open, a change to the
// recent colors (which selectedColor follows) must not reset the color being edited.
onSelectedColorChanged: {
if (!shouldBeVisible)
contentLoader?.item?.setColor(selectedColor);
}
onBackgroundClicked: hide()
onOpened: Qt.callLater(() => contentLoader?.item?.focusInitial())
onDialogClosed: {
@@ -388,11 +388,46 @@ DDialog {
Repeater {
model: SessionData.recentColors.slice(0, 5)
CommonWidgets.DColorButton {
Item {
id: recentSwatch
required property var modelData
swatchColor: modelData
selected: Qt.colorEqual(root.currentColor, swatchColor)
onClicked: root.setColor(swatchColor)
implicitWidth: recentButton.implicitWidth
implicitHeight: recentButton.implicitHeight
HoverHandler {
id: recentHover
}
CommonWidgets.DColorButton {
id: recentButton
anchors.fill: parent
swatchColor: recentSwatch.modelData
selected: Qt.colorEqual(root.currentColor, swatchColor)
onClicked: root.setColor(swatchColor)
Keys.onDeletePressed: SessionData.removeRecentColor(recentSwatch.modelData)
Keys.onPressed: event => {
if (event.key !== Qt.Key_Backspace)
return;
SessionData.removeRecentColor(recentSwatch.modelData);
event.accepted = true;
}
}
CommonWidgets.DActionButton {
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: -Theme.spacingXS
buttonSize: Theme.iconSizeSmall + Theme.spacingXS
iconSize: Theme.iconSizeSmall - Theme.spacingXS
iconName: "close"
backgroundColor: Theme.surfaceContainerHighest
focusPolicy: Qt.NoFocus
visible: recentHover.hovered
tooltipText: I18n.tr("Remove from recent colors", "button on a recently picked color swatch")
onClicked: SessionData.removeRecentColor(recentSwatch.modelData)
}
}
}
}
@@ -0,0 +1,42 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import vm from "node:vm";
import test from "node:test";
const source = readFileSync(new URL("../Common/SessionData.qml", import.meta.url), "utf8");
function session(recentColors) {
const context = vm.createContext({ recentColors, saves: 0 });
vm.runInContext("function saveSettings() { saves++; }", context);
const methods = ["addRecentColor", "removeRecentColor"];
const found = [];
for (const match of source.matchAll(/^ function (\w+)\([^\n]*\)(?:: \w+)? \{\n[\s\S]*?^ \}/gm)) {
if (!methods.includes(match[1]))
continue;
found.push(match[1]);
vm.runInContext(match[0], context);
}
assert.deepEqual(found.sort(), [...methods].sort());
return context;
}
test("removing a recent color drops only that color and saves", () => {
const context = session(["#ff0000", "#00ff00", "#0000ff"]);
context.removeRecentColor("#00ff00");
assert.deepEqual(Array.from(context.recentColors), ["#ff0000", "#0000ff"]);
assert.equal(context.saves, 1);
});
test("removing a color that is not in the list changes nothing", () => {
const context = session(["#ff0000"]);
context.removeRecentColor("#123456");
assert.deepEqual(Array.from(context.recentColors), ["#ff0000"]);
assert.equal(context.saves, 0);
});
test("a removed color can be picked again and comes back first", () => {
const context = session(["#ff0000", "#00ff00"]);
context.removeRecentColor("#ff0000");
context.addRecentColor("#ff0000");
assert.deepEqual(Array.from(context.recentColors), ["#ff0000", "#00ff00"]);
});