From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Stephen J. Turnbull" Newsgroups: gmane.emacs.devel Subject: RE: Gtk tabs in emacs, new branch. Date: Wed, 14 Apr 2010 19:30:48 +0900 Message-ID: <87wrwa2unb.fsf@uwakimon.sk.tsukuba.ac.jp> References: <30298845.656931270806476838.JavaMail.www@wwinf4631> <4BBF0C6C.7000909@swipnet.se> <4BC011F5.9010505@swipnet.se> <87tyri429l.fsf@uwakimon.sk.tsukuba.ac.jp> <203268BCBA374E2CA3097FC84362424A@us.oracle.com> <87wrwcfadg.fsf@mail.jurta.org> <87633w3sbh.fsf@uwakimon.sk.tsukuba.ac.jp> <130DBB4176F64517BC3B37A475FD979B@us.oracle.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1271243474 24909 80.91.229.12 (14 Apr 2010 11:11:14 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 14 Apr 2010 11:11:14 +0000 (UTC) Cc: 'Juri Linkov' , =?iso-8859-1?Q?Jan_Dj=E4rv?= , 'Stefan Monnier' , "'Emacs Dev \[emacs-devel\]'" To: "Drew Adams" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Apr 14 13:11:08 2010 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1O20Uq-0002JR-9b for ged-emacs-devel@m.gmane.org; Wed, 14 Apr 2010 13:11:04 +0200 Original-Received: from localhost ([127.0.0.1]:43935 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O20Up-0007RB-BJ for ged-emacs-devel@m.gmane.org; Wed, 14 Apr 2010 07:11:03 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O20JP-00032j-W2 for emacs-devel@gnu.org; Wed, 14 Apr 2010 06:59:16 -0400 Original-Received: from [140.186.70.92] (port=45236 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O20JN-00031s-2s for emacs-devel@gnu.org; Wed, 14 Apr 2010 06:59:15 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O20JK-00043L-9A for emacs-devel@gnu.org; Wed, 14 Apr 2010 06:59:12 -0400 Original-Received: from mtps01.sk.tsukuba.ac.jp ([130.158.97.223]:41912) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1O20JJ-00041g-Nv for emacs-devel@gnu.org; Wed, 14 Apr 2010 06:59:10 -0400 Original-Received: from uwakimon.sk.tsukuba.ac.jp (uwakimon.sk.tsukuba.ac.jp [130.158.99.156]) by mtps01.sk.tsukuba.ac.jp (Postfix) with ESMTP id E68A11535A8; Wed, 14 Apr 2010 19:32:29 +0900 (JST) Original-Received: by uwakimon.sk.tsukuba.ac.jp (Postfix, from userid 1000) id B91D21A3136; Wed, 14 Apr 2010 19:30:48 +0900 (JST) In-Reply-To: <130DBB4176F64517BC3B37A475FD979B@us.oracle.com> X-Mailer: VM 8.0.12-devo-585 under 21.5 (beta29) "garbanzo" a03421eb562b XEmacs Lucid (x86_64-unknown-linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:123622 Archived-At: Drew Adams writes: > > > I want a tab to be able to invoke any function whatever. > > > > While perhaps sufficient generality may require that ability, remember > > that tabs as a metaphor are *not* just a contiguous row of buttons. > > They are ordered, > > Yes. > > > and they "do the same thing" (but to different objects). > > How so? > > It's not clear to me, for example, what you mean by tabs > (necessarily) doing the same thing to different objects. Those are scare quotes. I wouldn't have quoted if I was able to *define* "do the same thing"! Let me start with some definitions: A *tab bar* (what in my previous post I called a "tab control") is a widget which contains several *tabs*, and (usually) a *pane* in which some kind of content is displayed. (In the implementation discussed below I assume the pane is an Emacs window, but that need not be true.) *Tabs* are clickable buttons, but they only appear as part of a tab bar. Within a tab bar, there is a distinguished *top tab*. In cases where the tabs control a specific pane in the display, the top tab is the one associated with the currently visible content. Tabs may also be ordered from left to right (assuming a horizontal orientation to avoid overloading the word "top"). The top tab need not be leftmost, but is always visible and visually distinguishable (unless the user has selected a weird face). Clicking on an individual tab will cause some action to occur, usually reflected by a change in the appearance of the content. It always causes the clicked tab to become the top tab. > Apart from the GUI aspects (including the display question), I see > a tab bar as an ordered sequence of named (Lisp) thingies that you > can select (e.g. by clicking). I therefore think of an alist, where > the keys are the tab names and the values are arbitrary Lisp > objects. That's very adequately represented visually by a toolbar. Why do you want to duplicate the functionality of toolbars in tab bars? > Unlike the case for menus, the structure of the VALUE part of a > bookmark is quite flexible and open (e.g. to user definition), and > the associated action (handler) need not be an Emacs command > (`interactive'). A default handler applies, if none is present > explicitly. To me, the bookmark model is quite general and > corresponds conceptually to a tab: a named Lisp value that can > represent some action to be performed when the tab is selected. "All hope abandon ye who enter here." That's a toolbar. (But I repeat myself. "What I say three times is true." Wait for it!) If toolbars have the restrictions that menus do (which are hardly restrictive, actually; anything that can take a function symbol as a value can implement arbitrary behavior), you can bet that tabs will suffer the same restrictions. > I mentioned that I would also like to be able to perform certain > operations on the tabs of a given tab bar that are similar to > operations that I perform on a list of bookmarks: (1) sort the tabs > in various ways, based on both NAME and VALUE, (2) mark the tabs > and then perform operations on the marked tabs, (3) hide certain > tabs (e.g. those marked), (4) show a set of tabs that might not > already have been shown and then hidden (e.g. to "open" a project > that involves multiple tabs). And so on. > > And I mentioned that (bookmark+) bookmarks can be tagged > (del.icio.us-style), which would mean that tabs would be tagged, so > you could easily manipulate sets of tabs - e.g. all the tabs that > correspond to a particular project or query. > > IOW, individual tabs can be selected, yes, but code (hence users) > should also be able to act on sets of tabs in various ways. Sure. A tab bar will surely be visible to Lisp as a sequence of some kind, and accessed by a variable. I don't see why any of the things you describe above will be prevented by any particular implementation of the action invoked by a tab. > What I'm concerned about is having the generality of associating an > arbitrary handler with each tab. That's a toolbar. Q.E.D. If you really really need both the visual cues provided by a tab bar, and an arbitrary handler for each tab, then (using your alist representation, which is probably as good as any other) you could have (defun my-tab-handler (tab ignored-datum) ; all tab handlers take 2 args (let ((name (nth 0 tab)) (handler (nth 1 tab)) (tab-data (nthcdr 2 tab))) (message "handling tab '%s'" name) (apply handler tab-data))) as the handler, and the tab bar would be represented in Lisp as something like ("This establishment serves only 17-year-old Scottish tabs." ; name/doc my-tab-handler (random) ; random tab-bar-wide datum, not used by my-tab-handler ("One name" handler-1 various data) ("Another name" handler-2 some information) ;; etc etc ) But in most cases, having tab-specific handlers is probably a bad fit for the tab metaphor. Use a toolbar. If your problem with that is that Emacs toolbars are too restrictive, then fix the restrictions. OTOH, a typical over-simplified buffer tab bar would be handled by (defun buffer-tab-handler (tab tab-controlled-window) (with-selected-window tab-controlled-window (switch-to-buffer (second tab)))) (defun make-buffer-tabs (how-many controlled-window) (let ((buffers (buffer-list)) (tabs '(controlled-window buffer-tab-handler "buffer tab"))) (while (and buffers (> how-many 0)) (setq tabs (cons (list (buffer-name (car buffers)) (car buffers)) tabs)) (setq how-many (1- how-many)) (setq buffers (cdr buffers))) (reverse tabs)))