Skip to content

Commit

Permalink
Ensure color format in color palette
Browse files Browse the repository at this point in the history
  • Loading branch information
misohena committed Feb 16, 2025
1 parent 1cac453 commit 1dcc021
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 26 deletions.
59 changes: 42 additions & 17 deletions edraw-color-picker.el
Original file line number Diff line number Diff line change
Expand Up @@ -359,13 +359,24 @@

;;;;; Palette Model

(defun edraw-color-picker-normalize-color-string (color)
"Return normalized COLOR string."
(defun edraw-color-picker-palette-color-to-string (color)
"Convert COLOR into a string for storing in
`edraw-color-picker-palette-model'.
COLOR must be an `edraw-color' or a string.
If it is a string, it must be in one of the following forms:
- #RRGGBB
- #RRGGBBAA
- rgba(R,G,B,A)
Do not pass a color name, as it may change between CSS and Emacs color names."
;; In the past, rgba() was output when A was not 1.
;; Currently only #RRGGBB or #RRGGBBAA is output.
;;@todo validate more
(edraw-to-string
(if (stringp color)
(edraw-color-from-string color)
color)))
(if (stringp color)
(edraw-to-string-hex
(edraw-color-from-string color)) ;; @todo What if a color name is passed?
(edraw-to-string-hex color)))

(defclass edraw-color-picker-palette-model (edraw-color-picker-observable)
((options :initarg :options)
Expand All @@ -391,9 +402,10 @@
(edraw-empty-p (edraw-as-list palette)))

(cl-defmethod edraw-assign ((palette edraw-color-picker-palette-model)
;; Do not pass color names
colors)
(setq colors
(mapcar #'edraw-color-picker-normalize-color-string colors))
(mapcar #'edraw-color-picker-palette-color-to-string colors))
(with-slots (options option-key colors-var) palette
(if-let* ((option-cell (assq option-key options)))
;; Write back to the OPTIONS alist
Expand All @@ -406,24 +418,27 @@

(cl-defmethod edraw-set-nth ((palette edraw-color-picker-palette-model)
n
;; Do not pass a color name
color)
(edraw-assign
palette
;; @todo Expand size?
(edraw-set-nth (edraw-to-new-list palette) n
(edraw-color-picker-normalize-color-string color))))
(edraw-color-picker-palette-color-to-string color))))

(cl-defmethod edraw-push-front-limit ((palette edraw-color-picker-palette-model)
color max-size)
(let ((color-str (edraw-color-picker-normalize-color-string color)))
;; Do not pass a color name
color
max-size)
(let ((color-str (edraw-color-picker-palette-color-to-string color)))
(edraw-assign
palette
(seq-take ;; Limit number of colors
(cons color-str ;; Push the color to front
;; Remove same color
(seq-remove (lambda (c)
(string=
(edraw-color-picker-normalize-color-string c)
(edraw-color-picker-palette-color-to-string c)
color-str))
(edraw-as-list palette)))
max-size))))
Expand All @@ -441,7 +456,9 @@
(with-temp-file file
(insert "# edraw-colors\n")
(dolist (color (edraw-as-list palette))
(insert (edraw-color-picker-normalize-color-string color) "\n"))))
;; In the past, rgba() was output when A was not 1.
;; Currently only #RRGGBB or #RRGGBBAA is output.
(insert (edraw-color-picker-palette-color-to-string color) "\n"))))

