summaryrefslogtreecommitdiff
path: root/openbox/menu_render.c
blob: 2ca1c77392af215ec9eb4163205e77f560242194 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* Functions for default rendering of menus. Might become pluginnable */

#include "menu.h"
#include "openbox.h"
#include "render/theme.h"

void menu_render_full(Menu *self);

void menu_render(Menu *self) {
    if (self->invalid) {
	if (self->update) {
	    self->update(self);
	} else {
	    menu_render_full(self);
	}
    }
}
	    

void menu_render_full(Menu *self) {
    GList *it;
    int items_h = 0;
    int nitems = 0; /* each item, only one is used */
    int item_y;

    self->size.width = 1;
    self->item_h = 1;

    /* set texture data and size them mofos out */
    if (self->label) {
	self->a_title->texture[0].data.text.string = self->label;
	RrMinsize(self->a_title, &self->title_min_w, &self->title_h);
	self->title_min_w += ob_rr_theme->bevel * 2;
	self->title_h += ob_rr_theme->bevel * 2;
	self->size.width = MAX(self->size.width, self->title_min_w);
    }

    for (it = self->entries; it; it = it->next) {
        MenuEntry *e = it->data;
        int h;

        e->a_item->texture[0].data.text.string = e->label;
        RrMinsize(e->a_item, &e->min_w, &self->item_h);
        self->size.width = MAX(self->size.width, e->min_w);

        e->a_disabled->texture[0].data.text.string = e->label;
        RrMinsize(e->a_disabled, &e->min_w, &h);
        self->item_h = MAX(self->item_h, h);
        self->size.width = MAX(self->size.width, e->min_w);
	
        e->a_hilite->texture[0].data.text.string = e->label;
        RrMinsize(e->a_hilite, &e->min_w, &h);
        self->item_h = MAX(self->item_h, h);
        self->size.width = MAX(self->size.width, e->min_w);

        e->min_w += ob_rr_theme->bevel * 2;
        ++nitems;
    }
    self->bullet_w = self->item_h + ob_rr_theme->bevel;
    self->size.width += 2 * self->bullet_w + 2 * ob_rr_theme->bevel;
    self->item_h += ob_rr_theme->bevel * 2;
    items_h = self->item_h * MAX(nitems, 1);

    XResizeWindow(ob_display, self->frame, self->size.width,
		  MAX(self->title_h + items_h, 1));
    if (self->label)
	XMoveResizeWindow(ob_display, self->title, -ob_rr_theme->bwidth,
			  -ob_rr_theme->bwidth,
                          self->size.width, self->title_h);

    XMoveResizeWindow(ob_display, self->items, 0, 
		      self->title_h + ob_rr_theme->bwidth, self->size.width, 
		      items_h);

    if (self->label)
	RrPaint(self->a_title, self->title, self->size.width, self->title_h);
    RrPaint(self->a_items, self->items, self->size.width, items_h);

    item_y = 0;
    for (it = self->entries; it; it = it->next) {
        ((MenuEntry*)it->data)->y = item_y;
        menu_entry_render(it->data);
        item_y += self->item_h;
    }
    
    self->size.height = item_y;
    self->invalid = FALSE;
}

void menu_entry_render(MenuEntry *self)
{
    Menu *menu = self->parent;
    RrAppearance *a;
    
    switch (self->render_type) {
    case MenuEntryRenderType_Submenu:
	/* TODO: submenu mask */
    case MenuEntryRenderType_Boolean:
	/* TODO: boolean check */
	a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item) 
	    : self->a_disabled;
	break;
    case MenuEntryRenderType_None:
	a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item )
	    : self->a_disabled;
	break;
    case MenuEntryRenderType_Separator:
	a = self->a_item;
	break;

    default:
	g_message("unhandled render_type");
	a = !self->enabled ? self->a_disabled :
        (self->hilite && 
         (self->action || self->render_type == MenuEntryRenderType_Submenu) ? 
         self->a_hilite : self->a_item);
	break;
    }

    XMoveResizeWindow(ob_display, self->item, 0, self->y,
                      menu->size.width, menu->item_h);

    a->surface.parent = menu->a_items;
    a->surface.parentx = 0;
    a->surface.parenty = self->y;

    RrPaint(a, self->item, menu->size.width, menu->item_h);
}