[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
;;; tooltip-at-point.el --- library for displaying tooltips at (point)
From: |
Kevin A. Burton (burtonator) |
Subject: |
;;; tooltip-at-point.el --- library for displaying tooltips at (point) |
Date: |
18 Dec 2002 16:14:00 -0800 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/21.2.90 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
first release... see commentary
;;; tooltip-at-point.el --- library for displaying tooltips at (point)
;; $Id: tooltip-at-point.el,v 1.12 2002/12/19 04:36:45 burton Exp $
;; Copyright (C) 2000-2003 Free Software Foundation, Inc.
;; Copyright (C) 2000-2003 Kevin A. Burton (address@hidden)
;; Author: Kevin A. Burton (address@hidden)
;; Maintainer: Kevin A. Burton (address@hidden)
;; Location: http://relativity.yi.org
;; Keywords:
;; Version: 1.0.0
;; This file is [not yet] part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify it under
;; the terms of the GNU General Public License as published by the Free Software
;; Foundation; either version 2 of the License, or any later version.
;;
;; This program is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;; details.
;;
;; You should have received a copy of the GNU General Public License along with
;; this program; if not, write to the Free Software Foundation, Inc., 59 Temple
;; Place - Suite 330, Boston, MA 02111-1307, USA.
;;; Commentary:
;;
;; This package provides the ability to bring up a tooltip at the current point.
;;
;; For the last year or so I have been frustrated with the fact that Emacs
;; doesn't provide floating windows.
;;
;; I think there is a lot of functionality that Emacs is missing because it
;; can't do complex "quick" user interfaces.
;; This prohibits a lot of functionality. For example I developed a library
;; called irepeat that takes an associated list of data (function calls, method
;; pointers, etc) and quickly sorts through the list as you type. If you have
;; bash it is very much like C-r but supports any data set.
;; The problem is that irepeat is limited to using the minibuffer which isn't
;; really a lot of information for the user. Ideally I would bring up a
;; lightweight buffer right above the minibuffer to show other options available
;; to the user.
;; This was accomplished with the tooltip support available within Emacs 21. The
;; interesting thing about this is that tooltips are implemented with standard
;; Emacs windows and buffers so I can use standard font properties and font-lock
;; code.
;; This could yield some very interesting functionality. I am specifically
;; thinking of eldoc style just-in-time method and function completion and quick
;; documentation lookup.
;; Most modern IDEs (Visual Studio, KDE Studio, Borland JBuilder, IBM Visual
;; Age, etc) support this functionality and there is no reason that Emacs should
;; be left behind.
;; The is only one area that Emacs needs improvement to support this type of
;; API. We need the ability to determine the X and Y (top and left) coords for
;; (point) on the screen (the current active cursor).
;; I have looked through all the Emacs code at length and have found NO way to
;; accomplish through lisp. The only way to do this is through C which
prohibits a
;; lot of innovation by developers.
;; I have tried looking at the Emacs event system but keyboard events to not
;; generate cursor position (only mouse events). I have also tried to pursue
using
;; a hack to move the mouse to the current cursor and back but this also is
;; impossible for a number of reasons.
;; It is also impossible to calculate the cursor position based on frame width,
;; position and window sizes due to the fact that Emacs can use dynamic fonts on
;; Emacs 21.
;; Can the GNU Emacs developers either:
;; # provide an API to determine the x and y coords of the current active
cursor (point)
;; # provide a x-show-top-at-point function that provided the exact same
functionality.
;; Either one of these should be fairly trivial to implement but would deliver a
;; lot of compelling functionality for Emacs users.
;; This package provides an initial tooltip-at-point implementation by
;; "cheating" by temporarily moving the mouse without the user noticing. We are
;; then able to obtain the top and left coords of the point and we then bring up
;; our tooltip at that point.
;; It is hoped that this package will motivate for Emacs developers to
;; incorporate this functionality into the core.
;; I documented my work on tooltips at to following URLs.
;;
;;
http://www.peerfear.org/rss/permalink/2002/11/22/1038017513-Emacs_tooltipatpoint_Implementation.shtml
;;
;;
http://www.peerfear.org/rss/permalink/2002/11/22/1038007519-Emacs_Needs_Floating_Windows.shtml
;; NOTE: If you enjoy this software, please consider a donation to the EFF
;; (http://www.eff.org)
;;; TODO:
;;
;; - Compute offsets based on the current face width and height and use those.
;; If we used fix values they might break on some machines that are using
;; dynamic fonts in some buffers.
;;
;; - is it possible to scroll the tooltip if it is too long? We are going to
;; have to do some serious hacking to get this to work. It would be really nice
;; though.
;;
;; - When we have a lot of lisp loaded the latency for tooltip creation is much
;; higher. Check into temp removing some hooks.
;;
;; - if the tooltip is in the bottom of a window we delete all windows and then
;; put it back.
;;; Code:
;;we need to always use the original functions and not ECB advised functions
(require 'ecb)
(require 'jde-complete-tooltip)
(require 'tooltip-at-point-jde)
(require 'tooltip-at-point-elisp)
(defgroup tooltip-at-point nil
"Tooltip at point options.")
(defcustom tooltip-at-point-x-offset 35
"X offset to use for point tooltips."
:group 'tooltip-at-point
:type 'integer)
(defcustom tooltip-at-point-y-offset -10
"Y offset to use for point tooltips."
:group 'tooltip-at-point
:type 'integer)
(defcustom tooltip-at-point-timeout 200
"Timeout for tooltips"
:group 'tooltip-at-point
:type 'integer)
(defvar tooltip-at-point-activated nil
"True if a tooltip is up that was generated from tooltip-at-point")
(defvar tooltip-at-point-activated-time 0
"Time the last tooltip was activated.")
;;FIXME: I think we should default to using the frames background and
;;foreground. This way we can still have decent UIs based on fonts.
(defface tooltip-at-point '((t (:foreground "black" :background "lightyellow")))
"Face for tooltips raised at the current point."
:group 'tooltip-at-point)
(defun tooltip-at-point--x-max-tooltip-size()
"Get the max tooltip size that we should be using."
;; determine this automatically in the future.
(cons 120 80))
(defun tooltip-at-point(content)
"Show a tooltip at the given point with the given content represented as a
string. See `x-show-tip'."
(interactive
(list "hello tooltip-at-point world"))
;;tooltip mode needs to be on for mouse tracking so that tips can be disabled
(tooltip-mode 1)
;;(recenter 2)
(let((mouse-position nil)
(point-position nil)
(tip-position nil)
(left 0)
(top 0)
(window-edges nil)
(ecb-activate-adviced-functions nil))
(save-window-excursion
;;cache the current mouse position.
(setq mouse-position (mouse-position))
;;set the position of the point.
(setq point-position (mouse-avoidance-point-position))
(set-mouse-position (car point-position)
(car (cdr point-position))
(cdr (cdr point-position)))
(setq tip-position (cdr (mouse-pixel-position)))
;;we now have the point position cached at tip-position
;;restore the mouse position
(let((mouse-x 0)
(mouse-y 0))
;;this is a trick.. if the mouse is off of screen the mouse-position
;;will contain 0... we actually want it to do this so that we don't keep
;;the mouse over the current (point) which would confuse the user.
(when (and (car (cdr mouse-position))
(cdr (cdr mouse-position)))
(setq mouse-x (car (cdr mouse-position)))
(setq mouse-y (cdr (cdr mouse-position))))
(set-mouse-position (car mouse-position) mouse-x mouse-y))
;;compute the left and top coords
(setq window-edges (window-edges))
(setq left (+ (car tip-position)
(frame-parameter (selected-frame) 'left)
tooltip-at-point-x-offset))
(setq top (+ (cdr tip-position)
(frame-parameter (selected-frame) 'top)
(nth 3 window-edges)
tooltip-at-point-y-offset)))
;;now display the tooltip at the tip-position
(let((tooltip-use-echo-area nil)
(tooltip-delay 0)
(tooltip-short-delay 0)
(tooltip-recent-seconds 0)
(x-max-tooltip-size (tooltip-at-point--x-max-tooltip-size)))
(setq tooltip-at-point-activated t)
(setq tooltip-at-point-activated-time (float-time))
(x-show-tip content
(selected-frame)
(list (cons 'left left)
(cons 'top top)
(cons 'foreground-color (face-attribute
'tooltip-at-point :foreground))
(cons 'border-color "lightyellow") ;;we should always
;;be lightyellow so that even in dark mode they
;;show up
(cons 'background-color (face-attribute
'tooltip-at-point :background)))
tooltip-at-point-timeout))))
(defun tooltip-hide (&optional ignored-arg)
"Hide a tooltip, if one is displayed.
Value is non-nil if tooltip was open."
(interactive)
;;FIXME: but we can go ahead and break if it is a keyboard event.
;;never hide if < X milliseconds
(if (and tooltip-at-point-activated
(> (- (float-time) tooltip-at-point-activated-time) 1))
(progn
(tooltip-hide--impl))
(if (null tooltip-at-point-activated)
(progn
(tooltip-hide--impl)))))
(defun tooltip-at-point--mouse-event-p(event)
"Return true if this was a mouse event."
(listp event))
(defun tooltip-hide--impl(&optional ignored-arg)
"Impl of tooltip hiding..."
(tooltip-cancel-delayed-tip)
(when (x-hide-tip)
(setq tooltip-hide-time (float-time))
(setq tooltip-at-point-activated nil)))
(provide 'tooltip-at-point)
;;; tooltip-at-point.el ends here?
- --
Kevin A. Burton ( address@hidden, address@hidden, address@hidden )
Location - San Francisco, CA, Cell - 415.595.9965
Jabber - address@hidden, Web - http://www.peerfear.org/
GPG fingerprint: 4D20 40A0 C734 307E C7B4 DCAA 0303 3AC5 BD9D 7C4D
IRC - openprojects.net #infoanarchy | #p2p-hackers | #reptile
National borders aren't even speed bumps on the information superhighway.
- --Tim May
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)
Comment: Get my public key at: http://relativity.yi.org/pgpkey.txt
iD8DBQE+AQ9IAwM6xb2dfE0RApZkAJ99YN0HR3BsO4/wVHuPBa4OY3ll0wCdHC5m
ZJf2Tcsc+uaHANZi+nXhkw4=
=z6n6
-----END PGP SIGNATURE-----
- ;;; tooltip-at-point.el --- library for displaying tooltips at (point),
Kevin A. Burton (burtonator) <=