]> git.decadent.org.uk Git - ion3.git/blob - mod_statusbar/draw.c
[svn-inject] Installing original source of ion3
[ion3.git] / mod_statusbar / draw.c
1 /*
2  * ion/mod_statusbar/draw.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2006. 
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                        const char *dfltattr, 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             grbrush_draw_string(brush, elems->x, ty, s, strlen(s), needfill, 
129                                 elems->attr ? elems->attr : dfltattr);
130             prevx=elems->x+elems->text_w;
131         }
132         elems++;
133         nelems--;
134     }
135
136     if(prevx<maxx){
137         g->x=prevx;
138         g->w=maxx-prevx;
139         grbrush_clear_area(brush, g);
140     }
141 }
142
143
144 void statusbar_draw(WStatusBar *sb, bool complete)
145 {
146     WRectangle g;
147     GrBorderWidths bdw;
148     GrFontExtents fnte;
149     Window win=sb->wwin.win;
150     int ty;
151
152     if(sb->brush==NULL)
153         return;
154     
155     grbrush_get_border_widths(sb->brush, &bdw);
156     grbrush_get_font_extents(sb->brush, &fnte);
157
158     g.x=0;
159     g.y=0;
160     g.w=REGION_GEOM(sb).w;
161     g.h=REGION_GEOM(sb).h;
162     
163     grbrush_begin(sb->brush, &g, (complete ? 0 : GRBRUSH_NO_CLEAR_OK));
164     
165     grbrush_draw_border(sb->brush, &g, NULL);
166     
167     if(sb->elems==NULL)
168         return;
169     
170     g.x+=bdw.left;
171     g.w-=bdw.left+bdw.right;
172     g.y+=bdw.top;
173     g.h-=bdw.top+bdw.bottom;
174
175     ty=(g.y+fnte.baseline+(g.h-fnte.max_height)/2);
176         
177     draw_elems(sb->brush, &g, ty, sb->elems, sb->nelems,
178                TRUE, NULL, complete);
179     
180     grbrush_end(sb->brush);
181 }
182
183