1 ;;; riece-layout.el --- layout management
2 ;; Copyright (C) 1998-2003 Daiki Ueno
4 ;; Author: Daiki Ueno <ueno@unixuser.org>
5 ;; TAKAHASHI "beatmaria" 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 ("default" . "middle-right"))
50 "An alist mapping the names to layout functions.
51 An element of this alist is either in the following forms:
53 \(NAME CONFIGURE-FUNCTION [PARAMETERS]\)
56 In the first form, NAME is a string which specifies the layout
57 setting, and CONFIGURE-FUNCTION is a function which does window
58 splitting, etc. PARAMETERS are collected and passed to CONFIGURE-FUNCTION.
59 In the second form, NAME1 is an alias for NAME2."
63 (defun riece-redraw-layout (&optional force)
64 "Reconfigure windows with the current layout.
65 If optional argument FORCE is non-nil, window reconfiguration will
66 happen unconditionally."
67 (let ((layout (cdr (assoc riece-layout riece-layout-alist))))
69 (error "No such layout!"))
71 (let ((riece-layout layout))
72 (riece-redraw-layout force))
74 (riece-reconfigure-windows-predicate))
75 (apply (car layout) (cdr layout))))))
77 (defun riece-set-window-points ()
78 (if (get-buffer-window riece-user-list-buffer)
79 (with-current-buffer riece-user-list-buffer
80 (unless (riece-frozen riece-user-list-buffer)
81 (set-window-start (get-buffer-window riece-user-list-buffer)
83 (if (get-buffer-window riece-channel-list-buffer)
84 (with-current-buffer riece-channel-list-buffer
85 (unless (riece-frozen riece-channel-list-buffer)
86 (set-window-start (get-buffer-window riece-channel-list-buffer)
88 (if (and riece-channel-buffer
89 (get-buffer-window riece-channel-buffer))
90 (with-current-buffer riece-channel-buffer
91 (if (riece-frozen riece-channel-buffer)
92 (if riece-channel-buffer-window-point
93 (set-window-point (get-buffer-window riece-channel-buffer)
94 riece-channel-buffer-window-point))
95 (set-window-point (get-buffer-window riece-channel-buffer)
97 (if (get-buffer-window riece-others-buffer)
98 (with-current-buffer riece-others-buffer
99 (unless (riece-frozen riece-others-buffer)
100 (set-window-point (get-buffer-window riece-others-buffer)
102 (if (get-buffer-window riece-dialogue-buffer)
103 (with-current-buffer riece-dialogue-buffer
104 (unless (riece-frozen riece-dialogue-buffer)
105 (set-window-point (get-buffer-window riece-dialogue-buffer)
108 (defun riece-reconfigure-windows-predicate ()
109 "Return t, if window reconfiguration is needed.
110 This function is used by \"default\" layout."
111 (memq (window-buffer (selected-window))
114 (defun riece-configure-windows (hpos vpos)
115 (let ((buffer (window-buffer))
117 (and riece-user-list-buffer-mode
118 riece-current-channel
119 ;; User list buffer is nuisance for private conversation.
120 (riece-channel-p (riece-identity-prefix
121 riece-current-channel)))))
122 ;; Can't expand minibuffer to full frame.
123 (if (eq (selected-window) (minibuffer-window))
125 (delete-other-windows)
126 (if (and riece-current-channel
127 (or show-user-list riece-channel-list-buffer-mode))
128 (let ((rest-window (split-window (selected-window)
131 (/ (window-width) 5))
132 (/ (window-width) 5))
134 (when (eq hpos 'left)
135 (setq rest-window (selected-window))
137 (if (and show-user-list riece-channel-list-buffer-mode)
139 (set-window-buffer (split-window)
140 riece-channel-list-buffer)
141 (set-window-buffer (selected-window)
142 riece-user-list-buffer))
144 (set-window-buffer (selected-window)
145 riece-user-list-buffer)
146 (if riece-channel-list-buffer-mode
147 (set-window-buffer (selected-window)
148 riece-channel-list-buffer))))
149 (select-window rest-window)))
150 (if (and riece-current-channel
151 riece-channel-buffer-mode)
154 (let ((rest-window (split-window nil 4)))
155 (set-window-buffer (selected-window)
156 riece-command-buffer)
157 (select-window rest-window)
158 (if riece-others-buffer-mode
159 (set-window-buffer (split-window rest-window)
160 riece-others-buffer))
161 (set-window-buffer (selected-window)
162 riece-channel-buffer))
163 (if (and (eq vpos 'middle)
164 riece-others-buffer-mode)
165 (let ((rest-window (split-window)))
166 (set-window-buffer (selected-window)
167 riece-channel-buffer)
168 (set-window-buffer (split-window rest-window 4)
170 (set-window-buffer rest-window
171 riece-command-buffer))
172 (let ((rest-window (split-window nil (- (window-height) 4))))
173 (if riece-others-buffer-mode
175 (set-window-buffer (selected-window)
177 (set-window-buffer (split-window)
178 riece-channel-buffer))
179 (set-window-buffer (selected-window)
180 riece-channel-buffer))
181 (set-window-buffer rest-window
182 riece-command-buffer)))))
183 (if (eq vpos 'bottom)
185 (set-window-buffer (selected-window)
186 riece-command-buffer)
187 (set-window-buffer (split-window (selected-window) 4)
188 riece-dialogue-buffer))
189 (set-window-buffer (split-window (selected-window) 4)
190 riece-dialogue-buffer)
191 (set-window-buffer (selected-window)
192 riece-command-buffer)))
193 (riece-set-window-points)
194 (select-window (or (get-buffer-window buffer)
195 (get-buffer-window riece-command-buffer)))))
197 (defun riece-configure-windows-top (&rest plist)
198 "Candidate of `riece-configure-windows-function'.
199 PLIST accept :command-height, :user-list-width, and :channel-list-width."
200 (let ((command-height (or (plist-get plist :command-height) 4))
201 (user-list-width (or (plist-get plist :user-list-width) (+ 9 1 1)))
202 (channel-list-width (or (plist-get plist :channel-list-width) 18))
203 (buffer (window-buffer))
205 (and riece-user-list-buffer-mode
206 riece-current-channel
207 ;; User list buffer is nuisance for private conversation.
208 (riece-channel-p (riece-identity-prefix
209 riece-current-channel)))))
210 ;; Can't expand minibuffer to full frame.
211 (when (eq (selected-window) (minibuffer-window))
213 (delete-other-windows)
215 (let ((rest-window (split-window (selected-window) command-height)))
216 (set-window-buffer (selected-window)
217 riece-command-buffer)
218 (select-window rest-window))
219 ;; middle of frame (vertical-spilit when need)
220 (when (or (and riece-current-channel riece-channel-buffer-mode)
223 (split-window (selected-window)
224 (/ (* 5 (+ (window-height) command-height)) 8))))
226 ;; channel-buffer + user-list
228 (and riece-current-channel riece-channel-buffer-mode))
229 (let ((user-list-window (split-window (selected-window) nil t)))
230 (set-window-buffer (selected-window) riece-channel-buffer)
231 (set-window-buffer user-list-window riece-user-list-buffer)
232 (select-window user-list-window)
233 (shrink-window-horizontally (- (window-width) user-list-width))))
236 (set-window-buffer (selected-window) riece-user-list-buffer))
237 ;; only channel-buffer
238 (riece-channel-buffer-mode
239 (set-window-buffer (selected-window) riece-channel-buffer)))
240 (select-window rest-window)))
242 (if (and riece-current-channel
243 riece-channel-list-buffer-mode)
244 (let ((channel-list-window (split-window (selected-window) nil t)))
245 (set-window-buffer (selected-window) riece-others-buffer)
246 (set-window-buffer channel-list-window riece-channel-list-buffer)
247 (select-window channel-list-window)
248 (shrink-window-horizontally (- (window-width) channel-list-width)))
249 (set-window-buffer (selected-window) riece-dialogue-buffer))
250 (riece-set-window-points)
251 (select-window (or (get-buffer-window buffer)
252 (get-buffer-window riece-command-buffer)))))
254 ;; +---+-------------------+---+
255 ;; | c | channel | u |
258 ;; | n |-------------------+ r | | +---+
259 ;; | n | command | s | | | |
260 ;; | e +-------------------+---+ | +-> |
261 ;; | l | others | +-----+
263 ;; +---+-----------------------+
264 (defun riece-configure-windows-spiral ()
265 "spiral placement of windows"
267 (let ((command-height 4)
270 (buffer (window-buffer)))
271 (when (eq (selected-window) (minibuffer-window)) (other-window 1))
272 (delete-other-windows)
274 ;; (1) create channels window
275 (let ((rest (split-window (selected-window) channels-width t)))
276 (set-window-buffer (selected-window) riece-channel-list-buffer)
277 (select-window rest))
279 ;; (2) create others window
280 (set-window-buffer (split-window (selected-window)
281 (+ (/ (window-height) 2)
285 ;; (3) create users window
286 (set-window-buffer (split-window (selected-window)
287 (- (window-width) users-width) t)
288 riece-user-list-buffer)
290 ;; (4) create current channel window
291 (let ((rest (split-window (selected-window)
292 (- (window-height) command-height))))
293 (set-window-buffer rest riece-command-buffer)
294 (set-window-buffer (selected-window) riece-channel-buffer))
296 (riece-set-window-points)
297 (select-window (or (get-buffer-window buffer)
298 (get-buffer-window riece-command-buffer)))))
300 (provide 'riece-layout)
302 ;;; riece-layout.el ends here