show a palette for current editor in color picker (#1068)
also keep the dialog visible for 30 seconds instead of 5
This commit is contained in:
parent
e6d73be049
commit
3cb9cbb862
|
@ -20,13 +20,11 @@
|
|||
defaults.extraKeys[keyName] = 'colorpicker';
|
||||
}
|
||||
defaults.colorpicker = {
|
||||
// FIXME: who uses this?
|
||||
// forceUpdate: editor.getEditors().length > 0,
|
||||
tooltip: t('colorpickerTooltip'),
|
||||
popup: {
|
||||
tooltipForSwitcher: t('colorpickerSwitchFormatTooltip'),
|
||||
hexUppercase: prefs.get('editor.colorpicker.hexUppercase'),
|
||||
hideDelay: 5000,
|
||||
hideDelay: 30e3,
|
||||
embedderCallback: state => {
|
||||
['hexUppercase', 'color']
|
||||
.filter(name => state[name] !== prefs.get('editor.colorpicker.' + name))
|
||||
|
|
|
@ -357,3 +357,15 @@
|
|||
.colorpicker-format-change-button:hover {
|
||||
color: var(--label-color-hover);
|
||||
}
|
||||
|
||||
.colorpicker-palette:not(:empty) {
|
||||
padding: 0 8px 8px;
|
||||
min-height: 14px; /* same as padding-left in .colorview-swatch */
|
||||
max-height: 10vw;
|
||||
overflow: auto;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.colorpicker-palette .colorview-swatch {
|
||||
padding-bottom: 14px; /* same as padding-left in .colorview-swatch */
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
let $swatch;
|
||||
let $formatChangeButton;
|
||||
let $hexCode;
|
||||
let $palette;
|
||||
const $inputGroups = {};
|
||||
const $inputs = {};
|
||||
const $rgb = {};
|
||||
|
@ -164,6 +165,7 @@
|
|||
$formatChangeButton = $('format-change-button', {textContent: '↔'}),
|
||||
]}),
|
||||
]}),
|
||||
$palette = $('palette'),
|
||||
]});
|
||||
|
||||
$inputs.hex = [$hexCode];
|
||||
|
@ -221,6 +223,11 @@
|
|||
if (!isNaN(options.left) && !isNaN(options.top)) {
|
||||
reposition();
|
||||
}
|
||||
if (Array.isArray(options.palette)) {
|
||||
// Might need to clear a lot of elements so this is known to be faster than textContent = ''
|
||||
while ($palette.firstChild) $palette.firstChild.remove();
|
||||
$palette.append(...(options.palette));
|
||||
}
|
||||
}
|
||||
|
||||
function hide() {
|
||||
|
@ -454,7 +461,7 @@
|
|||
const newHSV = color.type === 'hsl' ?
|
||||
colorConverter.HSLtoHSV(color) :
|
||||
colorConverter.RGBtoHSV(color);
|
||||
if (Object.keys(newHSV).every(k => Math.abs(newHSV[k] - HSV[k]) < 1e-3)) {
|
||||
if (Object.entries(newHSV).every(([k, v]) => v === HSV[k] || Math.abs(v - HSV[k]) < 1e-3)) {
|
||||
return;
|
||||
}
|
||||
HSV = newHSV;
|
||||
|
@ -574,6 +581,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
/** @param {MouseEvent} e */
|
||||
function onPaletteClicked(e) {
|
||||
if (e.target !== e.currentTarget) {
|
||||
e.preventDefault();
|
||||
if (!e.button && setColor(e.target.__color)) {
|
||||
userActivity = performance.now();
|
||||
colorpickerCallback();
|
||||
} else if (e.button === 2 && options.paletteCallback) {
|
||||
options.paletteCallback(e.target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseUp(event) {
|
||||
releaseMouse(event, ['saturation', 'hue', 'opacity']);
|
||||
if (onMouseDown.outsideClick) {
|
||||
|
@ -710,6 +730,8 @@
|
|||
$opacity.addEventListener('mousedown', onOpacityMouseDown);
|
||||
$hexLettercase.true.addEventListener('click', onHexLettercaseClicked);
|
||||
$hexLettercase.false.addEventListener('click', onHexLettercaseClicked);
|
||||
$palette.addEventListener('click', onPaletteClicked);
|
||||
$palette.addEventListener('contextmenu', onPaletteClicked);
|
||||
|
||||
stopSnoozing();
|
||||
if (!options.isShortCut) {
|
||||
|
@ -735,6 +757,8 @@
|
|||
$opacity.removeEventListener('mousedown', onOpacityMouseDown);
|
||||
$hexLettercase.true.removeEventListener('click', onHexLettercaseClicked);
|
||||
$hexLettercase.false.removeEventListener('click', onHexLettercaseClicked);
|
||||
$palette.removeEventListener('click', onPaletteClicked);
|
||||
$palette.removeEventListener('contextmenu', onPaletteClicked);
|
||||
releaseMouse();
|
||||
stopSnoozing();
|
||||
}
|
||||
|
|
|
@ -532,6 +532,8 @@
|
|||
color: data.color,
|
||||
prevColor: data.color || '',
|
||||
callback: popupOnChange,
|
||||
palette: makePalette(state),
|
||||
paletteCallback: el => paletteCallback(state, el),
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -551,6 +553,49 @@
|
|||
}
|
||||
}
|
||||
|
||||
function makePalette({cm, options}) {
|
||||
const palette = new Map();
|
||||
let i = 0;
|
||||
let nums;
|
||||
cm.eachLine(({markedSpans}) => {
|
||||
++i;
|
||||
if (!markedSpans) return;
|
||||
for (const {from, marker: m} of markedSpans) {
|
||||
if (from == null || m.className !== COLORVIEW_CLASS) continue;
|
||||
nums = palette.get(m.color);
|
||||
if (!nums) palette.set(m.color, (nums = []));
|
||||
nums.push(i);
|
||||
}
|
||||
});
|
||||
const res = [];
|
||||
if (palette.size > 1 || nums && nums.length > 1) {
|
||||
const old = new Map((options.popup.palette || []).map(el => [el.__color, el]));
|
||||
for (const [color, data] of palette) {
|
||||
res.push(old.get(color) || makePaletteSwatch(color, data));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function makePaletteSwatch(color, nums) {
|
||||
const s = nums.join(', ');
|
||||
const el = document.createElement('div');
|
||||
el.className = COLORVIEW_SWATCH_CLASS;
|
||||
el.style.cssText = COLORVIEW_SWATCH_CSS + color;
|
||||
el.title = color + (!s ? '' : `\nLine: ${s.length > 50 ? s.replace(/([^,]+,\s){10}/g, '$&\n') : s}`);
|
||||
el.__color = color;
|
||||
return el;
|
||||
}
|
||||
|
||||
function paletteCallback({cm}, el) {
|
||||
const lines = el.title.split('\n')[1].match(/\d+/g).map(Number);
|
||||
const curLine = cm.getCursor().line + 1;
|
||||
const i = lines.indexOf(curLine) + 1;
|
||||
const pos = {line: (lines[i] || curLine) - 1, ch: 0};
|
||||
cm.scrollIntoView(pos, cm.defaultTextHeight());
|
||||
cm.setCursor(pos);
|
||||
}
|
||||
|
||||
//endregion
|
||||
//region Utility
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user