Skip to content

Commit

Permalink
Use edraw-color-syntax in edraw-color-picker-read-color
Browse files Browse the repository at this point in the history
  • Loading branch information
misohena committed Feb 15, 2025
1 parent ec46e32 commit 3133fc5
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 78 deletions.
181 changes: 108 additions & 73 deletions edraw-color-picker.el
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,10 @@
;; edraw-list : a list of palette color strings
;; :recent-colors
;; edraw-list : a list of recently used color strings
;; :color-float-format (default: 4)
;; integer : number of digits after the decimal point
;; string : format string (e.g. "%s")
;; function : format function (funcall f value)
;; :color-format
;; :color-syntax-system
;; symbol
;; nil : hex or rgb
;; 'hex : #RRGGBB or #RRGGBBAA
;; 'rgba : rgba(R, G, B, A)
;; :color-name-scheme
;; symbol
;; 'emacs : Use emacs color name
;; 'web : Use web color keyword
;; 'emacs : Use emacs color syntax
;; 'css : Use CSS color syntax
;; :scale
;; float : scaling factor for color picker image
;; (rate from default image size)
Expand Down Expand Up @@ -2780,7 +2771,7 @@ events."
initial-color
:begin (point)
:end (point)
:syntax-system (edraw-color-picker-syntax-system options nil))
:syntax-system (edraw-color-picker-syntax-system options))
options)
t)

Expand Down Expand Up @@ -2844,7 +2835,7 @@ events."
(when-let* ((color-info
(edraw-color-info-at
(point)
(edraw-color-picker-syntax-system options nil)
(edraw-color-picker-syntax-system options)
t)))
(edraw-color-picker-replace-color-region color-info options)
t))
Expand Down Expand Up @@ -3015,17 +3006,6 @@ H:%5.1fdeg, S:%5.1f%%, B:%5.1f%%, RL:%5.1f%%"
(* bri 100)
(* rl 100))))

;;;; Color Syntax System

