Skip to content

Commit

Permalink
Add color setting functionality by color name to the color picker
Browse files Browse the repository at this point in the history
This is not a function that makes the color picker output the color
name, but a function that changes the current color of the color
picker by specifying a color name. The color names that can be
specified are not limited to the color names defined by Emacs or
CSS. You can use your favorite color swatches by changing the
edraw-color-read-name-sources variable.
  • Loading branch information
misohena committed Feb 21, 2025
1 parent 838ecce commit 408d2d0
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 2 deletions.
14 changes: 12 additions & 2 deletions edraw-color-picker.el
Original file line number Diff line number Diff line change
Expand Up @@ -1910,6 +1910,13 @@ but the reverse can also be done."
(/ value 255.0)
value))))

(defun edraw-color-picker-set-color-by-name-read ()
(interactive)
(when-let* ((picker
(edraw-color-picker-at-input-or-error last-command-event))
(color-name-source
(edraw-color-read-color-by-name (edraw-msg "Color Name: "))))
(edraw-set-current-color picker (car color-name-source))))

(defun edraw-color-picker-define-keys-for-color-set (km
&optional
Expand All @@ -1927,7 +1934,9 @@ but the reverse can also be done."
(define-key km (kb "g") '("Green" . edraw-color-picker-set-color-green))
(define-key km (kb "b") '("Blue" . edraw-color-picker-set-color-blue))
(define-key km (kb "a") '("Opacity" . edraw-color-picker-set-opacity))
(define-key km (kb "o") '("Opacity" . edraw-color-picker-set-opacity))))
(define-key km (kb "o") '("Opacity" . edraw-color-picker-set-opacity))
(define-key km (kb "n") '("Color Name"
. edraw-color-picker-set-color-by-name-read))))

;;;;; Palette

Expand Down Expand Up @@ -2096,7 +2105,8 @@ but the reverse can also be done."
((edraw-msg "Opacity...") edraw-color-picker-set-opacity)
((edraw-msg "Hue...") edraw-color-picker-set-color-hue)
((edraw-msg "Saturation...") edraw-color-picker-set-color-saturation)
((edraw-msg "Brightness...") edraw-color-picker-set-color-brightness)))
((edraw-msg "Brightness...") edraw-color-picker-set-color-brightness)
((edraw-msg "Color Name...") edraw-color-picker-set-color-by-name-read)))
;; For displaying key bindings to users (not for actual use)
((edraw-msg "Increase/Decrease")
(((format (edraw-msg "Increase X by %d")
Expand Down
121 changes: 121 additions & 0 deletions edraw-color.el
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,12 @@ Signals an error if something unexpected occurs and never returns nil."

;;;;;; Color names

(defun edraw-color-emacs-color-name-alist ()
"Return an alist of colors defined by Emacs and `edraw-color' objects."
(mapcar (lambda (name)
(cons name (apply #'edraw-color-f (color-name-to-rgb name))))
(defined-colors)))

(defun edraw-color-from-emacs-color-name (name)
"Convert a Emacs color name to an `edraw-color' object."
(when-let* ((rgb (color-name-to-rgb name)))
Expand Down Expand Up @@ -959,6 +965,13 @@ Signals an error if there is a syntax or other problem, never returns nil."
("transparent" . "#00000000"))
"An alist of CSS color names and their associated hex color values.")

(defun edraw-color-css-color-name-alist ()
"Return an alist of colors defined by CSS and `edraw-color' objects."
(mapcar (lambda (name-hex)
(cons (car name-hex)
(edraw-color-from-hex-string (cdr name-hex))))
edraw-color-css-color-names))

(defun edraw-color-css-color-name-to-hex-color (name)
"Convert a CSS color name to a HEX color."
(alist-get name edraw-color-css-color-names nil nil 'string=))
Expand Down Expand Up @@ -2053,5 +2066,113 @@ is assumed to be specified."
;; TEST: (edraw-color-info-from-string "Dust hsl( 30 50 50) dust " 4 'css " *\\'") => nil


;;;; Read Color Name

(defvar edraw-color-read-name-sources
'(("emacs" . edraw-color-emacs-color-name-alist)
("css" . edraw-color-css-color-name-alist)
;; You may add various color swatches here.
))

(defvar edraw-color-read-name--align-pos 0)
(defvar edraw-color-read-name--align-str nil)

(defface edraw-color-read-name-annotation
'((t))
"Face used to color annotations."
:group 'edraw)

(defun edraw-color-read-name--annotate-color (color)
(propertize
(concat
(edraw-to-string-hex color)
" "
(let ((hsl (edraw-color-to-hsl-list color)))
(format "%3%3d%% %3d%%"
(round (car hsl))
(round (* 100 (cadr hsl)))
(round (* 100 (caddr hsl))))))
'face 'edraw-color-read-name-annotation))

(defvar edraw-color-read-name-annotator
#'edraw-color-read-name--annotate-color)

(defun edraw-color-read-name--annotate-name (name)
(pcase (get-text-property 0 'edraw-color-name-source name)
(`(,color ,_name ,_source)
(concat
edraw-color-read-name--align-str
(truncate-string-to-width
(funcall edraw-color-read-name-annotator color)
(max 0
(- (window-width (minibuffer-window))
edraw-color-read-name--align-pos
2)))))))

(defun edraw-color-read-color-by-name (&optional prompt sources)
"Read a color name and return the information of that color.
This function is intended to provide a way to specify colors by color
names defined by various color sets. It is not intended to read the
color names themselves.
Return (COLOR COLOR-NAME COLOR-SOURCE), where COLOR is an `edraw-color'
object, COLOR-NAME is the color name string, and COLOR-SOURCE is the
string that is the key of the SOURCES alist.
If SOURCES is nil, the alist specified in
`edraw-color-read-name-sources' is used."
(unless sources (setq sources edraw-color-read-name-sources))
(let* ((names
(cl-loop
for (source-name . source-def) in sources
for alist = (cond
((functionp source-def)
(funcall source-def))
((and (symbolp source-def) (boundp source-def))
(symbol-value source-def))
(t source-def))
nconc
(cl-loop for (color-name . color) in alist
do (setq color
(cond
((stringp color)
(edraw-color-from-string color))
((cl-typep color 'edraw-color)
color)))
when color
collect (propertize
(concat source-name "/" color-name)
'face (list
:background (edraw-to-string-hex color)
:foreground (if (> (edraw-relative-luminance
color)
0.5)
"#000000" "#ffffff"))
'edraw-color-name-source
(list color color-name source-name)))))
(align-pos (1+ (cl-loop for str in names maximize (string-width str))))
(edraw-color-read-name--align-pos align-pos)
(edraw-color-read-name--align-str
(propertize " " 'display `(space :align-to ,align-pos)))
(selected-name
(completing-read (or prompt "Color Name: ")
(lambda (string pred action)
(if (eq action 'metadata)
`(metadata
;; Prevent overwriting by `marginalia-mode'.
;; See `marginalia-prompt-categories'
(category . edraw-color-source-and-name)
(annotation-function
. ,#'edraw-color-read-name--annotate-name))
(complete-with-action action names string pred)))
nil t)))
(unless (string-empty-p selected-name)
(when-let* ((selected-name-with-props (car (member selected-name names))))
(get-text-property 0 'edraw-color-name-source
selected-name-with-props)))))
;; EXAMPLE: (edraw-color-read-color-by-name)
;; EXAMPLE: (edraw-color-read-color-by-name nil '(("monochrome" ("gray-1" . "#111") ("gray-8" . "#888") ("gray-15" . "#fff"))))

(provide 'edraw-color)
;;; edraw-color.el ends here
2 changes: 2 additions & 0 deletions msg/edraw-msg-ja.el
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@
"Closed" "閉じました"
"Coil Line" "コイル線"
"Color Components" "色成分"
"Color Name..." "色名..."
"Color Picker Menu" "カラーピッカーメニュー"
"Color Name: " "色名: "
"Color" ""
"Combine Paths" "パスの結合"
"Connected" "接続しました"
Expand Down
11 changes: 11 additions & 0 deletions todo.org
Original file line number Diff line number Diff line change
Expand Up @@ -6606,3 +6606,14 @@ CLOSED: [2025-02-17 Mon 11:13]
一応メニューから分かるようにした。

[[*色/カラーピッカーから出力する形式を変更できるようにする][色/カラーピッカーから出力する形式を変更できるようにする]]
** DONE 色/カラーピッカーで様々な色名から色を設定できるようにする。
CLOSED: [2025-02-21 Fri 14:50]
色名を設定するのではなく、色名から色を検索して設定できるようにする。

これは色名を入力することが目的では無い。あくまで色名を使って色を入力することが目的。

検索できる色名はEmacsやCSSに限定されない。様々な色見本の色名を検索できる柔軟性を持たせる。

色名の頭には色ソースを識別する接頭辞を追加する。css/green, emacs/greenのように。

現在のsyntax-systemが何であろうと、全ての色名で検索できる。

0 comments on commit 408d2d0

Please sign in to comment.