Mercurial > hg > xemacs-beta
comparison lisp/packages/balloon-help.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 8fc7fe29b841 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; Balloon help for XEmacs (requires 19.12 or later) | |
2 ;;; Copyright (C) 1995 Kyle E. Jones | |
3 ;;; | |
4 ;;; This program is free software; you can redistribute it and/or modify | |
5 ;;; it under the terms of the GNU General Public License as published by | |
6 ;;; the Free Software Foundation; either version 1, or (at your option) | |
7 ;;; any later version. | |
8 ;;; | |
9 ;;; This program is distributed in the hope that it will be useful, | |
10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ;;; GNU General Public License for more details. | |
13 ;;; | |
14 ;;; A copy of the GNU General Public License can be obtained from this | |
15 ;;; program's author (send electronic mail to kyle@uunet.uu.net) or from | |
16 ;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA | |
17 ;;; 02139, USA. | |
18 ;;; | |
19 ;;; Send bug reports to kyle@wonderworks.com | |
20 | |
21 ;;; Synched up with: Not in FSF. | |
22 | |
23 ;; Balloon help pops up a small frame to display help text | |
24 ;; relating to objects that the mouse cursor passes over. | |
25 ;; | |
26 ;; Installation: | |
27 ;; | |
28 ;; Byte-compile the file balloon-help.el (with M-x byte-compile-file) | |
29 ;; and put the .elc file in a directory in your load-path. Add the | |
30 ;; following line to your .emacs: | |
31 ;; | |
32 ;; (require 'balloon-help) | |
33 ;; | |
34 ;; For 19.12 users: | |
35 ;; If you are using fvwm, [tv]twm or ol[v]wm, you can also add | |
36 ;; the following lines to various configuration file to use | |
37 ;; minimal decorations on the balloon help frames. | |
38 ;; | |
39 ;; In .emacs: | |
40 ;; (setq balloon-help-frame-name "balloon-help") | |
41 ;; | |
42 ;; For ol[v]wm use this in .Xdefaults: | |
43 ;; olvwm.NoDecor: balloon-help | |
44 ;; or | |
45 ;; olwm.MinimalDecor: balloon-help | |
46 ;; | |
47 ;; For fvvm use this in your .fvwmrc: | |
48 ;; NoTitle balloon-help | |
49 ;; or | |
50 ;; Style "balloon-help" NoTitle, NoHandles, BorderWidth 0 | |
51 ;; | |
52 ;; For twm use this in your .twmrc: | |
53 ;; NoTitle { "balloon-help" } | |
54 ;; | |
55 ;; Under 19.13 and later versions the balloon-help frame uses a | |
56 ;; transient window that is not normally decorated by window | |
57 ;; managers. So the window manager directives should not be | |
58 ;; needed for XEmacs 19.13 and beyond. | |
59 | |
60 (provide 'balloon-help) | |
61 | |
62 (defvar balloon-help-version "1.02" | |
63 "Version string for Balloon Help.") | |
64 | |
65 (defvar balloon-help-mode t | |
66 "*Non-nil means Balloon help mode is enabled.") | |
67 | |
68 (defvar balloon-help-timeout 1500 | |
69 "*Display help after this many milliseconds of mouse inactivity.") | |
70 | |
71 (defvar balloon-help-foreground "black" | |
72 "*The foreground color for displaying balloon help text.") | |
73 | |
74 (defvar balloon-help-background "rgb:c0/c0/c0" | |
75 "*The background color for the balloon help frame.") | |
76 | |
77 (defvar balloon-help-background-pixmap "" | |
78 "*The background pixmap for the balloon help frame.") | |
79 | |
80 (defvar balloon-help-font "fixed" | |
81 "*The font for displaying balloon help text.") | |
82 | |
83 (defvar balloon-help-border-color "black" | |
84 "*The color for displaying balloon help frame's border.") | |
85 | |
86 (defvar balloon-help-use-sound nil | |
87 "*Non-nil value means play a sound to herald the appearance | |
88 and disappearance of the help frame. | |
89 | |
90 `balloon-help-appears' will be played when the frame appears. | |
91 `balloon-help-disappears' will be played when the frame disappears. | |
92 | |
93 See the documentation for the function load-sound-file to see how | |
94 define sounds.") | |
95 | |
96 (defvar balloon-help-frame-name nil | |
97 "*The frame name to use for the frame to display the balloon help.") | |
98 | |
99 ;;; | |
100 ;;; End of user variables. | |
101 ;;; | |
102 | |
103 (defvar mouse-motion-hook mouse-motion-handler | |
104 "Hooks to be run whenever the user moves the mouse. | |
105 Each hook is called with one argument, the mouse motion event.") | |
106 | |
107 (defun mouse-motion-hook (event) | |
108 "Run the hooks attached to mouse-motion-hook." | |
109 (run-hook-with-args 'mouse-motion-hook event)) | |
110 | |
111 (setq mouse-motion-handler 'mouse-motion-hook) | |
112 | |
113 (defvar balloon-help-frame nil | |
114 "Balloon help is displayed in this frame.") | |
115 | |
116 (defvar balloon-help-help-object nil | |
117 "Object that the mouse is over that has a help property, nil otherwise.") | |
118 | |
119 (defvar balloon-help-help-object-x nil | |
120 "Last horizontal mouse position over balloon-help-help-object.") | |
121 | |
122 (defvar balloon-help-help-object-y nil | |
123 "Last vertical mouse position over balloon-help-help-object.") | |
124 | |
125 (defvar balloon-help-buffer nil | |
126 "Buffer used to display balloon help.") | |
127 | |
128 (defvar balloon-help-timeout-id nil | |
129 "Timeout id for the balloon help timeout.") | |
130 | |
131 (defvar balloon-help-display-pending nil | |
132 "Non-nil value means the help frame will be visible as soon | |
133 as the X server gets around to displaying it. Nil means it | |
134 will be invisible as soon as the X server decides to hide it.") | |
135 | |
136 (defvar balloon-help-bar-cursor nil) | |
137 | |
138 (defun balloon-help-mode (&optional arg) | |
139 "Toggle Balloon Help mode. | |
140 With arg, turn Balloon Help mode on iff arg is positive. | |
141 | |
142 With Balloon Help enabled, a small frame is displayed whenever | |
143 the mouse rests on an object that has a help property of some | |
144 kind. The text of that help property is displayed in the frame. | |
145 | |
146 For extents, the 'balloon-help' property is | |
147 checked. | |
148 | |
149 For toolbar buttons, the help-string slot of the toolbar button | |
150 is checked. | |
151 | |
152 If the value is a string, it is used as the help message. | |
153 | |
154 If the property's value is a symbol, it is assumed to be the name | |
155 of a function and it will be called with one argument, the object | |
156 under the mouse, and the return value of that function will be | |
157 used as the help message." | |
158 (interactive "P") | |
159 (setq balloon-help-mode (or (and arg (> (prefix-numeric-value arg) 0)) | |
160 (and (null arg) (null balloon-help-mode)))) | |
161 (if (null balloon-help-mode) | |
162 (balloon-help-undisplay-help))) | |
163 | |
164 (defun balloon-help-displayed () | |
165 (and (frame-live-p balloon-help-frame) | |
166 (frame-visible-p balloon-help-frame))) | |
167 | |
168 (defun balloon-help-motion-hook (event) | |
169 (cond | |
170 ((null balloon-help-mode) t) | |
171 ((button-press-event-p event) | |
172 (setq balloon-help-help-object nil) | |
173 (if balloon-help-timeout-id | |
174 (disable-timeout balloon-help-timeout-id)) | |
175 (if (balloon-help-displayed) | |
176 (balloon-help-undisplay-help))) | |
177 (t | |
178 (let* ((buffer (event-buffer event)) | |
179 (frame (event-frame event)) | |
180 (point (and buffer (event-point event))) | |
181 (glyph-extent (event-glyph-extent event)) | |
182 (glyph-extent (if (and glyph-extent | |
183 (extent-property glyph-extent | |
184 'balloon-help)) | |
185 glyph-extent)) | |
186 (extent (and point | |
187 (extent-at point buffer 'balloon-help))) | |
188 (button (event-toolbar-button event)) | |
189 (button (if (and button (toolbar-button-help-string button)) | |
190 button | |
191 nil)) | |
192 (object (or glyph-extent extent button)) | |
193 (id balloon-help-timeout-id)) | |
194 (if (null object) | |
195 (if (and balloon-help-frame | |
196 (not (eq frame balloon-help-frame))) | |
197 (progn | |
198 (setq balloon-help-help-object nil) | |
199 (if id | |
200 (disable-timeout id)) | |
201 (if (balloon-help-displayed) | |
202 (balloon-help-undisplay-help)))) | |
203 (let* ((params (frame-parameters frame)) | |
204 (top (cdr (assq 'top params))) | |
205 (left (cdr (assq 'left params))) | |
206 (xtop-toolbar-height | |
207 (if (specifier-instance top-toolbar) | |
208 (specifier-instance top-toolbar-height) | |
209 0)) | |
210 (xleft-toolbar-width | |
211 (if (specifier-instance left-toolbar) | |
212 (specifier-instance left-toolbar-width) | |
213 0)) | |
214 (menubar-height (if current-menubar 22 0))) | |
215 (setq balloon-help-help-object-x | |
216 (+ left xleft-toolbar-width (event-x-pixel event)) | |
217 balloon-help-help-object-y | |
218 (+ top xtop-toolbar-height menubar-height | |
219 (event-y-pixel event)))) | |
220 (cond ((eq frame balloon-help-frame) t) | |
221 ((eq object balloon-help-help-object) | |
222 (if (balloon-help-displayed) | |
223 (balloon-help-move-help-frame))) | |
224 ((balloon-help-displayed) | |
225 (setq balloon-help-help-object object) | |
226 (balloon-help-display-help)) | |
227 (t | |
228 (setq balloon-help-help-object object) | |
229 (if id | |
230 (disable-timeout id)) | |
231 (setq balloon-help-timeout-id | |
232 (add-timeout (/ balloon-help-timeout 1000.0) | |
233 (function balloon-help-display-help) | |
234 nil))))))))) | |
235 | |
236 (defun balloon-help-pre-command-hook (&rest ignored) | |
237 (setq balloon-help-help-object nil) | |
238 (if (balloon-help-displayed) | |
239 (balloon-help-undisplay-help))) | |
240 | |
241 (fset 'balloon-help-post-command-hook 'balloon-help-pre-command-hook) | |
242 (fset 'balloon-help-mouse-leave-frame-hook 'balloon-help-pre-command-hook) | |
243 (fset 'balloon-help-deselect-frame-hook 'balloon-help-pre-command-hook) | |
244 | |
245 (defun balloon-help-display-help (&rest ignored) | |
246 (setq balloon-help-timeout-id nil) | |
247 (if balloon-help-help-object | |
248 (let* ((object balloon-help-help-object) | |
249 (help (or (and (extent-live-p object) | |
250 (extent-property object 'balloon-help)) | |
251 (and (toolbar-button-p object) | |
252 (toolbar-button-help-string object)) | |
253 (and (stringp object) object)))) | |
254 ;; if help is non-null and is not a string, run it as | |
255 ;; function to produuce the help string. | |
256 (if (or (null help) (not (symbolp help))) | |
257 nil | |
258 (condition-case data | |
259 (setq help (funcall help object)) | |
260 (error | |
261 (setq help (format "help function signaled: %S" data))))) | |
262 (if (stringp help) | |
263 (save-excursion | |
264 (if (not (bufferp balloon-help-buffer)) | |
265 (setq balloon-help-buffer | |
266 (get-buffer-create " *balloon-help*"))) | |
267 (if (not (frame-live-p balloon-help-frame)) | |
268 (setq balloon-help-frame (balloon-help-make-help-frame))) | |
269 (setq bar-cursor t) | |
270 (set-buffer balloon-help-buffer) | |
271 (erase-buffer) | |
272 (insert help) | |
273 (if (not (bolp)) | |
274 (insert ?\n)) | |
275 ;; help strings longer than 2 lines have the last | |
276 ;; line stolen by the minibuffer, so make sure the | |
277 ;; last line is blank. Make the top line blank for | |
278 ;; some symmetry. | |
279 (if (< 2 (count-lines (point-min) (point-max))) | |
280 (progn | |
281 (insert ?\n) | |
282 ;; add a second blank line at the end to | |
283 ;; prevent the modeline bar from clipping the | |
284 ;; descenders of the last line of text. | |
285 (insert ?\n) | |
286 (goto-char (point-min)) | |
287 (insert ?\n))) | |
288 ;; cursor will be at point-min because we're just | |
289 ;; moving point which doesn't affect window-point | |
290 ;; when the window isn't selected. Indent | |
291 ;; everything so that the cursor will be over a | |
292 ;; space. The 1-pixel bar cursor will be | |
293 ;; completely invisible this way. | |
294 (indent-rigidly (point-min) (point-max) 1) | |
295 (balloon-help-move-help-frame) | |
296 (balloon-help-resize-help-frame) | |
297 (balloon-help-expose-help-frame)))))) | |
298 | |
299 (defun balloon-help-undisplay-help () | |
300 (setq bar-cursor balloon-help-bar-cursor) | |
301 (balloon-help-hide-help-frame)) | |
302 | |
303 (defun balloon-help-hide-help-frame () | |
304 (if (balloon-help-displayed) | |
305 (progn | |
306 (make-frame-invisible balloon-help-frame) | |
307 (if (and balloon-help-use-sound balloon-help-display-pending) | |
308 (play-sound 'balloon-help-disappears)) | |
309 (setq balloon-help-display-pending nil)))) | |
310 | |
311 (defun balloon-help-expose-help-frame () | |
312 (if (not (balloon-help-displayed)) | |
313 (progn | |
314 (make-frame-visible balloon-help-frame) | |
315 (if (and balloon-help-use-sound (null balloon-help-display-pending)) | |
316 (play-sound 'balloon-help-appears)) | |
317 (setq balloon-help-display-pending t)))) | |
318 | |
319 (defun balloon-help-resize-help-frame () | |
320 (save-excursion | |
321 (set-buffer balloon-help-buffer) | |
322 (let ((longest 0) | |
323 (lines 0) | |
324 (done nil) | |
325 (window-min-height 1) | |
326 (window-min-width 1)) | |
327 (goto-char (point-min)) | |
328 (while (not done) | |
329 (end-of-line) | |
330 (setq longest (max longest (current-column)) | |
331 done (not (= 0 (forward-line)))) | |
332 (and (not done) (setq lines (1+ lines)))) | |
333 (set-frame-size balloon-help-frame (+ 1 longest) lines)))) | |
334 | |
335 (defun balloon-help-make-help-frame () | |
336 (save-excursion | |
337 (setq balloon-help-bar-cursor bar-cursor) | |
338 (set-buffer balloon-help-buffer) | |
339 (set-buffer-menubar nil) | |
340 (let* ((x (balloon-help-compute-help-frame-x-location)) | |
341 (y (balloon-help-compute-help-frame-y-location)) | |
342 (window-min-height 1) | |
343 (window-min-width 1) | |
344 (frame (make-frame (list | |
345 '(initially-unmapped . t) | |
346 ;; try to evade frame decorations | |
347 (cons 'name (or balloon-help-frame-name | |
348 "xclock")) | |
349 '(border-width . 2) | |
350 (cons 'border-color balloon-help-border-color) | |
351 (cons 'top y) | |
352 (cons 'left x) | |
353 (cons 'popup (selected-frame)) | |
354 '(width . 3) | |
355 '(height . 1))))) | |
356 (set-face-font 'default balloon-help-font frame) | |
357 (set-face-foreground 'default balloon-help-foreground frame) | |
358 (set-face-background 'default balloon-help-background frame) | |
359 (set-face-background-pixmap 'default balloon-help-background-pixmap | |
360 frame) | |
361 (set-window-buffer (frame-selected-window frame) balloon-help-buffer) | |
362 (set-specifier has-modeline-p (cons frame nil)) | |
363 (set-specifier top-toolbar-height (cons frame 0)) | |
364 (set-specifier left-toolbar-width (cons frame 0)) | |
365 (set-specifier right-toolbar-width (cons frame 0)) | |
366 (set-specifier bottom-toolbar-height (cons frame 0)) | |
367 (set-specifier top-toolbar (cons frame nil)) | |
368 (set-specifier left-toolbar (cons frame nil)) | |
369 (set-specifier right-toolbar (cons frame nil)) | |
370 (set-specifier bottom-toolbar (cons frame nil)) | |
371 (set-specifier scrollbar-width (cons frame 0)) | |
372 (set-specifier scrollbar-height (cons frame 0)) | |
373 (set-specifier modeline-shadow-thickness (cons frame 0)) | |
374 (set-face-background 'modeline balloon-help-background frame) | |
375 frame ))) | |
376 | |
377 (defun balloon-help-compute-help-frame-x-location () | |
378 (max 0 (+ 32 balloon-help-help-object-x))) | |
379 | |
380 (defun balloon-help-compute-help-frame-y-location () | |
381 (max 0 (+ 48 balloon-help-help-object-y))) | |
382 | |
383 (defun balloon-help-move-help-frame () | |
384 (let ((x (balloon-help-compute-help-frame-x-location)) | |
385 (y (balloon-help-compute-help-frame-y-location))) | |
386 (set-frame-position balloon-help-frame x y))) | |
387 | |
388 (add-hook 'mouse-motion-hook 'balloon-help-motion-hook) | |
389 (add-hook 'pre-command-hook 'balloon-help-pre-command-hook) | |
390 (add-hook 'post-command-hook 'balloon-help-post-command-hook) | |
391 (add-hook 'mouse-leave-frame-hook 'balloon-help-mouse-leave-frame-hook) | |
392 (add-hook 'deselect-frame-hook 'balloon-help-deselect-frame-hook) |