diff options
| author | Stefan Monnier | 2008-05-07 18:16:28 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-05-07 18:16:28 +0000 |
| commit | c8fcd943a9667e4d0d20933d6d9ce84f47a509e0 (patch) | |
| tree | b13253dd31de3e38aed9ffa0f8c771daba638030 | |
| parent | 42a83f4b6c4b0c43b23ee81a5de9163ae7ea59ef (diff) | |
| download | emacs-c8fcd943a9667e4d0d20933d6d9ce84f47a509e0.tar.gz emacs-c8fcd943a9667e4d0d20933d6d9ce84f47a509e0.zip | |
Choose images dynamically.
(tool-bar-make-keymap, tool-bar-find-image): New function.
(tool-bar-find-image-cache): New var.
(tool-bar-local-item, tool-bar-local-item-from-menu):
Don't select the image yet, do it later in tool-bar-make-keymap.
| -rw-r--r-- | lisp/ChangeLog | 20 | ||||
| -rw-r--r-- | lisp/tool-bar.el | 146 |
2 files changed, 97 insertions, 69 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e276d537995..e88850fdea7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2008-05-07 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * tool-bar.el: Choose images dynamically. | ||
| 4 | (tool-bar-make-keymap, tool-bar-find-image): New function. | ||
| 5 | (tool-bar-find-image-cache): New var. | ||
| 6 | (tool-bar-local-item, tool-bar-local-item-from-menu): | ||
| 7 | Don't select the image yet, do it later in tool-bar-make-keymap. | ||
| 8 | |||
| 1 | 2008-05-07 Andreas Schwab <schwab@suse.de> | 9 | 2008-05-07 Andreas Schwab <schwab@suse.de> |
| 2 | 10 | ||
| 3 | * window.el: Require 'cl when compiling. | 11 | * window.el: Require 'cl when compiling. |
| @@ -60,8 +68,7 @@ | |||
| 60 | 2008-05-06 Chong Yidong <cyd@stupidchicken.com> | 68 | 2008-05-06 Chong Yidong <cyd@stupidchicken.com> |
| 61 | 69 | ||
| 62 | * progmodes/compile.el (compilation-error-regexp-alist-alist): | 70 | * progmodes/compile.el (compilation-error-regexp-alist-alist): |
| 63 | Tweak Open Watcom regexp to distinguish between errors and | 71 | Tweak Open Watcom regexp to distinguish between errors and warnings. |
| 64 | warnings. | ||
| 65 | 72 | ||
| 66 | 2008-05-06 Stefan Monnier <monnier@iro.umontreal.ca> | 73 | 2008-05-06 Stefan Monnier <monnier@iro.umontreal.ca> |
| 67 | 74 | ||
| @@ -103,7 +110,7 @@ | |||
| 103 | 110 | ||
| 104 | * vc-dispatcher.el (vc-dir-mark-buffer-changed): Fix typo | 111 | * vc-dispatcher.el (vc-dir-mark-buffer-changed): Fix typo |
| 105 | client-mode -> vc-client-object, and guess `funcall' was meant. | 112 | client-mode -> vc-client-object, and guess `funcall' was meant. |
| 106 | (vc-dir-mode): Rename client-mode -> vc-client.mode. | 113 | (vc-dir-mode): Rename client-mode -> vc-client-mode. |
| 107 | 114 | ||
| 108 | 2008-05-05 Dan Nicolaescu <dann@ics.uci.edu> | 115 | 2008-05-05 Dan Nicolaescu <dann@ics.uci.edu> |
| 109 | 116 | ||
| @@ -152,10 +159,9 @@ | |||
| 152 | The separation is not yet completely clean, but it's a good start. | 159 | The separation is not yet completely clean, but it's a good start. |
| 153 | * vc.el: This file is about 1700 lines shorter now. | 160 | * vc.el: This file is about 1700 lines shorter now. |
| 154 | Remove obsolete logentry-check from the backend API. | 161 | Remove obsolete logentry-check from the backend API. |
| 155 | * vc-sccs.el (vc-sccs-logentry-check): Remove . This was | 162 | * vc-sccs.el (vc-sccs-logentry-check): Remove . This was the only |
| 156 | was the only implementation of the logentry-check method, and | 163 | implementation of the logentry-check method, and it guarded against |
| 157 | it guarded against a log length limit that has probably been | 164 | a log length limit that has probably been obsolete for 15 years (!). |
| 158 | obsolete for 15 years (!). | ||
| 159 | 165 | ||
| 160 | 2008-05-02 Sam Steingold <sds@gnu.org> | 166 | 2008-05-02 Sam Steingold <sds@gnu.org> |
| 161 | 167 | ||
diff --git a/lisp/tool-bar.el b/lisp/tool-bar.el index d493272b72c..f0f2ff1f234 100644 --- a/lisp/tool-bar.el +++ b/lisp/tool-bar.el | |||
| @@ -86,7 +86,35 @@ Define this locally to override the global tool bar.") | |||
| 86 | 86 | ||
| 87 | (global-set-key [tool-bar] | 87 | (global-set-key [tool-bar] |
| 88 | '(menu-item "tool bar" ignore | 88 | '(menu-item "tool bar" ignore |
| 89 | :filter (lambda (ignore) tool-bar-map))) | 89 | :filter tool-bar-make-keymap)) |
| 90 | |||
| 91 | (defun tool-bar-make-keymap (&optional ignore) | ||
| 92 | "Generate an actual keymap from `tool-bar-map'. | ||
| 93 | Its main job is to figure out which images to use based on the display's | ||
| 94 | color capability and based on the available image libraries." | ||
| 95 | (mapcar (lambda (bind) | ||
| 96 | (let (image-exp) | ||
| 97 | (when (and (eq (car-safe (cdr-safe bind)) 'menu-item) | ||
| 98 | (setq image-exp (plist-get bind :image)) | ||
| 99 | (consp image-exp) | ||
| 100 | (not (eq (car image-exp) 'image)) | ||
| 101 | (fboundp (car image-exp))) | ||
| 102 | (if (not (display-images-p)) | ||
| 103 | (setq bind nil) | ||
| 104 | (let ((image (eval image-exp))) | ||
| 105 | (unless (image-mask-p image) | ||
| 106 | (setq image (append image '(:mask heuristic)))) | ||
| 107 | (setq bind (copy-sequence bind)) | ||
| 108 | (plist-put bind :image image)))) | ||
| 109 | bind)) | ||
| 110 | tool-bar-map)) | ||
| 111 | |||
| 112 | (defconst tool-bar-find-image-cache (make-hash-table :weakness t :test 'equal)) | ||
| 113 | |||
| 114 | (defun tool-bar-find-image (specs) | ||
| 115 | "Like `find-image' but with caching." | ||
| 116 | (or (gethash specs tool-bar-find-image-cache) | ||
| 117 | (puthash specs (find-image specs) tool-bar-find-image-cache))) | ||
| 90 | 118 | ||
| 91 | ;;;###autoload | 119 | ;;;###autoload |
| 92 | (defun tool-bar-add-item (icon def key &rest props) | 120 | (defun tool-bar-add-item (icon def key &rest props) |
| @@ -114,7 +142,7 @@ PROPS are additional items to add to the menu item specification. See | |||
| 114 | Info node `(elisp)Tool Bar'. Items are added from left to right. | 142 | Info node `(elisp)Tool Bar'. Items are added from left to right. |
| 115 | 143 | ||
| 116 | ICON is the base name of a file containing the image to use. The | 144 | ICON is the base name of a file containing the image to use. The |
| 117 | function will first try to use low-color/ICON.xpm if display-color-cells | 145 | function will first try to use low-color/ICON.xpm if `display-color-cells' |
| 118 | is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally | 146 | is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally |
| 119 | ICON.xbm, using `find-image'." | 147 | ICON.xbm, using `find-image'." |
| 120 | (let* ((fg (face-attribute 'tool-bar :foreground)) | 148 | (let* ((fg (face-attribute 'tool-bar :foreground)) |
| @@ -130,16 +158,13 @@ ICON.xbm, using `find-image'." | |||
| 130 | (concat icon ".pbm")) colors)) | 158 | (concat icon ".pbm")) colors)) |
| 131 | (xbm-spec (append (list :type 'xbm :file | 159 | (xbm-spec (append (list :type 'xbm :file |
| 132 | (concat icon ".xbm")) colors)) | 160 | (concat icon ".xbm")) colors)) |
| 133 | (image (find-image | 161 | (image-exp `(tool-bar-find-image |
| 134 | (if (display-color-p) | 162 | (if (display-color-p) |
| 135 | (list xpm-lo-spec xpm-spec pbm-spec xbm-spec) | 163 | ',(list xpm-lo-spec xpm-spec pbm-spec xbm-spec) |
| 136 | (list pbm-spec xbm-spec xpm-lo-spec xpm-spec))))) | 164 | ',(list pbm-spec xbm-spec xpm-lo-spec xpm-spec))))) |
| 137 | 165 | ||
| 138 | (when (and (display-images-p) image) | 166 | (define-key-after map (vector key) |
| 139 | (unless (image-mask-p image) | 167 | `(menu-item ,(symbol-name key) ,def :image ,image-exp ,@props)))) |
| 140 | (setq image (append image '(:mask heuristic)))) | ||
| 141 | (define-key-after map (vector key) | ||
| 142 | `(menu-item ,(symbol-name key) ,def :image ,image ,@props))))) | ||
| 143 | 168 | ||
| 144 | ;;;###autoload | 169 | ;;;###autoload |
| 145 | (defun tool-bar-add-item-from-menu (command icon &optional map &rest props) | 170 | (defun tool-bar-add-item-from-menu (command icon &optional map &rest props) |
| @@ -185,44 +210,41 @@ holds a keymap." | |||
| 185 | (concat icon ".pbm")) colors)) | 210 | (concat icon ".pbm")) colors)) |
| 186 | (xbm-spec (append (list :type 'xbm :file | 211 | (xbm-spec (append (list :type 'xbm :file |
| 187 | (concat icon ".xbm")) colors)) | 212 | (concat icon ".xbm")) colors)) |
| 188 | (spec (if (display-color-p) | 213 | (image-exp `(tool-bar-find-image |
| 189 | (list xpm-lo-spec xpm-spec pbm-spec xbm-spec) | 214 | (if (display-color-p) |
| 190 | (list pbm-spec xbm-spec xpm-lo-spec xpm-spec))) | 215 | ',(list xpm-lo-spec xpm-spec pbm-spec xbm-spec) |
| 191 | (image (find-image spec)) | 216 | ',(list pbm-spec xbm-spec xpm-lo-spec xpm-spec)))) |
| 192 | submap key) | 217 | submap key) |
| 193 | (when (and (display-images-p) image) | 218 | ;; We'll pick up the last valid entry in the list of keys if |
| 194 | ;; We'll pick up the last valid entry in the list of keys if | 219 | ;; there's more than one. |
| 195 | ;; there's more than one. | 220 | (dolist (k keys) |
| 196 | (dolist (k keys) | 221 | ;; We're looking for a binding of the command in a submap of |
| 197 | ;; We're looking for a binding of the command in a submap of | 222 | ;; the menu bar map, so the key sequence must be two or more |
| 198 | ;; the menu bar map, so the key sequence must be two or more | 223 | ;; long. |
| 199 | ;; long. | 224 | (if (and (vectorp k) |
| 200 | (if (and (vectorp k) | 225 | (> (length k) 1)) |
| 201 | (> (length k) 1)) | 226 | (let ((m (lookup-key menu-bar-map (substring k 0 -1))) |
| 202 | (let ((m (lookup-key menu-bar-map (substring k 0 -1))) | 227 | ;; Last element in the bound key sequence: |
| 203 | ;; Last element in the bound key sequence: | 228 | (kk (aref k (1- (length k))))) |
| 204 | (kk (aref k (1- (length k))))) | 229 | (if (and (keymapp m) |
| 205 | (if (and (keymapp m) | 230 | (symbolp kk)) |
| 206 | (symbolp kk)) | 231 | (setq submap m |
| 207 | (setq submap m | 232 | key kk))))) |
| 208 | key kk))))) | 233 | (when (and (symbolp submap) (boundp submap)) |
| 209 | (when (and (symbolp submap) (boundp submap)) | 234 | (setq submap (eval submap))) |
| 210 | (setq submap (eval submap))) | 235 | (let ((defn (assq key (cdr submap)))) |
| 211 | (unless (image-mask-p image) | 236 | (if (eq (cadr defn) 'menu-item) |
| 212 | (setq image (append image '(:mask heuristic)))) | 237 | (define-key-after in-map (vector key) |
| 213 | (let ((defn (assq key (cdr submap)))) | 238 | (append (cdr defn) (list :image image-exp) props)) |
| 214 | (if (eq (cadr defn) 'menu-item) | 239 | (setq defn (cdr defn)) |
| 215 | (define-key-after in-map (vector key) | 240 | (define-key-after in-map (vector key) |
| 216 | (append (cdr defn) (list :image image) props)) | 241 | (let ((rest (cdr defn))) |
| 217 | (setq defn (cdr defn)) | 242 | ;; If the rest of the definition starts |
| 218 | (define-key-after in-map (vector key) | 243 | ;; with a list of menu cache info, get rid of that. |
| 219 | (let ((rest (cdr defn))) | 244 | (if (and (consp rest) (consp (car rest))) |
| 220 | ;; If the rest of the definition starts | 245 | (setq rest (cdr rest))) |
| 221 | ;; with a list of menu cache info, get rid of that. | 246 | (append `(menu-item ,(car defn) ,rest) |
| 222 | (if (and (consp rest) (consp (car rest))) | 247 | (list :image image-exp) props))))))) |
| 223 | (setq rest (cdr rest))) | ||
| 224 | (append `(menu-item ,(car defn) ,rest) | ||
| 225 | (list :image image) props)))))))) | ||
| 226 | 248 | ||
| 227 | ;;; Set up some global items. Additions/deletions up for grabs. | 249 | ;;; Set up some global items. Additions/deletions up for grabs. |
| 228 | 250 | ||
| @@ -267,24 +289,24 @@ holds a keymap." | |||
| 267 | 289 | ||
| 268 | ;; There's no icon appropriate for News and we need a command rather | 290 | ;; There's no icon appropriate for News and we need a command rather |
| 269 | ;; than a lambda for Read Mail. | 291 | ;; than a lambda for Read Mail. |
| 270 | ;;(tool-bar-add-item-from-menu 'compose-mail "mail/compose") | 292 | ;;(tool-bar-add-item-from-menu 'compose-mail "mail/compose") |
| 271 | 293 | ||
| 272 | (tool-bar-add-item-from-menu 'print-buffer "print") | 294 | (tool-bar-add-item-from-menu 'print-buffer "print") |
| 273 | 295 | ||
| 274 | ;; tool-bar-add-item-from-menu itself operates on | 296 | ;; tool-bar-add-item-from-menu itself operates on |
| 275 | ;; (default-value 'tool-bar-map), but when we don't use that function, | 297 | ;; (default-value 'tool-bar-map), but when we don't use that function, |
| 276 | ;; we must explicitly operate on the default value. | 298 | ;; we must explicitly operate on the default value. |
| 277 | 299 | ||
| 278 | (let ((tool-bar-map (default-value 'tool-bar-map))) | 300 | (let ((tool-bar-map (default-value 'tool-bar-map))) |
| 279 | (tool-bar-add-item "preferences" 'customize 'customize | 301 | (tool-bar-add-item "preferences" 'customize 'customize |
| 280 | :help "Edit preferences (customize)") | 302 | :help "Edit preferences (customize)") |
| 281 | 303 | ||
| 282 | (tool-bar-add-item "help" (lambda () | 304 | (tool-bar-add-item "help" (lambda () |
| 283 | (interactive) | 305 | (interactive) |
| 284 | (popup-menu menu-bar-help-menu)) | 306 | (popup-menu menu-bar-help-menu)) |
| 285 | 'help | 307 | 'help |
| 286 | :help "Pop up the Help menu")) | 308 | :help "Pop up the Help menu")) |
| 287 | (setq tool-bar-setup t)))) | 309 | (setq tool-bar-setup t)))) |
| 288 | 310 | ||
| 289 | 311 | ||
| 290 | (provide 'tool-bar) | 312 | (provide 'tool-bar) |