]> git.decadent.org.uk Git - ion3.git/blob - mod_query/wmessage.c
e7c5d3d70cda4ad81553dffd0ab103ca200c4b7a
[ion3.git] / mod_query / wmessage.c
1 /*
2  * ion/mod_query/wmessage.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 <libtu/objp.h>
15 #include <ioncore/common.h>
16 #include <ioncore/strings.h>
17 #include <ioncore/global.h>
18 #include <ioncore/event.h>
19 #include <ioncore/gr-util.h>
20 #include <ioncore/sizehint.h>
21 #include <ioncore/resize.h>
22 #include "wmessage.h"
23 #include "inputp.h"
24
25
26 #define WMSG_BRUSH(WMSG) ((WMSG)->input.brush)
27 #define WMSG_WIN(WMSG) ((WMSG)->input.win.win)
28
29
30 /*{{{ Sizecalc */
31
32
33 static void get_geom(WMessage *wmsg, bool max, WRectangle *geom)
34 {
35     if(max){
36         geom->w=wmsg->input.last_fp.g.w;
37         geom->h=wmsg->input.last_fp.g.h;
38     }else{
39         geom->w=REGION_GEOM(wmsg).w;
40         geom->h=REGION_GEOM(wmsg).h;
41     }
42     geom->x=0;
43     geom->y=0;
44 }
45
46
47 static void wmsg_calc_size(WMessage *wmsg, WRectangle *geom)
48 {
49     WRectangle max_geom=*geom;
50     GrBorderWidths bdw;
51     int h=16;
52
53     if(WMSG_BRUSH(wmsg)!=NULL){
54         WRectangle g;
55         g.w=max_geom.w;
56         g.h=max_geom.h;
57         g.x=0;
58         g.y=0;
59         
60         fit_listing(WMSG_BRUSH(wmsg), &g, &(wmsg->listing));
61
62         grbrush_get_border_widths(WMSG_BRUSH(wmsg), &bdw);
63         
64         h=bdw.top+bdw.bottom+wmsg->listing.toth;
65     }
66     
67     if(h>max_geom.h || !(wmsg->input.last_fp.mode&REGION_FIT_BOUNDS))
68         h=max_geom.h;
69     
70     geom->h=h;
71     geom->w=max_geom.w;
72     geom->y=max_geom.y+max_geom.h-geom->h;
73     geom->x=max_geom.x;
74 }
75
76
77 void wmsg_size_hints(WMessage *wmsg, WSizeHints *hints_ret)
78 {
79     int w=1, h=1;
80     
81     if(WMSG_BRUSH(wmsg)!=NULL){
82         mod_query_get_minimum_extents(WMSG_BRUSH(wmsg), FALSE, &w, &h);
83
84         w+=grbrush_get_text_width(WMSG_BRUSH(wmsg), "xxxxx", 5);
85     }
86     
87     hints_ret->min_set=TRUE;
88     hints_ret->min_width=w;
89     hints_ret->min_height=h;
90 }
91
92
93 /*}}}*/
94
95
96 /*{{{ Draw */
97
98
99 GR_DEFATTR(active);
100 GR_DEFATTR(inactive);
101
102
103 static void init_attr()
104 {
105     GR_ALLOCATTR_BEGIN;
106     GR_ALLOCATTR(active);
107     GR_ALLOCATTR(inactive);
108     GR_ALLOCATTR_END;
109 }
110
111
112 static void wmsg_draw(WMessage *wmsg, bool complete)
113 {
114     WRectangle geom;
115     
116     if(WMSG_BRUSH(wmsg)==NULL)
117         return;
118     
119     get_geom(wmsg, FALSE, &geom);
120     
121     grbrush_begin(WMSG_BRUSH(wmsg), &geom, 
122                   (complete ? 0 : GRBRUSH_NO_CLEAR_OK));
123     
124     grbrush_set_attr(WMSG_BRUSH(wmsg), REGION_IS_ACTIVE(wmsg)
125                                        ? GR_ATTR(active)
126                                        : GR_ATTR(inactive));
127     
128     draw_listing(WMSG_BRUSH(wmsg), &geom, &(wmsg->listing), 
129                  FALSE, GRATTR_NONE);
130     
131     grbrush_end(WMSG_BRUSH(wmsg));
132 }
133
134
135 /*}}}*/
136
137
138 /*{{{ Scroll */
139
140
141 static void wmsg_scrollup(WMessage *wmsg)
142 {
143     if(scrollup_listing(&(wmsg->listing)))
144         wmsg_draw(wmsg, TRUE);
145 }
146
147
148 static void wmsg_scrolldown(WMessage *wmsg)
149 {
150     if(scrolldown_listing(&(wmsg->listing)))
151         wmsg_draw(wmsg, TRUE);
152 }
153
154
155 /*}}}*/
156
157
158 /*{{{ Init, deinit draw config update */
159
160
161 static bool wmsg_init(WMessage *wmsg, WWindow *par, const WFitParams *fp,
162                       const char *msg)
163 {
164     char **ptr;
165     int k, n=0;
166     char *cmsg;
167     const char *p;
168     size_t l;
169     
170     p=msg;
171     while(1){
172         n=n+1;
173         p=strchr(p, '\n');
174         if(p==NULL || *(p+1)=='\0')
175             break;
176         p=p+1;
177     }
178     
179     if(n==0)
180         return FALSE;
181         
182     ptr=ALLOC_N(char*, n);
183     
184     if(ptr==NULL)
185         return FALSE;
186     
187     for(k=0; k<n; k++)
188         ptr[k]=NULL;
189     
190     p=msg;
191     k=0;
192     while(k<n){
193         l=strcspn(p, "\n");
194         cmsg=ALLOC_N(char, l+1);
195         if(cmsg==NULL){
196             while(k>0){
197                 k--;
198                 free(ptr[k]);
199             }
200             free(ptr);
201             return FALSE;
202         }
203         strncpy(cmsg, p, l);
204         cmsg[l]='\0';
205         ptr[k]=cmsg;
206         k++;
207         if(p[l]=='\0')
208             break;
209         p=p+l+1;
210     }
211     
212     init_attr();
213     
214     init_listing(&(wmsg->listing));
215     setup_listing(&(wmsg->listing), ptr, k, TRUE);
216     
217     if(!input_init((WInput*)wmsg, par, fp)){
218         deinit_listing(&(wmsg->listing));
219         return FALSE;
220     }
221
222     return TRUE;
223 }
224
225
226 WMessage *create_wmsg(WWindow *par, const WFitParams *fp, const char *msg)
227 {
228     CREATEOBJ_IMPL(WMessage, wmsg, (p, par, fp, msg));
229 }
230
231
232 static void wmsg_deinit(WMessage *wmsg)
233 {
234     if(wmsg->listing.strs!=NULL)
235         deinit_listing(&(wmsg->listing));
236
237     input_deinit((WInput*)wmsg);
238 }
239
240
241 static const char *wmsg_style(WMessage *wmsg)
242 {
243     return "input-message";
244 }
245
246
247 /*}}}*/
248
249
250 /*{{{ Dynamic function table and class implementation */
251
252
253 static DynFunTab wmsg_dynfuntab[]={
254     {window_draw, wmsg_draw},
255     {input_calc_size, wmsg_calc_size},
256     {input_scrollup, wmsg_scrollup},
257     {input_scrolldown, wmsg_scrolldown},
258     {(DynFun*)input_style, (DynFun*)wmsg_style},
259     {region_size_hints, wmsg_size_hints},
260     END_DYNFUNTAB
261 };
262
263
264 EXTL_EXPORT
265 IMPLCLASS(WMessage, WInput, wmsg_deinit, wmsg_dynfuntab);
266
267     
268 /*}}}*/