]> Dogcows Code - chaz/openbox/blob - openbox/menu_render.c
add a menuOverlap property to themes, and use it in the submenu placement
[chaz/openbox] / openbox / menu_render.c
1 /* Functions for default rendering of menus. Might become pluginnable */
2
3 #include "menu.h"
4 #include "openbox.h"
5 #include "render/theme.h"
6
7 void menu_render_full(ObMenu *self);
8
9 void menu_render(ObMenu *self) {
10 if (self->update) {
11 self->update(self);
12 } else if (self->invalid) {
13 menu_render_full(self);
14 }
15 }
16
17 void menu_render_full(ObMenu *self) {
18 GList *it;
19 int items_h = 0;
20 int nitems = 0; /* each item, only one is used */
21 int item_y;
22
23 self->size.width = 1;
24 self->item_h = 1;
25
26 if (self->a_title == NULL) {
27 XSetWindowBorderWidth(ob_display, self->frame, ob_rr_theme->bwidth);
28 XSetWindowBackground(ob_display, self->frame,
29 RrColorPixel(ob_rr_theme->b_color));
30 XSetWindowBorderWidth(ob_display, self->title, ob_rr_theme->bwidth);
31 XSetWindowBorder(ob_display, self->frame,
32 RrColorPixel(ob_rr_theme->b_color));
33 XSetWindowBorder(ob_display, self->title,
34 RrColorPixel(ob_rr_theme->b_color));
35
36 self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title);
37 self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu);
38 }
39
40 /* set texture data and size them mofos out */
41 if (self->label) {
42 self->a_title->texture[0].data.text.string = self->label;
43 RrMinsize(self->a_title, &self->title_min_w, &self->title_h);
44 self->title_min_w += ob_rr_theme->bevel * 2;
45 self->title_h += ob_rr_theme->bevel * 2;
46 self->size.width = MAX(self->size.width, self->title_min_w);
47 }
48
49 for (it = self->entries; it; it = it->next) {
50 ObMenuEntry *e = it->data;
51 int h;
52
53 if (e->a_item == NULL) {
54 e->a_item = RrAppearanceCopy(ob_rr_theme->a_menu_item);
55 e->a_disabled = RrAppearanceCopy(ob_rr_theme->a_menu_disabled);
56 e->a_hilite = RrAppearanceCopy(ob_rr_theme->a_menu_hilite);
57 }
58
59 e->a_item->texture[0].data.text.string = e->label;
60 RrMinsize(e->a_item, &e->min_w, &self->item_h);
61 self->size.width = MAX(self->size.width, e->min_w);
62
63 e->a_disabled->texture[0].data.text.string = e->label;
64 RrMinsize(e->a_disabled, &e->min_w, &h);
65 self->item_h = MAX(self->item_h, h);
66 self->size.width = MAX(self->size.width, e->min_w);
67
68 e->a_hilite->texture[0].data.text.string = e->label;
69 RrMinsize(e->a_hilite, &e->min_w, &h);
70 self->item_h = MAX(self->item_h, h);
71 self->size.width = MAX(self->size.width, e->min_w);
72
73 e->min_w += ob_rr_theme->bevel * 2;
74 ++nitems;
75 }
76 self->bullet_w = self->item_h + ob_rr_theme->bevel;
77 self->size.width += 2 * self->bullet_w + 2 * ob_rr_theme->bevel;
78 self->item_h += ob_rr_theme->bevel * 2;
79 items_h = self->item_h * MAX(nitems, 1);
80
81 self->size.height = MAX(self->title_h + items_h + ob_rr_theme->bwidth, 1);
82 XResizeWindow(ob_display, self->frame, self->size.width,self->size.height);
83 if (self->label)
84 XMoveResizeWindow(ob_display, self->title, -ob_rr_theme->bwidth,
85 -ob_rr_theme->bwidth,
86 self->size.width, self->title_h);
87
88 XMoveResizeWindow(ob_display, self->items, 0,
89 self->title_h + ob_rr_theme->bwidth, self->size.width,
90 items_h);
91
92 if (self->label)
93 RrPaint(self->a_title, self->title, self->size.width, self->title_h);
94 RrPaint(self->a_items, self->items, self->size.width, items_h);
95
96 item_y = 0;
97 for (it = self->entries; it; it = it->next) {
98 ((ObMenuEntry*)it->data)->y = item_y;
99 menu_entry_render(it->data);
100 item_y += self->item_h;
101 }
102
103 self->invalid = FALSE;
104 }
105
106 void menu_entry_render(ObMenuEntry *self)
107 {
108 ObMenu *menu = self->parent;
109 RrAppearance *a;
110
111 switch (self->render_type) {
112 case OB_MENU_ENTRY_RENDER_TYPE_SUBMENU:
113 /* TODO: submenu mask */
114 case OB_MENU_ENTRY_RENDER_TYPE_BOOLEAN:
115 /* TODO: boolean check */
116 a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item)
117 : self->a_disabled;
118 break;
119 case OB_MENU_ENTRY_RENDER_TYPE_NONE:
120 a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item )
121 : self->a_disabled;
122 break;
123 case OB_MENU_ENTRY_RENDER_TYPE_SEPARATOR:
124 a = self->a_item;
125 break;
126
127 default:
128 g_message("unhandled render_type");
129 a = !self->enabled ? self->a_disabled :
130 (self->hilite &&
131 (self->action ||
132 self->render_type == OB_MENU_ENTRY_RENDER_TYPE_SUBMENU) ?
133 self->a_hilite : self->a_item);
134 break;
135 }
136 g_message ("%s %d", self->label, self->hilite);
137
138 XMoveResizeWindow(ob_display, self->item, 0, self->y,
139 menu->size.width, menu->item_h);
140
141 a->surface.parent = menu->a_items;
142 a->surface.parentx = 0;
143 a->surface.parenty = self->y;
144
145 RrPaint(a, self->item, menu->size.width, menu->item_h);
146 }
This page took 0.038243 seconds and 4 git commands to generate.