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