clean some tag stuff
[awesome.git] / widgets / taglist.c
blob6d9b57c461367a357d07ea05c583f8a8272636f7
1 /*
2 * taglist.c - tag list widget
4 * Copyright © 2007 Aldo Cortesi <aldo@nullcube.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "config.h"
23 #include "client.h"
24 #include "util.h"
25 #include "widget.h"
26 #include "tag.h"
27 #include "event.h"
29 extern AwesomeConf globalconf;
31 /** Check if at least one client is tagged with tag number t and is on screen
32 * screen
33 * \param screen screen number
34 * \param t tag
35 * \return True or False
37 static Bool
38 isoccupied(Tag *t)
40 Client *c;
42 for(c = globalconf.clients; c; c = c->next)
43 if(is_client_tagged(c, t) && !c->skip)
44 return True;
45 return False;
48 static Bool
49 isurgent(Tag *t)
51 Client *c;
53 for(c = globalconf.clients; c; c = c->next)
54 if(is_client_tagged(c, t) && c->isurgent)
55 return True;
57 return False;
60 static int
61 taglist_draw(Widget *widget,
62 DrawCtx *ctx,
63 int offset,
64 int used __attribute__ ((unused)))
66 Tag *tag;
67 Client *sel = globalconf.focus->client;
68 VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
69 int w = 0, flagsize;
70 XColor *colors;
71 Area area;
73 flagsize = (vscreen.font->height + 2) / 3;
75 widget->area.width = 0;
77 for(tag = vscreen.tags; tag; tag = tag->next)
78 widget->area.width += draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
80 if(!widget->user_supplied_x)
81 widget->area.x = widget_calculate_offset(widget->statusbar->width,
82 widget->area.width,
83 offset,
84 widget->alignment);
86 if(!widget->user_supplied_y)
87 widget->area.y = 0;
89 widget->area.width = 0;
90 for(tag = vscreen.tags; tag; tag = tag->next)
92 w = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
93 if(tag->selected)
94 colors = vscreen.colors_selected;
95 else if(isurgent(tag))
96 colors = vscreen.colors_urgent;
97 else
98 colors = vscreen.colors_normal;
99 area.x = widget->area.x + widget->area.width;
100 area.y = widget->area.y;
101 area.width = w;
102 area.height = widget->statusbar->height;
103 draw_text(ctx, area,
104 AlignCenter,
105 vscreen.font->height / 2,
106 vscreen.font,
107 tag->name,
108 colors[ColFG],
109 colors[ColBG]);
110 if(isoccupied(tag))
112 Area rectangle = { widget->area.x + widget->area.width,
113 widget->area.y,
114 flagsize,
115 flagsize };
116 draw_rectangle(ctx, rectangle, sel && is_client_tagged(sel, tag), colors[ColFG]);
118 widget->area.width += w;
121 widget->area.height = widget->statusbar->height;
122 return widget->area.width;
125 static void
126 taglist_button_press(Widget *widget, XButtonPressedEvent *ev)
128 VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
129 Button *b;
130 Tag *tag;
131 char buf[4];
132 int prev_width = 0, width = 0, i = 1;
134 for(b = widget->buttons; b; b = b->next)
135 if(ev->button == b->button && CLEANMASK(ev->state) == b->mod && b->func)
136 switch(widget->statusbar->position)
138 case Top:
139 case Bottom:
140 for(tag = vscreen.tags; tag; tag = tag->next, i++)
142 width = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
143 if(ev->x >= widget->area.x + prev_width
144 && ev->x < widget->area.x + prev_width + width)
146 snprintf(buf, sizeof(buf), "%d", i);
147 b->func(widget->statusbar->screen, buf);
148 return;
150 prev_width += width;
152 break;
153 case Right:
154 for(tag = vscreen.tags; tag; tag = tag->next, i++)
156 width = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
157 if(ev->y >= widget->area.x + prev_width
158 && ev->y < widget->area.x + prev_width + width)
160 snprintf(buf, sizeof(buf), "%d", i);
161 b->func(widget->statusbar->screen, buf);
162 return;
164 prev_width += width;
166 break;
167 default:
168 for(tag = vscreen.tags; tag; tag = tag->next, i++)
170 width = draw_textwidth(vscreen.font, tag->name) + vscreen.font->height;
171 if(widget->statusbar->width - ev->y >= widget->area.x + prev_width
172 && widget->statusbar->width - ev->y < widget->area.x + prev_width + width)
174 snprintf(buf, sizeof(buf), "%d", i);
175 b->func(widget->statusbar->screen, buf);
176 return;
178 prev_width += width;
180 break;
184 Widget *
185 taglist_new(Statusbar *statusbar, cfg_t *config)
187 Widget *w;
188 w = p_new(Widget, 1);
189 widget_common_new(w, statusbar, config);
190 w->draw = taglist_draw;
191 w->button_press = taglist_button_press;
193 /* Set cache property */
194 w->cache.flags = WIDGET_CACHE_TAGS | WIDGET_CACHE_CLIENTS;
196 return w;
199 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80