]> git.decadent.org.uk Git - ion3.git/blob - mod_statusbar/draw.c
19ba93a25582f74b92ee1ca2b3406a1654922f24
[ion3.git] / mod_statusbar / draw.c
1 /*
2  * ion/mod_statusbar/draw.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2007. 
5  *
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.
10  */
11
12 #include <string.h>
13
14 #include <ioncore/common.h>
15 #include <ioncore/mplex.h>
16 #include "statusbar.h"
17 #include "draw.h"
18
19
20 static void calc_elems_x(WRectangle *g, WSBElem *elems, int nelems)
21 {
22     int x=g->x;
23     
24     while(nelems>0){
25         elems->x=x;
26         if(elems->type==WSBELEM_STRETCH)
27             x+=elems->text_w+elems->stretch;
28         else
29             x+=elems->text_w;
30         
31         nelems--;
32         elems++;
33     }
34 }
35
36
37 static void calc_elems_x_ra(WRectangle *g, WSBElem *elems, int nelems)
38 {
39     int x=g->x+g->w;
40     
41     elems+=nelems-1;
42     
43     while(nelems>0){
44         if(elems->type==WSBELEM_STRETCH)
45             x-=elems->text_w+elems->stretch;
46         else
47             x-=elems->text_w;
48         elems->x=x;
49         
50         elems--;
51         nelems--;
52     }
53 }
54
55
56 void statusbar_calculate_xs(WStatusBar *sb)
57 {
58     WRectangle g;
59     GrBorderWidths bdw;
60     WMPlex *mgr=NULL;
61     bool right_align=FALSE;
62     int minx, maxx;
63     int nleft=0, nright=0;
64     
65     if(sb->brush==NULL || sb->elems==NULL)
66         return;
67     
68     grbrush_get_border_widths(sb->brush, &bdw);
69
70     g.x=0;
71     g.y=0;
72     g.w=REGION_GEOM(sb).w;
73     g.h=REGION_GEOM(sb).h;
74     
75     mgr=OBJ_CAST(REGION_PARENT(sb), WMPlex);
76     if(mgr!=NULL){
77         WRegion *std=NULL;
78         WMPlexSTDispInfo din;
79         din.pos=MPLEX_STDISP_TL;
80         mplex_get_stdisp(mgr, &std, &din);
81         if(std==(WRegion*)sb)
82             right_align=(din.pos==MPLEX_STDISP_TR || din.pos==MPLEX_STDISP_BR);
83     }
84     
85     g.x+=bdw.left;
86     g.w-=bdw.left+bdw.right;
87     g.y+=bdw.top;
88     g.h-=bdw.top+bdw.bottom;
89
90     if(sb->filleridx>=0){
91         nleft=sb->filleridx;
92         nright=sb->nelems-(sb->filleridx+1);
93     }else if(!right_align){
94         nleft=sb->nelems;
95         nright=0;
96     }else{
97         nleft=0;
98         nright=sb->nelems;
99     }
100
101     if(nleft>0)
102         calc_elems_x(&g, sb->elems, nleft);
103     
104     if(nright>0)
105         calc_elems_x_ra(&g, sb->elems+sb->nelems-nright, nright);
106 }
107
108
109
110 static void draw_elems(GrBrush *brush, WRectangle *g, int ty,
111                        WSBElem *elems, int nelems, bool needfill, 
112                        bool complete)
113 {
114     int prevx=g->x;
115     int maxx=g->x+g->w;
116     
117     while(nelems>0){
118         if(prevx<elems->x){
119             g->x=prevx;
120             g->w=elems->x-prevx;
121             grbrush_clear_area(brush, g);
122         }
123             
124         if(elems->type==WSBELEM_TEXT || elems->type==WSBELEM_METER){
125             const char *s=(elems->text!=NULL
126                            ? elems->text 
127                            : STATUSBAR_NX_STR);
128             
129             grbrush_set_attr(brush, elems->attr);
130             grbrush_set_attr(brush, elems->meter);
131                 
132             grbrush_draw_string(brush, elems->x, ty, s, strlen(s), needfill);
133             
134             grbrush_unset_attr(brush, elems->meter);
135             grbrush_unset_attr(brush, elems->attr);
136             
137             prevx=elems->x+elems->text_w;
138         }
139         elems++;
140         nelems--;
141     }
142
143     if(prevx<maxx){
144         g->x=prevx;
145         g->w=maxx-prevx;
146         grbrush_clear_area(brush, g);
147     }
148 }
149
150
151 void statusbar_draw(WStatusBar *sb, bool complete)
152 {
153     WRectangle g;
154     GrBorderWidths bdw;
155     GrFontExtents fnte;
156     Window win=sb->wwin.win;
157     int ty;
158
159     if(sb->brush==NULL)
160         return;
161     
162     grbrush_get_border_widths(sb->brush, &bdw);
163     grbrush_get_font_extents(sb->brush, &fnte);
164
165     g.x=0;
166     g.y=0;
167     g.w=REGION_GEOM(sb).w;
168     g.h=REGION_GEOM(sb).h;
169     
170     grbrush_begin(sb->brush, &g, (complete ? 0 : GRBRUSH_NO_CLEAR_OK));
171     
172     grbrush_draw_border(sb->brush, &g);
173     
174     if(sb->elems==NULL)
175         return;
176     
177     g.x+=bdw.left;
178     g.w-=bdw.left+bdw.right;
179     g.y+=bdw.top;
180     g.h-=bdw.top+bdw.bottom;
181
182     ty=(g.y+fnte.baseline+(g.h-fnte.max_height)/2);
183         
184     draw_elems(sb->brush, &g, ty, sb->elems, sb->nelems, TRUE, complete);
185     
186     grbrush_end(sb->brush);
187 }
188
189