* riece-xemacs.el (riece-mouse-2): New variable.
[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   "Manage 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   '(("default" riece-configure-windows riece-reconfigure-windows-predicate)
42     ("top" riece-configure-windows-top riece-reconfigure-windows-predicate))
43   "An alist mapping the names to layout functions.
44 An element of this alist is in the following form:
45 (NAME CONFIGURE-FUNCTION RECONFIGURE-PREDICATE)
46 NAME is a string which specifies the layout setting.
47 CONFIGURE-FUNCTION is a function which does window splitting, etc.
48 RECONFIGURE-PREDICATE is a function to examine whether windows
49 reconfiguration is needed."
50   :type 'list
51   :group 'riece-layout)
52
53 (defun riece-redraw-layout (&optional force)
54   "Reconfigure windows with the current layout.
55 If optional argument FORCE is non-nil, window reconfiguration will
56 happen unconditionally."
57   (let ((layout (cdr (assoc riece-layout riece-layout-alist))))
58     (unless layout
59       (error "No such layout!"))
60     (if (or force
61             (funcall (nth 1 layout)))
62         (funcall (car layout)))))
63   
64 (defun riece-set-window-points ()
65   (if (get-buffer-window riece-user-list-buffer)
66       (with-current-buffer riece-user-list-buffer
67         (unless (riece-frozen riece-user-list-buffer)
68           (set-window-start (get-buffer-window riece-user-list-buffer)
69                             (point-min)))))
70   (if (get-buffer-window riece-channel-list-buffer)
71       (with-current-buffer riece-channel-list-buffer
72         (unless (riece-frozen riece-channel-list-buffer)
73           (set-window-start (get-buffer-window riece-channel-list-buffer)
74                             (point-min))))))
75
76 (defun riece-configure-windows ()
77   "Configure windows.
78 This function is used by \"default\" layout."
79   (let ((buffer (window-buffer))
80         (show-user-list
81          (and riece-user-list-buffer-mode
82               riece-current-channel
83               ;; User list buffer is nuisance for private conversation.
84               (riece-channel-p (riece-identity-prefix
85                                 riece-current-channel)))))
86     ;; Can't expand minibuffer to full frame.
87     (if (eq (selected-window) (minibuffer-window))
88         (other-window 1))
89     (delete-other-windows)
90     (if (and riece-current-channel
91              (or show-user-list riece-channel-list-buffer-mode))
92         (let ((rest-window (split-window (selected-window)
93                                          (/ (window-width) 5) t)))
94           (if (and show-user-list riece-channel-list-buffer-mode)
95               (progn
96                 (set-window-buffer (split-window)
97                                    riece-channel-list-buffer)
98                 (set-window-buffer (selected-window)
99                                    riece-user-list-buffer))
100             (if show-user-list
101                 (set-window-buffer (selected-window)
102                                    riece-user-list-buffer)
103               (if riece-channel-list-buffer-mode
104                   (set-window-buffer (selected-window)
105                                      riece-channel-list-buffer))))
106           (select-window rest-window)))
107     (if (and riece-current-channel
108              riece-channel-buffer-mode)
109         (let ((rest-window (split-window)))
110           (set-window-buffer (selected-window)
111                              riece-channel-buffer)
112           (set-window-buffer (split-window rest-window 4)
113                              riece-others-buffer)
114           (with-current-buffer riece-channel-buffer
115             (setq truncate-partial-width-windows nil))
116           (with-current-buffer riece-others-buffer
117             (setq truncate-partial-width-windows nil))
118           (set-window-buffer rest-window
119                              riece-command-buffer))
120       (set-window-buffer (split-window (selected-window) 4)
121                          riece-dialogue-buffer)
122       (set-window-buffer (selected-window)
123                          riece-command-buffer))
124     (riece-set-window-points)
125     (select-window (or (get-buffer-window buffer)
126                        (get-buffer-window riece-command-buffer)))))
127
128 (defun riece-reconfigure-windows-predicate ()
129   "Return t, if window reconfiguration is needed.
130 This function is used by \"default\" layout."
131   ;; Check whether there is a buffer which belongs to Riece is visible.
132   (let ((buffers riece-buffer-list))
133     (catch 'found
134       (while buffers
135         (if (and (buffer-live-p (car buffers))
136                  (get-buffer-window (car buffers)))
137             (throw 'found t)
138           (setq buffers (cdr buffers)))))))
139
140 (defun riece-configure-windows-top (&optional plist)
141   "Candidate of `riece-configure-windows-function'.
142 PLIST accept :command-height, :user-list-width, and :channel-list-width."
143   (let ((command-height (or (plist-get plist :command-height) 4))
144         (user-list-width (or (plist-get plist :user-list-width) (+ 9 1 1)))
145         (channel-list-width (or (plist-get plist :channel-list-width) 18))
146         (buffer (window-buffer))
147         (show-user-list
148          (and riece-user-list-buffer-mode
149               riece-current-channel
150               ;; User list buffer is nuisance for private conversation.
151               (riece-channel-p (riece-identity-prefix
152                                 riece-current-channel)))))
153     ;; Can't expand minibuffer to full frame.
154     (when (eq (selected-window) (minibuffer-window))
155       (other-window 1))
156     (delete-other-windows)
157     ;; top of frame
158     (let ((rest-window (split-window (selected-window) command-height)))
159       (set-window-buffer (selected-window)
160                          riece-command-buffer)
161       (select-window rest-window))
162     ;; middle of frame (vertical-spilit when need)
163     (when (or (and riece-current-channel riece-channel-buffer-mode)
164               show-user-list)
165       (let ((rest-window
166              (split-window (selected-window)
167                            (/ (* 5 (+ (window-height) command-height)) 8))))
168         (cond
169          ;; channel-buffer + user-list
170          ((and show-user-list
171                (and riece-current-channel riece-channel-buffer-mode))
172           (let ((user-list-window (split-window (selected-window) nil t)))
173             (set-window-buffer (selected-window) riece-channel-buffer)
174             (set-window-buffer user-list-window riece-user-list-buffer)
175             (select-window user-list-window)
176             (shrink-window-horizontally (- (window-width) user-list-width))
177             (setq truncate-partial-width-windows nil)))
178          ;; only user-list
179          (show-user-list
180           (set-window-buffer (selected-window) riece-user-list-buffer))
181          ;; only channel-buffer
182          (riece-channel-buffer-mode
183           (set-window-buffer (selected-window) riece-channel-buffer)))
184         (select-window rest-window)))
185     ;; bottom of frame
186     (if (and riece-current-channel
187              riece-channel-list-buffer-mode)
188         (let ((channel-list-window (split-window (selected-window) nil t)))
189           (set-window-buffer (selected-window) riece-others-buffer)
190           (set-window-buffer channel-list-window riece-channel-list-buffer)
191           (select-window channel-list-window)
192           (shrink-window-horizontally (- (window-width) channel-list-width))
193           (setq truncate-partial-width-windows nil))
194       (set-window-buffer (selected-window) riece-dialogue-buffer))
195     (riece-set-window-points)
196     (select-window (or (get-buffer-window buffer)
197                        (get-buffer-window riece-command-buffer)))))
198
199 (provide 'riece-layout)
200
201 ;;; riece-layout.el ends here