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."
60 :type '(repeat (choice (list :tag "Layout"
62 (function :tag "Configure function")
63 (repeat :tag "Parameters" :inline t symbol))
64 (cons :tag "Alias" string string)))
67 (defun riece-redraw-layout (&optional force)
68 "Reconfigure windows with the current layout.
69 If optional argument FORCE is non-nil, window reconfiguration will
70 happen unconditionally."
71 (let ((layout (cdr (assoc riece-layout riece-layout-alist))))
73 (error "No such layout!"))
75 (let ((riece-layout layout))
76 (riece-redraw-layout force))
78 (riece-reconfigure-windows-predicate))
79 (apply (car layout) (cdr layout))))))
81 (defun riece-set-window-points ()
82 (if (get-buffer-window riece-user-list-buffer)
83 (with-current-buffer riece-user-list-buffer
84 (unless (riece-frozen riece-user-list-buffer)
85 (set-window-start (get-buffer-window riece-user-list-buffer)
87 (if (get-buffer-window riece-channel-list-buffer)
88 (with-current-buffer riece-channel-list-buffer
89 (unless (riece-frozen riece-channel-list-buffer)
90 (set-window-start (get-buffer-window riece-channel-list-buffer)
92 (if (and riece-channel-buffer
93 (get-buffer-window riece-channel-buffer))
94 (with-current-buffer riece-channel-buffer
95 (if (riece-frozen riece-channel-buffer)
96 (if riece-channel-buffer-window-point
97 (set-window-point (get-buffer-window riece-channel-buffer)
98 riece-channel-buffer-window-point))
99 (set-window-point (get-buffer-window riece-channel-buffer)
101 (if (get-buffer-window riece-others-buffer)
102 (with-current-buffer riece-others-buffer
103 (unless (riece-frozen riece-others-buffer)
104 (set-window-point (get-buffer-window riece-others-buffer)
106 (if (get-buffer-window riece-dialogue-buffer)
107 (with-current-buffer riece-dialogue-buffer
108 (unless (riece-frozen riece-dialogue-buffer)
109 (set-window-point (get-buffer-window riece-dialogue-buffer)
112 (defun riece-reconfigure-windows-predicate ()
113 "Return t, if window reconfiguration is needed.
114 This function is used by \"default\" layout."
115 (memq (window-buffer (selected-window))
118 (defun riece-configure-windows (hpos vpos)
119 (let ((buffer (window-buffer))
121 (and riece-user-list-buffer-mode
122 riece-current-channel
123 ;; User list buffer is nuisance for private conversation.
124 (riece-channel-p (riece-identity-prefix
125 riece-current-channel)))))
126 ;; Can't expand minibuffer to full frame.
127 (if (eq (selected-window) (minibuffer-window))
129 (delete-other-windows)
130 (if (and riece-current-channel
131 (or show-user-list riece-channel-list-buffer-mode))
132 (let ((rest-window (split-window (selected-window)
135 (/ (window-width) 5))
136 (/ (window-width) 5))
138 (when (eq hpos 'left)
139 (setq rest-window (selected-window))
141 (if (and show-user-list riece-channel-list-buffer-mode)
143 (set-window-buffer (split-window)
144 riece-channel-list-buffer)
145 (set-window-buffer (selected-window)
146 riece-user-list-buffer))
148 (set-window-buffer (selected-window)
149 riece-user-list-buffer)
150 (if riece-channel-list-buffer-mode
151 (set-window-buffer (selected-window)
152 riece-channel-list-buffer))))
153 (select-window rest-window)))
154 (if (and riece-current-channel
155 riece-channel-buffer-mode)
158 (let ((rest-window (split-window nil 4)))
159 (set-window-buffer (selected-window)
160 riece-command-buffer)
161 (select-window rest-window)
162 (if riece-others-buffer-mode
163 (set-window-buffer (split-window rest-window)
164 riece-others-buffer))
165 (set-window-buffer (selected-window)
166 riece-channel-buffer))
167 (if (and (eq vpos 'middle)
168 riece-others-buffer-mode)
169 (let ((rest-window (split-window)))
170 (set-window-buffer (selected-window)
171 riece-channel-buffer)
172 (set-window-buffer (split-window rest-window 4)
174 (set-window-buffer rest-window
175 riece-command-buffer))
176 (let ((rest-window (split-window nil (- (window-height) 4))))
177 (if riece-others-buffer-mode
179 (set-window-buffer (selected-window)
181 (set-window-buffer (split-window)
182 riece-channel-buffer))
183 (set-window-buffer (selected-window)
184 riece-channel-buffer))
185 (set-window-buffer rest-window
186 riece-command-buffer)))))
187 (if (eq vpos 'bottom)
189 (set-window-buffer (selected-window)
190 riece-command-buffer)
191 (set-window-buffer (split-window (selected-window) 4)
192 riece-dialogue-buffer))
193 (set-window-buffer (split-window (selected-window) 4)
194 riece-dialogue-buffer)
195 (set-window-buffer (selected-window)
196 riece-command-buffer)))
197 (riece-set-window-points)
198 (select-window (or (get-buffer-window buffer)
199 (get-buffer-window riece-command-buffer)))))
201 (defun riece-configure-windows-top (&rest plist)
202 "Candidate of `riece-configure-windows-function'.
203 PLIST accept :command-height, :user-list-width, and :channel-list-width."
204 (let ((command-height (or (plist-get plist :command-height) 4))
205 (user-list-width (or (plist-get plist :user-list-width) (+ 9 1 1)))
206 (channel-list-width (or (plist-get plist :channel-list-width) 18))
207 (buffer (window-buffer))
209 (and riece-user-list-buffer-mode
210 riece-current-channel
211 ;; User list buffer is nuisance for private conversation.
212 (riece-channel-p (riece-identity-prefix
213 riece-current-channel)))))
214 ;; Can't expand minibuffer to full frame.
215 (when (eq (selected-window) (minibuffer-window))
217 (delete-other-windows)
219 (let ((rest-window (split-window (selected-window) command-height)))
220 (set-window-buffer (selected-window)
221 riece-command-buffer)
222 (select-window rest-window))
223 ;; middle of frame (vertical-spilit when need)
224 (when (or (and riece-current-channel riece-channel-buffer-mode)
227 (split-window (selected-window)
228 (/ (* 5 (+ (window-height) command-height)) 8))))
230 ;; channel-buffer + user-list
232 (and riece-current-channel riece-channel-buffer-mode))
233 (let ((user-list-window (split-window (selected-window) nil t)))
234 (set-window-buffer (selected-window) riece-channel-buffer)
235 (set-window-buffer user-list-window riece-user-list-buffer)
236 (select-window user-list-window)
237 (shrink-window-horizontally (- (window-width) user-list-width))))
240 (set-window-buffer (selected-window) riece-user-list-buffer))
241 ;; only channel-buffer
242 (riece-channel-buffer-mode
243 (set-window-buffer (selected-window) riece-channel-buffer)))
244 (select-window rest-window)))
246 (if (and riece-current-channel
247 riece-channel-list-buffer-mode)
248 (let ((channel-list-window (split-window (selected-window) nil t)))
249 (set-window-buffer (selected-window) riece-others-buffer)
250 (set-window-buffer channel-list-window riece-channel-list-buffer)
251 (select-window channel-list-window)
252 (shrink-window-horizontally (- (window-width) channel-list-width)))
253 (set-window-buffer (selected-window) riece-dialogue-buffer))
254 (riece-set-window-points)
255 (select-window (or (get-buffer-window buffer)
256 (get-buffer-window riece-command-buffer)))))
258 ;; +---+-------------------+---+
259 ;; | c | channel | u |
262 ;; | n |-------------------+ r | | +---+
263 ;; | n | command | s | | | |
264 ;; | e +-------------------+---+ | +-> |
265 ;; | l | others | +-----+
267 ;; +---+-----------------------+
268 (defun riece-configure-windows-spiral ()
269 "spiral placement of windows"
271 (let ((command-height 4)
274 (buffer (window-buffer)))
275 (when (eq (selected-window) (minibuffer-window)) (other-window 1))
276 (delete-other-windows)
278 ;; (1) create channels window
279 (let ((rest (split-window (selected-window) channels-width t)))
280 (set-window-buffer (selected-window) riece-channel-list-buffer)
281 (select-window rest))
283 ;; (2) create others window
284 (set-window-buffer (split-window (selected-window)
285 (+ (/ (window-height) 2)
289 ;; (3) create users window
290 (set-window-buffer (split-window (selected-window)
291 (- (window-width) users-width) t)
292 riece-user-list-buffer)
294 ;; (4) create current channel window
295 (let ((rest (split-window (selected-window)
296 (- (window-height) command-height))))
297 (set-window-buffer rest riece-command-buffer)
298 (set-window-buffer (selected-window) riece-channel-buffer))
300 (riece-set-window-points)
301 (select-window (or (get-buffer-window buffer)
302 (get-buffer-window riece-command-buffer)))))
304 (provide 'riece-layout)
306 ;;; riece-layout.el ends here