(cl-defmethod edraw-read-from-file ((palette edraw-color-picker-palette-model)
file)
Expand All @@ -453,6 +470,9 @@
(error "Not in edraw-colors format")) ;; @todo This error is barely visible
(forward-line)
(while (not (eobp))
;; #RRGGBB
;; #RRGGBBAA
;; rgba(R,G,B,A) (For compatibility)
(when (looking-at
(concat " *\\(" edraw-color-string-patterns-re "\\)"))
(when-let* ((color (edraw-color-from-string (match-string 1))))
Expand Down Expand Up @@ -550,23 +570,25 @@
(edraw-as-list
(edraw-color-picker-get-recent-colors-model options)))

(defun edraw-color-picker-add-recent-color (options color)
(defun edraw-color-picker-add-recent-color (options
;; Do not pass a color name
color)
(edraw-push-front-limit
(edraw-color-picker-get-recent-colors-model options)
color
edraw-color-picker-recent-colors-max-size))

(defun edraw-color-picker-make-history-list (options initial-color)
"Create a color history list for `read-from-minibuffer'."
(let ((hist (mapcar #'edraw-color-picker-normalize-color-string
(let ((hist (mapcar #'edraw-color-picker-palette-color-to-string
(edraw-color-picker-get-recent-colors options))))
(when (or
;; Use car of HIST as initial-color
(null initial-color)
;; Same color
(and
hist
(equal (edraw-color-picker-normalize-color-string initial-color)
(equal (edraw-color-picker-palette-color-to-string initial-color)
(car hist))))
(pop hist))
hist))
Expand Down Expand Up @@ -2636,7 +2658,7 @@ correctly."
(when (= (plist-get (cdr info) :hist-pos) 0)
(edraw-plist-set (cdr info)
:hist-current
(edraw-color-picker-normalize-color-string
(edraw-color-picker-palette-color-to-string
(edraw-get-current-color picker))))
(let ((color-str
(cond
Expand Down Expand Up @@ -2679,6 +2701,8 @@ The default keymap is `edraw-color-picker--transient-keymap'"
(setf (alist-get :transient-keymap-var options)
'edraw-color-picker--transient-keymap))

(setq initial-color (edraw-color-picker-ensure-color initial-color options))

(let ((picker (edraw-color-picker-open-near-point initial-color options)))
;; Start transient-map
(edraw-color-picker--set-transient-map
Expand Down Expand Up @@ -3069,7 +3093,8 @@ H:%5.1fdeg, S:%5.1f%%, B:%5.1f%%, RL:%5.1f%%"

(unwind-protect
(let ((edraw-color-picker-read-color--history
(edraw-color-picker-make-history-list options initial-color))
(edraw-color-picker-make-history-list options
initial-color-normalized))
(max-mini-window-height 1.0)
(initial-input
(cond
Expand Down
69 changes: 60 additions & 9 deletions todo.org
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@
** TODO 色/カラーピッカー外のクリックでまた開かないようにしたい
色置き換え・挿入コマンド使用時、ピッカーの外をクリックした時に、その場所でまた開かないようにしたい。downイベントで閉じてclickイベントで開いてしまう。

** TODO 色/新しい構文解析・文字列化機構に合わせて既存の文字列処理を修正
新しい仕組みと古い仕組みで機能が被っている。

- :color-name-schemeは廃止したい。色名だけに留まらない。

- edraw-widget.el や edraw-property-editor.el への影響を調べる。 edraw-color-string-patterns-re なんかを使っている箇所があるんだけど。これだとhsl等に対応できないので、新しい仕組みを使うように変更すべき。

- edraw-color.elのFrom StringとTo Stringはどうしよう。新しい仕組みと機能が重複するんだけど。できれば消したいけど、とにかく形式は何でもいいから文字列化・復帰できれば良い場合や効率重視の場合に利用価値があるかもしれない。その方向で整理すべき。color-name-schemeの仕組みは廃止してシンプル化したい。8-bit精度のRGBAが保持できれば良い。

** TODO 色/color-syntax-systemのフォールバック機構
Custom-mode内からCSSの色をカラーピッカーで指定したい場合もあるのではないか。
customize-variableからのedraw関連の設定などは特にCustom-modeバッファ内でCSSの色を指定する機会があるはず(まぁ、専用のwidgetを使えば良いんだけど)。
Expand All @@ -27,6 +18,7 @@ customize-variableからのedraw関連の設定などは特にCustom-modeバッ
- 関数名の大文字小文字維持
- ファイル毎の自動デフォルト形式判定(どの書き方が一番多いか)
- 設定方法の改善
- alphaが1未満の時にHEXよりもrgbaを優先する(#RRGGBBAAはCSS4からなので)

** TODO 選択ツールで選択図形の色をツールバーから変更できるようにする
選択ツールでは、現在選択中の図形のstrokeとfill色をツールバーに表示する。
Expand Down Expand Up @@ -6491,3 +6483,62 @@ CLOSED: [2025-02-15 Sat 18:49]
- edraw-color-picker-color-from-string を修正すればとりあえず新しい構文を入力・解釈できる。
- edraw-color-picker-read-colorの最初の方で、initial-colorが文字列だったときは解析してcolor-infoのプロパティを保存するようにした。文字列化するときはその情報も加味する。
- post-command-hookでは文字列を手動で変更した場合、color-infoプロパティを更新するようにした。
** DONE 色/新しい構文解析・文字列化機構に合わせて既存の文字列処理を修正
CLOSED: [2025-02-16 Sun 14:29]
新しい仕組みと古い仕組みで機能が被っている。

- :color-name-schemeは廃止したい。色名だけに留まらない。

- edraw-widget.el や edraw-property-editor.el への影響を調べる。 edraw-color-string-patterns-re なんかを使っている箇所があるんだけど。これだとhsl等に対応できないので、新しい仕組みを使うように変更すべき。

- edraw-color.elのFrom StringとTo Stringはどうしよう。新しい仕組みと機能が重複するんだけど。できれば消したいけど、とにかく形式は何でもいいから文字列化・復帰できれば良い場合や効率重視の場合に利用価値があるかもしれない。その方向で整理すべき。color-name-schemeの仕組みは廃止してシンプル化したい。8-bit精度のRGBAが保持できれば良い。

(edraw-to-string <edraw-color>)はaが1ならhex、そうでないならrgbaで出力している。なので、その反対操作である(edraw-color-from-string str)は両方に対応せざるを得ない。

色名はどうしよう。そもそもcolor-name-schemeで切り替える必要があるのか。

色名の被りはあるのか。

#+begin_src elisp :results pp
(seq-intersection (mapcar #'car edraw-color-css-color-names) (defined-colors))
#+end_src

#+RESULTS:
: ("aquamarine" "azure" "beige" "bisque" "black" "blue" "brown"
: "burlywood" "chartreuse" "chocolate" "coral" "cornsilk" "cyan"
: "firebrick" "gainsboro" "gold" "goldenrod" "gray" "green" "grey"
: "honeydew" "ivory" "khaki" "lavender" "linen" "magenta" "maroon"
: "moccasin" "navy" "orange" "orchid" "peru" "pink" "plum" "purple"
: "red" "salmon" "seashell" "sienna" "snow" "tan" "thistle" "tomato"
: "turquoise" "violet" "wheat" "white" "yellow")

一致しない色はあるのか。

#+begin_src elisp
(cl-loop for name in (seq-intersection (mapcar #'car edraw-color-css-color-names) (defined-colors))
for emacs-rgb = (apply #'color-rgb-to-hex (append (color-name-to-rgb name) '(2)))
for css-rgb = (alist-get name edraw-color-css-color-names nil nil #'equal)
unless (equal emacs-rgb css-rgb)
collect (list name emacs-rgb css-rgb))
#+end_src

#+RESULTS:
| gray | #bebebe | #808080 |
| green | #00ff00 | #008000 |
| grey | #bebebe | #808080 |
| maroon | #b03060 | #800000 |
| purple | #a020f0 | #800080 |

うわー、結構あるな。

この辺りはそのままで残して置いた方が良さそう。
ただ、すでに edraw-color-name-scheme を設定しているところは存在しない。

気になるのは edraw-color-string-patterns-re や edraw-color-string-patterns を参照しているところ。

- (edraw-widget-web-color-match (_widget value))
- (edraw-read-from-file ((palette edraw-color-picker-palette-model) file))

widgetは修正した。hslも認識するようになった。

edraw-read-from-fileは互換性のために必要。Aが1.0ではないときにrgbaを出力しているたので。#RRGGBBAAを出力するように修正したが、互換性のために edraw-color-string-patterns-re で判定する必要がある。

0 comments on commit 1dcc021

Please sign in to comment.