* riece-addon.el (riece-command-list-addons): Use
[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., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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     ("default" . "middle-right"))
49   "An alist mapping the names to layout functions.
50 An element of this alist is either in the following forms:
51
52 \(NAME CONFIGURE-FUNCTION [PARAMETERS]\)
53 \(NAME1 . NAME2\)
54
55 In the first form, NAME is a string which specifies the layout
56 setting, and CONFIGURE-FUNCTION is a function which does window
57 splitting, etc.  PARAMETERS are collected and passed to CONFIGURE-FUNCTION.
58 In the second form, NAME1 is an alias for NAME2."
59   :type 'list
60   :group 'riece-layout)
61
62 (defun riece-redraw-layout (&optional force)
63   "Reconfigure windows with the current layout.
64 If optional argument FORCE is non-nil, window reconfiguration will
65 happen unconditionally."
66   (let ((layout (cdr (assoc riece-layout riece-layout-alist))))
67     (unless layout
68       (error "No such layout!"))
69     (if (stringp layout)
70         (let ((riece-layout layout))
71           (riece-redraw-layout force))
72       (if (or force
73               (riece-reconfigure-windows-predicate))
74           (apply (car layout) (cdr layout))))))
75
76 (defun riece-set-window-points ()
77   (if (get-buffer-window riece-user-list-buffer)
78       (with-current-buffer riece-user-list-buffer
79         (unless (riece-frozen riece-user-list-buffer)
80           (set-window-start (get-buffer-window riece-user-list-buffer)
81                             (point-min)))))
82   (if (get-buffer-window riece-channel-list-buffer)
83       (with-current-buffer riece-channel-list-buffer
84         (unless (riece-frozen riece-channel-list-buffer)
85           (set-window-start (get-buffer-window riece-channel-list-buffer)
86                             (point-min)))))
87   (if (and riece-channel-buffer
88            (get-buffer-window riece-channel-buffer))
89       (with-current-buffer riece-channel-buffer
90         (if (riece-frozen riece-channel-buffer)
91             (if riece-channel-buffer-window-point
92                 (set-window-point (get-buffer-window riece-channel-buffer)
93                                   riece-channel-buffer-window-point))
94           (set-window-point (get-buffer-window riece-channel-buffer)
95                             (point-max)))))
96   (if (get-buffer-window riece-others-buffer)
97       (with-current-buffer riece-others-buffer
98         (unless (riece-frozen riece-others-buffer)
99           (set-window-point (get-buffer-window riece-others-buffer)
100                             (point-max)))))
101   (if (get-buffer-window riece-dialogue-buffer)
102       (with-current-buffer riece-dialogue-buffer
103         (unless (riece-frozen riece-dialogue-buffer)
104           (set-window-point (get-buffer-window riece-dialogue-buffer)
105                             (point-max))))))
106
107 (defun riece-reconfigure-windows-predicate ()
108   "Return t, if window reconfiguration is needed.
109 This function is used by \"default\" layout."
110   (memq (window-buffer (selected-window))
111         riece-buffer-list))
112
113 (defun riece-configure-windows (hpos vpos)
114   (let ((buffer (window-buffer))
115         (show-user-list
116          (and riece-user-list-buffer-mode
117               riece-current-channel
118               ;; User list buffer is nuisance for private conversation.
119               (riece-channel-p (riece-identity-prefix
120                                 riece-current-channel)))))
121     ;; Can't expand minibuffer to full frame.
122     (if (eq (selected-window) (minibuffer-window))
123         (other-window 1))
124     (delete-other-windows)
125     (if (and riece-current-channel
126              (or show-user-list riece-channel-list-buffer-mode))
127         (let ((rest-window (split-window (selected-window)
128                                          (if (eq hpos 'left)
129                                              (- (window-width)
130                                                 (/ (window-width) 5))
131                                            (/ (window-width) 5))
132                                          t)))
133           (when (eq hpos 'left)
134             (setq rest-window (selected-window))
135             (other-window 1))
136           (if (and show-user-list riece-channel-list-buffer-mode)
137               (progn
138                 (set-window-buffer (split-window)
139                                    riece-channel-list-buffer)
140                 (set-window-buffer (selected-window)
141                                    riece-user-list-buffer))
142             (if show-user-list
143                 (set-window-buffer (selected-window)
144                                    riece-user-list-buffer)
145               (if riece-channel-list-buffer-mode
146                   (set-window-buffer (selected-window)
147                                      riece-channel-list-buffer))))
148           (select-window rest-window)))
149     (if (and riece-current-channel
150              riece-channel-buffer-mode)
151         (progn
152           (if (eq vpos 'top)
153               (let ((rest-window (split-window nil 4)))
154                 (set-window-buffer (selected-window)
155                                    riece-command-buffer)
156                 (select-window rest-window)
157                 (if riece-others-buffer-mode
158                     (set-window-buffer (split-window rest-window)
159                                        riece-others-buffer))
160                 (set-window-buffer (selected-window)
161                                    riece-channel-buffer))
162             (if (and (eq vpos 'middle)
163                      riece-others-buffer-mode)
164                 (let ((rest-window (split-window)))
165                   (set-window-buffer (selected-window)
166                                      riece-channel-buffer)
167                   (set-window-buffer (split-window rest-window 4)
168                                      riece-others-buffer)
169                   (set-window-buffer rest-window
170                                      riece-command-buffer))
171               (let ((rest-window (split-window nil (- (window-height) 4))))
172                 (if riece-others-buffer-mode
173                     (progn
174                       (set-window-buffer (selected-window)
175                                          riece-others-buffer)
176                       (set-window-buffer (split-window)
177                                          riece-channel-buffer))
178                   (set-window-buffer (selected-window)
179                                      riece-channel-buffer))
180                 (set-window-buffer rest-window
181                                    riece-command-buffer)))))
182       (if (eq vpos 'bottom)
183           (progn
184             (set-window-buffer (selected-window)
185                                riece-command-buffer)
186             (set-window-buffer (split-window (selected-window) 4)
187                                riece-dialogue-buffer))
188         (set-window-buffer (split-window (selected-window) 4)
189                            riece-dialogue-buffer)
190         (set-window-buffer (selected-window)
191                            riece-command-buffer)))
192     (riece-set-window-points)
193     (select-window (or (get-buffer-window buffer)
194                        (get-buffer-window riece-command-buffer)))))
195
196 (defun riece-configure-windows-top (&rest plist)
197   "Candidate of `riece-configure-windows-function'.
198 PLIST accept :command-height, :user-list-width, and :channel-list-width."
199   (let ((command-height (or (plist-get plist :command-height) 4))
200         (user-list-width (or (plist-get plist :user-list-width) (+ 9 1 1)))
201         (channel-list-width (or (plist-get plist :channel-list-width) 18))
202         (buffer (window-buffer))
203         (show-user-list
204          (and riece-user-list-buffer-mode
205               riece-current-channel
206               ;; User list buffer is nuisance for private conversation.
207               (riece-channel-p (riece-identity-prefix
208                                 riece-current-channel)))))
209     ;; Can't expand minibuffer to full frame.
210     (when (eq (selected-window) (minibuffer-window))
211       (other-window 1))
212     (delete-other-windows)
213     ;; top of frame
214     (let ((rest-window (split-window (selected-window) command-height)))
215       (set-window-buffer (selected-window)
216                          riece-command-buffer)
217       (select-window rest-window))
218     ;; middle of frame (vertical-spilit when need)
219     (when (or (and riece-current-channel riece-channel-buffer-mode)
220               show-user-list)
221       (let ((rest-window
222              (split-window (selected-window)
223                            (/ (* 5 (+ (window-height) command-height)) 8))))
224         (cond
225          ;; channel-buffer + user-list
226          ((and show-user-list
227                (and riece-current-channel riece-channel-buffer-mode))
228           (let ((user-list-window (split-window (selected-window) nil t)))
229             (set-window-buffer (selected-window) riece-channel-buffer)
230             (set-window-buffer user-list-window riece-user-list-buffer)
231             (select-window user-list-window)
232             (shrink-window-horizontally (- (window-width) user-list-width))))
233          ;; only user-list
234          (show-user-list
235           (set-window-buffer (selected-window) riece-user-list-buffer))
236          ;; only channel-buffer
237          (riece-channel-buffer-mode
238           (set-window-buffer (selected-window) riece-channel-buffer)))
239         (select-window rest-window)))
240     ;; bottom of frame
241     (if (and riece-current-channel
242              riece-channel-list-buffer-mode)
243         (let ((channel-list-window (split-window (selected-window) nil t)))
244           (set-window-buffer (selected-window) riece-others-buffer)
245           (set-window-buffer channel-list-window riece-channel-list-buffer)
246           (select-window channel-list-window)
247           (shrink-window-horizontally (- (window-width) channel-list-width)))
248       (set-window-buffer (selected-window) riece-dialogue-buffer))
249     (riece-set-window-points)
250     (select-window (or (get-buffer-window buffer)
251                        (get-buffer-window riece-command-buffer)))))
252
253 (provide 'riece-layout)
254
255 ;;; riece-layout.el ends here