1 ;;; --------------------------------------------------------------------------
2 ;;; CLFSWM - FullScreen Window Manager
4 ;;; --------------------------------------------------------------------------
5 ;;; Documentation: Toolbar
6 ;;; --------------------------------------------------------------------------
8 ;;; (C) 2011 Philippe Brochard <hocwp@free.fr>
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 3 of the License, or
13 ;;; (at your option) any later version.
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 this program; if not, write to the Free Software
22 ;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 ;;; Documentation: If you want to use this file, just add this line in
25 ;;; your configuration file:
27 ;;; (load-contrib "toolbar.lisp")
29 ;;; --------------------------------------------------------------------------
33 (format t
"Loading Toolbar code... ")
35 (defstruct toolbar root-x root-y root direction size thickness placement refresh-delay
36 autohide modules font window gc border-size
)
38 (defparameter *toolbar-list
* nil
)
39 (defparameter *toolbar-module-list
* nil
)
41 ;;; CONFIG - Toolbar window string colors
42 (defconfig *toolbar-window-font-string
* *default-font-string
*
43 'Toolbar
"Toolbar window font string")
44 (defconfig *toolbar-window-background
* "black"
45 'Toolbar
"Toolbar Window background color")
46 (defconfig *toolbar-window-foreground
* "green"
47 'Toolbar
"Toolbar Window foreground color")
48 (defconfig *toolbar-window-border
* "red"
49 'Toolbar
"Toolbar Window border color")
50 (defconfig *toolbar-default-border-size
* 0
51 'Toolbar
"Toolbar Window border size")
52 (defconfig *toolbar-window-transparency
* *default-transparency
*
53 'Toolbar
"Toolbar window background transparency")
54 (defconfig *toolbar-default-thickness
* 20
55 'Toolbar
"Toolbar default thickness")
56 (defconfig *toolbar-default-refresh-delay
* 30
57 'Toolbar
"Toolbar default refresh delay")
58 (defconfig *toolbar-default-autohide
* nil
59 'Toolbar
"Toolbar default autohide value")
61 (defconfig *toolbar-window-placement
* 'top-left-placement
62 'Placement
"Toolbar window placement")
64 (defun toolbar-symbol-fun (name)
65 (create-symbol 'toolbar- name
'-module
))
67 (defun toolbar-adjust-root-size (toolbar)
68 (unless (toolbar-autohide toolbar
)
69 (let ((root (toolbar-root toolbar
))
70 (placement-name (symbol-name (toolbar-placement toolbar
)))
71 (thickness (+ (toolbar-thickness toolbar
) (* 2 (toolbar-border-size toolbar
)))))
73 (case (toolbar-direction toolbar
)
74 (:horiz
(cond ((search "TOP" placement-name
)
75 (incf (root-y root
) thickness
)
76 (decf (root-h root
) thickness
))
77 ((search "BOTTOM" placement-name
)
78 (decf (root-h root
) thickness
))))
79 (t (cond ((search "LEFT" placement-name
)
80 (incf (root-x root
) thickness
)
81 (decf (root-w root
) thickness
))
82 ((search "RIGHT" placement-name
)
83 (decf (root-w root
) thickness
)))))))))
86 (defun toolbar-draw-text (toolbar pos1 pos2 text
)
87 "pos1: percent, pos2: pixels"
88 (labels ((horiz-text ()
89 (let* ((height (- (xlib:font-ascent
(toolbar-font toolbar
)) (xlib:font-descent
(toolbar-font toolbar
))))
90 (dy (truncate (+ pos2
(/ height
2))))
91 (width (xlib:text-width
(toolbar-font toolbar
) text
))
92 (pos (truncate (/ (* (- (xlib:drawable-width
(toolbar-window toolbar
)) width
) pos1
) 100))))
93 (xlib:draw-glyphs
*pixmap-buffer
* (toolbar-gc toolbar
) pos dy text
)))
95 (let* ((width (xlib:max-char-width
(toolbar-font toolbar
)))
96 (dx (truncate (- pos2
(/ width
2))))
97 (dpos (xlib:max-char-ascent
(toolbar-font toolbar
)))
98 (height (* dpos
(length text
)))
99 (pos (+ (truncate (/ (* (- (xlib:drawable-height
(toolbar-window toolbar
)) height
100 (xlib:max-char-descent
(toolbar-font toolbar
)))
102 (xlib:font-ascent
(toolbar-font toolbar
)))))
103 (loop for c across text
104 do
(xlib:draw-glyphs
*pixmap-buffer
* (toolbar-gc toolbar
) dx pos
(string c
))
106 (case (toolbar-direction toolbar
)
107 (:horiz
(horiz-text))
108 (:vert
(vert-text)))))
112 (defun refresh-toolbar (toolbar)
113 (add-timer (toolbar-refresh-delay toolbar
)
115 (refresh-toolbar toolbar
))
117 (clear-pixmap-buffer (toolbar-window toolbar
) (toolbar-gc toolbar
))
118 (dolist (module (toolbar-modules toolbar
))
119 (let ((fun (toolbar-symbol-fun (first module
))))
121 (funcall fun toolbar module
))))
122 (copy-pixmap-buffer (toolbar-window toolbar
) (toolbar-gc toolbar
)))
125 (create-event-hook :exposure
)
127 (defun define-toolbar-hooks (toolbar)
128 (define-event-hook :exposure
(window)
129 (when (and (xlib:window-p window
) (xlib:window-equal
(toolbar-window toolbar
) window
))
130 (refresh-toolbar toolbar
))))
135 (let ((windows-list nil
))
136 (defun is-toolbar-window-p (win)
137 (and (xlib:window-p win
) (member win windows-list
:test
'xlib
:window-equal
)))
139 (defun close-toolbar (toolbar)
140 (erase-timer :refresh-toolbar-window
)
141 (setf *never-managed-window-list
*
142 (remove (list #'is-toolbar-window-p nil
)
143 *never-managed-window-list
* :test
#'equal
))
144 (awhen (toolbar-gc toolbar
)
145 (xlib:free-gcontext it
))
146 (awhen (toolbar-window toolbar
)
147 (xlib:destroy-window it
))
148 (awhen (toolbar-font toolbar
)
149 (xlib:close-font it
))
150 (xlib:display-finish-output
*display
*)
151 (setf (toolbar-window toolbar
) nil
152 (toolbar-gc toolbar
) nil
153 (toolbar-font toolbar
) nil
))
155 (defun open-toolbar (toolbar)
156 (let ((root (find-root-by-coordinates (toolbar-root-x toolbar
) (toolbar-root-y toolbar
))))
158 (setf (toolbar-root toolbar
) root
)
159 (let ((*get-current-root-fun
* (lambda () root
)))
160 (setf (toolbar-font toolbar
) (xlib:open-font
*display
* *toolbar-window-font-string
*))
161 (let* ((width (if (equal (toolbar-direction toolbar
) :horiz
)
162 (round (/ (* (root-w root
) (toolbar-size toolbar
)) 100))
163 (toolbar-thickness toolbar
)))
164 (height (if (equal (toolbar-direction toolbar
) :horiz
)
165 (toolbar-thickness toolbar
)
166 (round (/ (* (root-h root
) (toolbar-size toolbar
)) 100)))))
167 (with-placement ((toolbar-placement toolbar
) x y width height
(toolbar-border-size toolbar
))
168 (setf (toolbar-window toolbar
) (xlib:create-window
:parent
*root
*
173 :background
(get-color *toolbar-window-background
*)
174 :border-width
(toolbar-border-size toolbar
)
175 :border
(when (plusp (toolbar-border-size toolbar
))
176 (get-color *toolbar-window-border
*))
177 :colormap
(xlib:screen-default-colormap
*screen
*)
178 :event-mask
'(:exposure
:key-press
))
179 (toolbar-gc toolbar
) (xlib:create-gcontext
:drawable
(toolbar-window toolbar
)
180 :foreground
(get-color *toolbar-window-foreground
*)
181 :background
(get-color *toolbar-window-background
*)
182 :font
(toolbar-font toolbar
)
184 (push (toolbar-window toolbar
) windows-list
)
185 (setf (window-transparency (toolbar-window toolbar
)) *toolbar-window-transparency
*)
186 (push (list #'is-toolbar-window-p nil
) *never-managed-window-list
*)
187 (map-window (toolbar-window toolbar
))
188 (raise-window (toolbar-window toolbar
))
189 (refresh-toolbar toolbar
)
190 (xlib:display-finish-output
*display
*)
191 (define-toolbar-hooks toolbar
))))))))
193 (defun open-all-toolbars ()
195 (dolist (toolbar *toolbar-list
*)
196 (open-toolbar toolbar
))
197 (dolist (toolbar *toolbar-list
*)
198 (toolbar-adjust-root-size toolbar
)))
200 (defun close-all-toolbars ()
201 (dolist (toolbar *toolbar-list
*)
202 (close-toolbar toolbar
)))
205 (defun add-toolbar (root-x root-y direction size placement
&rest modules
)
207 root-x, root-y: root coordinates
208 direction: one of :horiz or :vert
209 size: toolbar size in percent of root size"
210 (let ((toolbar (make-toolbar :root-x root-x
:root-y root-y
211 :direction direction
:size size
212 :thickness
*toolbar-default-thickness
*
214 :autohide
*toolbar-default-autohide
*
215 :refresh-delay
*toolbar-default-refresh-delay
*
216 :border-size
*toolbar-default-border-size
*
218 (push toolbar
*toolbar-list
*)
222 (add-hook *init-hook
* 'open-all-toolbars
)
223 (add-hook *close-hook
* 'close-all-toolbars
)
226 (defmacro define-toolbar-module
((name) &body body
)
227 (let ((symbol-fun (toolbar-symbol-fun name
)))
229 (pushnew ',name
*toolbar-module-list
*)
230 (defun ,symbol-fun
(toolbar module
)
235 (define-toolbar-module (clock)
237 (multiple-value-bind (s m h
)
240 (toolbar-draw-text toolbar
(second module
) (/ *toolbar-default-thickness
* 2)
241 (format nil
"~2,'0D:~2,'0D" h m
))))
244 (define-toolbar-module (label)
246 (toolbar-draw-text toolbar
(second module
) (/ *toolbar-default-thickness
* 2)