add helper functions for manipulating the focus_order list.
[mikachu/openbox.git] / openbox / framerender.c
1 #include "frame.h"
2 #include "openbox.h"
3 #include "screen.h"
4 #include "framerender.h"
5 #include "render/theme.h"
6
7 static void framerender_label(Frame *self, Appearance *a);
8 static void framerender_icon(Frame *self, Appearance *a);
9 static void framerender_max(Frame *self, Appearance *a);
10 static void framerender_iconify(Frame *self, Appearance *a);
11 static void framerender_desk(Frame *self, Appearance *a);
12 static void framerender_shade(Frame *self, Appearance *a);
13 static void framerender_close(Frame *self, Appearance *a);
14
15 void framerender_frame(Frame *self)
16 {
17     if (self->focused)
18         XSetWindowBorder(ob_display, self->plate,
19                          theme_cb_focused_color->pixel);
20     else
21         XSetWindowBorder(ob_display, self->plate,
22                          theme_cb_unfocused_color->pixel);
23
24     if (self->client->decorations & Decor_Titlebar) {
25         Appearance *t, *l, *m, *n, *i, *d, *s, *c;
26
27         t = (self->focused ?
28              self->a_focused_title : self->a_unfocused_title);
29         l = (self->focused ?
30              self->a_focused_label : self->a_unfocused_label);
31         m = (self->focused ?
32              (self->client->max_vert || self->client->max_horz ?
33               theme_a_focused_pressed_set_max :
34               (self->max_press ?
35                theme_a_focused_pressed_max : theme_a_focused_unpressed_max)) :
36              (self->client->max_vert || self->client->max_horz ?
37               theme_a_unfocused_pressed_set_max :
38               (self->max_press ?
39                theme_a_unfocused_pressed_max :
40                theme_a_unfocused_unpressed_max)));
41         n = self->a_icon;
42         i = (self->focused ?
43              (self->iconify_press ?
44               theme_a_focused_pressed_iconify :
45               theme_a_focused_unpressed_iconify) :
46              (self->iconify_press ?
47               theme_a_unfocused_pressed_iconify :
48               theme_a_unfocused_unpressed_iconify));
49         d = (self->focused ?
50              (self->client->desktop == DESKTOP_ALL ?
51               theme_a_focused_pressed_set_desk :
52               (self->desk_press ?
53                theme_a_focused_pressed_desk :
54                theme_a_focused_unpressed_desk)) :
55              (self->client->desktop == DESKTOP_ALL ?
56               theme_a_unfocused_pressed_set_desk :
57               (self->desk_press ?
58                theme_a_unfocused_pressed_desk :
59                theme_a_unfocused_unpressed_desk)));
60         s = (self->focused ?
61              (self->client->shaded ?
62               theme_a_focused_pressed_set_shade :
63               (self->shade_press ?
64                theme_a_focused_pressed_shade :
65                theme_a_focused_unpressed_shade)) :
66              (self->client->shaded ?
67               theme_a_unfocused_pressed_set_shade :
68               (self->shade_press ?
69                theme_a_unfocused_pressed_shade :
70                theme_a_unfocused_unpressed_shade)));
71         c = (self->focused ?
72              (self->close_press ?
73               theme_a_focused_pressed_close :
74               theme_a_focused_unpressed_close) :
75              (self->close_press ?
76               theme_a_unfocused_pressed_close :
77               theme_a_unfocused_unpressed_close));
78
79         paint(self->title, t);
80
81         /* set parents for any parent relative guys */
82         l->surface.data.planar.parent = t;
83         l->surface.data.planar.parentx = self->label_x;
84         l->surface.data.planar.parenty = theme_bevel;
85
86         m->surface.data.planar.parent = t;
87         m->surface.data.planar.parentx = self->max_x;
88         m->surface.data.planar.parenty = theme_bevel + 1;
89
90         n->surface.data.planar.parent = t;
91         n->surface.data.planar.parentx = self->icon_x;
92         n->surface.data.planar.parenty = theme_bevel;
93
94         i->surface.data.planar.parent = t;
95         i->surface.data.planar.parentx = self->iconify_x;
96         i->surface.data.planar.parenty = theme_bevel + 1;
97
98         d->surface.data.planar.parent = t;
99         d->surface.data.planar.parentx = self->desk_x;
100         d->surface.data.planar.parenty = theme_bevel + 1;
101
102         s->surface.data.planar.parent = t;
103         s->surface.data.planar.parentx = self->shade_x;
104         s->surface.data.planar.parenty = theme_bevel + 1;
105
106         c->surface.data.planar.parent = t;
107         c->surface.data.planar.parentx = self->close_x;
108         c->surface.data.planar.parenty = theme_bevel + 1;
109
110         framerender_label(self, l);
111         framerender_max(self, m);
112         framerender_icon(self, n);
113         framerender_iconify(self, i);
114         framerender_desk(self, d);
115         framerender_shade(self, s);
116         framerender_close(self, c);
117     }
118
119     if (self->client->decorations & Decor_Handle) {
120         Appearance *h, *g;
121
122         h = (self->focused ?
123              self->a_focused_handle : self->a_unfocused_handle);
124         g = (self->focused ?
125              theme_a_focused_grip : theme_a_unfocused_grip);
126
127         if (g->surface.data.planar.grad == Background_ParentRelative) {
128             g->surface.data.planar.parent = h;
129             paint(self->handle, h);
130         } else
131             paint(self->handle, h);
132
133         g->surface.data.planar.parentx = 0;
134         g->surface.data.planar.parenty = 0;
135
136         paint(self->lgrip, g);
137
138         g->surface.data.planar.parentx = self->width - theme_grip_width;
139         g->surface.data.planar.parenty = 0;
140
141         paint(self->rgrip, g);
142     }
143 }
144
145 static void framerender_label(Frame *self, Appearance *a)
146 {
147     if (self->label_x < 0) return;
148
149
150     /* set the texture's text! */
151     a->texture[0].data.text.string = self->client->title;
152     RECT_SET(a->texture[0].position, 0, 0,
153              self->label_width, theme_label_height);
154
155     paint(self->label, a);
156 }
157
158 static void framerender_icon(Frame *self, Appearance *a)
159 {
160     if (self->icon_x < 0) return;
161
162     if (self->client->nicons) {
163         Icon *icon = client_icon(self->client,
164                                  theme_button_size + 2, theme_button_size + 2);
165         a->texture[0].type = RGBA;
166         a->texture[0].data.rgba.width = icon->width;
167         a->texture[0].data.rgba.height = icon->height;
168         a->texture[0].data.rgba.data = icon->data;
169         RECT_SET(self->a_icon->texture[0].position, 0, 0,
170                  theme_button_size + 2, theme_button_size + 2);
171     } else
172         a->texture[0].type = NoTexture;
173
174     paint(self->icon, a);
175 }
176
177 static void framerender_max(Frame *self, Appearance *a)
178 {
179     if (self->max_x < 0) return;
180
181     RECT_SET(a->texture[0].position, 0, 0,
182              theme_button_size, theme_button_size);
183     paint(self->max, a);
184 }
185
186 static void framerender_iconify(Frame *self, Appearance *a)
187 {
188     if (self->iconify_x < 0) return;
189
190     RECT_SET(a->texture[0].position, 0, 0,
191              theme_button_size, theme_button_size);
192     paint(self->iconify, a);
193 }
194
195 static void framerender_desk(Frame *self, Appearance *a)
196 {
197     if (self->desk_x < 0) return;
198
199     RECT_SET(a->texture[0].position, 0, 0,
200              theme_button_size, theme_button_size);
201     paint(self->desk, a);
202 }
203
204 static void framerender_shade(Frame *self, Appearance *a)
205 {
206     if (self->shade_x < 0) return;
207
208     RECT_SET(a->texture[0].position, 0, 0,
209              theme_button_size, theme_button_size);
210     paint(self->shade, a);
211 }
212
213 static void framerender_close(Frame *self, Appearance *a)
214 {
215     if (self->close_x < 0) return;
216
217     RECT_SET(a->texture[0].position, 0, 0,
218              theme_button_size, theme_button_size);
219     paint(self->close, a);
220 }
221
222 void framerender_popup_label(Window win, Size *sz, char *text)
223 {
224     Appearance *a;
225
226     a = theme_app_hilite_label;
227     a->texture[0].data.text.string = text;
228     RECT_SET(a->area, 0, 0, sz->width, sz->height);
229     a->texture[0].position = a->area;
230     a->texture[0].position.x += theme_bevel;
231     a->texture[0].position.y += theme_bevel;
232     a->texture[0].position.width -= theme_bevel * 2;
233     a->texture[0].position.height -= theme_bevel * 2;
234
235     XSetWindowBorderWidth(ob_display, win, theme_bwidth);
236     XSetWindowBorder(ob_display, win, theme_b_color->pixel);
237
238     paint(win, a);
239 }
240
241 void framerender_size_popup_label(char *text, Size *sz)
242 {
243     Appearance *a;
244
245     a = theme_app_hilite_label;
246     a->texture[0].data.text.string = text;
247
248     appearance_minsize(a, &sz->width, &sz->height);
249     sz->width += theme_bevel * 2;
250     sz->height += theme_bevel * 2;
251 }