Merge branch 'remotes/jsbackus/mpd_lua52'
[notion.git] / mod_statusbar / draw.c
blob75291743a84ed26c5a249db501ba53ed9fd15ee0
1 /*
2 * ion/mod_statusbar/draw.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
11 #include <ioncore/common.h>
12 #include <ioncore/mplex.h>
13 #include "statusbar.h"
14 #include "draw.h"
17 static void calc_elems_x(WRectangle *g, WSBElem *elems, int nelems)
19 int x=g->x;
21 while(nelems>0){
22 elems->x=x;
23 if(elems->type==WSBELEM_STRETCH)
24 x+=elems->text_w+elems->stretch;
25 else
26 x+=elems->text_w;
28 nelems--;
29 elems++;
34 static void calc_elems_x_ra(WRectangle *g, WSBElem *elems, int nelems)
36 int x=g->x+g->w;
38 elems+=nelems-1;
40 while(nelems>0){
41 if(elems->type==WSBELEM_STRETCH)
42 x-=elems->text_w+elems->stretch;
43 else
44 x-=elems->text_w;
45 elems->x=x;
47 elems--;
48 nelems--;
53 void statusbar_calculate_xs(WStatusBar *sb)
55 WRectangle g;
56 GrBorderWidths bdw;
57 WMPlex *mgr=NULL;
58 bool right_align=FALSE;
59 int nleft=0, nright=0;
61 if(sb->brush==NULL || sb->elems==NULL)
62 return;
64 grbrush_get_border_widths(sb->brush, &bdw);
66 g.x=0;
67 g.y=0;
68 g.w=REGION_GEOM(sb).w;
69 g.h=REGION_GEOM(sb).h;
71 mgr=OBJ_CAST(REGION_PARENT(sb), WMPlex);
72 if(mgr!=NULL){
73 WRegion *std=NULL;
74 WMPlexSTDispInfo din;
75 din.pos=MPLEX_STDISP_TL;
76 mplex_get_stdisp(mgr, &std, &din);
77 if(std==(WRegion*)sb)
78 right_align=(din.pos==MPLEX_STDISP_TR || din.pos==MPLEX_STDISP_BR);
81 g.x+=bdw.left;
82 g.w-=bdw.left+bdw.right;
83 g.y+=bdw.top;
84 g.h-=bdw.top+bdw.bottom;
86 if(sb->filleridx>=0){
87 nleft=sb->filleridx;
88 nright=sb->nelems-(sb->filleridx+1);
89 }else if(!right_align){
90 nleft=sb->nelems;
91 nright=0;
92 }else{
93 nleft=0;
94 nright=sb->nelems;
97 if(nleft>0)
98 calc_elems_x(&g, sb->elems, nleft);
100 if(nright>0)
101 calc_elems_x_ra(&g, sb->elems+sb->nelems-nright, nright);
106 static void draw_elems(GrBrush *brush, WRectangle *g, int ty,
107 WSBElem *elems, int nelems, bool needfill,
108 bool complete)
110 int prevx=g->x;
111 int maxx=g->x+g->w;
113 while(nelems>0){
114 if(prevx<elems->x){
115 g->x=prevx;
116 g->w=elems->x-prevx;
117 grbrush_clear_area(brush, g);
120 if(elems->type==WSBELEM_TEXT || elems->type==WSBELEM_METER){
121 const char *s=(elems->text!=NULL
122 ? elems->text
123 : STATUSBAR_NX_STR);
125 grbrush_set_attr(brush, elems->attr);
126 grbrush_set_attr(brush, elems->meter);
128 grbrush_draw_string(brush, elems->x, ty, s, strlen(s), needfill);
130 grbrush_unset_attr(brush, elems->meter);
131 grbrush_unset_attr(brush, elems->attr);
133 prevx=elems->x+elems->text_w;
135 elems++;
136 nelems--;
139 if(prevx<maxx){
140 g->x=prevx;
141 g->w=maxx-prevx;
142 grbrush_clear_area(brush, g);
147 void statusbar_draw(WStatusBar *sb, bool complete)
149 WRectangle g;
150 GrBorderWidths bdw;
151 GrFontExtents fnte;
152 int ty;
154 if(sb->brush==NULL)
155 return;
157 grbrush_get_border_widths(sb->brush, &bdw);
158 grbrush_get_font_extents(sb->brush, &fnte);
160 g.x=0;
161 g.y=0;
162 g.w=REGION_GEOM(sb).w;
163 g.h=REGION_GEOM(sb).h;
165 grbrush_begin(sb->brush, &g, (complete ? 0 : GRBRUSH_NO_CLEAR_OK));
167 grbrush_draw_border(sb->brush, &g);
169 if(sb->elems==NULL)
170 return;
172 g.x+=bdw.left;
173 g.w-=bdw.left+bdw.right;
174 g.y+=bdw.top;
175 g.h-=bdw.top+bdw.bottom;
177 ty=(g.y+fnte.baseline+(g.h-fnte.max_height)/2);
179 draw_elems(sb->brush, &g, ty, sb->elems, sb->nelems, TRUE, complete);
181 grbrush_end(sb->brush);