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