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
28 #include <fontforge-config.h>
29
30 #include "gdraw.h"
31 #include "ggadgetP.h"
32 #include "gresource.h"
33
34 GBox _GGroup_LineBox = GBOX_EMPTY; /* Don't initialize here */
35 static GBox group_box = GBOX_EMPTY; /* Don't initialize here */
36 static int ggroup_inited = false;
37
38 static GGadgetCreateData gline_gcd[] = {
39 { GLineCreate, { { 0, 0, 100, 0 }, NULL, 0, 0, 0, 0, 0, NULL, { NULL }, gg_visible|gg_enabled, NULL, NULL }, NULL, NULL }
40 };
41 static GGadgetCreateData *larray[] = { GCD_Glue, &gline_gcd[0], GCD_Glue, NULL, NULL };
42 static GGadgetCreateData linebox =
43 { GHVGroupCreate, { { 2, 2, 0, 0 }, NULL, 0, 0, 0, 0, 0, NULL, { (GTextInfo *) larray }, gg_visible|gg_enabled, NULL, NULL }, NULL, NULL };
44 GResInfo gline_ri = {
45 NULL, &ggadget_ri, NULL, NULL,
46 &_GGroup_LineBox,
47 NULL,
48 &linebox,
49 NULL,
50 N_("Line"),
51 N_("A separator line drawn across a dialog or in a menu"),
52 "GLine",
53 "Gdraw",
54 false,
55 omf_border_type|omf_border_shape|omf_padding,
56 NULL,
57 GBOX_EMPTY,
58 NULL,
59 NULL,
60 NULL
61 };
62
_GGroup_Init(void)63 void _GGroup_Init(void) {
64 if ( ggroup_inited )
65 return;
66 _GGadgetCopyDefaultBox(&_GGroup_LineBox);
67 _GGadgetCopyDefaultBox(&group_box);
68 group_box.border_type = _GGroup_LineBox.border_type = bt_engraved;
69 group_box.border_shape = _GGroup_LineBox.border_shape = bs_rect;
70 group_box.padding = _GGroup_LineBox.padding = 0;
71 /*group_box.flags = _GGroup_LineBox.flags = 0;*/
72 group_box.main_background = COLOR_TRANSPARENT;
73 group_box.disabled_background = COLOR_TRANSPARENT;
74 _GGadgetInitDefaultBox("GLine.",&_GGroup_LineBox,NULL);
75 _GGadgetInitDefaultBox("GGroup.",&group_box,NULL);
76 ggroup_inited = true;
77 }
78
ggroup_expose(GWindow pixmap,GGadget * g,GEvent * event)79 static int ggroup_expose(GWindow pixmap, GGadget *g, GEvent *event) {
80 GRect old1, border;
81
82 if ( g->state == gs_invisible )
83 return( false );
84
85 GDrawPushClip(pixmap,&g->r,&old1);
86 /* Background should be transpearant */
87 /*GBoxDrawBackground(pixmap,&g->r,g->box, g->state,false);*/
88 border = g->r;
89 if ( g->prevlabel ) {
90 int off = (g->prev->r.height-GBoxBorderWidth(g->base,g->box))/2;
91 border.y += off; border.height -= off;
92 }
93 GBoxDrawBorder(pixmap,&border,g->box,g->state,false);
94
95 GDrawPopClip(pixmap,&old1);
96 return( true );
97 }
98
gline_expose(GWindow pixmap,GGadget * g,GEvent * event)99 static int gline_expose(GWindow pixmap, GGadget *g, GEvent *event) {
100 GRect old1;
101
102 if ( g->state == gs_invisible )
103 return( false );
104
105 GDrawPushClip(pixmap,&g->r,&old1);
106 if ( g->vert )
107 GBoxDrawVLine(pixmap,&g->r,g->box);
108 else
109 GBoxDrawHLine(pixmap,&g->r,g->box);
110 GDrawPopClip(pixmap,&old1);
111 return( true );
112 }
113
GGroupGetDesiredSize(GGadget * g,GRect * outer,GRect * inner)114 static void GGroupGetDesiredSize(GGadget *g, GRect *outer, GRect *inner) {
115 if ( outer!=NULL ) {
116 int bp = GBoxBorderWidth(g->base,g->box);
117 outer->x = outer->y = 0;
118 outer->width = outer->height = 2*bp+2;
119 if ( g->desired_width>0 ) outer->width = g->desired_width;
120 if ( g->desired_height>0 ) outer->height = g->desired_height;
121 }
122 if ( inner!=NULL ) {
123 inner->x = inner->y = 0;
124 inner->width = inner->height = 1;
125 }
126 }
127
128 struct gfuncs gline_funcs = {
129 0,
130 sizeof(struct gfuncs),
131
132 gline_expose,
133 _ggadget_noop,
134 _ggadget_noop,
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139
140 _ggadget_redraw,
141 _ggadget_move,
142 _ggadget_resize,
143 _ggadget_setvisible,
144 _ggadget_setenabled,
145 _ggadget_getsize,
146 _ggadget_getinnersize,
147
148 _ggadget_destroy,
149
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155
156 NULL,
157 NULL,
158
159 NULL,
160 NULL,
161 NULL,
162 NULL,
163 NULL,
164 NULL,
165 NULL,
166 NULL,
167 NULL,
168 NULL,
169 NULL,
170
171 GGroupGetDesiredSize,
172 _ggadget_setDesiredSize,
173 NULL,
174 NULL
175 };
176
177 struct gfuncs ggroup_funcs = {
178 0,
179 sizeof(struct gfuncs),
180
181 ggroup_expose,
182 _ggadget_noop,
183 _ggadget_noop,
184 NULL,
185 NULL,
186 NULL,
187 NULL,
188
189 _ggadget_redraw,
190 _ggadget_move,
191 _ggadget_resize,
192 _ggadget_setvisible,
193 _ggadget_setenabled,
194 _ggadget_getsize,
195 _ggadget_getinnersize,
196
197 _ggadget_destroy,
198
199 NULL,
200 NULL,
201 NULL,
202 NULL,
203 NULL,
204
205 NULL,
206 NULL,
207
208 NULL,
209 NULL,
210 NULL,
211 NULL,
212 NULL,
213 NULL,
214 NULL,
215 NULL,
216 NULL,
217 NULL,
218 NULL,
219
220 GGroupGetDesiredSize,
221 _ggadget_setDesiredSize,
222 NULL,
223 NULL
224 };
225
GLineFit(GGadget * g)226 static void GLineFit(GGadget *g) {
227 int bp = GBoxBorderWidth(g->base,g->box);
228
229 if ( g->r.width==0 && !g->vert ) {
230 GRect size;
231 GDrawGetSize(g->base,&size);
232 g->r.width = size.width - g->r.x - GDrawPointsToPixels(g->base,_GGadget_Skip);
233 }
234 if ( g->r.height==0 && !g->vert )
235 g->r.height = bp;
236 if ( g->r.width==0 && g->vert )
237 g->r.width = bp;
238 g->inner = g->r;
239 g->inner.width = g->inner.height = 0;
240 }
241
GGroupFit(GGadget * g)242 static void GGroupFit(GGadget *g) {
243 int bp = GBoxBorderWidth(g->base,g->box);
244
245 if ( g->r.width==0 || g->r.height==0 )
246 g->opengroup = true;
247 g->inner = g->r;
248 g->inner.x += bp;
249 if ( g->prevlabel )
250 g->inner.y += (g->prev->r.height-bp)/2 + bp;
251 else
252 g->inner.y += bp;
253 if ( g->r.width != 0 )
254 g->inner.width = g->r.width - 2*bp;
255 if ( g->r.height != 0 )
256 g->inner.height = g->r.y + g->r.height - bp - g->inner.y;
257 }
258
GLineCreate(struct gwindow * base,GGadgetData * gd,void * data)259 GGadget *GLineCreate(struct gwindow *base, GGadgetData *gd,void *data) {
260 GGadget *g = calloc(1,sizeof(GLine));
261
262 if ( !ggroup_inited )
263 _GGroup_Init();
264 g->funcs = &gline_funcs;
265 _GGadget_Create(g,base,gd,data,&_GGroup_LineBox);
266 if ( gd->flags & gg_line_vert )
267 g->vert = true;
268
269 GLineFit(g);
270 _GGadget_FinalPosition(g,base,gd);
271 return( g );
272 }
273
GGroupCreate(struct gwindow * base,GGadgetData * gd,void * data)274 GGadget *GGroupCreate(struct gwindow *base, GGadgetData *gd,void *data) {
275 GGadget *g = calloc(1,sizeof(GGroup));
276
277 if ( !ggroup_inited )
278 _GGroup_Init();
279 g->funcs = &ggroup_funcs;
280 _GGadget_Create(g,base,gd,data,&group_box);
281
282 if ( (gd->flags&gg_group_prevlabel) && g->prev!=NULL )
283 g->prevlabel = true;
284 if ( g->prevlabel && gd->pos.x==0 )
285 g->r.x = g->prev->r.x - GDrawPointsToPixels(base,_GGadget_Skip);
286 GGroupFit(g);
287 _GGadget_FinalPosition(g,base,gd);
288 return( g );
289 }
290
_GLineRIHead(void)291 GResInfo *_GLineRIHead(void) {
292
293 _GGroup_Init();
294 return( &gline_ri );
295 }
296