Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "gdraw.h"
28 : #include "gresource.h"
29 : #include "ggadgetP.h"
30 :
31 : GBox _GGroup_LineBox = GBOX_EMPTY; /* Don't initialize here */
32 : static GBox group_box = GBOX_EMPTY; /* Don't initialize here */
33 : static int ggroup_inited = false;
34 :
35 : static GGadgetCreateData gline_gcd[] = {
36 : { GLineCreate, { { 0, 0, 100, 0 }, NULL, 0, 0, 0, 0, 0, NULL, { NULL }, gg_visible|gg_enabled, NULL, NULL }, NULL, NULL }
37 : };
38 : static GGadgetCreateData *larray[] = { GCD_Glue, &gline_gcd[0], GCD_Glue, NULL, NULL };
39 : static GGadgetCreateData linebox =
40 : { GHVGroupCreate, { { 2, 2, 0, 0 }, NULL, 0, 0, 0, 0, 0, NULL, { (GTextInfo *) larray }, gg_visible|gg_enabled, NULL, NULL }, NULL, NULL };
41 : GResInfo gline_ri = {
42 : NULL, &ggadget_ri, NULL, NULL,
43 : &_GGroup_LineBox,
44 : NULL,
45 : &linebox,
46 : NULL,
47 : N_("Line"),
48 : N_("A separator line drawn across a dialog or in a menu"),
49 : "GLine",
50 : "Gdraw",
51 : false,
52 : omf_border_type|omf_border_shape|omf_padding,
53 : NULL,
54 : GBOX_EMPTY,
55 : NULL,
56 : NULL,
57 : NULL
58 : };
59 :
60 0 : void _GGroup_Init(void) {
61 0 : if ( ggroup_inited )
62 0 : return;
63 0 : _GGadgetCopyDefaultBox(&_GGroup_LineBox);
64 0 : _GGadgetCopyDefaultBox(&group_box);
65 0 : group_box.border_type = _GGroup_LineBox.border_type = bt_engraved;
66 0 : group_box.border_shape = _GGroup_LineBox.border_shape = bs_rect;
67 0 : group_box.padding = _GGroup_LineBox.padding = 0;
68 : /*group_box.flags = _GGroup_LineBox.flags = 0;*/
69 0 : group_box.main_background = COLOR_TRANSPARENT;
70 0 : group_box.disabled_background = COLOR_TRANSPARENT;
71 0 : _GGadgetInitDefaultBox("GLine.",&_GGroup_LineBox,NULL);
72 0 : _GGadgetInitDefaultBox("GGroup.",&group_box,NULL);
73 0 : ggroup_inited = true;
74 : }
75 :
76 0 : static int ggroup_expose(GWindow pixmap, GGadget *g, GEvent *event) {
77 : GRect old1, border;
78 :
79 0 : if ( g->state == gs_invisible )
80 0 : return( false );
81 :
82 0 : GDrawPushClip(pixmap,&g->r,&old1);
83 : /* Background should be transpearant */
84 : /*GBoxDrawBackground(pixmap,&g->r,g->box, g->state,false);*/
85 0 : border = g->r;
86 0 : if ( g->prevlabel ) {
87 0 : int off = (g->prev->r.height-GBoxBorderWidth(g->base,g->box))/2;
88 0 : border.y += off; border.height -= off;
89 : }
90 0 : GBoxDrawBorder(pixmap,&border,g->box,g->state,false);
91 :
92 0 : GDrawPopClip(pixmap,&old1);
93 0 : return( true );
94 : }
95 :
96 0 : static int gline_expose(GWindow pixmap, GGadget *g, GEvent *event) {
97 : GRect old1;
98 :
99 0 : if ( g->state == gs_invisible )
100 0 : return( false );
101 :
102 0 : GDrawPushClip(pixmap,&g->r,&old1);
103 0 : if ( g->vert )
104 0 : GBoxDrawVLine(pixmap,&g->r,g->box);
105 : else
106 0 : GBoxDrawHLine(pixmap,&g->r,g->box);
107 0 : GDrawPopClip(pixmap,&old1);
108 0 : return( true );
109 : }
110 :
111 0 : static void GGroupGetDesiredSize(GGadget *g, GRect *outer, GRect *inner) {
112 0 : if ( outer!=NULL ) {
113 0 : int bp = GBoxBorderWidth(g->base,g->box);
114 0 : outer->x = outer->y = 0;
115 0 : outer->width = outer->height = 2*bp+2;
116 0 : if ( g->desired_width>0 ) outer->width = g->desired_width;
117 0 : if ( g->desired_height>0 ) outer->height = g->desired_height;
118 : }
119 0 : if ( inner!=NULL ) {
120 0 : inner->x = inner->y = 0;
121 0 : inner->width = inner->height = 1;
122 : }
123 0 : }
124 :
125 : struct gfuncs gline_funcs = {
126 : 0,
127 : sizeof(struct gfuncs),
128 :
129 : gline_expose,
130 : _ggadget_noop,
131 : _ggadget_noop,
132 : NULL,
133 : NULL,
134 : NULL,
135 : NULL,
136 :
137 : _ggadget_redraw,
138 : _ggadget_move,
139 : _ggadget_resize,
140 : _ggadget_setvisible,
141 : _ggadget_setenabled,
142 : _ggadget_getsize,
143 : _ggadget_getinnersize,
144 :
145 : _ggadget_destroy,
146 :
147 : NULL,
148 : NULL,
149 : NULL,
150 : NULL,
151 : NULL,
152 :
153 : NULL,
154 : NULL,
155 :
156 : NULL,
157 : NULL,
158 : NULL,
159 : NULL,
160 : NULL,
161 : NULL,
162 : NULL,
163 : NULL,
164 : NULL,
165 : NULL,
166 : NULL,
167 :
168 : GGroupGetDesiredSize,
169 : _ggadget_setDesiredSize,
170 : NULL,
171 : NULL
172 : };
173 :
174 : struct gfuncs ggroup_funcs = {
175 : 0,
176 : sizeof(struct gfuncs),
177 :
178 : ggroup_expose,
179 : _ggadget_noop,
180 : _ggadget_noop,
181 : NULL,
182 : NULL,
183 : NULL,
184 : NULL,
185 :
186 : _ggadget_redraw,
187 : _ggadget_move,
188 : _ggadget_resize,
189 : _ggadget_setvisible,
190 : _ggadget_setenabled,
191 : _ggadget_getsize,
192 : _ggadget_getinnersize,
193 :
194 : _ggadget_destroy,
195 :
196 : NULL,
197 : NULL,
198 : NULL,
199 : NULL,
200 : NULL,
201 :
202 : NULL,
203 : NULL,
204 :
205 : NULL,
206 : NULL,
207 : NULL,
208 : NULL,
209 : NULL,
210 : NULL,
211 : NULL,
212 : NULL,
213 : NULL,
214 : NULL,
215 : NULL,
216 :
217 : GGroupGetDesiredSize,
218 : _ggadget_setDesiredSize,
219 : NULL,
220 : NULL
221 : };
222 :
223 0 : static void GLineFit(GGadget *g) {
224 0 : int bp = GBoxBorderWidth(g->base,g->box);
225 :
226 0 : if ( g->r.width==0 && !g->vert ) {
227 : GRect size;
228 0 : GDrawGetSize(g->base,&size);
229 0 : g->r.width = size.width - g->r.x - GDrawPointsToPixels(g->base,_GGadget_Skip);
230 : }
231 0 : if ( g->r.height==0 && !g->vert )
232 0 : g->r.height = bp;
233 0 : if ( g->r.width==0 && g->vert )
234 0 : g->r.width = bp;
235 0 : g->inner = g->r;
236 0 : g->inner.width = g->inner.height = 0;
237 0 : }
238 :
239 0 : static void GGroupFit(GGadget *g) {
240 0 : int bp = GBoxBorderWidth(g->base,g->box);
241 :
242 0 : if ( g->r.width==0 || g->r.height==0 )
243 0 : g->opengroup = true;
244 0 : g->inner = g->r;
245 0 : g->inner.x += bp;
246 0 : if ( g->prevlabel )
247 0 : g->inner.y += (g->prev->r.height-bp)/2 + bp;
248 : else
249 0 : g->inner.y += bp;
250 0 : if ( g->r.width != 0 )
251 0 : g->inner.width = g->r.width - 2*bp;
252 0 : if ( g->r.height != 0 )
253 0 : g->inner.height = g->r.y + g->r.height - bp - g->inner.y;
254 0 : }
255 :
256 0 : GGadget *GLineCreate(struct gwindow *base, GGadgetData *gd,void *data) {
257 0 : GGadget *g = calloc(1,sizeof(GLine));
258 :
259 0 : if ( !ggroup_inited )
260 0 : _GGroup_Init();
261 0 : g->funcs = &gline_funcs;
262 0 : _GGadget_Create(g,base,gd,data,&_GGroup_LineBox);
263 0 : if ( gd->flags & gg_line_vert )
264 0 : g->vert = true;
265 :
266 0 : GLineFit(g);
267 0 : _GGadget_FinalPosition(g,base,gd);
268 0 : return( g );
269 : }
270 :
271 0 : GGadget *GGroupCreate(struct gwindow *base, GGadgetData *gd,void *data) {
272 0 : GGadget *g = calloc(1,sizeof(GGroup));
273 :
274 0 : if ( !ggroup_inited )
275 0 : _GGroup_Init();
276 0 : g->funcs = &ggroup_funcs;
277 0 : _GGadget_Create(g,base,gd,data,&group_box);
278 :
279 0 : if ( (gd->flags&gg_group_prevlabel) && g->prev!=NULL )
280 0 : g->prevlabel = true;
281 0 : if ( g->prevlabel && gd->pos.x==0 )
282 0 : g->r.x = g->prev->r.x - GDrawPointsToPixels(base,_GGadget_Skip);
283 0 : GGroupFit(g);
284 0 : _GGadget_FinalPosition(g,base,gd);
285 0 : return( g );
286 : }
287 :
288 0 : GResInfo *_GLineRIHead(void) {
289 :
290 0 : _GGroup_Init();
291 0 : return( &gline_ri );
292 : }
|