(defun edraw-color-picker-syntax-system (options default-syntax-system)
(or
(alist-get :color-syntax-system options)
(pcase (alist-get :color-name-scheme options)
('web 'css)
('css 'css)
('emacs 'emacs)
(_ (edraw-color-syntax-system-default
(or default-syntax-system 'emacs))))))

;;;;; Read Color from Minibuffer

Expand All @@ -3044,33 +3024,53 @@ H:%5.1fdeg, S:%5.1f%%, B:%5.1f%%, RL:%5.1f%%"
(when (eq allow-strings t)
(setq allow-strings '(""))) ;;allow-empty

(let* ((overlay (let ((ov (make-overlay (point) (point) nil t nil)))
;; Determine the color syntax system
(unless (alist-get :color-syntax-system options)
(push (cons :color-syntax-system
(edraw-color-picker-syntax-system options))
options))

(push (cons :transient-keymap-var 'edraw-color-picker-minibuffer-mode-map)
options)

(let* (;; Normalize INITIAL-COLOR and save original text format
(initial-color-info
(when (stringp initial-color)
(edraw-color-picker-color-info-from-string initial-color options)))
(initial-color-normalized
(if initial-color-info
(car initial-color-info)
(edraw-color-picker-ensure-color initial-color options)))
;; Make :color-info-props property
(_
(push (cons :color-info-props
(when initial-color-info
(edraw-color-info-props initial-color-info)))
options))

;; Create an overlay and a color picker object
(overlay (let ((ov (make-overlay (point) (point) nil t nil)))
(delete-overlay ov)
(overlay-put ov 'after-string "\n")
ov))
(picker (edraw-color-picker-overlay
overlay 'before-string initial-color
(cons
'(:transient-keymap-var
. edraw-color-picker-minibuffer-mode-map)
options)))
(on-minibuffer-setup
(lambda ()
(edraw-color-picker-minibuffer--on-minibuffer-setup picker)))
(edraw-color-picker-read-color--history
(edraw-color-picker-make-history-list options initial-color)))
overlay 'before-string initial-color-normalized options)))

;; Add hooks to picker
(edraw-add-hook picker 'ok #'edraw-color-picker-minibuffer--on-ok)
(edraw-add-hook picker 'cancel #'edraw-color-picker-minibuffer--on-cancel)
(edraw-add-hook picker 'ok
#'edraw-color-picker-minibuffer--on-ok)
(edraw-add-hook picker 'cancel
#'edraw-color-picker-minibuffer--on-cancel)
(when (alist-get :no-color options)
(edraw-add-hook picker 'no-color
#'edraw-color-picker-minibuffer--on-no-color))
(edraw-add-hook picker 'color-change
#'edraw-color-picker-minibuffer--on-color-change)

(unwind-protect
(let ((max-mini-window-height 1.0)
(let ((edraw-color-picker-read-color--history
(edraw-color-picker-make-history-list options initial-color))
(max-mini-window-height 1.0)
(initial-input
(cond
((cl-typep initial-color 'edraw-color)
Expand All @@ -3088,12 +3088,15 @@ H:%5.1fdeg, S:%5.1f%%, B:%5.1f%%, RL:%5.1f%%"
;; If the minibuffer is re-entered recursively,
;; on-minibuffer-setup will only be called
;; once, for the outermost use of the minibuffer.
on-minibuffer-setup
(lambda ()
(edraw-color-picker-minibuffer--on-minibuffer-setup
picker))
(read-string (edraw-color-picker-minibuffer--prompt
prompt allow-strings options)
initial-input
'edraw-color-picker-read-color--history))))
(when (or (member input allow-strings)
;; INPUT is a valid color?
(edraw-color-picker-color-from-string input options))
(setq result input))))
(when-let* ((result-color
Expand All @@ -3108,10 +3111,8 @@ H:%5.1fdeg, S:%5.1f%%, B:%5.1f%%, RL:%5.1f%%"
"Create a prompt for `edraw-color-picker-read-color'."
(or prompt
(format
"Color (%s name or %s%s): "
(alist-get :color-name-scheme options 'emacs)
(if (alist-get 'enable-opacity options t)
"#RGBA" "#RGB")
"Color (%s syntax%s): "
(edraw-color-picker-syntax-system options)
(if allow-strings
(concat
" or "
Expand Down Expand Up @@ -3168,8 +3169,10 @@ correctly."
(picker-color-str (edraw-color-picker-color-to-string
picker-color options))
(minibuffer-string (minibuffer-contents-no-properties))
(minibuffer-color (edraw-color-picker-color-from-string
minibuffer-string options)))
(minibuffer-color-info (edraw-color-picker-color-info-from-string
minibuffer-string options))
(minibuffer-color (edraw-color-info-color
minibuffer-color-info)))
;; update color picker
(when (and
;; not equals string representation of picker color
Expand All @@ -3182,6 +3185,19 @@ correctly."
(not (edraw-color-equal-p minibuffer-color
picker-color)))
(edraw-set-current-color picker minibuffer-color))
;; update format
(when (and
;; not equals string representation of picker color
;; (set by last on-color-change)
(not (string= minibuffer-string
picker-color-str))
;; is valid color
minibuffer-color-info
;; @todo Block if color name?
)
(when-let* ((cell (assq :color-info-props options)))
(setcdr cell (edraw-color-info-props minibuffer-color-info))))

;; callback minibuffer string change
;; (include invalid string. e.g. "none")
(edraw-color-picker-minibuffer--notify-input-change
Expand Down Expand Up @@ -3257,44 +3273,63 @@ of input changes."



;;;; Color Utility
;;;; Color Text Conversion

(defun edraw-color-picker-syntax-system (options
&optional default-syntax-system)
(or
(alist-get :color-syntax-system options)
(pcase (alist-get :color-name-scheme options)
('web 'css)
('css 'css)
('emacs 'emacs)
(_ (edraw-color-syntax-system-default
(or default-syntax-system 'emacs))))))

(defun edraw-color-picker-color-to-string (color options)
"Convert COLOR edraw-color object to string.
Valid OPTIONS are:
(:color-float-format . num-digits or format-string or format-function)
(:color-format . nil or \\='hex or \\='rgb)
(:enable-opacity . nil or t)
"
(let ((edraw-color-string-float-format
(alist-get :color-float-format options 4))
(color (if (alist-get :enable-opacity options t)
color
(edraw-replace-a color 1.0))))
(pcase (alist-get :color-format options)
('nil
(edraw-to-string color))
('hex
(edraw-to-string-hex color))
((or 'rgb 'rgba)
(edraw-to-string-rgba-or-rgb color)))))
(:color-syntax-system . emacs or css)
(:color-name-scheme . emacs or css or web)
(:color-serializer-options . <plist>)
(:color-info-props . <plist>)
(:enable-opacity . nil or t)"
(unless (alist-get :enable-opacity options t)
(setq color (edraw-replace-a color 1.0)))

(edraw-color-syntax-serialize
color
(append (alist-get :color-serializer-options options)
;; Append original format
(alist-get :color-info-props options))
(edraw-color-picker-syntax-system options)))

(defun edraw-color-picker-color-info-from-string (string options)
"Convert STRING to parsed color info.
Valid options are:
(:color-syntax-system . emacs or css)
(:color-name-scheme . emacs or css or web)
(:enable-opacity . nil or t)"
(let ((color-info
(edraw-color-info-from-string
string nil
(edraw-color-picker-syntax-system options)
"[ \t\n\r\f]*\\'")))
(when (or (alist-get :enable-opacity options t)
(and color-info (= (edraw-color-a (car color-info)) 1.0)))
;; Accept opacity or opaque
color-info)))

(defun edraw-color-picker-color-from-string (string options)
"Convert STRING to edraw-color object.
Valid options are:
(:color-name-scheme . emacs or web)
(:enable-opacity . nil or t)
"
(let ((edraw-color-name-scheme (alist-get :color-name-scheme options 'emacs)))
(let ((color (edraw-color-from-string string)))
(if (alist-get :enable-opacity options t)
color
(if (and color (= (oref color a) 1.0))
color
nil)))))
(:color-syntax-system . emacs or css)
(:color-name-scheme . emacs or css or web)
(:enable-opacity . nil or t)"
(car (edraw-color-picker-color-info-from-string string options)))

(defun edraw-color-picker-ensure-color (obj options)
(if (cl-typep obj 'edraw-color)
Expand Down
10 changes: 8 additions & 2 deletions edraw-color.el
Original file line number Diff line number Diff line change
Expand Up @@ -1932,7 +1932,9 @@ color text."
(ignore-errors
(edraw-color-syntax-matched-color-info syntax-system))))

(defun edraw-color-info-from-string (string &optional position syntax-system)
(defun edraw-color-info-from-string (string
&optional position syntax-system
trailing-regexp)
"Return the color information of the color text written at the POSITION
in STRING.
Expand All @@ -1949,8 +1951,10 @@ words, if (edraw-color-info-from-string \"#1122334455\" 0 \\='css) is
evaluated, it will match the \"#11223344\" part. If POSITION is nil, 0
is assumed to be specified."
(when (and (string-match (concat
"[ \t\n\r\f]*\\(?:\\(?:"
"\\(?:\\(?:[ \t\n\r\f]*\\(?:"
(edraw-color-syntax-regexp syntax-system)
"\\)"
trailing-regexp
"\\)\\|\\)")
string position)
(< (match-beginning 0) (match-end 0)))
Expand All @@ -1961,6 +1965,8 @@ is assumed to be specified."
;; TEST: (edraw-color-info-from-string "Dust #44448888cccc dust" 4 'emacs) => (#s(edraw-color 0.26666666666666666 0.5333333333333333 0.8 1.0) :num-components 3 :hex-digits-per-component 4 :syntax emacs-hex-color :begin 4 :end 20 :syntax-system emacs)
;; TEST: (edraw-color-info-from-string "Dust #44448888cccc dust" 4 'css) => (#s(edraw-color 0.26666666666666666 0.26666666666666666 0.5333333333333333 0.5333333333333333) :num-components 4 :hex-digits-per-component 2 :syntax css-hex-color :begin 4 :end 16 :syntax-system css)
;; TEST: (car (edraw-color-info-from-string "Dust hsl( 30 50 50/0.5)dust" 4 'css)) => #s(edraw-color 0.75 0.5 0.25 0.5)
;; TEST: (car (edraw-color-info-from-string "Dust hsl( 30 50 50) " 4 'css " *\\'")) => #s(edraw-color 0.75 0.5 0.25 1.0)
;; TEST: (edraw-color-info-from-string "Dust hsl( 30 50 50) dust " 4 'css " *\\'") => nil


(provide 'edraw-color)
Expand Down
10 changes: 7 additions & 3 deletions todo.org
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ Custom-mode内からCSSの色をカラーピッカーで指定したい場合も
customize-variableからのedraw関連の設定などは特にCustom-modeバッファ内でCSSの色を指定する機会があるはず(まぁ、専用のwidgetを使えば良いんだけど)。
そうなると、フォールバック的に他のsyntax-systemも試すような仕組みが必要ではないだろうか。

** TODO 色/新しい色テキスト処理をミニバッファ入力方式にも適用する
今のままだとedraw-editorからhslやらが使えない。

** TODO 色/edraw-color-syntax-serializeのoptionsを改善する
様々な形式を指定出来るようにする。もしくは元々の表記をより反映する。
- 細かい書式の改善
Expand Down Expand Up @@ -6487,3 +6484,10 @@ edraw-color-picker-global-mode
** DONE 色/edraw-color-picker-read-colorで無効な色を入力したとき
CLOSED: [2025-02-15 Sat 18:26]
再度入力になるがカラーピッカーが消えてしまう。
** DONE 色/新しい色テキスト処理をミニバッファ入力方式にも適用する
CLOSED: [2025-02-15 Sat 18:49]
今のままだとedraw-editorからhslやらが使えない。

- edraw-color-picker-color-from-string を修正すればとりあえず新しい構文を入力・解釈できる。
- edraw-color-picker-read-colorの最初の方で、initial-colorが文字列だったときは解析してcolor-infoのプロパティを保存するようにした。文字列化するときはその情報も加味する。
- post-command-hookでは文字列を手動で変更した場合、color-infoプロパティを更新するようにした。

0 comments on commit 3133fc5

Please sign in to comment.