]> Dogcows Code - chaz/openbox/blob - openbox/popup.c
2e65570e518634cf3ecd74d8244d5eb48fd6d4a6
[chaz/openbox] / openbox / popup.c
1 #include "openbox.h"
2 #include "frame.h"
3 #include "window.h"
4 #include "stacking.h"
5 #include "render/render.h"
6 #include "render/theme.h"
7
8 typedef struct Popup {
9 ObWindow obwin;
10 Window bg;
11
12 Window icon;
13 Window text;
14
15 gboolean hasicon;
16 RrAppearance *a_bg;
17 RrAppearance *a_icon;
18 RrAppearance *a_text;
19 int gravity;
20 int x;
21 int y;
22 int w;
23 int h;
24 gboolean mapped;
25 } Popup;
26
27 Popup *popup_new(gboolean hasicon)
28 {
29 Popup *self = g_new(Popup, 1);
30 self->obwin.type = Window_Internal;
31 self->hasicon = hasicon;
32 self->bg = None;
33 self->a_text = NULL;
34 self->gravity = NorthWestGravity;
35 self->x = self->y = self->w = self->h = 0;
36 self->mapped = FALSE;
37 stacking_add(INTERNAL_AS_WINDOW(self));
38 stacking_raise(INTERNAL_AS_WINDOW(self));
39 return self;
40 }
41
42 void popup_free(Popup *self)
43 {
44 if (self->bg) {
45 XDestroyWindow(ob_display, self->bg);
46 XDestroyWindow(ob_display, self->text);
47 XDestroyWindow(ob_display, self->icon);
48 RrAppearanceFree(self->a_bg);
49 if (self->hasicon)
50 RrAppearanceFree(self->a_icon);
51 }
52 if (self->a_text)
53 RrAppearanceFree(self->a_text);
54 stacking_remove(self);
55 g_free(self);
56 }
57
58 void popup_position(Popup *self, int gravity, int x, int y)
59 {
60 self->gravity = gravity;
61 self->x = x;
62 self->y = y;
63 }
64
65 void popup_size(Popup *self, int w, int h)
66 {
67 self->w = w;
68 self->h = h;
69 }
70
71 void popup_size_to_string(Popup *self, char *text)
72 {
73 int textw, texth;
74 int iconw;
75
76 if (!self->a_text)
77 self->a_text = RrAppearanceCopy(theme_app_hilite_label);
78
79 self->a_text->texture[0].data.text.string = text;
80 RrMinsize(self->a_text, &textw, &texth);
81 textw += theme_bevel * 2;
82 texth += theme_bevel * 2;
83
84 self->h = texth + theme_bevel * 2;
85 iconw = (self->hasicon ? texth : 0);
86 self->w = textw + iconw + theme_bevel * (self->hasicon ? 3 : 2);
87 }
88
89 void popup_show(Popup *self, char *text, Icon *icon)
90 {
91 XSetWindowAttributes attrib;
92 int x, y, w, h;
93 int textw, texth;
94 int iconw;
95
96 /* create the shit if needed */
97 if (!self->bg) {
98 attrib.override_redirect = True;
99 self->bg = XCreateWindow(ob_display, ob_root,
100 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
101 InputOutput, RrVisual(ob_rr_inst),
102 CWOverrideRedirect, &attrib);
103
104 XSetWindowBorderWidth(ob_display, self->bg, theme_bwidth);
105 XSetWindowBorder(ob_display, self->bg, theme_b_color->pixel);
106
107 self->text = XCreateWindow(ob_display, self->bg,
108 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
109 InputOutput, RrVisual(ob_rr_inst), 0, NULL);
110 if (self->hasicon)
111 self->icon = XCreateWindow(ob_display, self->bg,
112 0, 0, 1, 1, 0,
113 RrDepth(ob_rr_inst), InputOutput,
114 RrVisual(ob_rr_inst), 0, NULL);
115
116 XMapWindow(ob_display, self->text);
117 XMapWindow(ob_display, self->icon);
118
119 self->a_bg = RrAppearanceCopy(theme_app_hilite_bg);
120 if (self->hasicon)
121 self->a_icon = RrAppearanceCopy(theme_app_icon);
122 }
123 if (!self->a_text)
124 self->a_text = RrAppearanceCopy(theme_app_hilite_label);
125
126 /* set up the textures */
127 self->a_text->texture[0].data.text.string = text;
128 if (self->hasicon) {
129 if (icon) {
130 self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
131 self->a_icon->texture[0].data.rgba.width = icon->width;
132 self->a_icon->texture[0].data.rgba.height = icon->height;
133 self->a_icon->texture[0].data.rgba.data = icon->data;
134 } else
135 self->a_icon->texture[0].type = RR_TEXTURE_NONE;
136 }
137
138 /* measure the shit out */
139 RrMinsize(self->a_text, &textw, &texth);
140 textw += theme_bevel * 2;
141 texth += theme_bevel * 2;
142
143 /* set the sizes up and reget the text sizes from the calculated
144 outer sizes */
145 if (self->h) {
146 h = self->h;
147 texth = h - (theme_bevel * 2);
148 } else
149 h = texth + theme_bevel * 2;
150 iconw = (self->hasicon ? texth : 0);
151 if (self->w) {
152 w = self->w;
153 textw = w - (iconw + theme_bevel * (self->hasicon ? 3 : 2));
154 } else
155 w = textw + iconw + theme_bevel * (self->hasicon ? 3 : 2);
156 /* sanity checks to avoid crashes! */
157 if (w < 1) w = 1;
158 if (h < 1) h = 1;
159 if (textw < 1) textw = 1;
160 if (texth < 1) texth = 1;
161
162 /* set up the x coord */
163 x = self->x;
164 switch (self->gravity) {
165 case NorthGravity:
166 case CenterGravity:
167 case SouthGravity:
168 x -= w / 2;
169 break;
170 case NorthEastGravity:
171 case EastGravity:
172 case SouthEastGravity:
173 x -= w;
174 break;
175 }
176
177 /* set up the y coord */
178 y = self->y;
179 switch (self->gravity) {
180 case WestGravity:
181 case CenterGravity:
182 case EastGravity:
183 y -= h / 2;
184 break;
185 case SouthWestGravity:
186 case SouthGravity:
187 case SouthEastGravity:
188 y -= h;
189 break;
190 }
191
192 /* set the windows/appearances up */
193 XMoveResizeWindow(ob_display, self->bg, x, y, w, h);
194
195 self->a_text->surface.parent = self->a_bg;
196 self->a_text->surface.parentx = iconw +
197 theme_bevel * (self->hasicon ? 2 : 1);
198 self->a_text->surface.parenty = theme_bevel;
199 XMoveResizeWindow(ob_display, self->text,
200 iconw + theme_bevel * (self->hasicon ? 2 : 1),
201 theme_bevel, textw, texth);
202
203 if (self->hasicon) {
204 if (iconw < 1) iconw = 1; /* sanity check for crashes */
205 self->a_icon->surface.parent = self->a_bg;
206 self->a_icon->surface.parentx = theme_bevel;
207 self->a_icon->surface.parenty = theme_bevel;
208 XMoveResizeWindow(ob_display, self->icon,
209 theme_bevel, theme_bevel, iconw, texth);
210 }
211
212 RrPaint(self->a_bg, self->bg, w, h);
213 RrPaint(self->a_text, self->text, textw, texth);
214 if (self->hasicon)
215 RrPaint(self->a_icon, self->icon, iconw, texth);
216
217 if (!self->mapped) {
218 XMapWindow(ob_display, self->bg);
219 stacking_raise(INTERNAL_AS_WINDOW(self));
220 self->mapped = TRUE;
221 }
222 }
223
224 void popup_hide(Popup *self)
225 {
226 if (self->mapped) {
227 XUnmapWindow(ob_display, self->bg);
228 self->mapped = FALSE;
229 }
230 }
This page took 0.041463 seconds and 3 git commands to generate.