Log startup
[notion/jeffpc.git] / mod_statusbar / draw.c
blob6a9750ecf26843a9430ce3350375fb6c3d5e8876
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 minx, maxx;
60 int nleft=0, nright=0;
62 if(sb->brush==NULL || sb->elems==NULL)
63 return;
65 grbrush_get_border_widths(sb->brush, &bdw);
67 g.x=0;
68 g.y=0;
69 g.w=REGION_GEOM(sb).w;
70 g.h=REGION_GEOM(sb).h;
72 mgr=OBJ_CAST(REGION_PARENT(sb), WMPlex);
73 if(mgr!=NULL){
74 WRegion *std=NULL;
75 WMPlexSTDispInfo din;
76 din.pos=MPLEX_STDISP_TL;
77 mplex_get_stdisp(mgr, &std, &din);
78 if(std==(WRegion*)sb)
79 right_align=(din.pos==MPLEX_STDISP_TR || din.pos==MPLEX_STDISP_BR);
82 g.x+=bdw.left;
83 g.w-=bdw.left+bdw.right;
84 g.y+=bdw.top;
85 g.h-=bdw.top+bdw.bottom;
87 if(sb->filleridx>=0){
88 nleft=sb->filleridx;
89 nright=sb->nelems-(sb->filleridx+1);
90 }else if(!right_align){
91 nleft=sb->nelems;
92 nright=0;
93 }else{
94 nleft=0;
95 nright=sb->nelems;
98 if(nleft>0)
99 calc_elems_x(&g, sb->elems, nleft);
101 if(nright>0)
102 calc_elems_x_ra(&g, sb->elems+sb->nelems-nright, nright);
107 static void draw_elems(GrBrush *brush, WRectangle *g, int ty,
108 WSBElem *elems, int nelems, bool needfill,
109 bool complete)
111 int prevx=g->x;
112 int maxx=g->x+g->w;
114 while(nelems>0){
115 if(prevx<elems->x){
116 g->x=prevx;
117 g->w=elems->x-prevx;
118 grbrush_clear_area(brush, g);
121 if(elems->type==WSBELEM_TEXT || elems->type==WSBELEM_METER){
122 const char *s=(elems->text!=NULL
123 ? elems->text
124 : STATUSBAR_NX_STR);
126 grbrush_set_attr(brush, elems->attr);
127 grbrush_set_attr(brush, elems->meter);
129 grbrush_draw_string(brush, elems->x, ty, s, strlen(s), needfill);
131 grbrush_unset_attr(brush, elems->meter);
132 grbrush_unset_attr(brush, elems->attr);
134 prevx=elems->x+elems->text_w;
136 elems++;
137 nelems--;
140 if(prevx<maxx){
141 g->x=prevx;
142 g->w=maxx-prevx;
143 grbrush_clear_area(brush, g);
148 void statusbar_draw(WStatusBar *sb, bool complete)
150 WRectangle g;
151 GrBorderWidths bdw;
152 GrFontExtents fnte;
153 Window win=sb->wwin.win;
154 int ty;
156 if(sb->brush==NULL)
157 return;
159 grbrush_get_border_widths(sb->brush, &bdw);
160 grbrush_get_font_extents(sb->brush, &fnte);
162 g.x=0;
163 g.y=0;
164 g.w=REGION_GEOM(sb).w;
165 g.h=REGION_GEOM(sb).h;
167 grbrush_begin(sb->brush, &g, (complete ? 0 : GRBRUSH_NO_CLEAR_OK));
169 grbrush_draw_border(sb->brush, &g);
171 if(sb->elems==NULL)
172 return;
174 g.x+=bdw.left;
175 g.w-=bdw.left+bdw.right;
176 g.y+=bdw.top;
177 g.h-=bdw.top+bdw.bottom;
179 ty=(g.y+fnte.baseline+(g.h-fnte.max_height)/2);
181 draw_elems(sb->brush, &g, ty, sb->elems, sb->nelems, TRUE, complete);
183 grbrush_end(sb->brush);