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 <math.h>
28 : #include <gdraw.h>
29 : #include <ggadget.h>
30 : #include "ggadgetP.h"
31 :
32 0 : static void FigureBorderCols(GBox *design, Color *cols) {
33 0 : if ( design->border_type==bt_box || design->border_type==bt_double ) {
34 0 : cols[0] = design->border_brightest;
35 0 : cols[1] = design->border_brighter;
36 0 : cols[2] = design->border_darkest;
37 0 : cols[3] = design->border_darker;
38 0 : } else if ( design->border_type==bt_raised || design->border_type==bt_embossed ) {
39 0 : if ( design->flags&box_generate_colors ) {
40 0 : int r = COLOR_RED(design->border_brightest), g=COLOR_GREEN(design->border_brightest), b = COLOR_BLUE(design->border_brightest);
41 0 : cols[0] = design->border_brightest;
42 0 : cols[1] = COLOR_CREATE(15*r/16,15*g/16,15*b/16);
43 0 : cols[2] = COLOR_CREATE(7*r/16,7*g/16,7*b/16);
44 0 : cols[3] = COLOR_CREATE(r/2,g/2,b/2);
45 : } else {
46 0 : cols[0] = design->border_brightest;
47 0 : cols[1] = design->border_brighter;
48 0 : cols[2] = design->border_darkest;
49 0 : cols[3] = design->border_darker;
50 : }
51 0 : } else if ( design->border_type==bt_lowered || design->border_type==bt_engraved ) {
52 0 : if ( design->flags&box_generate_colors ) {
53 0 : int r = COLOR_RED(design->border_brightest), g=COLOR_GREEN(design->border_brightest), b = COLOR_BLUE(design->border_brightest);
54 0 : cols[2] = design->border_brightest;
55 0 : cols[3] = COLOR_CREATE(15*r/16,15*g/16,15*b/16);
56 0 : cols[0] = COLOR_CREATE(7*r/16,7*g/16,7*b/16);
57 0 : cols[1] = COLOR_CREATE(r/2,g/2,b/2);
58 : } else {
59 0 : cols[2] = design->border_brightest;
60 0 : cols[3] = design->border_brighter;
61 0 : cols[0] = design->border_darkest;
62 0 : cols[1] = design->border_darker;
63 : }
64 : }
65 0 : }
66 :
67 0 : static void DrawLeftTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
68 : GPoint pts[5];
69 :
70 0 : --width;
71 0 : if ( width==0 ) {
72 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+inset,pos->x+inset,pos->y+pos->height-1-inset,col);
73 : } else {
74 0 : pts[0].x = pos->x+inset;
75 0 : pts[0].y = pos->y+inset;
76 0 : pts[1].x = pos->x+inset+width;
77 0 : pts[1].y = pos->y+inset+width;
78 0 : pts[2].x = pts[1].x;
79 0 : pts[2].y = pos->y+pos->height-1-(inset+width);
80 0 : pts[3].x = pts[0].x;
81 0 : pts[3].y = pos->y+pos->height-1-inset;
82 0 : pts[4] = pts[0];
83 0 : GDrawFillPoly(gw,pts,5,col);
84 : }
85 0 : }
86 :
87 0 : static void DrawULTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
88 : GPoint pts[5];
89 : /* for drawing a diamond shape */
90 :
91 0 : --width;
92 0 : if ( width==0 ) {
93 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+pos->height/2,pos->x+pos->width/2,pos->y+inset,col);
94 : } else {
95 0 : pts[0].x = pos->x+inset;
96 0 : pts[0].y = pos->y+pos->height/2;
97 0 : pts[1].x = pos->x+inset+width;
98 0 : pts[1].y = pts[0].y;
99 0 : pts[2].x = pos->x+pos->width/2;
100 0 : pts[2].y = pos->y+inset+width;
101 0 : pts[3].x = pts[2].x;
102 0 : pts[3].y = pos->y+inset;
103 0 : pts[4] = pts[0];
104 0 : GDrawFillPoly(gw,pts,5,col);
105 : }
106 0 : }
107 :
108 0 : static void DrawTopTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
109 : GPoint pts[5];
110 :
111 0 : --width;
112 0 : if ( width==0 ) {
113 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+inset,pos->x+pos->width-1-inset,pos->y+inset,col);
114 : } else {
115 0 : pts[0].x = pos->x+inset;
116 0 : pts[0].y = pos->y+inset;
117 0 : pts[1].x = pos->x+inset+width;
118 0 : pts[1].y = pos->y+inset+width;
119 0 : pts[2].x = pos->x+pos->width-1-(inset+width);
120 0 : pts[2].y = pts[1].y;
121 0 : pts[3].x = pos->x+pos->width-1-inset;
122 0 : pts[3].y = pts[0].y;
123 0 : pts[4] = pts[0];
124 0 : GDrawFillPoly(gw,pts,5,col);
125 : }
126 0 : }
127 :
128 0 : static void DrawURTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
129 : GPoint pts[5];
130 :
131 0 : --width;
132 0 : if ( width==0 ) {
133 0 : GDrawDrawLine(gw,pos->x+pos->width-1-inset,pos->y+pos->height/2,pos->x+pos->width/2,pos->y+inset,col);
134 : } else {
135 0 : pts[0].x = pos->x+pos->width-1-inset;
136 0 : pts[0].y = pos->y+pos->height/2;
137 0 : pts[1].x = pts[0].x-width;
138 0 : pts[1].y = pts[0].y;
139 0 : pts[2].x = pos->x+pos->width/2;
140 0 : pts[2].y = pos->y+inset+width;
141 0 : pts[3].x = pts[2].x;
142 0 : pts[3].y = pts[2].y-width;
143 0 : pts[4] = pts[0];
144 0 : GDrawFillPoly(gw,pts,5,col);
145 : }
146 0 : }
147 :
148 0 : static void DrawRightTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
149 : GPoint pts[5];
150 :
151 0 : --width;
152 0 : if ( width==0 ) {
153 0 : GDrawDrawLine(gw,pos->x+pos->width-1-inset,pos->y+inset,pos->x+pos->width-1-inset,pos->y+pos->height-1-inset,col);
154 : } else {
155 0 : pts[0].x = pos->x+pos->width-1-inset;
156 0 : pts[0].y = pos->y+inset;
157 0 : pts[1].x = pos->x+pos->width-1-(inset+width);
158 0 : pts[1].y = pos->y+inset+width;
159 0 : pts[2].x = pts[1].x;
160 0 : pts[2].y = pos->y+pos->height-1-(inset+width);
161 0 : pts[3].x = pts[0].x;
162 0 : pts[3].y = pos->y+pos->height-1-inset;
163 0 : pts[4] = pts[0];
164 0 : GDrawFillPoly(gw,pts,5,col);
165 : }
166 0 : }
167 :
168 0 : static void DrawLRTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
169 : GPoint pts[5];
170 :
171 0 : --width;
172 0 : if ( width==0 ) {
173 0 : GDrawDrawLine(gw,pos->x+pos->width-1-inset,pos->y+pos->height/2,pos->x+pos->width/2,pos->y+pos->height-1-inset,col);
174 : } else {
175 0 : pts[0].x = pos->x+pos->width-1-inset;
176 0 : pts[0].y = pos->y+pos->height/2;
177 0 : pts[1].x = pts[0].x-width;
178 0 : pts[1].y = pts[0].y;
179 0 : pts[2].x = pos->x+pos->width/2;
180 0 : pts[2].y = pos->y+pos->height-1-inset-width;
181 0 : pts[3].x = pts[2].x;
182 0 : pts[3].y = pts[2].y+width;
183 0 : pts[4] = pts[0];
184 0 : GDrawFillPoly(gw,pts,5,col);
185 : }
186 0 : }
187 :
188 0 : static void DrawBottomTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
189 : GPoint pts[5];
190 :
191 0 : --width;
192 0 : if ( width==0 ) {
193 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+pos->height-1-inset,pos->x+pos->width-1-inset,pos->y+pos->height-1-inset,col);
194 : } else {
195 0 : pts[0].x = pos->x+inset;
196 0 : pts[0].y = pos->y+pos->height-1-inset;
197 0 : pts[1].x = pos->x+inset+width;
198 0 : pts[1].y = pos->y+pos->height-1-(inset+width);
199 0 : pts[2].x = pos->x+pos->width-1-(inset+width);
200 0 : pts[2].y = pts[1].y;
201 0 : pts[3].x = pos->x+pos->width-1-inset;
202 0 : pts[3].y = pts[0].y;
203 0 : pts[4] = pts[0];
204 0 : GDrawFillPoly(gw,pts,5,col);
205 : }
206 0 : }
207 :
208 0 : static void DrawLLTrap(GWindow gw,GRect *pos,int inset,int width,Color col) {
209 : GPoint pts[5];
210 :
211 0 : --width;
212 0 : if ( width==0 ) {
213 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+pos->height/2,pos->x+pos->width/2,pos->y+pos->height-1-inset,col);
214 : } else {
215 0 : pts[0].x = pos->x+inset;
216 0 : pts[0].y = pos->y+pos->height/2;
217 0 : pts[1].x = pts[0].x+width;
218 0 : pts[1].y = pts[0].y;
219 0 : pts[2].x = pos->x+pos->width/2;
220 0 : pts[2].y = pos->y+pos->height-1-inset-width;
221 0 : pts[3].x = pts[2].x;
222 0 : pts[3].y = pts[2].y+width;
223 0 : pts[4] = pts[0];
224 0 : GDrawFillPoly(gw,pts,5,col);
225 : }
226 0 : }
227 :
228 0 : static void GetULRect(GRect *res, GRect *rect,int inset,int radius) {
229 0 : res->x = rect->x+inset; res->y = rect->y+inset;
230 0 : res->width = res->height = 2*(radius-inset);
231 0 : }
232 :
233 0 : static void DrawULArc(GWindow gw, GRect *rect,int inset,int radius, Color col) {
234 : GRect r;
235 0 : if ( inset>=radius )
236 0 : return;
237 0 : GetULRect(&r,rect,inset,radius);
238 0 : GDrawDrawArc(gw,&r,90*64,90*64,col);
239 : }
240 :
241 0 : static void DrawULArcs(GWindow gw, GRect *rect,int inset,int radius, Color col1, Color col2) {
242 : GRect r;
243 0 : if ( inset>=radius )
244 0 : return;
245 0 : GetULRect(&r,rect,inset,radius);
246 0 : if ( col1==col2 )
247 0 : GDrawDrawArc(gw,&r,90*64,90*64,col2);
248 : else {
249 0 : GDrawDrawArc(gw,&r,135*64,45*64,col1);
250 0 : GDrawDrawArc(gw,&r,90*64,45*64,col2);
251 : }
252 : }
253 :
254 0 : static void GetURRect(GRect *res, GRect *rect,int inset,int radius) {
255 0 : res->width = res->height = 2*(radius-inset);
256 0 : res->x = rect->x+rect->width-1-inset-res->width; res->y = rect->y+inset;
257 0 : }
258 :
259 0 : static void DrawURArc(GWindow gw, GRect *rect,int inset,int radius, Color col) {
260 : GRect r;
261 0 : if ( inset>=radius )
262 0 : return;
263 0 : GetURRect(&r,rect,inset,radius);
264 0 : GDrawDrawArc(gw,&r,0*64,90*64,col);
265 : }
266 :
267 0 : static void DrawURArcs(GWindow gw, GRect *rect,int inset,int radius, Color col1, Color col2) {
268 : GRect r;
269 0 : if ( inset>=radius )
270 0 : return;
271 0 : GetURRect(&r,rect,inset,radius);
272 0 : if ( col1==col2 )
273 0 : GDrawDrawArc(gw,&r,0*64,90*64,col2);
274 : else {
275 0 : GDrawDrawArc(gw,&r,45*64,45*64,col1);
276 0 : GDrawDrawArc(gw,&r,0*64,45*64,col2);
277 : }
278 : }
279 :
280 0 : static void GetLRRect(GRect *res, GRect *rect,int inset,int radius) {
281 0 : res->width = res->height = 2*(radius-inset);
282 0 : res->x = rect->x+rect->width-1-inset-res->width;
283 0 : res->y = rect->y+rect->height-1-inset-res->height;
284 0 : }
285 :
286 0 : static void DrawLRArc(GWindow gw, GRect *rect,int inset,int radius, Color col) {
287 : GRect r;
288 0 : if ( inset>=radius )
289 0 : return;
290 0 : GetLRRect(&r,rect,inset,radius);
291 0 : GDrawDrawArc(gw,&r,-90*64,90*64,col);
292 : }
293 :
294 0 : static void DrawLRArcs(GWindow gw, GRect *rect,int inset,int radius, Color col1, Color col2) {
295 : GRect r;
296 0 : if ( inset>=radius )
297 0 : return;
298 0 : GetLRRect(&r,rect,inset,radius);
299 0 : if ( col1==col2 )
300 0 : GDrawDrawArc(gw,&r,-90*64,90*64,col2);
301 : else {
302 0 : GDrawDrawArc(gw,&r,-45*64,45*64,col1);
303 0 : GDrawDrawArc(gw,&r,-90*64,45*64,col2);
304 : }
305 : }
306 :
307 0 : static void GetLLRect(GRect *res, GRect *rect,int inset,int radius) {
308 0 : res->width = res->height = 2*(radius-inset);
309 0 : res->x = rect->x+inset;
310 0 : res->y = rect->y+rect->height-1-inset-res->height;
311 0 : }
312 :
313 0 : static void DrawLLArc(GWindow gw, GRect *rect,int inset,int radius, Color col) {
314 : GRect r;
315 0 : if ( inset>=radius )
316 0 : return;
317 0 : GetLLRect(&r,rect,inset,radius);
318 0 : GDrawDrawArc(gw,&r,-180*64,90*64,col);
319 : }
320 :
321 0 : static void DrawLLArcs(GWindow gw, GRect *rect,int inset,int radius, Color col1, Color col2) {
322 : GRect r;
323 0 : if ( inset>=radius )
324 0 : return;
325 0 : GetLLRect(&r,rect,inset,radius);
326 0 : if ( col1==col2 )
327 0 : GDrawDrawArc(gw,&r,-180*64,90*64,col2);
328 : else {
329 0 : GDrawDrawArc(gw,&r,-135*64,45*64,col1);
330 0 : GDrawDrawArc(gw,&r,-180*64,45*64,col2);
331 : }
332 : }
333 :
334 0 : static void DrawRoundRect(GWindow gw, GRect *pos,int inset,int radius,
335 : Color col) {
336 : int off;
337 0 : if ( inset<radius ) {
338 0 : off = radius;
339 0 : DrawULArc(gw,pos,inset,radius,col);
340 0 : DrawURArc(gw,pos,inset,radius,col);
341 0 : DrawLRArc(gw,pos,inset,radius,col);
342 0 : DrawLLArc(gw,pos,inset,radius,col);
343 : } else
344 0 : off = inset;
345 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+off,pos->x+inset,pos->y+pos->height-1-off,col);
346 0 : GDrawDrawLine(gw,pos->x+off,pos->y+inset,pos->x+pos->width-1-off,pos->y+inset,col);
347 0 : GDrawDrawLine(gw,pos->x+pos->width-1-inset,pos->y+off,pos->x+pos->width-1-inset,pos->y+pos->height-1-off,col);
348 0 : GDrawDrawLine(gw,pos->x+off,pos->y+pos->height-1-inset,pos->x+pos->width-1-off,pos->y+pos->height-1-inset,col);
349 0 : }
350 :
351 0 : static void DrawRoundTab(GWindow gw, GRect *pos,int inset,int radius,
352 : Color col1, Color col2, Color col3, Color col4, int active) {
353 : int off;
354 0 : if ( inset<radius ) {
355 0 : off = radius;
356 0 : DrawULArc(gw,pos,inset,radius,col1);
357 0 : DrawURArc(gw,pos,inset,radius,col3);
358 : } else
359 0 : off = inset;
360 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+off,pos->x+inset,pos->y+pos->height-1,col1);
361 0 : GDrawDrawLine(gw,pos->x+off,pos->y+inset,pos->x+pos->width-1-off,pos->y+inset,col2);
362 0 : GDrawDrawLine(gw,pos->x+pos->width-1-inset,pos->y+off,pos->x+pos->width-1-inset,pos->y+pos->height-1,col3);
363 0 : if ( !active )
364 0 : GDrawDrawLine(gw,pos->x,pos->y+pos->height-1,pos->x+pos->width-1,pos->y+pos->height-1,col4);
365 0 : }
366 :
367 0 : static void DrawRoundRects(GWindow gw, GRect *pos,int inset,int radius,
368 : Color col1, Color col2, Color col3, Color col4) {
369 : int off;
370 0 : if ( inset<radius ) {
371 0 : off = radius;
372 0 : DrawULArcs(gw,pos,inset,radius,col1,col2);
373 0 : DrawURArcs(gw,pos,inset,radius,col2,col3);
374 0 : DrawLRArcs(gw,pos,inset,radius,col3,col4);
375 0 : DrawLLArcs(gw,pos,inset,radius,col4,col1);
376 : } else
377 0 : off = inset;
378 0 : GDrawDrawLine(gw,pos->x+inset,pos->y+off,pos->x+inset,pos->y+pos->height-1-off,col1);
379 0 : GDrawDrawLine(gw,pos->x+off,pos->y+inset,pos->x+pos->width-1-off,pos->y+inset,col2);
380 0 : GDrawDrawLine(gw,pos->x+pos->width-1-inset,pos->y+off,pos->x+pos->width-1-inset,pos->y+pos->height-1-off,col3);
381 0 : GDrawDrawLine(gw,pos->x+off,pos->y+pos->height-1-inset,pos->x+pos->width-1-off,pos->y+pos->height-1-inset,col4);
382 0 : }
383 :
384 0 : static int GBoxRectBorder(GWindow gw,GRect *pos,GBox *design,
385 : enum gadget_state state, int is_def) {
386 0 : int bw = GDrawPointsToPixels(gw,design->border_width);
387 0 : int inset = 0;
388 : GRect cur;
389 0 : int scale = GDrawPointsToPixels(gw,1);
390 0 : enum border_type bt = design->border_type;
391 : Color cols[4];
392 0 : Color fg = state==gs_disabled?design->disabled_foreground:
393 0 : design->main_foreground==COLOR_DEFAULT?GDrawGetDefaultForeground(GDrawGetDisplayOfWindow(gw)):
394 : design->main_foreground;
395 0 : Color color_inner = design->border_inner == COLOR_DEFAULT ? fg : design->border_inner;
396 0 : Color color_outer = design->border_outer == COLOR_DEFAULT ? fg : design->border_outer;
397 :
398 0 : FigureBorderCols(design,cols);
399 0 : if ( is_def && (design->flags & box_draw_default) && bt!=bt_none ) {
400 0 : DrawLeftTrap(gw,pos,inset,scale,cols[2]);
401 0 : DrawTopTrap(gw,pos,inset,scale,cols[3]);
402 0 : DrawRightTrap(gw,pos,inset,scale,cols[0]);
403 0 : DrawBottomTrap(gw,pos,inset,scale,cols[1]);
404 0 : inset = scale + GDrawPointsToPixels(gw,2);
405 : }
406 :
407 0 : if ( (design->flags & (box_foreground_border_outer|box_foreground_shadow_outer)) ) {
408 0 : GDrawSetLineWidth(gw,scale);
409 0 : cur = *pos;
410 0 : cur.x += inset; cur.y += inset; cur.width -= 2*inset; cur.height -= 2*inset;
411 0 : if ( scale>1 ) {
412 0 : cur.x += scale/2; cur.y += scale/2;
413 0 : cur.width -= scale; cur.height -= scale;
414 : }
415 0 : --cur.width; --cur.height;
416 0 : if ( design->flags&box_foreground_border_outer )
417 0 : GDrawDrawRect(gw,&cur,color_outer);
418 : else {
419 0 : GDrawDrawLine(gw,cur.x+scale,cur.y+cur.height,cur.x+cur.width,cur.y+cur.height,fg);
420 0 : GDrawDrawLine(gw,cur.x+cur.width,cur.y+scale,cur.x+cur.width,cur.y+cur.height,fg);
421 : }
422 0 : inset += scale;
423 : }
424 :
425 0 : if ( bt==bt_double && bw<3 )
426 0 : bt = bt_box;
427 0 : if (( bt==bt_engraved || bt==bt_embossed ) && bw<2 )
428 0 : bt = bt_box;
429 :
430 0 : if ( bw!=0 ) switch ( bt ) {
431 : case bt_none:
432 0 : break;
433 : case bt_box: case bt_raised: case bt_lowered:
434 0 : DrawLeftTrap(gw,pos,inset,bw,cols[0]);
435 0 : DrawTopTrap(gw,pos,inset,bw,cols[1]);
436 0 : DrawRightTrap(gw,pos,inset,bw,cols[2]);
437 0 : DrawBottomTrap(gw,pos,inset,bw,cols[3]);
438 0 : break;
439 : case bt_engraved: case bt_embossed:
440 0 : bw &= ~1;
441 0 : DrawLeftTrap(gw,pos,inset,bw/2,cols[0]);
442 0 : DrawTopTrap(gw,pos,inset,bw/2,cols[1]);
443 0 : DrawRightTrap(gw,pos,inset,bw/2,cols[2]);
444 0 : DrawBottomTrap(gw,pos,inset,bw/2,cols[3]);
445 :
446 0 : inset += bw/2;
447 0 : DrawLeftTrap(gw,pos,inset,bw/2,cols[2]);
448 0 : DrawTopTrap(gw,pos,inset,bw/2,cols[3]);
449 0 : DrawRightTrap(gw,pos,inset,bw/2,cols[0]);
450 0 : DrawBottomTrap(gw,pos,inset,bw/2,cols[1]);
451 0 : inset -= bw/2;
452 0 : break;
453 : case bt_double: {
454 0 : int width = (bw+1)/3;
455 0 : DrawLeftTrap(gw,pos,inset,width,cols[0]);
456 0 : DrawTopTrap(gw,pos,inset,width,cols[1]);
457 0 : DrawRightTrap(gw,pos,inset,width,cols[2]);
458 0 : DrawBottomTrap(gw,pos,inset,width,cols[3]);
459 :
460 0 : inset += bw-width;
461 0 : DrawLeftTrap(gw,pos,inset,width,cols[0]);
462 0 : DrawTopTrap(gw,pos,inset,width,cols[1]);
463 0 : DrawRightTrap(gw,pos,inset,width,cols[2]);
464 0 : DrawBottomTrap(gw,pos,inset,width,cols[3]);
465 0 : inset -= bw-width;
466 0 : } break;
467 : }
468 0 : inset += bw;
469 :
470 0 : if ( (design->flags & box_foreground_border_inner) ||
471 0 : ((design->flags & box_active_border_inner) && state==gs_active)) {
472 0 : GDrawSetLineWidth(gw,scale);
473 0 : cur = *pos;
474 0 : cur.x += inset; cur.y += inset;
475 0 : cur.width -= 2*inset; cur.height -= 2*inset;
476 0 : if ( scale>1 ) {
477 0 : cur.x += scale/2; cur.y += scale/2;
478 0 : cur.width -= scale; cur.height -= scale;
479 : }
480 0 : --cur.width; --cur.height;
481 0 : GDrawDrawRect(gw,&cur,
482 0 : state == gs_active && (design->flags & box_active_border_inner) ?
483 : design->active_border : color_inner);
484 0 : inset += scale;
485 : }
486 0 : return( inset );
487 : }
488 :
489 0 : int GBoxDrawHLine(GWindow gw,GRect *pos,GBox *design) {
490 0 : int bw = GDrawPointsToPixels(gw,design->border_width);
491 : int x,y,xend;
492 0 : int scale = GDrawPointsToPixels(gw,1);
493 0 : enum border_type bt = design->border_type;
494 : Color cols[4];
495 0 : Color fg = design->main_foreground==COLOR_DEFAULT?GDrawGetDefaultForeground(GDrawGetDisplayOfWindow(gw)):
496 : design->main_foreground;
497 0 : Color color_inner = design->border_inner == COLOR_DEFAULT ? fg : design->border_inner;
498 0 : Color color_outer = design->border_outer == COLOR_DEFAULT ? fg : design->border_outer;
499 0 : int bp = GBoxBorderWidth(gw,design);
500 :
501 0 : FigureBorderCols(design,cols);
502 :
503 0 : x = pos->x; xend = x+pos->width -1;
504 0 : y = pos->y + (pos->height-bp)/2;
505 :
506 0 : if ( (design->flags & box_foreground_border_outer) ) {
507 0 : GDrawSetLineWidth(gw,scale);
508 0 : GDrawDrawLine(gw,x,y+scale/2,xend,y+scale/2,color_outer);
509 0 : y += scale;
510 : }
511 :
512 0 : if ( bt==bt_double && bw<3 )
513 0 : bt = bt_box;
514 0 : if (( bt==bt_engraved || bt==bt_embossed ) && bw<2 )
515 0 : bt = bt_box;
516 :
517 0 : if ( bw!=0 ) switch ( bt ) {
518 : case bt_none:
519 0 : break;
520 : case bt_box: case bt_raised: case bt_lowered:
521 0 : GDrawSetLineWidth(gw,bw);
522 0 : GDrawDrawLine(gw,x,y+bw/2,xend,y+bw/2,cols[1]);
523 0 : break;
524 : case bt_engraved: case bt_embossed:
525 0 : bw &= ~1;
526 0 : GDrawSetLineWidth(gw,bw/2);
527 0 : GDrawDrawLine(gw,x,y+bw/4,xend,y+bw/4,cols[1]);
528 0 : y += bw/2;
529 0 : GDrawDrawLine(gw,x,y+bw/4,xend,y+bw/4,cols[3]);
530 0 : y -= bw/2;
531 0 : break;
532 : case bt_double: {
533 0 : int width = (bw+1)/3;
534 0 : GDrawSetLineWidth(gw,width);
535 0 : GDrawDrawLine(gw,x,y+width/2,xend,y+width/2,cols[1]);
536 0 : y += bw-width;
537 0 : GDrawDrawLine(gw,x,y+width/2,xend,y+width/2,cols[1]);
538 0 : y -= bw-width;
539 0 : } break;
540 : }
541 0 : y += bw;
542 :
543 0 : if ( design->flags & box_foreground_border_inner ) {
544 0 : GDrawSetLineWidth(gw,scale);
545 0 : GDrawDrawLine(gw,x,y+scale/2,xend,y+scale/2,color_inner);
546 0 : y += scale;
547 : }
548 0 : return( y );
549 : }
550 :
551 0 : int GBoxDrawVLine(GWindow gw,GRect *pos,GBox *design) {
552 0 : int bw = GDrawPointsToPixels(gw,design->border_width);
553 : int x,y,yend;
554 0 : int scale = GDrawPointsToPixels(gw,1);
555 0 : enum border_type bt = design->border_type;
556 : Color cols[4];
557 0 : Color fg = design->main_foreground==COLOR_DEFAULT?GDrawGetDefaultForeground(GDrawGetDisplayOfWindow(gw)):
558 : design->main_foreground;
559 0 : Color color_inner = design->border_inner == COLOR_DEFAULT ? fg : design->border_inner;
560 0 : Color color_outer = design->border_outer == COLOR_DEFAULT ? fg : design->border_outer;
561 0 : int bp = GBoxBorderWidth(gw,design);
562 :
563 0 : FigureBorderCols(design,cols);
564 :
565 0 : x = pos->x + (pos->width-bp)/2;
566 0 : y = pos->y; yend = y+pos->height -1;
567 :
568 0 : if ( (design->flags & box_foreground_border_outer) ) {
569 0 : GDrawSetLineWidth(gw,scale);
570 0 : GDrawDrawLine(gw,x+scale/2,y,x+scale/2,yend,color_outer);
571 0 : x += scale;
572 : }
573 :
574 0 : if ( bt==bt_double && bw<3 )
575 0 : bt = bt_box;
576 0 : if (( bt==bt_engraved || bt==bt_embossed ) && bw<2 )
577 0 : bt = bt_box;
578 :
579 0 : if ( bw!=0 ) switch ( bt ) {
580 : case bt_none:
581 0 : break;
582 : case bt_box: case bt_raised: case bt_lowered:
583 0 : GDrawSetLineWidth(gw,bw);
584 0 : GDrawDrawLine(gw,x+bw/2,y,x+bw/2,yend,cols[0]);
585 0 : break;
586 : case bt_engraved: case bt_embossed:
587 0 : bw &= ~1;
588 0 : GDrawSetLineWidth(gw,bw/2);
589 0 : GDrawDrawLine(gw,x+bw/4,y,x+bw/4,yend,cols[0]);
590 0 : x += bw/2;
591 0 : GDrawDrawLine(gw,x+bw/4,y,x+bw/4,yend,cols[2]);
592 0 : x -= bw/2;
593 0 : break;
594 : case bt_double: {
595 0 : int width = (bw+1)/3;
596 0 : GDrawSetLineWidth(gw,width);
597 0 : GDrawDrawLine(gw,x+width/2,y,x+width/2,yend,cols[0]);
598 0 : x += bw-width;
599 0 : GDrawDrawLine(gw,x+width/2,y,x+width/2,yend,cols[0]);
600 0 : x -= bw-width;
601 0 : } break;
602 : }
603 0 : x += bw;
604 :
605 0 : if ( design->flags & box_foreground_border_inner ) {
606 0 : GDrawSetLineWidth(gw,scale);
607 0 : GDrawDrawLine(gw,x+scale/2,y,x+scale/2,yend,color_inner);
608 0 : x += scale;
609 : }
610 0 : return( x );
611 : }
612 :
613 0 : static int GBoxRoundRectBorder(GWindow gw,GRect *pos,GBox *design,
614 : enum gadget_state state, int is_def) {
615 0 : int bw = GDrawPointsToPixels(gw,design->border_width);
616 0 : int inset = 0;
617 0 : int scale = GDrawPointsToPixels(gw,1);
618 0 : enum border_type bt = design->border_type;
619 : Color cols[4];
620 0 : int rr = GDrawPointsToPixels(gw,design->rr_radius);
621 0 : Color fg = state==gs_disabled?design->disabled_foreground:
622 0 : design->main_foreground==COLOR_DEFAULT?GDrawGetDefaultForeground(GDrawGetDisplayOfWindow(gw)):
623 : design->main_foreground;
624 0 : Color color_inner = design->border_inner == COLOR_DEFAULT ? fg : design->border_inner;
625 0 : Color color_outer = design->border_outer == COLOR_DEFAULT ? fg : design->border_outer;
626 :
627 0 : if ( rr==0 )
628 0 : rr = pos->width/2;
629 0 : if ( is_def && (design->flags & box_draw_default) )
630 0 : rr += scale + GDrawPointsToPixels(gw,2);
631 0 : if ( rr>pos->width/2 )
632 0 : rr = pos->width/2;
633 0 : if ( rr>pos->height/2 )
634 0 : rr = pos->height/2;
635 0 : if ( !(scale&1)) --scale;
636 0 : if ( scale==0 ) scale = 1;
637 :
638 0 : FigureBorderCols(design,cols);
639 0 : if ( is_def && (design->flags & box_draw_default) && bt!=bt_none ) {
640 0 : GDrawSetLineWidth(gw,scale);
641 0 : DrawRoundRects(gw,pos,inset+scale/2,rr,cols[2],cols[3],cols[0],cols[1]);
642 0 : inset += scale + GDrawPointsToPixels(gw,2);
643 : }
644 :
645 0 : if ( design->flags & (box_foreground_border_outer|box_foreground_shadow_outer) ) {
646 0 : GDrawSetLineWidth(gw,scale);
647 0 : if ( design->flags&box_foreground_border_outer )
648 0 : DrawRoundRect(gw,pos,scale/2,rr,color_outer);
649 : else {
650 0 : GDrawDrawLine(gw,pos->x+scale+rr,pos->y+pos->height,pos->x+pos->width,pos->y+pos->height,fg);
651 0 : GDrawDrawLine(gw,pos->x+pos->width,pos->y+scale+rr,pos->x+pos->width,pos->y+pos->height,fg);
652 : }
653 0 : inset += scale;
654 : }
655 :
656 0 : if ( bt==bt_double && bw<3 )
657 0 : bt = bt_box;
658 0 : if (( bt==bt_engraved || bt==bt_embossed ) && bw<2 )
659 0 : bt = bt_box;
660 :
661 0 : if ( bw!=0 ) switch ( bt ) {
662 : case bt_none:
663 0 : break;
664 : case bt_box: case bt_raised: case bt_lowered:
665 0 : if ( !(bw&1) ) --bw;
666 0 : GDrawSetLineWidth(gw,bw);
667 0 : DrawRoundRects(gw,pos,inset+bw/2,rr,cols[0],cols[1],cols[2],cols[3]);
668 0 : break;
669 : case bt_engraved: case bt_embossed:
670 0 : bw &= ~1;
671 0 : if ( !(bw&2 ) )
672 0 : bw -= 2;
673 0 : if ( bw<=0 )
674 0 : bw = 2;
675 0 : GDrawSetLineWidth(gw,bw/2);
676 0 : DrawRoundRects(gw,pos,inset+bw/4,rr,cols[0],cols[1],cols[2],cols[3]);
677 0 : DrawRoundRects(gw,pos,inset+bw/2+bw/4,rr,cols[2],cols[3],cols[0],cols[1]);
678 0 : break;
679 : case bt_double: {
680 0 : int width = (bw+1)/3;
681 0 : if ( !(width&1) ) {
682 0 : if ( 2*(width+1) < bw )
683 0 : ++width;
684 : else
685 0 : --width;
686 : }
687 0 : GDrawSetLineWidth(gw,width);
688 0 : DrawRoundRects(gw,pos,inset+width/2,rr,cols[0],cols[1],cols[2],cols[3]);
689 0 : DrawRoundRects(gw,pos,inset+bw-(width+1)/2,rr,cols[0],cols[1],cols[2],cols[3]);
690 0 : } break;
691 : }
692 0 : inset += bw;
693 :
694 0 : if ( (design->flags & box_foreground_border_inner) ||
695 0 : ((design->flags & box_active_border_inner) && state==gs_active)) {
696 0 : GDrawSetLineWidth(gw,scale);
697 0 : DrawRoundRect(gw,pos,inset+scale/2,rr,
698 0 : state == gs_active && (design->flags & box_active_border_inner) ?
699 : design->active_border : color_inner);
700 0 : inset += scale;
701 : }
702 0 : return( inset );
703 : }
704 :
705 0 : static int GBoxElipseBorder(GWindow gw,GRect *pos,GBox *design,
706 : enum gadget_state state, int is_def) {
707 0 : int bw = GDrawPointsToPixels(gw,design->border_width);
708 0 : int inset = 0;
709 : GRect cur;
710 0 : int scale = GDrawPointsToPixels(gw,1);
711 0 : enum border_type bt = design->border_type;
712 : Color cols[4];
713 0 : Color fg = state==gs_disabled?design->disabled_foreground:
714 0 : design->main_foreground==COLOR_DEFAULT?GDrawGetDefaultForeground(GDrawGetDisplayOfWindow(gw)):
715 : design->main_foreground;
716 0 : Color color_inner = design->border_inner == COLOR_DEFAULT ? fg : design->border_inner;
717 0 : Color color_outer = design->border_outer == COLOR_DEFAULT ? fg : design->border_outer;
718 :
719 0 : if ( !(scale&1)) --scale;
720 0 : if ( scale==0 ) scale = 1;
721 :
722 0 : FigureBorderCols(design,cols);
723 0 : if ( is_def && (design->flags & box_draw_default) && bt!=bt_none ) {
724 0 : int temp = scale;
725 0 : if ( !(temp&1) ) --temp;
726 0 : GDrawSetLineWidth(gw,temp);
727 0 : cur = *pos;
728 0 : cur.x += inset+temp/2; cur.y += inset+temp/2;
729 0 : cur.width -= 2*(inset+temp/2)+1; cur.height -= 2*(inset+temp/2)+1;
730 0 : GDrawDrawArc(gw,&cur,90*64,90*64,cols[2]);
731 0 : GDrawDrawArc(gw,&cur,0*64,90*64,cols[3]);
732 0 : GDrawDrawArc(gw,&cur,-90*64,90*64,cols[0]);
733 0 : GDrawDrawArc(gw,&cur,-180*64,90*64,cols[1]);
734 0 : inset += scale + GDrawPointsToPixels(gw,2);
735 : }
736 :
737 0 : if ( design->flags & box_foreground_border_outer ) {
738 0 : GDrawSetLineWidth(gw,scale);
739 0 : cur = *pos;
740 0 : if ( scale>1 ) {
741 0 : cur.x += scale/2; cur.y += scale/2;
742 0 : cur.width -= scale; cur.height -= scale;
743 : }
744 0 : --cur.width; --cur.height;
745 0 : GDrawDrawElipse(gw,&cur,color_outer);
746 0 : inset += scale;
747 : }
748 :
749 0 : if ( bt==bt_double && bw<3 )
750 0 : bt = bt_box;
751 0 : if (( bt==bt_engraved || bt==bt_embossed ) && bw<2 )
752 0 : bt = bt_box;
753 0 : FigureBorderCols(design,cols);
754 :
755 0 : if ( bw!=0 ) switch ( bt ) {
756 : case bt_none:
757 0 : break;
758 : case bt_box: case bt_raised: case bt_lowered:
759 0 : if ( !(bw&1) ) --bw;
760 0 : GDrawSetLineWidth(gw,bw);
761 0 : cur = *pos;
762 0 : cur.x += inset+bw/2; cur.y += inset+bw/2;
763 0 : cur.width -= 2*(inset+bw/2)+1; cur.height -= 2*(inset+bw/2)+1;
764 0 : GDrawDrawArc(gw,&cur,90*64,90*64,cols[0]);
765 0 : GDrawDrawArc(gw,&cur,0*64,90*64,cols[1]);
766 0 : GDrawDrawArc(gw,&cur,-90*64,90*64,cols[2]);
767 0 : GDrawDrawArc(gw,&cur,-180*64,90*64,cols[3]);
768 0 : break;
769 : case bt_engraved: case bt_embossed:
770 0 : bw &= ~1;
771 0 : if ( !(bw&2 ) )
772 0 : bw -= 2;
773 0 : if ( bw<=0 )
774 0 : bw = 2;
775 0 : GDrawSetLineWidth(gw,bw/2);
776 0 : cur = *pos;
777 0 : cur.x += inset+bw/4; cur.y += inset+bw/4;
778 0 : cur.width -= 2*(inset+bw/4)+1; cur.height -= 2*(inset+bw/4)+1;
779 0 : GDrawDrawArc(gw,&cur,90*64,90*64,cols[0]);
780 0 : GDrawDrawArc(gw,&cur,0*64,90*64,cols[1]);
781 0 : GDrawDrawArc(gw,&cur,-90*64,90*64,cols[2]);
782 0 : GDrawDrawArc(gw,&cur,-180*64,90*64,cols[3]);
783 0 : cur.x += bw/2; cur.y += bw/2;
784 0 : cur.width -= bw; cur.height -= bw;
785 0 : GDrawDrawArc(gw,&cur,90*64,90*64,cols[2]);
786 0 : GDrawDrawArc(gw,&cur,0*64,90*64,cols[3]);
787 0 : GDrawDrawArc(gw,&cur,-90*64,90*64,cols[0]);
788 0 : GDrawDrawArc(gw,&cur,-180*64,90*64,cols[1]);
789 0 : GDrawSetLineWidth(gw,scale);
790 0 : break;
791 : case bt_double: {
792 0 : int width = (bw+1)/3;
793 0 : if ( !(width&1) ) {
794 0 : if ( 2*(width+1) < bw )
795 0 : ++width;
796 : else
797 0 : --width;
798 : }
799 0 : GDrawSetLineWidth(gw,width);
800 0 : cur = *pos;
801 0 : cur.x += inset+width/2; cur.y += inset+width/2;
802 0 : cur.width -= 2*(inset+width/2)+1; cur.height -= 2*(inset+width/2)+1;
803 0 : GDrawDrawArc(gw,&cur,90*64,90*64,cols[0]);
804 0 : GDrawDrawArc(gw,&cur,0*64,90*64,cols[1]);
805 0 : GDrawDrawArc(gw,&cur,-90*64,90*64,cols[2]);
806 0 : GDrawDrawArc(gw,&cur,-180*64,90*64,cols[3]);
807 0 : cur = *pos;
808 0 : cur.x += inset+bw-(width+1)/2; cur.y += inset+bw-(width+1)/2;
809 0 : cur.width -= 2*(inset+bw-(width+1)/2)+1; cur.height -= 2*(inset+bw-(width+1)/2)+1;
810 0 : GDrawDrawArc(gw,&cur,90*64,90*64,cols[0]);
811 0 : GDrawDrawArc(gw,&cur,0*64,90*64,cols[1]);
812 0 : GDrawDrawArc(gw,&cur,-90*64,90*64,cols[2]);
813 0 : GDrawDrawArc(gw,&cur,-180*64,90*64,cols[3]);
814 0 : GDrawSetLineWidth(gw,scale);
815 0 : } break;
816 : }
817 0 : inset += bw;
818 :
819 0 : if ( (design->flags & box_foreground_border_inner) ||
820 0 : ((design->flags & box_active_border_inner) && state==gs_active)) {
821 0 : GDrawSetLineWidth(gw,scale);
822 0 : cur = *pos;
823 0 : cur.x += inset; cur.y += inset;
824 0 : cur.width -= 2*inset; cur.height -= 2*inset;
825 0 : if ( scale>1 ) {
826 0 : cur.x += scale/2; cur.y += scale/2;
827 0 : cur.width -= scale; cur.height -= scale;
828 : }
829 0 : --cur.width; --cur.height;
830 0 : GDrawDrawElipse(gw,&cur,
831 0 : state == gs_active && (design->flags & box_active_border_inner) ?
832 : design->active_border : color_inner);
833 0 : inset += scale;
834 : }
835 0 : return( inset );
836 : }
837 :
838 0 : static int GBoxDiamondBorder(GWindow gw,GRect *pos,GBox *design,
839 : enum gadget_state state, int is_def) {
840 0 : int bw = GDrawPointsToPixels(gw,design->border_width);
841 0 : int inset = 0;
842 0 : int scale = GDrawPointsToPixels(gw,1);
843 0 : enum border_type bt = design->border_type;
844 : Color cols[4];
845 0 : Color fg = state==gs_disabled?design->disabled_foreground:
846 0 : design->main_foreground==COLOR_DEFAULT?GDrawGetDefaultForeground(GDrawGetDisplayOfWindow(gw)):
847 : design->main_foreground;
848 0 : Color color_inner = design->border_inner == COLOR_DEFAULT ? fg : design->border_inner;
849 0 : Color color_outer = design->border_outer == COLOR_DEFAULT ? fg : design->border_outer;
850 :
851 0 : FigureBorderCols(design,cols);
852 0 : if ( is_def && (design->flags & box_draw_default) && bt!=bt_none ) {
853 0 : DrawULTrap(gw,pos,inset,scale,cols[2]);
854 0 : DrawURTrap(gw,pos,inset,scale,cols[3]);
855 0 : DrawLRTrap(gw,pos,inset,scale,cols[0]);
856 0 : DrawLLTrap(gw,pos,inset,scale,cols[1]);
857 0 : inset += scale + GDrawPointsToPixels(gw,2);
858 : }
859 :
860 0 : if ( design->flags & box_foreground_border_outer ) {
861 : GPoint pts[5];
862 0 : GDrawSetLineWidth(gw,scale);
863 0 : pts[0].x = pos->x+scale/2; pts[0].y = pos->y+pos->height/2;
864 0 : pts[1].x = pos->x+pos->width/2; pts[1].y = pos->y+scale/2;
865 0 : pts[2].x = pos->x+pos->width-1-scale/2; pts[2].y = pts[0].y;
866 0 : pts[3].x = pts[1].x; pts[3].y = pos->y+pos->height-1-scale/2;
867 0 : pts[4] = pts[0];
868 0 : GDrawDrawPoly(gw,pts,5,color_outer);
869 0 : inset += scale;
870 : }
871 :
872 0 : if ( bt==bt_double && bw<3 )
873 0 : bt = bt_box;
874 0 : if (( bt==bt_engraved || bt==bt_embossed ) && bw<2 )
875 0 : bt = bt_box;
876 0 : FigureBorderCols(design,cols);
877 :
878 0 : if ( bw!=0 ) switch ( bt ) {
879 : case bt_none:
880 0 : break;
881 : case bt_box: case bt_raised: case bt_lowered:
882 0 : DrawULTrap(gw,pos,inset,bw,cols[0]);
883 0 : DrawURTrap(gw,pos,inset,bw,cols[1]);
884 0 : DrawLRTrap(gw,pos,inset,bw,cols[2]);
885 0 : DrawLLTrap(gw,pos,inset,bw,cols[3]);
886 0 : break;
887 : case bt_engraved: case bt_embossed:
888 0 : bw &= ~1;
889 0 : DrawULTrap(gw,pos,inset,bw/2,cols[0]);
890 0 : DrawURTrap(gw,pos,inset,bw/2,cols[1]);
891 0 : DrawLRTrap(gw,pos,inset,bw/2,cols[2]);
892 0 : DrawLLTrap(gw,pos,inset,bw/2,cols[3]);
893 :
894 0 : inset += bw/2;
895 0 : DrawULTrap(gw,pos,inset,bw/2,cols[2]);
896 0 : DrawURTrap(gw,pos,inset,bw/2,cols[3]);
897 0 : DrawLRTrap(gw,pos,inset,bw/2,cols[0]);
898 0 : DrawLLTrap(gw,pos,inset,bw/2,cols[1]);
899 0 : inset -= bw/2;
900 0 : break;
901 : case bt_double: {
902 0 : int width = (bw+1)/3;
903 0 : DrawULTrap(gw,pos,inset,width,cols[0]);
904 0 : DrawURTrap(gw,pos,inset,width,cols[1]);
905 0 : DrawLRTrap(gw,pos,inset,width,cols[2]);
906 0 : DrawLLTrap(gw,pos,inset,width,cols[3]);
907 :
908 0 : inset += bw-width;
909 0 : DrawULTrap(gw,pos,inset,width,cols[0]);
910 0 : DrawURTrap(gw,pos,inset,width,cols[1]);
911 0 : DrawLRTrap(gw,pos,inset,width,cols[2]);
912 0 : DrawLLTrap(gw,pos,inset,width,cols[3]);
913 0 : inset -= bw-width;
914 0 : } break;
915 : }
916 0 : inset += bw;
917 :
918 0 : if ( (design->flags & box_foreground_border_inner) ||
919 0 : ((design->flags & box_active_border_inner) && state==gs_active)) {
920 : GPoint pts[5];
921 0 : GDrawSetLineWidth(gw,scale);
922 0 : pts[0].x = pos->x+inset+scale/2; pts[0].y = pos->y+pos->height/2;
923 0 : pts[1].x = pos->x+pos->width/2; pts[1].y = pos->y+inset+scale/2;
924 0 : pts[2].x = pos->x+pos->width-1-inset-scale/2; pts[2].y = pts[0].y;
925 0 : pts[3].x = pts[1].x; pts[3].y = pos->y+pos->height-1-inset-scale/2;
926 0 : pts[4] = pts[0];
927 0 : GDrawDrawPoly(gw,pts,5,
928 0 : state == gs_active && (design->flags & box_active_border_inner) ?
929 : design->active_border : color_inner);
930 0 : inset += scale;
931 : }
932 0 : return( inset );
933 : }
934 :
935 0 : int GBoxDrawBorder(GWindow gw,GRect *pos,GBox *design,enum gadget_state state,
936 : int is_default) {
937 0 : int ret = 0;
938 :
939 0 : if ( state == gs_disabled )
940 0 : GDrawSetStippled(gw,1,0,0);
941 0 : switch ( design->border_shape ) {
942 : case bs_rect:
943 0 : ret = GBoxRectBorder(gw,pos,design,state,is_default);
944 0 : break;
945 : case bs_roundrect:
946 0 : ret = GBoxRoundRectBorder(gw,pos,design,state,is_default);
947 0 : break;
948 : case bs_elipse:
949 0 : ret = GBoxElipseBorder(gw,pos,design,state,is_default);
950 0 : break;
951 : case bs_diamond:
952 0 : ret = GBoxDiamondBorder(gw,pos,design,state,is_default);
953 0 : break;
954 : }
955 0 : if ( state == gs_disabled )
956 0 : GDrawSetStippled(gw,0,0,0);
957 0 : return( ret );
958 : }
959 :
960 0 : static void BoxGradientRect(GWindow gw, GRect *r, Color start, Color end)
961 : {
962 0 : int xend = r->x + r->width - 1;
963 : int i;
964 :
965 0 : int rstart = COLOR_RED(start);
966 0 : int gstart = COLOR_GREEN(start);
967 0 : int bstart = COLOR_BLUE(start);
968 0 : int rdiff = COLOR_RED(end) - rstart;
969 0 : int gdiff = COLOR_GREEN(end) - gstart;
970 0 : int bdiff = COLOR_BLUE(end) - bstart;
971 :
972 0 : if (r->height <= 0)
973 0 : return;
974 :
975 0 : for (i = 0; i < r->height; i++)
976 0 : GDrawDrawLine(gw, r->x, r->y + i, xend, r->y + i, COLOR_CREATE(
977 : rstart + rdiff * i / r->height,
978 : gstart + gdiff * i / r->height,
979 : bstart + bdiff * i / r->height ));
980 : }
981 :
982 0 : static void BoxGradientElipse(GWindow gw, GRect *r, Color start, Color end)
983 : {
984 : /*
985 : * Ellipse borders are 1 unit wider and 1 unit higher than the passed GRect.
986 : * With corrected values the gradient-fill will fit its corresponding border.
987 : */
988 0 : int correctedwidth = r->width + 1;
989 0 : int correctedheight = r->height + 1;
990 :
991 0 : int xend = r->x + correctedwidth - 1;
992 0 : int yend = r->y + correctedheight - 1;
993 : int i, xoff;
994 :
995 0 : double a = (double)correctedwidth / 2.0;
996 0 : double b = (double)correctedheight / 2.0;
997 0 : double precalc = (a * a) / (b * b);
998 :
999 0 : int rstart = COLOR_RED(start);
1000 0 : int gstart = COLOR_GREEN(start);
1001 0 : int bstart = COLOR_BLUE(start);
1002 0 : int rdiff = COLOR_RED(end) - rstart;
1003 0 : int gdiff = COLOR_GREEN(end) - gstart;
1004 0 : int bdiff = COLOR_BLUE(end) - bstart;
1005 :
1006 0 : if (correctedheight <= 0)
1007 0 : return;
1008 :
1009 0 : for (i = 0; i < (correctedheight + 1) / 2; ++i) {
1010 0 : xoff = lrint(a - sqrt(precalc * (double)(i * (correctedheight - i)) ));
1011 :
1012 0 : GDrawDrawLine(gw, r->x + xoff, r->y + i, xend - xoff, r->y + i, COLOR_CREATE(
1013 : rstart + rdiff * i / correctedheight,
1014 : gstart + gdiff * i / correctedheight,
1015 : bstart + bdiff * i / correctedheight ));
1016 :
1017 0 : GDrawDrawLine(gw, r->x + xoff, yend - i, xend - xoff, yend - i, COLOR_CREATE(
1018 : rstart + rdiff * (correctedheight - i) / correctedheight,
1019 : gstart + gdiff * (correctedheight - i) / correctedheight,
1020 : bstart + bdiff * (correctedheight - i) / correctedheight ));
1021 : }
1022 : }
1023 :
1024 0 : static void BoxGradientRoundRect(GWindow gw, GRect *r, int rr, Color start, Color end)
1025 : {
1026 0 : int radius = rr <= (r->height+1)/2 ? (rr > 0 ? rr : 0) : (r->height+1)/2;
1027 0 : int xend = r->x + r->width - 1;
1028 0 : int yend = r->y + r->height - 1;
1029 0 : int precalc = radius * 2 - 1;
1030 : int i, xoff;
1031 :
1032 0 : int rstart = COLOR_RED(start);
1033 0 : int gstart = COLOR_GREEN(start);
1034 0 : int bstart = COLOR_BLUE(start);
1035 0 : int rdiff = COLOR_RED(end) - rstart;
1036 0 : int gdiff = COLOR_GREEN(end) - gstart;
1037 0 : int bdiff = COLOR_BLUE(end) - bstart;
1038 :
1039 0 : if (r->height <= 0)
1040 0 : return;
1041 :
1042 0 : for (i = 0; i < radius; i++) {
1043 0 : xoff = radius - lrint(sqrt( (double)(i * (precalc - i)) ));
1044 :
1045 0 : GDrawDrawLine(gw, r->x + xoff, r->y + i, xend - xoff, r->y + i, COLOR_CREATE(
1046 : rstart + rdiff * i / r->height,
1047 : gstart + gdiff * i / r->height,
1048 : bstart + bdiff * i / r->height ));
1049 :
1050 0 : GDrawDrawLine(gw, r->x + xoff, yend - i, xend - xoff, yend - i, COLOR_CREATE(
1051 : rstart + rdiff * (r->height - i) / r->height,
1052 : gstart + gdiff * (r->height - i) / r->height,
1053 : bstart + bdiff * (r->height - i) / r->height ));
1054 : }
1055 :
1056 0 : for (i = radius; i < r->height - radius; i++)
1057 0 : GDrawDrawLine(gw, r->x, r->y + i, xend, r->y + i, COLOR_CREATE(
1058 : rstart + rdiff * i / r->height,
1059 : gstart + gdiff * i / r->height,
1060 : bstart + bdiff * i / r->height ));
1061 : }
1062 :
1063 0 : void GBoxDrawBackground(GWindow gw,GRect *pos,GBox *design,
1064 : enum gadget_state state, int is_default) {
1065 0 : Color gbg = GDrawGetDefaultBackground(GDrawGetDisplayOfWindow(gw));
1066 0 : Color mbg = design->main_background==COLOR_DEFAULT?gbg:design->main_background;
1067 0 : Color dbg = design->disabled_background==COLOR_DEFAULT?gbg:design->disabled_background;
1068 0 : Color pbg = design->depressed_background==COLOR_DEFAULT?gbg:design->depressed_background;
1069 : Color ibg;
1070 0 : int def_off = is_default && (design->flags & box_draw_default) ?
1071 0 : GDrawPointsToPixels(gw,1) + GDrawPointsToPixels(gw,2): 0;
1072 :
1073 0 : if ( state == gs_disabled ) {
1074 0 : ibg=dbg;
1075 0 : GDrawSetStippled(gw,1,0,0);
1076 0 : } else if ( state == gs_pressedactive && (design->flags & box_do_depressed_background ))
1077 0 : ibg=pbg;
1078 : else
1079 0 : ibg=mbg;
1080 :
1081 0 : if ( design->border_shape==bs_rect && (def_off==0 || mbg==ibg) && !(design->flags & box_gradient_bg)) {
1082 0 : GDrawFillRect(gw,pos,ibg);
1083 : } else {
1084 : /* GDrawFillRect(gw,pos,mbg); */
1085 0 : if ( design->border_shape==bs_rect ) {
1086 : GRect cur;
1087 0 : cur = *pos;
1088 0 : cur.x += def_off; cur.y += def_off; cur.width -= 2*def_off; cur.height -= 2*def_off;
1089 0 : if ( design->flags & box_gradient_bg )
1090 0 : BoxGradientRect(gw,&cur,ibg,design->gradient_bg_end);
1091 : else
1092 0 : GDrawFillRect(gw,&cur,ibg);
1093 0 : } else if ( design->border_shape==bs_elipse ) {
1094 : GRect cur;
1095 0 : cur = *pos; --cur.width; --cur.height;
1096 0 : if ( def_off ) {
1097 0 : cur.x += def_off; cur.y += def_off; cur.width -= 2*def_off; cur.height -= 2*def_off;
1098 : }
1099 0 : if ( design->flags & box_gradient_bg )
1100 0 : BoxGradientElipse(gw,&cur,ibg,design->gradient_bg_end);
1101 : else
1102 0 : GDrawFillElipse(gw,&cur,ibg);
1103 0 : } else if ( design->border_shape==bs_diamond ) {
1104 : GPoint pts[5];
1105 0 : pts[0].x = pos->x+pos->width/2; pts[0].y = pos->y+def_off;
1106 0 : pts[1].x = pos->x+pos->width-1-def_off; pts[1].y = pos->y+pos->height/2;
1107 0 : pts[2].x = pts[0].x; pts[2].y = pos->y+pos->height-1-def_off;
1108 0 : pts[3].x = pos->x+def_off; pts[3].y = pts[1].y;
1109 0 : pts[4] = pts[0];
1110 0 : GDrawFillPoly(gw,pts,5,ibg);
1111 : } else {
1112 0 : int rr = GDrawPointsToPixels(gw,design->rr_radius);
1113 :
1114 0 : if ( rr==0 )
1115 0 : rr = pos->width/2-def_off;
1116 0 : if ( rr>pos->width/2-def_off )
1117 0 : rr = pos->width/2-def_off;
1118 0 : if ( rr>pos->height/2-def_off )
1119 0 : rr = pos->height/2-def_off;
1120 :
1121 0 : if ( design->flags & box_gradient_bg )
1122 0 : BoxGradientRoundRect(gw,pos,rr,ibg,design->gradient_bg_end);
1123 : else
1124 0 : GDrawFillRoundRect(gw,pos,rr,ibg);
1125 : }
1126 : }
1127 0 : if ( state == gs_disabled )
1128 0 : GDrawSetStippled(gw,0,0,0);
1129 0 : }
1130 :
1131 0 : int GBoxBorderWidth(GWindow gw, GBox *box) {
1132 0 : int scale = GDrawPointsToPixels(gw,1);
1133 0 : int bp = GDrawPointsToPixels(gw,box->border_width)+
1134 0 : GDrawPointsToPixels(gw,box->padding)+
1135 0 : ((box->flags & (box_foreground_border_outer|box_foreground_shadow_outer))?scale:0)+
1136 0 : ((box->flags &
1137 0 : (box_foreground_border_inner|box_active_border_inner))?scale:0);
1138 0 : return( bp );
1139 : }
1140 :
1141 0 : int GBoxExtraSpace(GGadget *g) {
1142 0 : if ( g->state==gs_invisible || !(g->box->flags & box_draw_default) ||
1143 0 : !GGadgetIsDefault(g))
1144 0 : return( 0 );
1145 :
1146 0 : return( GDrawPointsToPixels(g->base,1) + GDrawPointsToPixels(g->base,2) );
1147 : }
1148 :
1149 : /* Does not include the padding */
1150 0 : int GBoxDrawnWidth(GWindow gw, GBox *box) {
1151 0 : int scale = GDrawPointsToPixels(gw,1);
1152 0 : int bp = GDrawPointsToPixels(gw,box->border_width)+
1153 0 : ((box->flags & (box_foreground_border_outer|box_foreground_shadow_outer))?scale:0)+
1154 0 : ((box->flags &
1155 0 : (box_foreground_border_inner|box_active_border_inner))?scale:0);
1156 0 : return( bp );
1157 : }
1158 :
1159 0 : static void GBoxDrawTabBackground(GWindow pixmap, GRect *rect, int radius, Color color)
1160 : {
1161 0 : GRect older, r = *rect;
1162 :
1163 0 : GDrawPushClip(pixmap,rect,&older);
1164 0 : GDrawSetLineWidth(pixmap,1);
1165 0 : r.height*=2;
1166 0 : if (2*radius>=r.height) r.height=2*radius+1;
1167 0 : GDrawFillRoundRect(pixmap, &r, radius, color);
1168 0 : GDrawPopClip(pixmap,&older);
1169 0 : }
1170 :
1171 0 : void GBoxDrawTabOutline(GWindow pixmap, GGadget *g, int x, int y,
1172 : int width, int rowh, int active ) {
1173 : GRect r;
1174 0 : GBox *design = g->box;
1175 0 : int bp = GBoxBorderWidth(pixmap,design);
1176 0 : int dw = GBoxDrawnWidth(pixmap,design);
1177 0 : int rr = GDrawPointsToPixels(pixmap,design->rr_radius);
1178 0 : int scale = GDrawPointsToPixels(pixmap,1);
1179 0 : int bw = GDrawPointsToPixels(pixmap,design->border_width);
1180 0 : int inset = 0;
1181 0 : enum border_type bt = design->border_type;
1182 : Color cols[4];
1183 :
1184 0 : Color fg = g->state==gs_disabled?design->disabled_foreground:
1185 0 : design->main_foreground==COLOR_DEFAULT?GDrawGetDefaultForeground(GDrawGetDisplayOfWindow(pixmap)):
1186 : design->main_foreground;
1187 :
1188 0 : Color color_inner = design->border_inner == COLOR_DEFAULT ? fg : design->border_inner;
1189 0 : Color color_outer = design->border_outer == COLOR_DEFAULT ? fg : design->border_outer;
1190 :
1191 0 : Color gbg = GDrawGetDefaultBackground(GDrawGetDisplayOfWindow(pixmap));
1192 0 : Color mbg = design->main_background==COLOR_DEFAULT?gbg:design->main_background;
1193 0 : Color dbg = design->disabled_background==COLOR_DEFAULT?gbg:design->disabled_background;
1194 0 : Color pbg = design->depressed_background==COLOR_DEFAULT?gbg:design->depressed_background;
1195 : Color ibg;
1196 :
1197 0 : r.x = x; r.y = y; r.width = width; r.height = rowh;
1198 :
1199 0 : if ( rr==0 )
1200 0 : rr = GDrawPointsToPixels(pixmap,3);
1201 :
1202 0 : if ( !(scale&1)) --scale;
1203 0 : if ( scale==0 ) scale = 1;
1204 :
1205 0 : FigureBorderCols(design,cols);
1206 :
1207 0 : if ( active ) {
1208 0 : r.x -= bp; r.y -= bp; r.width += 2*bp; r.height += dw+bp;
1209 : }
1210 :
1211 0 : if ( g->state == gs_disabled ) {
1212 0 : ibg=dbg;
1213 0 : GDrawSetStippled(pixmap,1,0,0);
1214 0 : } else if ( !active && (design->flags & box_do_depressed_background ))
1215 0 : ibg=pbg;
1216 : else
1217 0 : ibg=mbg;
1218 :
1219 0 : GBoxDrawTabBackground(pixmap,&r,rr,ibg);
1220 0 : if ( g->state == gs_disabled )
1221 0 : GDrawSetStippled(pixmap,0,0,0);
1222 :
1223 0 : if ( design->flags & (box_foreground_border_outer|box_foreground_shadow_outer) ) {
1224 0 : GDrawSetLineWidth(pixmap,scale);
1225 0 : if ( design->flags&box_foreground_border_outer )
1226 0 : DrawRoundTab(pixmap,&r,scale/2,rr,color_outer,color_outer,color_outer,color_outer,active);
1227 : else
1228 0 : GDrawDrawLine(pixmap,r.x+r.width-1,r.y+rr,r.x+r.width-1,r.y+r.height-1,fg);
1229 0 : inset += scale;
1230 : }
1231 :
1232 0 : if ( bt==bt_double && bw<3 )
1233 0 : bt = bt_box;
1234 0 : if (( bt==bt_engraved || bt==bt_embossed ) && bw<2 )
1235 0 : bt = bt_box;
1236 :
1237 0 : if ( bw!=0 ) switch ( bt ) {
1238 : case bt_none:
1239 0 : break;
1240 : case bt_box: case bt_raised: case bt_lowered:
1241 0 : if ( !(bw&1) ) --bw;
1242 0 : GDrawSetLineWidth(pixmap,bw);
1243 0 : DrawRoundTab(pixmap,&r,inset+bw/2,rr,cols[0],cols[1],cols[2],cols[3],active);
1244 0 : break;
1245 : case bt_engraved: case bt_embossed:
1246 0 : bw &= ~1;
1247 0 : if ( !(bw&2 ) )
1248 0 : bw -= 2;
1249 0 : if ( bw<=0 )
1250 0 : bw = 2;
1251 0 : GDrawSetLineWidth(pixmap,bw/2);
1252 0 : DrawRoundTab(pixmap,&r,inset+bw/4,rr,cols[0],cols[1],cols[2],cols[3],active);
1253 0 : DrawRoundTab(pixmap,&r,inset+bw/2+bw/4,rr,cols[2],cols[3],cols[0],cols[1],active);
1254 0 : break;
1255 : case bt_double: {
1256 0 : int width = (bw+1)/3;
1257 0 : if ( !(width&1) ) {
1258 0 : if ( 2*(width+1) < bw )
1259 0 : ++width;
1260 : else
1261 0 : --width;
1262 : }
1263 0 : GDrawSetLineWidth(pixmap,width);
1264 0 : DrawRoundTab(pixmap,&r,inset+width/2,rr,cols[0],cols[1],cols[2],cols[3],active);
1265 0 : DrawRoundTab(pixmap,&r,inset+bw-(width+1)/2,rr,cols[0],cols[1],cols[2],cols[3],active);
1266 0 : } break;
1267 : }
1268 0 : inset += bw;
1269 :
1270 0 : if ( (design->flags & box_foreground_border_inner) ) {
1271 0 : GDrawSetLineWidth(pixmap,scale);
1272 0 : DrawRoundTab(pixmap,&r,inset+scale/2,rr,color_inner,color_inner,color_inner,color_inner,active);
1273 0 : inset += scale;
1274 : }
1275 0 : }
|