* riece-options.el (riece-use-full-window): Abolish unused option.
[riece] / lisp / riece-layout.el
1 ;;; riece-layout.el --- layout management
2 ;; Copyright (C) 1998-2003 Daiki Ueno
3
4 ;; Author: Daiki Ueno <ueno@unixuser.org>
5 ;;      TAKAHASHI "beatmaria" Kaoru <kaoru@kaisei.org>
6 ;; Keywords: IRC, riece
7
8 ;; This file is part of Riece.
9
10 ;; This program 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 ;; This program 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., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;;; Code:
26
27 (require 'riece-globals)
28 (require 'riece-misc)
29
30 (defgroup riece-layout nil
31   "Window layouts."
32   :prefix "riece-"
33   :group 'riece)
34
35 (defcustom riece-layout "default"
36   "Current layout setting."
37   :type 'string
38   :group 'riece-layout)
39
40 (defcustom riece-layout-alist
41   '(("middle-right" riece-configure-windows right middle)
42     ("middle-left" riece-configure-windows left middle)
43     ("top-right" riece-configure-windows right top)
44     ("top-left" riece-configure-windows left top)
45     ("bottom-right" riece-configure-windows right bottom)
46     ("bottom-left" riece-configure-windows left bottom)
47     ("top" riece-configure-windows-top)
48     ("spiral" riece-configure-windows-spiral)
49     ("one-window" riece-configure-windows-one-window)
50     ("default" . "middle-right"))
51   "An alist mapping the names to layout functions.
52 An element of this alist is either in the following forms:
53
54 \(NAME CONFIGURE-FUNCTION [PARAMETERS]\)
55 \(NAME1 . NAME2\)
56
57 In the first form, NAME is a string which specifies the layout
58 setting, and CONFIGURE-FUNCTION is a function which does window
59 splitting, etc.  PARAMETERS are collected and passed to CONFIGURE-FUNCTION.
60 In the second form, NAME1 is an alias for NAME2."
61   :type '(repeat (choice (list :tag "Layout"
62                                (string :tag "Name")
63                                (function :tag "Configure function")
64                                (repeat :tag "Parameters" :inline t symbol))
65                          (cons :tag "Alias" string string)))
66   :group 'riece-layout)
67
68 (defun riece-redraw-layout (&optional force)
69   "Reconfigure windows with the current layout.
70 If optional argument FORCE is non-nil, window reconfiguration will
71 happen unconditionally."
72   (let ((layout (cdr (assoc riece-layout riece-layout-alist))))
73     (unless layout
74       (error "No such layout!"))
75     (if (stringp layout)
76         (let ((riece-layout layout))
77           (riece-redraw-layout force))
78       (if (or force
79               (riece-reconfigure-windows-predicate))
80           (apply (car layout) (cdr layout))))))
81
82 (defun riece-set-window-points ()
83   (if (get-buffer-window riece-user-list-buffer)
84       (with-current-buffer riece-user-list-buffer
85         (unless (riece-frozen riece-user-list-buffer)
86           (set-window-start (get-buffer-window riece-user-list-buffer)
87                             (point-min)))))
88   (if (get-buffer-window riece-channel-list-buffer)
89       (with-current-buffer riece-channel-list-buffer
90         (unless (riece-frozen riece-channel-list-buffer)
91           (set-window-start (get-buffer-window riece-channel-list-buffer)
92                             (point-min)))))
93   (if (and riece-channel-buffer
94            (get-buffer-window riece-channel-buffer))
95       (with-current-buffer riece-channel-buffer
96         (if (riece-frozen riece-channel-buffer)
97             (if riece-channel-buffer-window-point
98                 (set-window-point (get-buffer-window riece-channel-buffer)
99                                   riece-channel-buffer-window-point))
100           (set-window-point (get-buffer-window riece-channel-buffer)
101                             (point-max)))))
102   (if (get-buffer-window riece-others-buffer)
103       (with-current-buffer riece-others-buffer
104         (unless (riece-frozen riece-others-buffer)
105           (set-window-point (get-buffer-window riece-others-buffer)
106                             (point-max)))))
107   (if (get-buffer-window riece-dialogue-buffer)
108       (with-current-buffer riece-dialogue-buffer
109         (unless (riece-frozen riece-dialogue-buffer)
110           (set-window-point (get-buffer-window riece-dialogue-buffer)
111                             (point-max))))))
112
113 (defun riece-reconfigure-windows-predicate ()
114   "Return t, if window reconfiguration is needed.
115 This function is used by \"default\" layout."
116   (memq (window-buffer (selected-window))
117         riece-buffer-list))
118
119 (defun riece-configure-windows (hpos vpos)
120   (let ((buffer (window-buffer))
121         (show-user-list
122          (and riece-user-list-buffer-mode
123               riece-current-channel
124               ;; User list buffer is nuisance for private conversation.
125               (riece-channel-p (riece-identity-prefix
126                                 riece-current-channel)))))
127     ;; Can't expand minibuffer to full frame.
128     (if (eq (selected-window) (minibuffer-window))
129         (other-window 1))
130     (delete-other-windows)
131     (if (and riece-current-channel
132              (or show-user-list riece-channel-list-buffer-mode))
133         (let ((rest-window (split-window (selected-window)
134                                          (if (eq hpos 'left)
135                                              (- (window-width)
136                                                 (/ (window-width) 5))
137                                            (/ (window-width) 5))
138                                          t)))
139           (when (eq hpos 'left)
140             (setq rest-window (selected-window))
141             (other-window 1))
142           (if (and show-user-list riece-channel-list-buffer-mode)
143               (progn
144                 (set-window-buffer (split-window)
145                                    riece-channel-list-buffer)
146                 (set-window-buffer (selected-window)
147                                    riece-user-list-buffer))
148             (if show-user-list
149                 (set-window-buffer (selected-window)
150                                    riece-user-list-buffer)
151               (if riece-channel-list-buffer-mode
152                   (set-window-buffer (selected-window)
153                                      riece-channel-list-buffer))))
154           (select-window rest-window)))
155     (if (and riece-current-channel
156              riece-channel-buffer-mode)
157         (progn
158           (if (eq vpos 'top)
159               (let ((rest-window (split-window nil 4)))
160                 (set-window-buffer (selected-window)
161                                    riece-command-buffer)
162                 (select-window rest-window)
163                 (if riece-others-buffer-mode
164                     (set-window-buffer (split-window rest-window)
165                                        riece-others-buffer))
166                 (set-window-buffer (selected-window)
167                                    riece-channel-buffer))
168             (if (and (eq vpos 'middle)
169                      riece-others-buffer-mode)
170                 (let ((rest-window (split-window)))
171                   (set-window-buffer (selected-window)
172                                      riece-channel-buffer)
173                   (set-window-buffer (split-window rest-window 4)
174                                      riece-others-buffer)
175                   (set-window-buffer rest-window
176                                      riece-command-buffer))
177               (let ((rest-window (split-window nil (- (window-height) 4))))
178                 (if riece-others-buffer-mode
179                     (progn
180                       (set-window-buffer (selected-window)
181                                          riece-others-buffer)
182                       (set-window-buffer (split-window)
183                                          riece-channel-buffer))
184                   (set-window-buffer (selected-window)
185                                      riece-channel-buffer))
186                 (set-window-buffer rest-window
187                                    riece-command-buffer)))))
188       (if (eq vpos 'bottom)
189           (progn
190             (set-window-buffer (selected-window)
191                                riece-command-buffer)
192             (set-window-buffer (split-window (selected-window) 4)
193                                riece-dialogue-buffer))
194         (set-window-buffer (split-window (selected-window) 4)
195                            riece-dialogue-buffer)
196         (set-window-buffer (selected-window)
197                            riece-command-buffer)))
198     (riece-set-window-points)
199     (select-window (or (get-buffer-window buffer)
200                        (get-buffer-window riece-command-buffer)))))
201
202 (defun riece-configure-windows-top (&rest plist)
203   "Candidate of `riece-configure-windows-function'.
204 PLIST accept :command-height, :user-list-width, and :channel-list-width."
205   (let ((command-height (or (plist-get plist :command-height) 4))
206         (user-list-width (or (plist-get plist :user-list-width) (+ 9 1 1)))
207         (channel-list-width (or (plist-get plist :channel-list-width) 18))
208         (buffer (window-buffer))
209         (show-user-list
210          (and riece-user-list-buffer-mode
211               riece-current-channel
212               ;; User list buffer is nuisance for private conversation.
213               (riece-channel-p (riece-identity-prefix
214                                 riece-current-channel)))))
215     ;; Can't expand minibuffer to full frame.
216     (when (eq (selected-window) (minibuffer-window))
217       (other-window 1))
218     (delete-other-windows)
219     ;; top of frame
220     (let ((rest-window (split-window (selected-window) command-height)))
221       (set-window-buffer (selected-window)
222                          riece-command-buffer)
223       (select-window rest-window))
224     ;; middle of frame (vertical-spilit when need)
225     (when (or (and riece-current-channel riece-channel-buffer-mode)
226               show-user-list)
227       (let ((rest-window
228              (split-window (selected-window)
229                            (/ (* 5 (+ (window-height) command-height)) 8))))
230         (cond
231          ;; channel-buffer + user-list
232          ((and show-user-list
233                (and riece-current-channel riece-channel-buffer-mode))
234           (let ((user-list-window (split-window (selected-window) nil t)))
235             (set-window-buffer (selected-window) riece-channel-buffer)
236             (set-window-buffer user-list-window riece-user-list-buffer)
237             (select-window user-list-window)
238             (shrink-window-horizontally (- (window-width) user-list-width))))
239          ;; only user-list
240          (show-user-list
241           (set-window-buffer (selected-window) riece-user-list-buffer))
242          ;; only channel-buffer
243          (riece-channel-buffer-mode
244           (set-window-buffer (selected-window) riece-channel-buffer)))
245         (select-window rest-window)))
246     ;; bottom of frame
247     (if (and riece-current-channel
248              riece-channel-list-buffer-mode)
249         (let ((channel-list-window (split-window (selected-window) nil t)))
250           (set-window-buffer (selected-window) riece-others-buffer)
251           (set-window-buffer channel-list-window riece-channel-list-buffer)
252           (select-window channel-list-window)
253           (shrink-window-horizontally (- (window-width) channel-list-width)))
254       (set-window-buffer (selected-window) riece-dialogue-buffer))
255     (riece-set-window-points)
256     (select-window (or (get-buffer-window buffer)
257                        (get-buffer-window riece-command-buffer)))))
258
259 ;; +---+-------------------+---+
260 ;; | c | channel           | u |
261 ;; | h |                   | s |
262 ;; | a |                   | e |
263 ;; | n |-------------------+ r |   | +---+
264 ;; | n | command           | s |   | |   |
265 ;; | e +-------------------+---+   | +-> |
266 ;; | l | others                |   +-----+
267 ;; | s |                       |
268 ;; +---+-----------------------+
269 (defun riece-configure-windows-spiral ()
270   "spiral placement of windows"
271 ;;  (interactive)
272   (let ((command-height 4)
273         (users-width    15)
274         (channels-width 30)
275         (buffer         (window-buffer)))
276     (when (eq (selected-window) (minibuffer-window)) (other-window 1))
277     (delete-other-windows)
278
279     ;; (1) create channels window
280     (let ((rest (split-window (selected-window) channels-width t)))
281       (set-window-buffer (selected-window) riece-channel-list-buffer)
282       (select-window rest))
283
284     ;; (2) create others window
285     (set-window-buffer (split-window (selected-window)
286                                      (+ (/ (window-height) 2)
287                                         command-height))
288                        riece-others-buffer)
289
290     ;; (3) create users window
291     (set-window-buffer (split-window (selected-window)
292                                      (- (window-width) users-width) t)
293                        riece-user-list-buffer)
294   
295     ;; (4) create current channel window
296     (let ((rest (split-window (selected-window)
297                               (- (window-height) command-height))))
298       (set-window-buffer rest riece-command-buffer)
299       (set-window-buffer (selected-window) riece-channel-buffer))
300
301     (riece-set-window-points)
302     (select-window (or (get-buffer-window buffer)
303                        (get-buffer-window riece-command-buffer)))))
304
305 (defun riece-configure-windows-one-window ()
306   ;; Can't expand minibuffer to full frame.
307   (if (eq (selected-window) (minibuffer-window))
308       (other-window 1))
309   (delete-other-windows)
310   (set-window-buffer (selected-window) riece-dialogue-buffer))
311
312 (provide 'riece-layout)
313
314 ;;; riece-layout.el ends here