trunk: changeset 1940
[notion/jeffpc.git] / mod_statusbar / statusbar.c
blob9a96f3199cc68affb9f339759244c7cbaba0c25c
1 /*
2 * ion/ioncore/statusbar.c
4 * Copyright (c) Tuomo Valkonen 1999-2005.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
12 #include <string.h>
14 #include <libtu/objp.h>
15 #include <ioncore/common.h>
16 #include <ioncore/global.h>
17 #include <ioncore/window.h>
18 #include <ioncore/binding.h>
19 #include <ioncore/regbind.h>
20 #include <ioncore/event.h>
21 #include <ioncore/resize.h>
22 #include <ioncore/gr.h>
24 #include "statusbar.h"
25 #include "main.h"
26 #include "draw.h"
29 static void statusbar_set_strings(WStatusBar *sb, ExtlTab t);
30 static void statusbar_free_strings(WStatusBar *sb);
31 static void statusbar_update_natural_size(WStatusBar *p);
34 /*{{{ Init/deinit */
37 bool statusbar_init(WStatusBar *p, WWindow *parent, const WFitParams *fp)
39 if(!window_init(&(p->wwin), parent, fp))
40 return FALSE;
42 p->brush=NULL;
43 p->strings=NULL;
44 p->nstrings=0;
45 p->natural_w=1;
46 p->natural_h=1;
47 p->natural_w_tmpl=NULL;
49 statusbar_updategr(p);
51 if(p->brush==NULL){
52 window_deinit(&(p->wwin));
53 return FALSE;
56 XSelectInput(ioncore_g.dpy, p->wwin.win, IONCORE_EVENTMASK_NORMAL);
58 region_add_bindmap((WRegion*)p, mod_statusbar_statusbar_bindmap);
60 ((WRegion*)p)->flags|=REGION_SKIP_FOCUS;
62 return TRUE;
67 WStatusBar *create_statusbar(WWindow *parent, const WFitParams *fp)
69 CREATEOBJ_IMPL(WStatusBar, statusbar, (p, parent, fp));
73 void statusbar_deinit(WStatusBar *p)
75 statusbar_free_strings(p);
77 if(p->brush!=NULL)
78 grbrush_release(p->brush, p->wwin.win);
80 if(p->natural_w_tmpl!=NULL)
81 free(p->natural_w_tmpl);
83 window_deinit(&(p->wwin));
87 /*}}}*/
90 /*{{{ Content stuff */
93 static GrTextElem *get_textelems(ExtlTab t, int *nret)
95 int i, n=extl_table_get_n(t);
96 GrTextElem *el;
98 *nret=0;
100 if(n<=0)
101 return NULL;
103 el=ALLOC_N(GrTextElem, n);
105 if(el==NULL)
106 return NULL;
108 for(i=0; i<n; i++){
109 ExtlTab tt;
111 el[i].text=NULL;
112 el[i].attr=NULL;
113 el[i].iw=0;
115 if(extl_table_geti_t(t, i+1, &tt)){
116 extl_table_gets_s(tt, "text", &(el[i].text));
117 extl_table_gets_s(tt, "attr", &(el[i].attr));
118 extl_unref_table(tt);
122 *nret=n;
124 return el;
128 static void free_textelems(GrTextElem *el, int n)
130 int i;
132 for(i=0; i<n; i++){
133 if(el[i].text!=NULL)
134 free(el[i].text);
135 if(el[i].attr!=NULL)
136 free(el[i].attr);
139 free(el);
143 static void statusbar_set_strings(WStatusBar *sb, ExtlTab t)
145 statusbar_free_strings(sb);
147 sb->strings=get_textelems(t, &(sb->nstrings));
151 static void statusbar_free_strings(WStatusBar *sb)
153 if(sb->strings!=NULL){
154 free_textelems(sb->strings, sb->nstrings);
155 sb->strings=NULL;
156 sb->nstrings=0;
161 /*EXTL_DOC
162 * Set statusbar contents.
164 EXTL_EXPORT_MEMBER
165 void statusbar_set_contents(WStatusBar *sb, ExtlTab t)
167 statusbar_set_strings(sb, t);
169 statusbar_update_natural_size(sb);
171 window_draw(&sb->wwin, TRUE);
175 /*}}}*/
179 /*{{{ Size stuff */
182 static void statusbar_resize(WStatusBar *p)
184 int rqflags=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
185 WRectangle g;
187 g.w=p->natural_w;
188 g.h=p->natural_h;
189 g.x=REGION_GEOM(p).x;
190 g.y=REGION_GEOM(p).y;
192 if(g.w!=REGION_GEOM(p).w || g.h!=REGION_GEOM(p).h)
193 region_rqgeom((WRegion*)p, rqflags, &g, NULL);
197 static void statusbar_update_natural_size(WStatusBar *p)
199 GrBorderWidths bdw;
200 GrFontExtents fnte;
201 const char *str=(p->natural_w_tmpl!=NULL ? p->natural_w_tmpl : "");
203 grbrush_get_border_widths(p->brush, &bdw);
204 grbrush_get_font_extents(p->brush, &fnte);
206 p->natural_w=bdw.left+bdw.right;
207 p->natural_w+=grbrush_get_text_width(p->brush, str, strlen(str));
208 p->natural_h=fnte.max_height+bdw.top+bdw.bottom;
212 /*EXTL_DOC
213 * Set natural width template string.
215 EXTL_EXPORT_MEMBER
216 void statusbar_set_natural_w(WStatusBar *p, const char *str)
218 GrBorderWidths bdw;
219 char *s=NULL;
221 if(str!=NULL){
222 s=scopy(str);
223 if(s==NULL)
224 return;
227 if(p->natural_w_tmpl!=NULL)
228 free(p->natural_w_tmpl);
230 p->natural_w_tmpl=s;
232 statusbar_update_natural_size(p);
233 statusbar_resize(p);
237 void statusbar_size_hints(WStatusBar *p, XSizeHints *h)
239 h->flags=PMaxSize|PMinSize;
240 h->min_width=p->natural_w;
241 h->min_height=p->natural_h;
242 h->max_width=p->natural_w;
243 h->max_height=p->natural_h;
247 /*}}}*/
250 /*{{{ Updategr */
253 void statusbar_updategr(WStatusBar *p)
255 GrBrush *nbrush;
257 nbrush=gr_get_brush(region_rootwin_of((WRegion*)p),
258 p->wwin.win, "stdisp-statusbar");
259 if(nbrush==NULL)
260 return;
262 if(p->brush!=NULL)
263 grbrush_release(p->brush, p->wwin.win);
265 p->brush=nbrush;
267 statusbar_update_natural_size(p);
269 window_draw(&(p->wwin), TRUE);
273 /*}}}*/
276 /*{{{ Load */
279 WRegion *statusbar_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
281 return (WRegion*)create_statusbar(par, fp);
285 /*}}}*/
288 /*{{{ Dynamic function table and class implementation */
291 static DynFunTab statusbar_dynfuntab[]={
292 {window_draw, statusbar_draw},
293 {region_updategr, statusbar_updategr},
294 {region_size_hints, statusbar_size_hints},
295 END_DYNFUNTAB
299 IMPLCLASS(WStatusBar, WWindow, statusbar_deinit, statusbar_dynfuntab);
302 /*}}}*/