]> git.decadent.org.uk Git - ion3.git/blob - mod_statusbar/draw.c
b4663068563701a714ea2f9dd61a08329d98978f
[ion3.git] / mod_statusbar / draw.c
1 /*
2  * ion/mod_statusbar/draw.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2008. 
5  *
6  * See the included file LICENSE for details.
7  */
8
9 #include <string.h>
10
11 #include <ioncore/common.h>
12 #include <ioncore/mplex.h>
13 #include "statusbar.h"
14 #include "draw.h"
15
16
17 static void calc_elems_x(WRectangle *g, WSBElem *elems, int nelems)
18 {
19     int x=g->x;
20     
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;
27         
28         nelems--;
29         elems++;
30     }
31 }
32
33
34 static void calc_elems_x_ra(WRectangle *g, WSBElem *elems, int nelems)
35 {
36     int x=g->x+g->w;
37     
38     elems+=nelems-1;
39     
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;
46         
47         elems--;
48         nelems--;
49     }
50 }
51
52
53 void statusbar_calculate_xs(WStatusBar *sb)
54 {
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;
61     
62     if(sb->brush==NULL || sb->elems==NULL)
63         return;
64     
65     grbrush_get_border_widths(sb->brush, &bdw);
66
67     g.x=0;
68     g.y=0;
69     g.w=REGION_GEOM(sb).w;
70     g.h=REGION_GEOM(sb).h;
71     
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);
80     }
81     
82     g.x+=bdw.left;
83     g.w-=bdw.left+bdw.right;
84     g.y+=bdw.top;
85     g.h-=bdw.top+bdw.bottom;
86
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;
96     }
97
98     if(nleft>0)
99         calc_elems_x(&g, sb->elems, nleft);
100     
101     if(nright>0)
102         calc_elems_x_ra(&g, sb->elems+sb->nelems-nright, nright);
103 }
104
105
106
107 static void draw_elems(GrBrush *brush, WRectangle *g, int ty,
108                        WSBElem *elems, int nelems, bool needfill, 
109                        bool complete)
110 {
111     int prevx=g->x;
112     int maxx=g->x+g->w;
113     
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);
119         }
120             
121         if(elems->type==WSBELEM_TEXT || elems->type==WSBELEM_METER){
122             const char *s=(elems->text!=NULL
123                            ? elems->text 
124                            : STATUSBAR_NX_STR);
125             
126             grbrush_set_attr(brush, elems->attr);
127             grbrush_set_attr(brush, elems->meter);
128                 
129             grbrush_draw_string(brush, elems->x, ty, s, strlen(s), needfill);
130             
131             grbrush_unset_attr(brush, elems->meter);
132             grbrush_unset_attr(brush, elems->attr);
133             
134             prevx=elems->x+elems->text_w;
135         }
136         elems++;
137         nelems--;
138     }
139
140     if(prevx<maxx){
141         g->x=prevx;
142         g->w=maxx-prevx;
143         grbrush_clear_area(brush, g);
144     }
145 }
146
147
148 void statusbar_draw(WStatusBar *sb, bool complete)
149 {
150     WRectangle g;
151     GrBorderWidths bdw;
152     GrFontExtents fnte;
153     Window win=sb->wwin.win;
154     int ty;
155
156     if(sb->brush==NULL)
157         return;
158     
159     grbrush_get_border_widths(sb->brush, &bdw);
160     grbrush_get_font_extents(sb->brush, &fnte);
161
162     g.x=0;
163     g.y=0;
164     g.w=REGION_GEOM(sb).w;
165     g.h=REGION_GEOM(sb).h;
166     
167     grbrush_begin(sb->brush, &g, (complete ? 0 : GRBRUSH_NO_CLEAR_OK));
168     
169     grbrush_draw_border(sb->brush, &g);
170     
171     if(sb->elems==NULL)
172         return;
173     
174     g.x+=bdw.left;
175     g.w-=bdw.left+bdw.right;
176     g.y+=bdw.top;
177     g.h-=bdw.top+bdw.bottom;
178
179     ty=(g.y+fnte.baseline+(g.h-fnte.max_height)/2);
180         
181     draw_elems(sb->brush, &g, ty, sb->elems, sb->nelems, TRUE, complete);
182     
183     grbrush_end(sb->brush);
184 }
185
186