]> Dogcows Code - chaz/tint2/blob - src/util/area.c
*add* more task states (normal, active, iconified, urgent), with each an own backgrou...
[chaz/tint2] / src / util / area.c
1 /**************************************************************************
2 *
3 * Tint2 : area
4 *
5 * Copyright (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2
9 * as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **************************************************************************/
19
20 #include <X11/Xlib.h>
21 #include <X11/Xutil.h>
22 #include <X11/Xatom.h>
23 #include <X11/extensions/Xrender.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <pango/pangocairo.h>
28
29 #include "area.h"
30 #include "server.h"
31 #include "panel.h"
32
33
34 // 1) resize child
35 // 2) resize parent
36 // 3) redraw parent
37 // 4) redraw child
38 void refresh (Area *a)
39 {
40 // don't draw and resize hide objects
41 if (!a->on_screen) return;
42
43 size(a);
44
45 // don't draw transparent objects (without foreground and without background)
46 if (a->redraw) {
47 a->redraw = 0;
48 // force redraw of child
49 GSList *l;
50 for (l = a->list ; l ; l = l->next)
51 set_redraw(l->data);
52
53 //printf("draw area posx %d, width %d\n", a->posx, a->width);
54 draw(a);
55 }
56
57 // draw current Area
58 if (a->pix == 0) printf("empty area posx %d, width %d\n", a->posx, a->width);
59 XCopyArea (server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
60
61 // and then refresh child object
62 GSList *l;
63 for (l = a->list; l ; l = l->next)
64 refresh(l->data);
65 }
66
67
68 void size (Area *a)
69 {
70 GSList *l;
71
72 if (a->resize) {
73 a->resize = 0;
74 // force the resize of childs
75 for (l = a->list; l ; l = l->next) {
76 Area *area = (Area*)l->data;
77 area->resize = 1;
78 size(area);
79 }
80
81 // resize can generate a redraw
82 if (a->_resize)
83 a->_resize(a);
84 }
85 }
86
87
88 void set_redraw (Area *a)
89 {
90 a->redraw = 1;
91
92 GSList *l;
93 for (l = a->list ; l ; l = l->next)
94 set_redraw(l->data);
95 }
96
97
98 void draw (Area *a)
99 {
100 if (a->pix) XFreePixmap (server.dsp, a->pix);
101 a->pix = XCreatePixmap (server.dsp, server.root_win, a->width, a->height, server.depth);
102
103 // add layer of root pixmap (or clear pixmap if real_transparency==true)
104 if (real_transparency)
105 clear_pixmap(a->pix, 0 ,0, a->width, a->height);
106 XCopyArea (server.dsp, ((Panel *)a->panel)->temp_pmap, a->pix, server.gc, a->posx, a->posy, a->width, a->height, 0, 0);
107
108 cairo_surface_t *cs;
109 cairo_t *c;
110
111 cs = cairo_xlib_surface_create (server.dsp, a->pix, server.visual, a->width, a->height);
112 c = cairo_create (cs);
113
114 draw_background (a, c);
115
116 if (a->_draw_foreground)
117 a->_draw_foreground(a, c);
118
119 cairo_destroy (c);
120 cairo_surface_destroy (cs);
121 }
122
123
124 void draw_background (Area *a, cairo_t *c)
125 {
126 if (a->bg->back.alpha > 0.0) {
127 //printf(" draw_background (%d %d) RGBA (%lf, %lf, %lf, %lf)\n", a->posx, a->posy, pix->back.color[0], pix->back.color[1], pix->back.color[2], pix->back.alpha);
128 draw_rect(c, a->bg->border.width, a->bg->border.width, a->width-(2.0 * a->bg->border.width), a->height-(2.0*a->bg->border.width), a->bg->border.rounded - a->bg->border.width/1.571);
129 cairo_set_source_rgba(c, a->bg->back.color[0], a->bg->back.color[1], a->bg->back.color[2], a->bg->back.alpha);
130 cairo_fill(c);
131 }
132
133 if (a->bg->border.width > 0 && a->bg->border.alpha > 0.0) {
134 cairo_set_line_width (c, a->bg->border.width);
135
136 // draw border inside (x, y, width, height)
137 draw_rect(c, a->bg->border.width/2.0, a->bg->border.width/2.0, a->width - a->bg->border.width, a->height - a->bg->border.width, a->bg->border.rounded);
138 /*
139 // convert : radian = degre * M_PI/180
140 // définir le dégradé dans un carré de (0,0) (100,100)
141 // ensuite ce dégradé est extrapolé selon le ratio width/height
142 // dans repère (0, 0) (100, 100)
143 double X0, Y0, X1, Y1, degre;
144 // x = X * (a->width / 100), y = Y * (a->height / 100)
145 double x0, y0, x1, y1;
146 X0 = 0;
147 Y0 = 100;
148 X1 = 100;
149 Y1 = 0;
150 degre = 45;
151 // et ensuite faire la changement d'unité du repère
152 // car ce qui doit resté inchangée est les traits et pas la direction
153
154 // il faut d'abord appliquer une rotation de 90° (et -180° si l'angle est supérieur à 180°)
155 // ceci peut être appliqué une fois pour toute au départ
156 // ensuite calculer l'angle dans le nouveau repère
157 // puis faire une rotation de 90°
158 x0 = X0 * ((double)a->width / 100);
159 x1 = X1 * ((double)a->width / 100);
160 y0 = Y0 * ((double)a->height / 100);
161 y1 = Y1 * ((double)a->height / 100);
162
163 x0 = X0 * ((double)a->height / 100);
164 x1 = X1 * ((double)a->height / 100);
165 y0 = Y0 * ((double)a->width / 100);
166 y1 = Y1 * ((double)a->width / 100);
167
168 cairo_pattern_t *linpat;
169 linpat = cairo_pattern_create_linear (x0, y0, x1, y1);
170 cairo_pattern_add_color_stop_rgba (linpat, 0, a->border.color[0], a->border.color[1], a->border.color[2], a->border.alpha);
171 cairo_pattern_add_color_stop_rgba (linpat, 1, a->border.color[0], a->border.color[1], a->border.color[2], 0);
172 cairo_set_source (c, linpat);
173 */
174 cairo_set_source_rgba (c, a->bg->border.color[0], a->bg->border.color[1], a->bg->border.color[2], a->bg->border.alpha);
175
176 cairo_stroke (c);
177 //cairo_pattern_destroy (linpat);
178 }
179 }
180
181
182 void remove_area (Area *a)
183 {
184 Area *parent = (Area*)a->parent;
185
186 parent->list = g_slist_remove(parent->list, a);
187 set_redraw (parent);
188
189 }
190
191
192 void add_area (Area *a)
193 {
194 Area *parent = (Area*)a->parent;
195
196 parent->list = g_slist_remove(parent->list, a);
197 set_redraw (parent);
198
199 }
200
201
202 void free_area (Area *a)
203 {
204 GSList *l0;
205 for (l0 = a->list; l0 ; l0 = l0->next)
206 free_area (l0->data);
207
208 if (a->list) {
209 g_slist_free(a->list);
210 a->list = 0;
211 }
212 if (a->pix) {
213 XFreePixmap (server.dsp, a->pix);
214 a->pix = 0;
215 }
216 }
217
218
219 void draw_rect(cairo_t *c, double x, double y, double w, double h, double r)
220 {
221 if (r > 0.0) {
222 double c1 = 0.55228475 * r;
223
224 cairo_move_to(c, x+r, y);
225 cairo_rel_line_to(c, w-2*r, 0);
226 cairo_rel_curve_to(c, c1, 0.0, r, c1, r, r);
227 cairo_rel_line_to(c, 0, h-2*r);
228 cairo_rel_curve_to(c, 0.0, c1, c1-r, r, -r, r);
229 cairo_rel_line_to (c, -w +2*r, 0);
230 cairo_rel_curve_to (c, -c1, 0, -r, -c1, -r, -r);
231 cairo_rel_line_to (c, 0, -h + 2 * r);
232 cairo_rel_curve_to (c, 0, -c1, r - c1, -r, r, -r);
233 }
234 else
235 cairo_rectangle(c, x, y, w, h);
236 }
237
238
239 void clear_pixmap(Pixmap p, int x, int y, int w, int h)
240 {
241 Picture pict = XRenderCreatePicture(server.dsp, p, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
242 XRenderColor col = { .red=0, .green=0, .blue=0, .alpha=0 };
243 XRenderFillRectangle(server.dsp, PictOpSrc, pict, &col, x, y, w, h);
244 XRenderFreePicture(server.dsp, pict);
245 }
This page took 0.045316 seconds and 5 git commands to generate.