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