1 ;;; riece-layout.el --- layout management
2 ;; Copyright (C) 1998-2003 Daiki Ueno
4 ;; Author: Daiki Ueno <ueno@unixuser.org>
5 ;; TAKAHASHI Kaoru <kaoru@kaisei.org>
6 ;; Keywords: IRC, riece
8 ;; This file is part of Riece.
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)
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.
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.
27 (require 'riece-globals)
30 (defgroup riece-layout nil
35 (defcustom riece-layout "default"
36 "Current layout setting."
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:
54 \(NAME CONFIGURE-FUNCTION [PARAMETERS]\)
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"
63 (function :tag "Configure function")
64 (repeat :tag "Parameters" :inline t symbol))
65 (cons :tag "Alias" string string)))
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))))
74 (error "No such layout!"))
76 (let ((riece-layout layout))
77 (riece-redraw-layout force))
79 (riece-reconfigure-windows-predicate))
80 (apply (car layout) (cdr layout))))))
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)
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)
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)
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)
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)
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))
119 (defun riece-configure-windows (hpos vpos)
120 (let ((buffer (window-buffer))
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))
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)
136 (/ (window-width) 5))
137 (/ (window-width) 5))
139 (when (eq hpos 'left)
140 (setq rest-window (selected-window))
142 (if (and show-user-list riece-channel-list-buffer-mode)
144 (set-window-buffer (split-window)
145 riece-channel-list-buffer)
146 (set-window-buffer (selected-window)
147 riece-user-list-buffer))
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)
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)
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
180 (set-window-buffer (selected-window)
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)
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)))))
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))
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))
218 (delete-other-windows)
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)
228 (split-window (selected-window)
229 (/ (* 5 (+ (window-height) command-height)) 8))))
231 ;; channel-buffer + 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))))
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)))
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)))))
259 ;; +---+-------------------+---+
260 ;; | c | channel | u |
263 ;; | n |-------------------+ r | | +---+
264 ;; | n | command | s | | | |
265 ;; | e +-------------------+---+ | +-> |
266 ;; | l | others | +-----+
268 ;; +---+-----------------------+
269 (defun riece-configure-windows-spiral ()
270 "spiral placement of windows"
272 (let ((command-height 4)
275 (buffer (window-buffer)))
276 (when (eq (selected-window) (minibuffer-window)) (other-window 1))
277 (delete-other-windows)
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))
284 ;; (2) create others window
285 (set-window-buffer (split-window (selected-window)
286 (+ (/ (window-height) 2)
290 ;; (3) create users window
291 (set-window-buffer (split-window (selected-window)
292 (- (window-width) users-width) t)
293 riece-user-list-buffer)
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))
301 (riece-set-window-points)
302 (select-window (or (get-buffer-window buffer)
303 (get-buffer-window riece-command-buffer)))))
305 (defun riece-configure-windows-one-window ()
306 ;; Can't expand minibuffer to full frame.
307 (if (eq (selected-window) (minibuffer-window))
309 (delete-other-windows)
310 (set-window-buffer (selected-window) riece-dialogue-buffer))
312 (provide 'riece-layout)
314 ;;; riece-layout.el ends here