]> git.decadent.org.uk Git - ion3.git/blob - ioncore/infowin.c
f3c2da9b2eed396d3c1e36ead232b89aeaceb8a6
[ion3.git] / ioncore / infowin.c
1 /*
2  * ion/ioncore/infowin.h
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 <libtu/objp.h>
15 #include "common.h"
16 #include "global.h"
17 #include "window.h"
18 #include "infowin.h"
19 #include "resize.h"
20 #include "gr.h"
21 #include "event.h"
22 #include "strings.h"
23
24
25 /*{{{ Init/deinit */
26
27
28 bool infowin_init(WInfoWin *p, WWindow *parent, const WFitParams *fp,
29                   const char *style)
30 {
31     XSetWindowAttributes attr;
32     
33     if(!window_init(&(p->wwin), parent, fp))
34         return FALSE;
35     
36     p->buffer=ALLOC_N(char, INFOWIN_BUFFER_LEN);
37     if(p->buffer==NULL)
38         goto fail;
39     p->buffer[0]='\0';
40     
41     if(style==NULL)
42         p->style=scopy("*");
43     else
44         p->style=scopy(style);
45     if(p->style==NULL)
46         goto fail2;
47     
48     p->brush=NULL;
49     
50     gr_stylespec_init(&p->attr);
51     
52     infowin_updategr(p);
53     
54     if(p->brush==NULL)
55         goto fail3;
56     
57     p->wwin.region.flags|=REGION_SKIP_FOCUS;
58     
59     /* Enable save unders */
60     attr.save_under=True;
61     XChangeWindowAttributes(ioncore_g.dpy, p->wwin.win, CWSaveUnder, &attr);
62     
63     window_select_input(&(p->wwin), IONCORE_EVENTMASK_NORMAL);
64
65     return TRUE;
66
67 fail3:
68     gr_stylespec_unalloc(&p->attr);
69     free(p->style);
70 fail2:
71     free(p->buffer);
72 fail:    
73     window_deinit(&(p->wwin));
74     return FALSE;
75 }
76
77
78 WInfoWin *create_infowin(WWindow *parent, const WFitParams *fp,
79                          const char *style)
80 {
81     CREATEOBJ_IMPL(WInfoWin, infowin, (p, parent, fp, style));
82 }
83
84
85 void infowin_deinit(WInfoWin *p)
86 {
87     if(p->buffer!=NULL){
88         free(p->buffer);
89         p->buffer=NULL;
90     }
91
92     if(p->style!=NULL){
93         free(p->style);
94         p->style=NULL;
95     }
96     
97     if(p->brush!=NULL){
98         grbrush_release(p->brush);
99         p->brush=NULL;
100     }
101     
102     gr_stylespec_unalloc(&p->attr);
103     
104     window_deinit(&(p->wwin));
105 }
106
107
108 /*}}}*/
109
110
111 /*{{{ Drawing and geometry */
112
113
114 void infowin_draw(WInfoWin *p, bool complete)
115 {
116     WRectangle g;
117     
118     if(p->brush==NULL)
119         return;
120     
121     g.x=0;
122     g.y=0;
123     g.w=REGION_GEOM(p).w;
124     g.h=REGION_GEOM(p).h;
125
126     grbrush_begin(p->brush, &g, GRBRUSH_NO_CLEAR_OK);
127     grbrush_init_attr(p->brush, &p->attr);
128     grbrush_draw_textbox(p->brush, &g, p->buffer, TRUE);
129     grbrush_end(p->brush);
130 }
131
132
133 void infowin_updategr(WInfoWin *p)
134 {
135     GrBrush *nbrush;
136     
137     assert(p->style!=NULL);
138     
139     nbrush=gr_get_brush(p->wwin.win, 
140                         region_rootwin_of((WRegion*)p),
141                         p->style);
142     if(nbrush==NULL)
143         return;
144     
145     if(p->brush!=NULL)
146         grbrush_release(p->brush);
147     
148     p->brush=nbrush;
149     
150     window_draw(&(p->wwin), TRUE);
151 }
152
153
154
155 /*}}}*/
156
157
158 /*{{{ Content-setting */
159
160
161 GrStyleSpec *infowin_stylespec(WInfoWin *p)
162 {
163     return &p->attr;
164 }
165
166
167 static void infowin_do_set_text(WInfoWin *p, const char *str)
168 {
169     strncpy(INFOWIN_BUFFER(p), str, INFOWIN_BUFFER_LEN);
170     INFOWIN_BUFFER(p)[INFOWIN_BUFFER_LEN-1]='\0';
171 }
172
173
174 static void infowin_resize(WInfoWin *p)
175 {
176     WRQGeomParams rq=RQGEOMPARAMS_INIT;
177     const char *str=INFOWIN_BUFFER(p);
178     GrBorderWidths bdw;
179     GrFontExtents fnte;
180     
181     rq.flags=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
182     
183     rq.geom.x=REGION_GEOM(p).x;
184     rq.geom.y=REGION_GEOM(p).y;
185     
186     grbrush_get_border_widths(p->brush, &bdw);
187     grbrush_get_font_extents(p->brush, &fnte);
188         
189     rq.geom.w=bdw.left+bdw.right;
190     rq.geom.w+=grbrush_get_text_width(p->brush, str, strlen(str));
191     rq.geom.h=fnte.max_height+bdw.top+bdw.bottom;
192
193     if(rectangle_compare(&rq.geom, &REGION_GEOM(p))!=RECTANGLE_SAME)
194         region_rqgeom((WRegion*)p, &rq, NULL);
195 }
196
197
198 /*EXTL_DOC
199  * Set contents of the info window.
200  */
201 EXTL_EXPORT_MEMBER
202 void infowin_set_text(WInfoWin *p, const char *str, int maxw)
203 {
204     bool set=FALSE;
205     
206     if(maxw>0 && p->brush!=NULL){
207         char *tmp=grbrush_make_label(p->brush, str, maxw);
208         if(tmp!=NULL){
209             infowin_do_set_text(p, tmp);
210             free(tmp);
211             set=TRUE;
212         }
213     }
214     
215     if(!set)
216         infowin_do_set_text(p, str);
217
218     infowin_resize(p);
219     
220     /* sometimes unnecessary */
221     window_draw((WWindow*)p, TRUE);
222 }
223
224
225 /*}}}*/
226
227
228 /*{{{ Load */
229
230
231 WRegion *infowin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
232 {
233     char *style=NULL, *text=NULL;
234     WInfoWin *p;
235     
236     extl_table_gets_s(tab, "style", &style);
237     
238     p=create_infowin(par, fp, style);
239     
240     free(style);
241     
242     if(p==NULL)
243         return NULL;
244
245     if(extl_table_gets_s(tab, "text", &text)){
246         infowin_do_set_text(p, text);
247         free(text);
248     }
249     
250     return (WRegion*)p;
251 }
252
253
254 /*}}}*/
255
256
257 /*{{{ Dynamic function table and class implementation */
258
259
260 static DynFunTab infowin_dynfuntab[]={
261     {window_draw, infowin_draw},
262     {region_updategr, infowin_updategr},
263     END_DYNFUNTAB
264 };
265
266
267 EXTL_EXPORT
268 IMPLCLASS(WInfoWin, WWindow, infowin_deinit, infowin_dynfuntab);
269
270     
271 /*}}}*/
272