]> code.delx.au - gnu-emacs/blob - lisp/toolbar/tool-bar.el
(tool-bar-mode): Doc fix.
[gnu-emacs] / lisp / toolbar / tool-bar.el
1 ;;; tool-bar.el --- Setting up the tool bar
2 ;;
3 ;; Copyright (C) 2000 Free Software Foundation, Inc.
4 ;;
5 ;; Author: Dave Love <fx@gnu.org>
6 ;; Keywords: mouse frames
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Commentary:
26
27 ;; Provides `tool-bar-mode' to control display of the tool -bar and
28 ;; bindings for the global tool bar with convenience functions
29 ;; `tool-bar-add-item' and `tool-bar-add-item-from-menu'.
30
31 ;; The normal global binding for [tool-bar] (below) uses the value of
32 ;; `tool-bar-map' as the actual keymap to define the tool bar. Modes
33 ;; may either bind items under the [tool-bar] prefix key of the local
34 ;; map to add to the global bar or may set `tool-bar-map'
35 ;; buffer-locally to override it. (Some items are removed from the
36 ;; global bar in modes which have `special' as their `mode-class'
37 ;; properlty.)
38
39 ;; Todo: Somehow make tool bars easily customizable by the naive?
40
41 ;;; Code:
42
43 ;;;###autoload
44 (define-minor-mode tool-bar-mode
45 "Toggle use of the tool bar.
46 With numeric ARG, display the tool bar if and only if ARG is positive.
47
48 See `tool-bar-add-item' and `tool-bar-add-item-from-menu' for
49 conveniently adding tool bar items."
50 :global t
51 :group 'mouse
52 :group 'frames
53 (let ((lines (if tool-bar-mode 1 0)))
54 ;; Alter existing frames...
55 (mapc (lambda (frame)
56 (modify-frame-parameters frame
57 (list (cons 'tool-bar-lines lines))))
58 (frame-list))
59 ;; ...and future ones.
60 (let ((elt (assq 'tool-bar-lines default-frame-alist)))
61 (if elt
62 (setcdr elt lines)
63 (add-to-list 'default-frame-alist (cons 'tool-bar-lines lines)))))
64 (if (and tool-bar-mode
65 (display-graphic-p)
66 (= 1 (length (default-value 'tool-bar-map)))) ; not yet setup
67 (tool-bar-setup)))
68
69 (defvar tool-bar-map (make-sparse-keymap)
70 "Keymap for the tool bar.
71 Define this locally to override the global tool bar.")
72
73 (global-set-key [tool-bar]
74 '(menu-item "tool bar" ignore
75 :filter (lambda (ignore) tool-bar-map)))
76
77 ;;;###autoload
78 (defun tool-bar-add-item (icon def key &rest props)
79 "Add an item to the tool bar.
80 ICON names the image, DEF is the key definition and KEY is a symbol
81 for the fake function key in the menu keymap. Remaining arguments
82 PROPS are additional items to add to the menu item specification. See
83 Info node `(elisp)Tool Bar'. Items are added from left to right.
84
85 ICON is the base name of a file cnntaining the image to use. The
86 function will try to use first ICON.xpm, ICON.pbm then ICON.xbm using
87 `find-image'.
88
89 Keybindings are made in the map `tool-bar-map'. To define items in
90 some local map, bind `tool-bar-map' with `let' around calls of this
91 function."
92 (let* ((fg (face-foreground 'tool-bar))
93 (bg (face-background 'tool-bar))
94 (image (find-image
95 (if (display-color-p)
96 `((:type xpm :file ,(concat icon ".xpm"))
97 (:type pbm :file ,(concat icon ".pbm")
98 :background ,bg
99 :foreground ,fg)
100 (:type xbm :file ,(concat icon ".xbm")
101 :background ,bg
102 :foreground ,fg))
103 `((:type pbm :file ,(concat icon ".pbm")
104 :background ,bg
105 :foreground ,fg)
106 (:type xbm :file ,(concat icon ".xbm")
107 :background ,bg
108 :foreground ,fg)
109 (:type xpm :file ,(concat icon ".xpm")))))))
110 (when image
111 (unless (image-mask-p image)
112 (setq image (append image '(:mask heuristic))))
113 (define-key-after tool-bar-map (vector key)
114 `(menu-item ,(symbol-name key) ,def :image ,image ,@props)))))
115
116 ;;;###autoload
117 (defun tool-bar-add-item-from-menu (command icon &optional map &rest props)
118 "Define tool bar binding for COMMAND using the given ICON in keymap MAP.
119 The binding of COMMAND is looked up in the menu bar in MAP (default
120 `global-map') and modified to add an image specification for ICON, which
121 is looked for as by `tool-bar-add-item'.
122 MAP must contain an appropriate keymap bound to `[menu-bar]'.
123 PROPS is a list of additional properties to add to the binding.
124
125 Keybindings are made in the map `tool-bar-map'. To define items in
126 some local map, bind `tool-bar-map' with `let' around calls of this
127 function."
128 (unless map
129 (setq map global-map))
130 (let* ((menu-bar-map (lookup-key map [menu-bar]))
131 (keys (where-is-internal command menu-bar-map))
132 (fg (if (eq (face-foreground 'tool-bar) 'unspecified)
133 nil
134 (list :foreground (face-foreground 'tool-bar))))
135 (bg (if (eq (face-background 'tool-bar) 'unspecified)
136 nil
137 (list :background (face-background 'tool-bar))))
138 (colors (nconc fg bg))
139 (spec (if (display-color-p)
140 (list (list :type 'xpm :file (concat icon ".xpm"))
141 (append (list :type 'pbm :file (concat icon ".pbm"))
142 colors)
143 (append (list :type 'xbm :file (concat icon ".xbm"))
144 colors))
145 (list (append (list :type 'pbm :file (concat icon ".pbm"))
146 colors)
147 (append (list :type 'xbm :file (concat icon ".xbm"))
148 colors)
149 (list :type 'xpm :file (concat icon ".xpm")))))
150 (image (find-image spec))
151 submap key)
152 (when image
153 ;; We'll pick up the last valid entry in the list of keys if
154 ;; there's more than one.
155 (dolist (k keys)
156 ;; We're looking for a binding of the command in a submap of
157 ;; the menu bar map, so the key sequence must be two or more
158 ;; long.
159 (if (and (vectorp k)
160 (> (length k) 1))
161 (let ((m (lookup-key menu-bar-map (substring k 0 -1)))
162 ;; Last element in the bound key sequence:
163 (kk (aref k (1- (length k)))))
164 (if (and (keymapp m)
165 (symbolp kk))
166 (setq submap m
167 key kk)))))
168 (when (and (symbolp submap) (boundp submap))
169 (setq submap (eval submap)))
170 (unless (image-mask-p image)
171 (setq image (append image '(:mask heuristic))))
172 (define-key-after tool-bar-map (vector key)
173 (append (cdr (assq key (cdr submap))) (list :image image) props)))))
174
175 ;;; Set up some global items. Additions/deletions up for grabs.
176
177 (defun tool-bar-setup ()
178 (tool-bar-add-item-from-menu 'save-buffers-kill-emacs "exit")
179 (tool-bar-add-item-from-menu 'find-file "new")
180 (tool-bar-add-item-from-menu 'dired "open")
181 (tool-bar-add-item-from-menu 'kill-this-buffer "close")
182 (tool-bar-add-item-from-menu 'save-buffer "save" nil
183 :visible '(not (eq 'special (get major-mode
184 'mode-class))))
185 (tool-bar-add-item-from-menu 'write-file "saveas" nil
186 :visible '(not (eq 'special (get major-mode
187 'mode-class))))
188 (tool-bar-add-item-from-menu 'undo "undo" nil
189 :visible '(not (eq 'special (get major-mode
190 'mode-class))))
191 (tool-bar-add-item-from-menu 'kill-region "cut" nil
192 :visible '(not (eq 'special (get major-mode
193 'mode-class))))
194 (tool-bar-add-item-from-menu 'menu-bar-kill-ring-save "copy")
195 (tool-bar-add-item-from-menu 'yank "paste" nil
196 :visible '(not (eq 'special (get major-mode
197 'mode-class))))
198 (tool-bar-add-item-from-menu 'nonincremental-search-forward "search")
199 ;;(tool-bar-add-item-from-menu 'ispell-buffer "spell")
200
201 ;; There's no icon appropriate for News and we need a command rather
202 ;; than a lambda for Read Mail.
203 ;;(tool-bar-add-item-from-menu 'compose-mail "mail_compose")
204
205 (tool-bar-add-item-from-menu 'print-buffer "print")
206 (tool-bar-add-item "preferences" 'customize 'customize
207 :help "Edit preferences (customize)")
208
209 (tool-bar-add-item "help" (lambda ()
210 (interactive)
211 (popup-menu menu-bar-help-menu))
212 'help
213 :help "Pop up the Help menu")
214 )
215
216 (provide 'tool-bar)
217
218 ;;; tool-bar.el ends here